From 9b4e4f7b6457c05dc35b4885290a03ef090844aa Mon Sep 17 00:00:00 2001 From: MrMelon Date: Sat, 24 Apr 2021 11:19:26 +0100 Subject: [PATCH] Add gui binary --- src/impl/gui/main.c | 134 ++++++++++++++++++++++++++++++++++++++ src/impl/gui/statusicon.c | 89 +++++++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 src/impl/gui/main.c create mode 100644 src/impl/gui/statusicon.c diff --git a/src/impl/gui/main.c b/src/impl/gui/main.c new file mode 100644 index 0000000..094deca --- /dev/null +++ b/src/impl/gui/main.c @@ -0,0 +1,134 @@ +#include +#include +#include + +#include "states.h" +#include "statusicon.h" +#include "magic_code.h" + +GtkApplication *app; +GdkPixbuf *appicon; +char *statusiconoff; +char *statusiconon; +States currentstate; + +void update_state(States state) { + currentstate = state; + if(currentstate == CONNECTED) { + status_icon_set_state(APP_INDICATOR_STATUS_ATTENTION); + } else if(currentstate == DISCONNECTED) { + status_icon_set_state(APP_INDICATOR_STATUS_PASSIVE); + } else { + status_icon_set_state(APP_INDICATOR_STATUS_ACTIVE); + } +} + +void open_about(GtkApplication* app) { + GtkWidget *about = gtk_about_dialog_new(); + gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),"Melon VPN"); + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),"v1.0.0"); + gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),"Copyright OnPointCoding"); + gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(about),GTK_LICENSE_UNKNOWN); + gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),"https://software.onpointcoding.net"); + gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),"OnPointCoding.net"); + gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),appicon); + + const char *authors[2] = {"MrMelon54",NULL}; + gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),authors); + + const char *artists[2] = {"MrMelon54",NULL}; + gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about),artists); + + gtk_widget_show_all(about); +} + +void open_paint_btn(GtkButton *button) { + update_state((currentstate + 1) % 3); +} + +void open_about_btn(GtkButton *button) { + open_about(app); +} + +void activate(GtkApplication* app) { + GtkWidget *window; + GtkWidget *box; + GtkWidget *button; + GtkWidget *button2; + + window = gtk_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(window),"Melon VPN"); + gtk_window_set_default_size(GTK_WINDOW(window),400,400); + + // Setup status icon now window is available + status_icon_create(window,statusiconoff,statusiconon); + status_icon_set_state(APP_INDICATOR_STATUS_PASSIVE); + + gtk_container_set_border_width(GTK_CONTAINER(window),8); + + button = gtk_button_new_with_label("Start"); + g_signal_connect(button,"clicked",G_CALLBACK(open_paint_btn),NULL); + + button2 = gtk_button_new_with_label("About"); + g_signal_connect(button2,"clicked",G_CALLBACK(open_about_btn),NULL); + + box = gtk_fixed_new(); + + gtk_container_add(GTK_CONTAINER(window),box); + gtk_fixed_put(GTK_FIXED(box),button,5,5); + gtk_fixed_put(GTK_FIXED(box),button2,100,60); + + gtk_widget_show_all(window); +} + +void get_magic_code(int *a, int *b) { + *a = MAGIC_CODE_A; + *b = MAGIC_CODE_B; +} + +int run_gui(int argc, char **argv) { + int status; + + statusiconoff = ""; + statusiconon = ""; + + if(access("melonvpn.png",R_OK) == 0) { + appicon = gdk_pixbuf_new_from_file("melonvpn.png",NULL); + } else if(access("/usr/lib/melonvpn/melonvpn.png",R_OK) == 0) { + appicon = gdk_pixbuf_new_from_file("/usr/lib/melonvpn/melonvpn.png",NULL); + } + + if(access("/usr/lib/melonvpn/statusmelonoff.png",R_OK) == 0) { + statusiconoff = "/usr/lib/melonvpn/statusmelonoff.png"; + } else { + fprintf(stderr,"WARN: Unable to find statusmelonoff.png\n"); + } + + if(access("/usr/lib/melonvpn/statusmelonon.png",R_OK) == 0) { + statusiconon = "/usr/lib/melonvpn/statusmelonon.png"; + } else { + fprintf(stderr,"WARN: Unable to find statusmelonon.png\n"); + } + + if(appicon == NULL) { + fprintf(stderr,"ERROR: Failed to load program logo\n"); + return 1; + } + if(statusiconoff == NULL) { + fprintf(stderr,"ERROR: Failed to load status off icon\n"); + return 1; + } + if(statusiconon == NULL) { + fprintf(stderr,"ERROR: Failed to load status on icon\n"); + return 1; + } + + currentstate = DISCONNECTED; + + app = gtk_application_new("net.onpointcoding.melonvpn",G_APPLICATION_FLAGS_NONE); + g_signal_connect(app,"activate",G_CALLBACK(activate),NULL); + status = g_application_run(G_APPLICATION(app),argc,argv); + g_object_unref(app); + + return status; +} diff --git a/src/impl/gui/statusicon.c b/src/impl/gui/statusicon.c new file mode 100644 index 0000000..61a2aec --- /dev/null +++ b/src/impl/gui/statusicon.c @@ -0,0 +1,89 @@ +#include +#include +#include "states.h" +#include "statusicon.h" + +GtkWidget *mainwindow; +AppIndicator *indicator; +States status_icon_currentstate; + +static void activate_action (GtkAction *action); + +static GtkActionEntry entries[] = { + {"FileMenu",NULL,"_File"}, + {"New","document-new","_New","N","Create a new file",G_CALLBACK(activate_action)}, + {"Open","document-open","_Open","O","Open a file",G_CALLBACK(activate_action)}, + {"Save","document-save","_Save","S","Save file",G_CALLBACK(activate_action)}, + {"Close","window-close","_Close","W","Close the window",G_CALLBACK(activate_action)}, + {"Quit","application-exit","_Quit","Q","Exit the application",G_CALLBACK(activate_action)}, +}; +static guint n_entries = G_N_ELEMENTS (entries); + +static const gchar *ui_info = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static void activate_action(GtkAction *action) { + const gchar *name = gtk_action_get_name(action); + if(strcmp(name,"Quit") == 0 || strcmp(name,"Close") == 0) { + if(mainwindow != NULL) { + gtk_window_close(GTK_WINDOW(mainwindow)); + return; + } + } + GtkWidget *dialog; + dialog = gtk_message_dialog_new(NULL,GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_INFO,GTK_BUTTONS_CLOSE,"You activated action: \"%s\"",name); + g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL); + gtk_widget_show(dialog); +} + +void status_icon_create(GtkWidget *window, char *statusoff, char *statuson) { + if(indicator == NULL) { + mainwindow = window; + GtkUIManager *uim; + GError *error = NULL; + GtkWidget *indicator_menu; + GtkActionGroup *action_group; + + action_group = gtk_action_group_new("AppActions"); + gtk_action_group_add_actions(action_group,entries,n_entries,window); + + uim = gtk_ui_manager_new(); + g_object_set_data_full(G_OBJECT(window),"ui-manager",uim,g_object_unref); + gtk_ui_manager_insert_action_group(uim,action_group,0); + gtk_window_add_accel_group(GTK_WINDOW(window),gtk_ui_manager_get_accel_group(uim)); + + if (!gtk_ui_manager_add_ui_from_string(uim,ui_info,-1,&error)) { + g_message("Failed to build menus: %s\n",error->message); + g_error_free(error); + error = NULL; + } + + indicator = app_indicator_new("melonvpn",statusoff,APP_INDICATOR_CATEGORY_APPLICATION_STATUS); + indicator_menu = gtk_ui_manager_get_widget(uim,"/ui/IndicatorPopup"); + app_indicator_set_status(indicator,APP_INDICATOR_STATUS_PASSIVE); + app_indicator_set_attention_icon(indicator,statuson); + app_indicator_set_menu(indicator,GTK_MENU(indicator_menu)); + } +} + +void status_icon_set_state(AppIndicatorStatus status) { + app_indicator_set_status(APP_INDICATOR(indicator),status); +}