commit ee55ecb8712955fc1d982b3a271c909896eb0631
parent 7e0a36c3954f7a054a3a7acab1cdfb239a466917
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Sat, 30 Oct 2021 21:13:51 +0200
Separated gtk, gnunet and events using both
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
12 files changed, 452 insertions(+), 157 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,6 +4,8 @@ INSTALL_DIR ?= /usr/local/
BINARY = messenger-gtk
SOURCES = messenger_gtk.c\
+ application.c\
+ event.c\
chat/messenger.c\
ui/messenger.c
diff --git a/resources/ui/messenger.ui b/resources/ui/messenger.ui
@@ -31,6 +31,7 @@ Author: Tobias Frisch
<property name="can-focus">False</property>
<property name="hhomogeneous-folded">False</property>
<property name="vhomogeneous-folded">False</property>
+ <property name="can-swipe-back">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
diff --git a/src/application.c b/src/application.c
@@ -0,0 +1,147 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file application.c
+ */
+
+#include "application.h"
+
+static void
+_load_ui_stylesheets(void)
+{
+ GdkScreen* screen = gdk_screen_get_default();
+ GtkCssProvider* provider = gtk_css_provider_new();
+ gtk_css_provider_load_from_path(
+ provider,
+ "resources/css/style.css",
+ NULL
+ );
+
+ gtk_style_context_add_provider_for_screen(
+ screen,
+ GTK_STYLE_PROVIDER(provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
+ );
+}
+
+void
+application_init(MESSENGER_Application *app,
+ int argc,
+ char **argv)
+{
+ app->argc = argc;
+ app->argv = argv;
+
+ gtk_init(&argc, &argv);
+
+ _load_ui_stylesheets();
+
+ app->chat.status = EXIT_FAILURE;
+ app->chat.tid = 0;
+ app->chat.signal = MESSENGER_NONE;
+
+ ui_messenger_init(app, &(app->ui.messenger));
+}
+
+static void*
+_application_chat_thread(void *args)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) args;
+
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ app->chat.status = (GNUNET_PROGRAM_run(
+ app->argc,
+ app->argv,
+ "messenger-gtk",
+ gettext_noop("A GTK based GUI for the Messenger service of GNUnet."),
+ options,
+ &chat_messenger_run,
+ app
+ ) == GNUNET_OK? EXIT_SUCCESS : EXIT_FAILURE);
+
+ return NULL;
+}
+
+void
+application_start(MESSENGER_Application *app)
+{
+ pthread_create(&(app->chat.tid), NULL, _application_chat_thread, app);
+
+ gtk_main();
+
+ pthread_join(app->chat.tid, NULL);
+}
+
+typedef struct MESSENGER_ApplicationEventCall
+{
+ MESSENGER_Application *app;
+ MESSENGER_ApplicationEvent event;
+} MESSENGER_ApplicationEventCall;
+
+static gboolean
+_application_event_call(gpointer user_data)
+{
+ //printf("_application_event_call\n");
+
+ MESSENGER_ApplicationEventCall *call;
+
+ call = (MESSENGER_ApplicationEventCall*) user_data;
+ call->event(call->app);
+
+ GNUNET_free(call);
+ return FALSE;
+}
+
+void
+application_call_event(MESSENGER_Application *app,
+ MESSENGER_ApplicationEvent event)
+{
+ //printf("application_call_event\n");
+
+ MESSENGER_ApplicationEventCall *call;
+
+ call = (MESSENGER_ApplicationEventCall*) GNUNET_malloc(
+ sizeof(MESSENGER_ApplicationEventCall)
+ );
+
+ call->app = app;
+ call->event = event;
+
+ g_idle_add(_application_event_call, call);
+}
+
+void
+application_exit(MESSENGER_Application *app,
+ MESSENGER_ApplicationSignal signal)
+{
+ app->chat.signal = signal;
+
+ gtk_main_quit();
+}
+
+int
+application_status(MESSENGER_Application *app)
+{
+ return app->chat.status;
+}
diff --git a/src/application.h b/src/application.h
@@ -0,0 +1,83 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file application.h
+ */
+
+#ifndef APPLICATION_H_
+#define APPLICATION_H_
+
+#include <pthread.h>
+
+#include "chat/messenger.h"
+
+#include "ui/messenger.h"
+
+#include "util.h"
+
+typedef enum MESSENGER_ApplicationSignal
+{
+ MESSENGER_NONE = 0,
+ MESSENGER_QUIT = 1,
+ MESSENGER_FAIL = 2
+} MESSENGER_ApplicationSignal;
+
+typedef struct MESSENGER_Application
+{
+ char** argv;
+ int argc;
+
+ struct {
+ int status;
+ pthread_t tid;
+
+ MESSENGER_ApplicationSignal signal;
+
+ CHAT_MESSENGER_Handle messenger;
+ } chat;
+
+ struct {
+ UI_MESSENGER_Handle messenger;
+ } ui;
+} MESSENGER_Application;
+
+void
+application_init(MESSENGER_Application *app,
+ int argc,
+ char **argv);
+
+void
+application_start(MESSENGER_Application *app);
+
+typedef void (*MESSENGER_ApplicationEvent) (MESSENGER_Application *app);
+
+void
+application_call_event(MESSENGER_Application *app,
+ MESSENGER_ApplicationEvent event);
+
+void
+application_exit(MESSENGER_Application *app,
+ MESSENGER_ApplicationSignal signal);
+
+int
+application_status(MESSENGER_Application *app);
+
+#endif /* APPLICATION_H_ */
diff --git a/src/chat/messenger.c b/src/chat/messenger.c
@@ -24,4 +24,65 @@
#include "messenger.h"
+#include "../event.h"
+static void
+_chat_messenger_idle(void *cls)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) cls;
+
+ if (MESSENGER_NONE == app->chat.signal)
+ {
+ app->chat.messenger.idle = GNUNET_SCHEDULER_add_delayed_with_priority(
+ GNUNET_TIME_relative_get_second_(),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ &_chat_messenger_idle,
+ app
+ );
+
+ return;
+ }
+
+ GNUNET_CHAT_stop(app->chat.messenger.handle);
+ app->chat.messenger.handle = NULL;
+
+ if (MESSENGER_QUIT != app->chat.signal)
+ GNUNET_SCHEDULER_shutdown();
+}
+
+static int
+_chat_messenger_message(void *cls,
+ UNUSED struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Message *message)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) cls;
+
+ if (GNUNET_CHAT_KIND_LOGIN == GNUNET_CHAT_message_get_kind(message))
+ application_call_event(app, event_update_profile);
+
+ return GNUNET_YES;
+}
+
+void
+chat_messenger_run(void *cls,
+ UNUSED char *const *args,
+ UNUSED const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) cls;
+
+ app->chat.messenger.handle = GNUNET_CHAT_start(
+ cfg,
+ "messenger-gtk",
+ "test",
+ &_chat_messenger_message,
+ app
+ );
+
+ app->chat.messenger.idle = GNUNET_SCHEDULER_add_delayed_with_priority(
+ GNUNET_TIME_relative_get_zero_(),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ &_chat_messenger_idle,
+ app
+ );
+}
diff --git a/src/chat/messenger.h b/src/chat/messenger.h
@@ -30,10 +30,18 @@
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_program_lib.h>
-struct CHAT_MESSENGER_Handle
+typedef struct MESSENGER_Application MESSENGER_Application;
+
+typedef struct CHAT_MESSENGER_Handle
{
struct GNUNET_CHAT_Handle *handle;
struct GNUNET_SCHEDULER_Task *idle;
-};
+} CHAT_MESSENGER_Handle;
+
+void
+chat_messenger_run(void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg);
#endif /* CHAT_MESSENGER_H_ */
diff --git a/src/event.c b/src/event.c
@@ -0,0 +1,41 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file event.c
+ */
+
+#include "event.h"
+
+void
+event_update_profile(MESSENGER_Application *app)
+{
+ //printf("event_update_profile\n");
+
+ const char *name = GNUNET_CHAT_get_name(app->chat.messenger.handle);
+
+ //printf("A: %s\n", name);
+
+ if (name)
+ {
+ hdy_avatar_set_text(app->ui.messenger.profile_avatar, name);
+ gtk_label_set_text(app->ui.messenger.profile_label, name);
+ }
+}
diff --git a/src/event.h b/src/event.h
@@ -0,0 +1,33 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file event.h
+ */
+
+#ifndef EVENT_H_
+#define EVENT_H_
+
+#include "application.h"
+
+void
+event_update_profile(MESSENGER_Application *app);
+
+#endif /* EVENT_H_ */
diff --git a/src/messenger_gtk.c b/src/messenger_gtk.c
@@ -22,148 +22,13 @@
* @file messenger_gtk.c
*/
-#include "chat/messenger.h"
-#include "ui/messenger.h"
-
-#include <pthread.h>
-
-#define UNUSED __attribute__((unused))
-
-struct main_program
-{
- int argc;
- char** argv;
-
- bool exit;
-
- struct CHAT_MESSENGER_Handle chat;
- struct UI_MESSENGER_Handle ui;
-};
-
-gboolean gtk_set_profile_name(gpointer user_data)
-{
- struct main_program *program = (struct main_program*) user_data;
-
- const char *name = GNUNET_CHAT_get_name(program->chat.handle);
-
- if (name)
- {
- hdy_avatar_set_text(program->ui.profile_avatar, name);
- gtk_label_set_text(program->ui.profile_label, name);
- }
-
- return FALSE;
-}
-
-int gnunet_chat_message(void *cls,
- UNUSED struct GNUNET_CHAT_Context *context,
- const struct GNUNET_CHAT_Message *message)
-{
- struct main_program *program = (struct main_program*) cls;
-
- if (GNUNET_CHAT_KIND_LOGIN == GNUNET_CHAT_message_get_kind(message))
- g_idle_add(gtk_set_profile_name, program);
-
- return GNUNET_YES;
-}
-
-void gnunet_idle(void *cls)
-{
- struct main_program *program = (struct main_program*) cls;
-
- if (program->exit)
- {
- GNUNET_CHAT_stop(program->chat.handle);
- program->chat.handle = NULL;
-
- GNUNET_SCHEDULER_shutdown();
- return;
- }
-
- program->chat.idle = GNUNET_SCHEDULER_add_delayed_with_priority(
- GNUNET_TIME_relative_get_second_(),
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- gnunet_idle,
- program
- );
-}
-
-void gnunet_task(void *cls,
- UNUSED char *const *args,
- UNUSED const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct main_program *program = (struct main_program*) cls;
-
- program->chat.handle = GNUNET_CHAT_start(
- cfg,
- "messenger-gtk",
- "test",
- &gnunet_chat_message,
- program
- );
-
- program->chat.idle = GNUNET_SCHEDULER_add_delayed_with_priority(
- GNUNET_TIME_relative_get_zero_(),
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- gnunet_idle,
- program
- );
-}
-
-void *gnunet_thread(void *args)
-{
- struct main_program *program = (struct main_program*) args;
-
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- GNUNET_PROGRAM_run(
- program->argc,
- program->argv,
- "messenger-gtk",
- gettext_noop("A GTK based GUI for the Messenger service of GNUnet."),
- options,
- &gnunet_task,
- program
- );
-
- return NULL;
-}
+#include "application.h"
int main(int argc, char **argv) {
- struct main_program program;
- program.argc = argc;
- program.argv = argv;
-
- program.exit = FALSE;
-
- pthread_t gnunet_tid;
- gtk_init(&argc, &argv);
-
- GdkScreen* screen = gdk_screen_get_default();
- GtkCssProvider* provider = gtk_css_provider_new();
- gtk_css_provider_load_from_path(
- provider,
- "resources/css/style.css",
- NULL
- );
-
- gtk_style_context_add_provider_for_screen(
- screen,
- GTK_STYLE_PROVIDER(provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
- );
-
- ui_messenger_init(&(program.ui));
-
- pthread_create(&gnunet_tid, NULL, gnunet_thread, &program);
-
- gtk_main();
+ MESSENGER_Application app;
- program.exit = TRUE;
+ application_init(&app, argc, argv);
+ application_start(&app);
- pthread_join(gnunet_tid, NULL);
- return 0;
+ return application_status(&app);
}
diff --git a/src/ui/messenger.c b/src/ui/messenger.c
@@ -24,8 +24,11 @@
#include "messenger.h"
-void handle_flap_via_button_click(UI_UNUSED GtkButton* button,
- gpointer user_data)
+#include "../application.h"
+
+static void
+handle_flap_via_button_click(UNUSED GtkButton* button,
+ gpointer user_data)
{
HdyFlap* flap = HDY_FLAP(user_data);
@@ -36,8 +39,9 @@ void handle_flap_via_button_click(UI_UNUSED GtkButton* button,
}
}
-void handle_account_details_button_click(UI_UNUSED GtkButton* button,
- gpointer user_data)
+static void
+handle_account_details_button_click(UNUSED GtkButton* button,
+ gpointer user_data)
{
GtkRevealer* revealer = GTK_REVEALER(user_data);
@@ -48,9 +52,10 @@ void handle_account_details_button_click(UI_UNUSED GtkButton* button,
}
}
-void handle_chats_listbox_row_activated(UI_UNUSED GtkListBox* listbox,
- UI_UNUSED GtkListBoxRow* row,
- gpointer user_data)
+static void
+handle_chats_listbox_row_activated(UNUSED GtkListBox* listbox,
+ UNUSED GtkListBoxRow* row,
+ gpointer user_data)
{
HdyLeaflet* leaflet = HDY_LEAFLET(user_data);
@@ -61,8 +66,9 @@ void handle_chats_listbox_row_activated(UI_UNUSED GtkListBox* listbox,
}
}
-void handle_back_button_click(UI_UNUSED GtkButton* button,
- gpointer user_data)
+static void
+handle_back_button_click(UNUSED GtkButton* button,
+ gpointer user_data)
{
HdyLeaflet* leaflet = HDY_LEAFLET(user_data);
@@ -73,8 +79,17 @@ void handle_back_button_click(UI_UNUSED GtkButton* button,
}
}
+static void
+handle_main_window_destroy(gpointer user_data)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) user_data;
+
+ application_exit(app, MESSENGER_QUIT);
+}
+
void
-ui_messenger_init(struct UI_MESSENGER_Handle *handle)
+ui_messenger_init(MESSENGER_Application *app,
+ UI_MESSENGER_Handle *handle)
{
GtkBuilder* builder = gtk_builder_new();
gtk_builder_add_from_file(
@@ -220,5 +235,10 @@ ui_messenger_init(struct UI_MESSENGER_Handle *handle)
gtk_widget_show(GTK_WIDGET(handle->main_window));
- g_signal_connect(handle->main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
+ g_signal_connect(
+ handle->main_window,
+ "destroy",
+ G_CALLBACK(handle_main_window_destroy),
+ app
+ );
}
diff --git a/src/ui/messenger.h b/src/ui/messenger.h
@@ -28,9 +28,9 @@
#include <gtk-3.0/gtk/gtk.h>
#include <libhandy-1/handy.h>
-#define UI_UNUSED __attribute__((unused))
+typedef struct MESSENGER_Application MESSENGER_Application;
-struct UI_MESSENGER_Handle
+typedef struct UI_MESSENGER_Handle
{
GtkApplicationWindow *main_window;
@@ -67,9 +67,13 @@ struct UI_MESSENGER_Handle
GtkButton *chat_details_button;
GtkButton *hide_chat_details_button;
-};
+} UI_MESSENGER_Handle;
void
-ui_messenger_init(struct UI_MESSENGER_Handle *handle);
+ui_messenger_init(MESSENGER_Application *app,
+ UI_MESSENGER_Handle *handle);
+
+void
+ui_messenger_update_profile(MESSENGER_Application *app);
#endif /* UI_MESSENGER_H_ */
diff --git a/src/util.h b/src/util.h
@@ -0,0 +1,30 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file util.h
+ */
+
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#define UNUSED __attribute__((unused))
+
+#endif /* UTIL_H_ */