diff --git a/data/eu.polonkai.gergely.SsbGtk.desktop.in b/data/eu.polonkai.gergely.SsbGtk.desktop.in
new file mode 100644
index 0000000..b442698
--- /dev/null
+++ b/data/eu.polonkai.gergely.SsbGtk.desktop.in
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Name=SSB-GTK+
+Exec=ssb-gtk
+Terminal=false
+Type=Application
+Categories=GTK;
+StartupNotify=true
diff --git a/data/meson.build b/data/meson.build
new file mode 100644
index 0000000..f6ba0b1
--- /dev/null
+++ b/data/meson.build
@@ -0,0 +1,19 @@
+ssb_resources = gnome.compile_resources(
+ 'ssb-resources',
+ join_paths('resources', 'eu.polonkai.gergely.SsbGtk.gresource.xml'),
+ source_dir: 'resources',
+ c_name: 'ssb')
+
+desktop_file = i18n.merge_file(
+ input: 'eu.polonkai.gergely.SsbGtk.desktop.in',
+ output: 'eu.polonkai.gergely.SsbGtk.desktop',
+ type: 'desktop',
+ po_dir: '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications'))
+
+desktop_utils = find_program('desktop-file-validate', required: false)
+if desktop_utils.found()
+ test('Validate desktop file', desktop_utils,
+ args: [desktop_file])
+endif
diff --git a/data/resources/eu.polonkai.gergely.SsbGtk.gresource.xml b/data/resources/eu.polonkai.gergely.SsbGtk.gresource.xml
new file mode 100644
index 0000000..cf828b4
--- /dev/null
+++ b/data/resources/eu.polonkai.gergely.SsbGtk.gresource.xml
@@ -0,0 +1,6 @@
+
+
+
+ ui/ssb-window.ui
+
+
diff --git a/data/resources/ui/ssb-window.ui b/data/resources/ui/ssb-window.ui
new file mode 100644
index 0000000..c3323b0
--- /dev/null
+++ b/data/resources/ui/ssb-window.ui
@@ -0,0 +1,42 @@
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+
diff --git a/meson.build b/meson.build
index 5eef17d..2fc30ff 100644
--- a/meson.build
+++ b/meson.build
@@ -1,9 +1,13 @@
project('ssb-gtk', 'c', version: '0.0.1')
+gnome = import('gnome')
+i18n = import('i18n')
+
glib_required = '>= 2.40'
gtk_required = '>= 3.20'
glib = dependency('glib-2.0', version: glib_required)
gtk = dependency('gtk+-3.0', version: gtk_required)
+subdir('data')
subdir('ssb-gtk')
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644
index 0000000..e69de29
diff --git a/ssb-gtk/meson.build b/ssb-gtk/meson.build
index f86415f..2b41041 100644
--- a/ssb-gtk/meson.build
+++ b/ssb-gtk/meson.build
@@ -1,8 +1,10 @@
sources = [
'main.c',
'ssb-app.c',
+ 'ssb-window.c',
+ 'sbot.c',
]
-executable('ssb-gtk', sources,
+executable('ssb-gtk', sources, ssb_resources,
dependencies: [glib, gtk],
install: true)
diff --git a/ssb-gtk/sbot.c b/ssb-gtk/sbot.c
new file mode 100644
index 0000000..2ecdb11
--- /dev/null
+++ b/ssb-gtk/sbot.c
@@ -0,0 +1,22 @@
+#include
+
+gboolean do_scuttling = TRUE;
+
+gpointer
+scuttle(gchar *ssb_dir)
+{
+ gchar *config_file = g_strdup_printf("%s/config", ssb_dir);
+ g_print("Read config file %s\n", config_file);
+ g_free(config_file);
+
+ g_print("Starting scuttle\n");
+
+ while (do_scuttling) {
+ g_usleep(G_USEC_PER_SEC);
+ g_print("Scuttle…\n");
+ }
+
+ g_print("Scuttling stopped\n");
+
+ return NULL;
+}
diff --git a/ssb-gtk/sbot.h b/ssb-gtk/sbot.h
new file mode 100644
index 0000000..60acd2f
--- /dev/null
+++ b/ssb-gtk/sbot.h
@@ -0,0 +1,10 @@
+#ifndef __SBOT_H__
+# define __SBOT_H__
+
+# include
+
+extern gboolean do_scuttling;
+
+gpointer scuttle(gchar *ssb_dir);
+
+#endif /* __SBOT_H__ */
diff --git a/ssb-gtk/ssb-app.c b/ssb-gtk/ssb-app.c
index ecd7b67..06998c3 100644
--- a/ssb-gtk/ssb-app.c
+++ b/ssb-gtk/ssb-app.c
@@ -1,9 +1,13 @@
#include "ssb-app.h"
+#include "ssb-window.h"
+#include "sbot.h"
struct _SsbApp {
GtkApplication parent_instance;
gchar *ssb_dir;
+ SsbWindow *window;
+ GThread *scuttle_thread;
};
G_DEFINE_TYPE(SsbApp, ssb_app, GTK_TYPE_APPLICATION);
@@ -18,7 +22,7 @@ static GOptionEntry entries[] = {
{"socket", 'u', 0, G_OPTION_ARG_FILENAME, NULL, "Unix socket path to connect to instead of a TCP socket. Conflicts with -s and -p", "PATH"},
{"key", 'k', 0, G_OPTION_ARG_STRING, NULL, "The key to connect to. Default is your public key as read from the private key file", "KEY"},
{"keypair-seed", 'K', 0, G_OPTION_ARG_STRING, NULL, "Private key seed to use for the secret handshake. Default is to use the private key from your privace key file.", "SEED"},
- {"version", 'v', NULL, }
+ {"version", 'v', 0, G_OPTION_ARG_NONE, NULL, "Print version information and exit", NULL},
{NULL}
};
@@ -29,7 +33,7 @@ print_version(void) {
}
static int
-local_options(GApplication *app, GVriantDict *options, gpointer user_data)
+local_options(GApplication *app, GVariantDict *options, gpointer user_data)
{
gboolean version = FALSE;
@@ -64,27 +68,58 @@ ssb_app_finalize(GObject *gobject)
SsbApp *app = SSB_APP(gobject);
app->ssb_dir = (g_free(app->ssb_dir), NULL);
+
+ G_OBJECT_CLASS(ssb_app_parent_class)->finalize(gobject);
}
static void
-ssb_app_startup(GApplication *app)
+ssb_app_dispose(GObject *gobject)
{
- G_APPLICATION_CLASS(ssb_app_parent_class)->startup(app);
- g_print("Starting up!\n");
+ SsbApp *app = SSB_APP(gobject);
+
+ g_clear_object(&(app->window));
+ G_OBJECT_CLASS(ssb_app_parent_class)->dispose(gobject);
+}
+
+static void
+ssb_app_startup(GApplication *gapp)
+{
+ SsbApp *app = SSB_APP(gapp);
+
+ G_APPLICATION_CLASS(ssb_app_parent_class)->startup(gapp);
+
+ if (app->scuttle_thread == NULL) {
+ app->scuttle_thread = g_thread_new("scuttler", (GThreadFunc)scuttle, app->ssb_dir);
+ }
+}
+
+static SsbWindow *
+ssb_app_get_or_create_window(SsbApp *app)
+{
+ SsbWindow *window = ssb_window_new(app);
+
+ return window;
}
static void
ssb_app_activate(GApplication *app)
{
G_APPLICATION_CLASS(ssb_app_parent_class)->activate(app);
- g_print("Activate!\n");
+
+ SsbWindow *window = ssb_app_get_or_create_window(SSB_APP(app));
+ gtk_window_present(GTK_WINDOW(window));
}
static void
-ssb_app_shutdown(GApplication *app)
+ssb_app_shutdown(GApplication *gapp)
{
- g_print("Shutting down…\n");
- G_APPLICATION_CLASS(ssb_app_parent_class)->shutdown(app);
+ SsbApp *app = SSB_APP(gapp);
+
+ do_scuttling = FALSE;
+
+ (void)g_thread_join(app->scuttle_thread);
+
+ G_APPLICATION_CLASS(ssb_app_parent_class)->shutdown(gapp);
}
static void
@@ -94,6 +129,8 @@ ssb_app_init(SsbApp *app)
const gchar *app_dir_path = g_environ_getenv(envp, "ssb_path");
app->ssb_dir = NULL;
+ app->window = NULL;
+ app->scuttle_thread = NULL;
if (app_dir_path != NULL) {
app->ssb_dir = g_strdup(app_dir_path);
@@ -124,6 +161,7 @@ ssb_app_class_init(SsbAppClass *klass)
GApplicationClass *app_class = G_APPLICATION_CLASS(klass);
gobject_class->finalize = ssb_app_finalize;
+ gobject_class->dispose = ssb_app_dispose;
app_class->activate = ssb_app_activate;
app_class->startup = ssb_app_startup;
app_class->shutdown = ssb_app_shutdown;
diff --git a/ssb-gtk/ssb-window.c b/ssb-gtk/ssb-window.c
new file mode 100644
index 0000000..96c4488
--- /dev/null
+++ b/ssb-gtk/ssb-window.c
@@ -0,0 +1,32 @@
+#include "ssb-window.h"\
+
+struct _SsbWindow {
+ GtkApplicationWindow parent_instance;
+};
+
+G_DEFINE_TYPE(SsbWindow, ssb_window, GTK_TYPE_APPLICATION_WINDOW);
+
+SsbWindow *
+ssb_window_new(SsbApp *app)
+{
+ SsbWindow *window = g_object_new(SSB_TYPE_WINDOW, NULL);
+
+ gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
+ gtk_window_set_icon_name(GTK_WINDOW(window), "ssb-gtk");
+
+ return window;
+}
+
+static void
+ssb_window_init(SsbWindow *window)
+{
+ gtk_widget_init_template(GTK_WIDGET(window));
+}
+
+static void
+ssb_window_class_init(SsbWindowClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+ gtk_widget_class_set_template_from_resource(widget_class, "/eu/polonkai/gergely/SsbGtk/ui/ssb-window.ui");
+}
diff --git a/ssb-gtk/ssb-window.h b/ssb-gtk/ssb-window.h
new file mode 100644
index 0000000..22d2b60
--- /dev/null
+++ b/ssb-gtk/ssb-window.h
@@ -0,0 +1,19 @@
+#ifndef __SSB_WINDOW_H__
+# define __SSB_WINDOW_H__
+
+# include
+# include
+
+# include "ssb-app.h"
+
+#define SSB_TYPE_WINDOW ssb_window_get_type()
+G_DECLARE_FINAL_TYPE(SsbWindow, ssb_window, SSB, WINDOW, GtkApplicationWindow)
+
+G_BEGIN_DECLS
+
+SsbWindow *ssb_window_new(SsbApp *app);
+
+G_END_DECLS
+
+
+#endif /* __SSB_WINDOW_H__ */