/* This file is part of GNUnet. (C) 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, 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 General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file src/gns/gnunet-gns-gtk.c * @brief Main function of gnunet-gns-gtk * @author Christian Grothoff */ #include "gnunet_gtk.h" #include /** * Handle to our main loop. */ static struct GNUNET_GTK_MainLoop *ml; /** * Should gnunet-gns-gtk start in tray mode? */ static int tray_only; /** * Hash of the public key of our zone. */ static GNUNET_HashCode zone; /** * Private key for the our zone. */ static struct GNUNET_CRYPTO_RsaPrivateKey *zone_pkey; /** * Handle to the namestore. */ static struct GNUNET_NAMESTORE_Handle *ns; /** * Name of our zone as a string. */ static char *zone_as_string; /** * Default directory of zone files as a string. */ static char *zonefile_directory; static GtkWidget *main_window; /** * Get cfg. */ static const struct GNUNET_CONFIGURATION_Handle * get_configuration () { return GNUNET_GTK_main_loop_get_configuration (ml); } /** * Get an object from the main window. * * @param name name of the object * @return NULL on error */ static GObject * get_object (const char *name) { return GNUNET_GTK_main_loop_get_object (ml, name); } /** * The user edited the preferred name (PSEU) of this namespace. * Push the update to the namestore. * * @param editable the edited widget * @param user_data unused */ void GNUNET_GNS_GTK_pseu_entry_changed_cb (GtkEditable *editable, gpointer user_data) { GNUNET_break (0); // FIXME, not implemented } /** * The user toggled the 'autoshort' option. Update the configuration. * * @param checkmenuitem the menu item * @param user_data unused */ void GNUNET_GNS_GTK_autoshort_imagemenuitem_toggled_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data) { GNUNET_break (0); // FIXME, not implemented } /** * The user selected 'NEW' in the menu. Open a dialog to enter a filename * to create a new zone (for editing). * * @param checkmenuitem the menu item * @param user_data unused */ void GNUNET_GNS_GTK_new_imagemenuitem_activate_cb (GtkMenuItem *menuitem, gpointer user_data) { GNUNET_break (0); // FIXME, not implemented } /** * Function called from the open-directory dialog upon completion. * * @param dialog the pseudonym selection dialog * @param response_id response code from the dialog * @param user_data the builder of the dialog */ void GNUNET_GNS_GTK_zone_open_dialog_response_cb (GtkDialog * dialog, gint response_id, gpointer user_data) { GtkBuilder *builder = user_data; char *filename; if (GTK_RESPONSE_OK != response_id) { gtk_widget_destroy (GTK_WIDGET (dialog)); g_object_unref (G_OBJECT (builder)); return; } filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_object_unref (G_OBJECT (builder)); /* FIXME: move to new zone 'filename' */ fprintf (stderr, "Got zone `%s'\n", filename); GNUNET_free (filename); } /** * The user selected 'OPEN' in the menu. Open a dialog to select * a different zonefile (for editing). * * @param checkmenuitem the menu item * @param user_data unused */ void GNUNET_GNS_GTK_open_imagemenuitem_activate_cb (GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *ad; GtkBuilder *builder; GtkWidget *toplevel; builder = GNUNET_GTK_get_new_builder ("gnunet_gns_gtk_zone_open.glade", NULL); if (NULL == builder) { GNUNET_break (0); return; } ad = GTK_WIDGET (gtk_builder_get_object (builder, "GNUNET_GNS_GTK_zone_open_filechooserdialog")); toplevel = gtk_widget_get_toplevel (menuitem); if (GTK_IS_WINDOW (toplevel)) gtk_window_set_transient_for (GTK_WINDOW (ad), GTK_WINDOW (toplevel)); gtk_window_present (GTK_WINDOW (ad)); } /** * The user clicked on the 'copy' button. Copy the full string * with the hash of our public key to the clipboard. * * @param button the button that was clicked * @param user_data unused */ void GNUNET_GNS_GTK_public_key_copy_button_clicked_cb (GtkButton *button, gpointer user_data) { GtkClipboard *cb; cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); gtk_clipboard_set_text (cb, zone_as_string, -1); } /** * Task run on shutdown. * * @param cls unused * @param tc scheduler context, unused */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (NULL != ns) { GNUNET_NAMESTORE_disconnect (ns, GNUNET_NO); ns = NULL; } if (NULL != zone_pkey) { GNUNET_CRYPTO_rsa_key_free (zone_pkey); zone_pkey = NULL; } if (NULL != zonefile_directory) { GNUNET_free (zonefile_directory); zonefile_directory = NULL; } } /** * Callback invoked if the application is supposed to exit (via menu). * * @param menuitem the quit menu * @param user_data unused */ void GNUNET_GNS_GTK_quit_imagemenuitem_activate_cb (GtkMenuItem *menuitem, gpointer user_data) { GNUNET_GTK_tray_icon_destroy (); GNUNET_GTK_main_loop_quit (ml); GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } /** * Callback invoked if the application is supposed to exit (via window-close). * * @param widget the main window * @param event deletion event * @param user_data unused */ void GNUNET_GNS_GTK_main_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) { GNUNET_GTK_tray_icon_destroy (); GNUNET_GTK_main_loop_quit (ml); GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } /** * Actual main function run right after GNUnet's scheduler * is initialized. Initializes up GTK and Glade. * * @param cls the 'struct GNUNET_GTK_MainLoop' * @param tc scheduler context */ static void run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; char *keyfile; char *label; ml = cls; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (get_configuration (), "namestore", "ZONEFILE_DIRECTORY", &zonefile_directory)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Option `%s' missing in section `%s'\n"), "ZONEFILE_DIRECTORY", "namestore"); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (get_configuration (), "gns", "ZONEKEY", &keyfile)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Option `%s' missing in section `%s'\n"), "ZONEKEY", "gns"); return; } zone_pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); GNUNET_free (keyfile); keyfile = NULL; if (NULL == zone_pkey) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read or create private zone key\n")); return; } GNUNET_CRYPTO_rsa_key_get_public (zone_pkey, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &zone); ns = GNUNET_NAMESTORE_connect (get_configuration ()); if (NULL == ns) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to namestore\n")); GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (ml, NULL)) { GNUNET_break (0); GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } zone_as_string = GNUNET_strdup (GNUNET_h2s_full (&zone)); label = g_markup_printf_escaped (_("Editing zone %s"), zone_as_string); gtk_label_set_markup (GTK_LABEL (get_object ("GNUNET_GNS_GTK_zone_label")), label); g_free (label); GNUNET_GTK_set_icon_search_path (); GNUNET_GTK_setup_nls (); /* setup main window */ main_window = GTK_WIDGET (get_object ("GNUNET_GNS_GTK_main_window")); //gtk_window_maximize (GTK_WINDOW (main_window)); GNUNET_GTK_tray_icon_create (GTK_WINDOW (main_window), "gnunet-gtk" /* FIXME: different icon? */ , "gnunet-gns-gtk"); /* make GUI visible */ if (!tray_only) { gtk_widget_show (main_window); gtk_window_present (GTK_WINDOW (main_window)); } } int main (int argc, char *const *argv) { static struct GNUNET_GETOPT_CommandLineOption options[] = { {'t', "tray", NULL, gettext_noop ("start in tray mode"), 0, &GNUNET_GETOPT_set_one, &tray_only}, GNUNET_GETOPT_OPTION_END }; if (GNUNET_OK != GNUNET_GTK_main_loop_start ("gnunet-gns-gtk", "GTK GUI for editing our zone", argc, argv, options, "gnunet_gns_gtk_main_window.glade", &run)) return 1; return 0; } /* end of gnunet-gns-gtk.c */