/* giFTui * Copyright (C) 2003 the giFTui team * * This program 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 of the * License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include "main.h" #include #include #ifdef HAVE_GETOPT_H # include #endif #include #include "configure.h" #include "util.h" /**/ static void giftui_print_help (const gchar *name) { printf (_("USAGE : %s [OPTION]...\n\n"), name); #ifdef HAVE_GETOPT_LONG printf (_(" -s, --server domain connect to this server\n")); printf (_(" -p, --port port connect to this port\n")); printf (_(" -k, --kill kill the daemon when exiting\n")); printf (_(" -l, --launch launch the daemon at startup\n")); printf (_(" -h, --help print this screen\n")); printf (_(" -v, --version print version of %s\n"), PACKAGE); #elif HAVE_GETOPT printf (_(" -s server connect to this server\n")); printf (_(" -p port connect to this port\n")); printf (_(" -k kill the daemon when exiting\n")); printf (_(" -l launch the daemon at startup\n")); printf (_(" -h print this screen\n")); printf (_(" -v print version of %s\n"), PACKAGE); #endif printf (_("Report any bug on http://giftui.tuxfamily.org.\n")); return; } static void giftui_print_version (void) { printf ("%s\n", VERSION); return; } /**************************************************************** * GCONF * ****************************************************************/ static GConfClient *giftui_config = NULL; void giftui_config_set_bool (const gchar *key, gboolean val) { gconf_client_set_bool (giftui_config, key, val, NULL); } void giftui_config_set_int (const gchar *key, gint val) { if (!gconf_client_set_int (giftui_config, key, val, NULL)) GIFTUI_PRINT_ERR (("%s", key)); } void giftui_config_set_str (const gchar *key, const gchar *str) { gconf_client_set_string (giftui_config, key, str, NULL); } void giftui_config_set_list (const gchar *key, GConfValueType type, GList *list) { GSList *slist; /* Convert GList to GSList */ gconf_client_set_list (giftui_config, key, type, slist, NULL); } gboolean giftui_config_get_bool (const gchar *key) { return gconf_client_get_bool (giftui_config, key, NULL); } gint giftui_config_get_int (const gchar *key) { return gconf_client_get_int (giftui_config, key, NULL); } gchar * giftui_config_get_str (const gchar *key) { return gconf_client_get_string (giftui_config, key, NULL); } GList * giftui_config_get_list (const gchar *key, GConfValueType type) { /* Convert GSList to GList */ return gconf_client_get_list (giftui_config, key, type, NULL); } /*guint giftui_config_notify_add (const gchar *key, GConfClientNotifyFunc func, gpointer data) { return gconf_client_notify_add (giftui_config, key, func, data, NULL, NULL); } void giftui_config_notify_remove (guint id) { gconf_client_notify_remove (giftui_config, id); }*/ /**************************************************************** * DATA * ****************************************************************/ static GData *datalist = NULL; void giftui_data_set (const gchar *keypath, gpointer value) { g_datalist_set_data (&datalist, keypath, value); giftui_signal_emit (keypath); return; } void giftui_data_set_full (const gchar *keypath, gpointer value, GDestroyNotify destroy_func) { g_datalist_remove_no_notify (&datalist, keypath); g_datalist_set_data_full (&datalist, keypath, value, destroy_func); giftui_signal_emit (keypath); return; } gpointer giftui_data_get (const gchar *keypath) { return g_datalist_get_data (&datalist, keypath); } /**************************************************************** * SIGNALS * ****************************************************************/ #define GIFTUI_SIGNAL(arg) ((GiftuiSignal_t *)(arg)) #define GIFTUI_HANDLER(arg) ((GiftuiHandler_t *)(arg)) typedef struct _GiftuiHandler_t { GiftuiHandlerCB_t handler; gpointer data; guint gconf_id; } GiftuiHandler_t; typedef struct _GiftuiSignal_t { gchar *name; GList *handlers; } GiftuiSignal_t; /**/ static GList *signals_list = NULL; /* Handlers */ static GiftuiHandler_t * giftui_handler_new (GiftuiHandlerCB_t handler, gpointer data) { GiftuiHandler_t *hand; hand = g_new0 (GiftuiHandler_t, 1); g_return_val_if_fail (hand != NULL, hand); hand->handler = handler; hand->data = data; return hand; } static void giftui_handler_free (GiftuiHandler_t *hand) { g_return_if_fail (hand != NULL); g_free (hand); return; } /**/ static gint _handler_find_by_handler (GiftuiHandler_t *hand1, GiftuiHandler_t *hand2) { if (hand1->handler != hand2->handler) return TRUE; return FALSE; } static gint _handler_find_by_data (GiftuiHandler_t *hand1, GiftuiHandler_t *hand2) { if (hand1->data != hand2->data) return TRUE; return FALSE; } static gint _handler_find_by_data_handler (GiftuiHandler_t *hand1, GiftuiHandler_t *hand2) { return (_handler_find_by_handler (hand1, hand2) || _handler_find_by_data (hand1, hand2)); } /* Signals */ static GiftuiSignal_t * giftui_signal_new (const gchar *name) { GiftuiSignal_t *sig; g_return_val_if_fail (name != NULL, NULL); sig = g_new0 (GiftuiSignal_t, 1); g_return_val_if_fail (sig != NULL, NULL); sig->name = g_strdup (name); return sig; } static void giftui_signal_free (GiftuiSignal_t *sig) { g_return_if_fail (sig != NULL); g_list_foreach (g_list_first (sig->handlers), (GFunc) giftui_handler_free, NULL); g_list_free (g_list_first (sig->handlers)); g_free (sig->name); g_free (sig); return; } static gint _signal_find_by_name (GiftuiSignal_t *sig, gchar *name) { return strcmp (sig->name, name); } /**/ static void giftui_signal_emit_gconf (GConfClient *client, guint cnxn_id, GConfEntry *entry, GiftuiHandler_t *hand) { g_return_if_fail (hand != NULL); hand->handler (hand->data); return; } void giftui_signal_emit (const gchar *name) { GList *l; GiftuiHandler_t *hand; g_return_if_fail (name != NULL); l = g_list_find_custom (g_list_first (signals_list), name, (GCompareFunc) _signal_find_by_name); if (!l) return; l = GIFTUI_SIGNAL (l->data)->handlers; while (l) { hand = GIFTUI_HANDLER (l->data); if (hand && hand->handler) hand->handler (hand->data); l = l->next; } return; } static GiftuiSignal_t * giftui_signal_add (const gchar *name) { GiftuiSignal_t *sig; g_return_val_if_fail (name != NULL, NULL); if ((sig = giftui_signal_new (name))) { signals_list = g_list_append (signals_list, sig); signals_list = g_list_first (signals_list); } return sig; } static void giftui_signal_remove (GList *el) { g_return_if_fail (el != NULL); signals_list = g_list_remove_link (signals_list, el); signals_list = g_list_first (signals_list); giftui_signal_free (GIFTUI_SIGNAL (el->data)); g_list_free_1 (el); return; } static void giftui_signal_add_handler (GiftuiSignal_t *sig, GiftuiHandler_t *hand) { g_return_if_fail (sig != NULL); g_return_if_fail (hand != NULL); if (gconf_valid_key (sig->name, NULL)) hand->gconf_id = gconf_client_notify_add (giftui_config, sig->name, (GConfClientNotifyFunc) giftui_signal_emit_gconf, hand, NULL, NULL); sig->handlers = g_list_append (sig->handlers, hand); sig->handlers = g_list_first (sig->handlers); return; } static void giftui_signal_remove_handler (GiftuiSignal_t *sig, GList *el) { GiftuiHandler_t *hand; g_return_if_fail (sig != NULL); g_return_if_fail (el != NULL); hand = el->data; if (hand->gconf_id) gconf_client_notify_remove (giftui_config, hand->gconf_id); sig->handlers = g_list_remove_link (sig->handlers, el); sig->handlers = g_list_first (sig->handlers); giftui_handler_free (hand); g_list_free_1 (el); return; } void giftui_signal_register (const gchar *name, GiftuiHandlerCB_t handler, gpointer data) { GList *l; GiftuiSignal_t *sig; GiftuiHandler_t *hand; g_return_if_fail (name != NULL); l = g_list_find_custom (g_list_first (signals_list), name, (GCompareFunc) _signal_find_by_name); if (l) sig = GIFTUI_SIGNAL (l->data); else sig = giftui_signal_add (name); if (sig && (hand = giftui_handler_new (handler, data))) giftui_signal_add_handler (sig, hand); return; } void giftui_signal_unregister (const gchar *name, GiftuiHandlerCB_t handler, gpointer data) { GList *e, *ls, *lh; GiftuiHandler_t sear; GiftuiSignal_t *sig; g_return_if_fail (name != NULL); ls = g_list_find_custom (g_list_first (signals_list), name, (GCompareFunc) _signal_find_by_name); /* Signal doesn't exist. */ if (!ls) return; sig = GIFTUI_SIGNAL (ls->data); sear.handler = handler; sear.data = data; lh = g_list_first (sig->handlers); while (lh && (e = g_list_find_custom (lh, &sear, (GCompareFunc) _handler_find_by_data_handler))) { lh = e->next; giftui_signal_remove_handler (sig, e); } /* No more handler ? So we remove the signal. */ if (!sig->handlers) giftui_signal_remove (ls); return; } void giftui_signal_unregister_by_handler (const gchar *name, GiftuiHandlerCB_t handler) { GList *e, *ls, *lh; GiftuiHandler_t sear; GiftuiSignal_t *sig; g_return_if_fail (name != NULL); ls = g_list_find_custom (g_list_first (signals_list), name, (GCompareFunc) _signal_find_by_name); /* Signal doesn't exist. */ if (!ls) return; sig = GIFTUI_SIGNAL (ls->data); sear.handler = handler; lh = g_list_first (sig->handlers); while (lh && (e = g_list_find_custom (lh, &sear, (GCompareFunc) _handler_find_by_handler))) { lh = e->next; giftui_signal_remove_handler (sig, e); } /* No more handler ? So we remove the signal. */ if (!sig->handlers) giftui_signal_remove (ls); return; } void giftui_signal_unregister_by_data (const gchar *name, gpointer data) { GList *e, *ls, *lh; GiftuiHandler_t sear; GiftuiSignal_t *sig; g_return_if_fail (name != NULL); ls = g_list_find_custom (g_list_first (signals_list), name, (GCompareFunc) _signal_find_by_name); /* Signal doesn't exist. */ if (!ls) return; sig = GIFTUI_SIGNAL (ls->data); sear.data = data; lh = g_list_first (sig->handlers); while (lh && (e = g_list_find_custom (lh, &sear, (GCompareFunc) _handler_find_by_data))) { lh = e->next; giftui_signal_remove_handler (sig, e); } /* No more handler ? So we remove the signal. */ if (!sig->handlers) giftui_signal_remove (ls); return; } /**/ gint giftui_config_init (void) { /* GConf */ if (giftui_config) gconf_client_clear_cache (giftui_config); giftui_config = gconf_client_get_default (); gconf_client_add_dir (giftui_config, "/apps/giftui", GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); /* Signals */ signals_list = NULL; /* Datas */ datalist = NULL; g_datalist_init (&datalist); return 1; } void giftui_config_end (void) { /* GConf */ if (giftui_config) { gconf_client_clear_cache (giftui_config); giftui_config = NULL; } /* Signals */ g_list_foreach (g_list_first (signals_list), (GFunc) giftui_signal_free, NULL); /* Datas */ g_datalist_clear (&datalist); return; } gboolean giftui_config_load_from_args (gint argc, gchar *argv[]) { gint version = FALSE, help = FALSE, c; #ifdef HAVE_GETOPT_LONG struct option long_options[] = { { "help", no_argument, NULL, 'h'}, { "version", no_argument, NULL, 'v'}, { "launch", no_argument, NULL, 'l'}, { "server", required_argument, NULL, 's'}, { "port", required_argument, NULL, 'p'}, { NULL, 0, NULL, 0} }; #endif #ifdef HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "hvlp:s:", long_options, NULL)) != -1) #elif HAVE_GETOPT while ((c = getopt (argc, argv, "hvlp:s:")) != -1) #endif { switch (c) { case 'h': help = TRUE; break; case 'v': version = TRUE; break; case 'l': giftui_config_set_bool (PREFS_DAEMON_LAUNCH, TRUE); break; case 'k': giftui_config_set_int (PREFS_DAEMON_KILL, TRUE); break; case 'p': giftui_config_set_int (PREFS_DAEMON_PORT, atoi (optarg)); break; case 's': giftui_config_set_str (PREFS_DAEMON_HOST, optarg); break; default: giftui_print_help (argv[0]); return TRUE; } } /* Help ? */ if (help) giftui_print_help (argv[0]); /* Version ? */ if (version) giftui_print_version (); return (help || version); }