anastasis-gtk.c (6884B)
1 /* 2 This file is part of anastasis-gtk. 3 Copyright (C) 2020, 2021, 2022 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 Anastasis is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with Anastasis; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21 /** 22 * @file src/anastasis/anastasis-gtk.c 23 * @brief Main function of anastasis-gtk 24 * @author Christian Grothoff 25 * @author Dennis Neufeld 26 */ 27 #include <gnunet/gnunet_util_lib.h> 28 #include "anastasis_gtk_util.h" 29 #include "anastasis-gtk_action.h" 30 #include "anastasis-gtk_helper.h" 31 #include <jansson.h> 32 33 /** 34 * Handle to our main loop. 35 */ 36 struct ANASTASIS_GTK_MainLoop *AG_ml; 37 38 /** 39 * Active policy discovery job, or NULL. 40 */ 41 struct ANASTASIS_PolicyDiscovery *AG_pd; 42 43 /** 44 * Our configuration. 45 */ 46 const struct GNUNET_CONFIGURATION_Handle *AG_cfg; 47 48 /** 49 * Application ID to include in the user attributes. 50 * (-a option). 51 */ 52 char *AG_application_id; 53 54 /** 55 * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). 56 */ 57 static struct GNUNET_CURL_RescheduleContext *rc; 58 59 /** 60 * Hash map from UUID hashes to GtkWidgets. 61 */ 62 struct GNUNET_CONTAINER_MultiHashMap *AG_entry_attributes; 63 64 /** 65 * Curl context for communication with taler backend 66 */ 67 struct GNUNET_CURL_Context *AG_ctx; 68 69 /** 70 * Handle to an ongoing action. 71 */ 72 struct ANASTASIS_ReduxAction *AG_ra; 73 74 /** 75 * Handle to an ongoing background action. 76 */ 77 struct ANASTASIS_LongAction AG_lacs[ANASTASIS_LP_CNT]; 78 79 80 /** 81 * Actual state. 82 */ 83 json_t *AG_redux_state; 84 85 86 void 87 AG_stop_long_action (void) 88 { 89 for (enum ANASTASIS_LongActionKind i = 0; 90 i < ANASTASIS_LP_CNT; 91 i++) 92 { 93 struct ANASTASIS_LongAction *la = &AG_lacs[i]; 94 95 if (NULL != la->ra) 96 { 97 ANASTASIS_redux_action_cancel (la->ra); 98 la->ra = NULL; 99 } 100 if (NULL != la->task) 101 { 102 GNUNET_SCHEDULER_cancel (la->task); 103 la->task = NULL; 104 } 105 } 106 } 107 108 109 /** 110 * Task run on shutdown. 111 * 112 * @param cls unused 113 */ 114 static void 115 shutdown_task (void *cls) 116 { 117 (void) cls; 118 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 119 "Shutdown initiated\n"); 120 if (NULL != AG_pd) 121 { 122 ANASTASIS_policy_discovery_stop (AG_pd); 123 AG_pd = NULL; 124 } 125 ANASTASIS_redux_done (); 126 if (NULL != AG_ra) 127 { 128 ANASTASIS_redux_action_cancel (AG_ra); 129 AG_ra = NULL; 130 } 131 AG_stop_long_action (); 132 if (NULL != AG_ctx) 133 { 134 GNUNET_CURL_fini (AG_ctx); 135 AG_ctx = NULL; 136 } 137 if (NULL != rc) 138 { 139 GNUNET_CURL_gnunet_rc_destroy (rc); 140 rc = NULL; 141 } 142 ANASTASIS_GTK_main_loop_quit (AG_ml); 143 AG_ml = NULL; 144 GNUNET_CONTAINER_multihashmap_destroy (AG_entry_attributes); 145 AG_entry_attributes = NULL; 146 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 147 "Shutdown complete\n"); 148 } 149 150 151 /** 152 * Callback invoked if the application is supposed to exit. 153 * 154 * @param object 155 * @param user_data unused 156 */ 157 void 158 anastasis_gtk_quit_cb (GObject *object, 159 gpointer user_data) 160 { 161 GNUNET_SCHEDULER_shutdown (); 162 } 163 164 165 /** 166 * User clicked the "quit" button. 167 * 168 * @param button the button 169 * @param user_data unused 170 */ 171 void 172 anastasis_gtk_main_window_quit_button_clicked_cb (GtkButton *button, 173 gpointer user_data) 174 { 175 GNUNET_SCHEDULER_shutdown (); 176 } 177 178 179 void 180 AG_load (const char *filename) 181 { 182 json_error_t error; 183 json_t *in; 184 185 in = json_load_file (filename, 186 JSON_REJECT_DUPLICATES, 187 &error); 188 if (NULL == in) 189 { 190 AG_error ("Failed to parse file `%s' at %d:%d: %s\n", 191 filename, 192 error.line, 193 error.column, 194 error.text); 195 return; 196 } 197 AG_action_cb (NULL, 198 TALER_EC_NONE, 199 in); 200 json_decref (in); 201 } 202 203 204 /** 205 * Actual main function run right after GNUnet's scheduler 206 * is initialized. Initializes up GTK and Glade. 207 * 208 * @param cls NULL 209 */ 210 static void 211 run (void *cls) 212 { 213 GtkWidget *main_window; 214 int argc; 215 char *const *argv; 216 217 AG_ml = cls; 218 AG_entry_attributes = GNUNET_CONTAINER_multihashmap_create (16, 219 GNUNET_NO); 220 ANASTASIS_GTK_setup_nls (); 221 if (GNUNET_OK != 222 ANASTASIS_GTK_main_loop_build_window (ANASTASIS_GTK_project_data (), 223 AG_ml, 224 NULL)) 225 return; 226 AG_cfg = ANASTASIS_GTK_main_loop_get_gtk_configuration (AG_ml); 227 ANASTASIS_GTK_main_loop_get_args (AG_ml, 228 &argc, 229 &argv); 230 /* setup main window */ 231 main_window = GTK_WIDGET ( 232 GCG_get_main_window_object ("anastasis_gtk_main_window")); 233 gtk_window_maximize (GTK_WINDOW (main_window)); 234 AG_insensitive ("anastasis_gtk_main_window_forward_button"); 235 /* make GUI visible */ 236 gtk_widget_show (main_window); 237 gtk_window_present (GTK_WINDOW (main_window)); 238 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 239 NULL); 240 /* initialize HTTP client */ 241 AG_ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, 242 &rc); 243 rc = GNUNET_CURL_gnunet_rc_create (AG_ctx); 244 ANASTASIS_redux_init (AG_ctx); 245 if (0 != argc) 246 AG_load (argv[0]); 247 } 248 249 250 /** 251 * Main function of anastasis-gtk. 252 * 253 * @param argc number of arguments 254 * @param argv arguments 255 * @return 0 on success 256 */ 257 int 258 main (int argc, 259 char *const *argv) 260 { 261 struct GNUNET_GETOPT_CommandLineOption options[] = { 262 GNUNET_GETOPT_option_string ('A', 263 "application", 264 "ID", 265 "set the application ID", 266 &AG_application_id), 267 GNUNET_GETOPT_OPTION_END 268 }; 269 int ret; 270 271 AG_application_id = GNUNET_strdup ("anastasis-standalone"); 272 if (GNUNET_OK != 273 ANASTASIS_GTK_main_loop_start (ANASTASIS_GTK_project_data (), 274 "anastasis-gtk", 275 "GTK GUI for Anastasis", 276 argc, 277 argv, 278 options, 279 "anastasis_gtk_main_window.glade", 280 &run)) 281 ret = 1; 282 else 283 ret = 0; 284 GNUNET_free (AG_application_id); 285 return ret; 286 } 287 288 289 /* end of anastasis-gtk.c */