/* X G N O K I I A Linux/Unix GUI for Nokia mobile phones. Copyright (C) 1999 Pavel Janík ml., Hugh Blemings & Ján Derfiòák . Released under the terms of the GNU GPL, see file COPYING for more details. Last modification: Mon May 01 2000 Modified by Jan Derfinak */ #ifndef WIN32 # include # include # include # include #endif #include #include #include "misc.h" /* for _() */ #include "xgnokii_common.h" #include "xgnokii.h" #include "xpm/quest.xpm" #include "xpm/stop.xpm" #include "xpm/info.xpm" typedef struct { GUIEventType type; void (*func)(void); } GUIEvent; static GSList *guiEvents = NULL; inline void DeleteEvent (const GtkWidget *widget, const GdkEvent *event, const gpointer data) { gtk_widget_hide (GTK_WIDGET (widget)); } inline void CancelDialog (const GtkWidget *widget, const gpointer data) { gtk_widget_hide (GTK_WIDGET (data)); } void CreateErrorDialog (ErrorDialog *errorDialog, GtkWidget *window) { GtkWidget *button, *hbox, *pixmap; errorDialog->dialog = gtk_dialog_new (); gtk_window_set_title (GTK_WINDOW (errorDialog->dialog), _("Error")); gtk_window_set_modal (GTK_WINDOW (errorDialog->dialog), TRUE); gtk_window_position (GTK_WINDOW (errorDialog->dialog), GTK_WIN_POS_MOUSE); gtk_container_set_border_width (GTK_CONTAINER (errorDialog->dialog), 5); gtk_signal_connect (GTK_OBJECT (errorDialog->dialog), "delete_event", GTK_SIGNAL_FUNC (DeleteEvent), NULL); button = gtk_button_new_with_label (_("Cancel")); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (errorDialog->dialog)->action_area), button, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (CancelDialog), (gpointer) errorDialog->dialog); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); gtk_widget_show (button); hbox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (errorDialog->dialog)->vbox), hbox); gtk_widget_show (hbox); if (window) { pixmap = NewPixmap (stop_xpm, window->window, &window->style->bg[GTK_STATE_NORMAL]); gtk_box_pack_start (GTK_BOX(hbox), pixmap, FALSE, FALSE, 10); gtk_widget_show (pixmap); } errorDialog->text = gtk_label_new (""); gtk_box_pack_start (GTK_BOX(hbox), errorDialog->text, FALSE, FALSE, 10); gtk_widget_show (errorDialog->text); } void CreateInfoDialog (InfoDialog *infoDialog, GtkWidget *window) { GtkWidget *hbox, *pixmap; infoDialog->dialog = gtk_dialog_new (); gtk_window_set_title (GTK_WINDOW (infoDialog->dialog), _("Info")); gtk_window_set_modal (GTK_WINDOW (infoDialog->dialog), TRUE); gtk_window_position (GTK_WINDOW (infoDialog->dialog), GTK_WIN_POS_MOUSE); gtk_container_set_border_width (GTK_CONTAINER (infoDialog->dialog), 5); gtk_signal_connect (GTK_OBJECT (infoDialog->dialog), "delete_event", GTK_SIGNAL_FUNC (DeleteEvent), NULL); hbox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (infoDialog->dialog)->vbox), hbox); gtk_widget_show_now (hbox); if (window) { pixmap = NewPixmap (info_xpm, window->window, &window->style->bg[GTK_STATE_NORMAL]); gtk_box_pack_start (GTK_BOX(hbox), pixmap, FALSE, FALSE, 10); gtk_widget_show_now (pixmap); } infoDialog->text = gtk_label_new (""); gtk_box_pack_start (GTK_BOX(hbox), infoDialog->text, FALSE, FALSE, 10); gtk_widget_show_now (infoDialog->text); } void CreateYesNoDialog (YesNoDialog *yesNoDialog, const GtkSignalFunc yesFunc, const GtkSignalFunc noFunc, GtkWidget *window) { GtkWidget *button, *hbox, *pixmap; yesNoDialog->dialog = gtk_dialog_new (); gtk_window_position (GTK_WINDOW (yesNoDialog->dialog), GTK_WIN_POS_MOUSE); gtk_window_set_modal (GTK_WINDOW (yesNoDialog->dialog), TRUE); gtk_container_set_border_width (GTK_CONTAINER (yesNoDialog->dialog), 5); gtk_signal_connect (GTK_OBJECT (yesNoDialog->dialog), "delete_event", GTK_SIGNAL_FUNC (DeleteEvent), NULL); button = gtk_button_new_with_label (_("Yes")); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (yesNoDialog->dialog)->action_area), button, FALSE, TRUE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (yesFunc), (gpointer) yesNoDialog->dialog); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); gtk_widget_show (button); button = gtk_button_new_with_label (_("No")); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (yesNoDialog->dialog)->action_area), button, FALSE, TRUE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (noFunc), (gpointer) yesNoDialog->dialog); gtk_widget_show (button); button = gtk_button_new_with_label (_("Cancel")); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (yesNoDialog->dialog)->action_area), button, FALSE, TRUE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (CancelDialog), (gpointer) yesNoDialog->dialog); gtk_widget_show (button); hbox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (yesNoDialog->dialog)->vbox), hbox); gtk_widget_show (hbox); if (window) { pixmap = NewPixmap (quest_xpm, window->window, &window->style->bg[GTK_STATE_NORMAL]); gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, FALSE, 10); gtk_widget_show (pixmap); } yesNoDialog->text = gtk_label_new (""); gtk_box_pack_start (GTK_BOX (hbox), yesNoDialog->text, FALSE, FALSE, 10); gtk_widget_show (yesNoDialog->text); } GtkWidget* NewPixmap (gchar **data, GdkWindow *window, GdkColor *background) { GtkWidget *wpixmap; GdkPixmap *pixmap; GdkBitmap *mask; pixmap = gdk_pixmap_create_from_xpm_d (window, &mask, background, data); wpixmap = gtk_pixmap_new (pixmap, mask); return wpixmap; } gint LaunchProcess (const gchar *p, const gchar *arg, const gint infile, const gint outfile, const gint errfile) { pid_t pid; if (p == 0) return (1); pid = fork (); if (pid == -1) return (-1); if (pid == 0) { pid = getpid (); setpgid (pid, pid); if (getuid () != geteuid ()) seteuid (getuid ()); signal (SIGINT, SIG_DFL); signal (SIGQUIT, SIG_DFL); signal (SIGTSTP, SIG_DFL); signal (SIGTTIN, SIG_DFL); signal (SIGTTOU, SIG_DFL); signal (SIGCHLD, SIG_DFL); if (infile != STDIN_FILENO) { dup2 (infile, STDIN_FILENO); close (infile); } if (outfile != STDOUT_FILENO) { dup2 (outfile, STDOUT_FILENO); close (outfile); } if (errfile != STDERR_FILENO) { dup2 (errfile, STDERR_FILENO); close (errfile); } execlp (p, p, arg, NULL); g_print (_("Can't exec %s\n"), p); execlp ("/bin/false", p, NULL); return (-1); } setpgid (pid, pid); return (0); } void RemoveZombie (const gint sign) { gint status; wait (&status); } void Help (const GtkWidget *w, const gpointer data) { gchar buf[255] = "file:"; strncat (buf, xgnokiiConfig.xgnokiidir, 255 - strlen (buf)); buf[254] = '\0'; strncat (buf, (gchar *) data, 255 - strlen (buf)); buf[254] = '\0'; LaunchProcess (xgnokiiConfig.helpviewer, buf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO); } inline gint strrncmp (const gchar * const s1, const gchar * const s2, size_t n) { gint l1 = strlen (s1); gint l2 = strlen (s2); if (l1 == 0 && l2 != 0) return (-1); else if (l1 != 0 && l2 == 0) return (1); while (l1-- > 0 && l2-- > 0 && n-- > 0) { if (s1[l1] < s2[l2]) return (-1); else if (s1[l1] > s2[l2]) return (1); } return (0); } inline void GUI_Refresh (void) { while (gtk_events_pending()) gtk_main_iteration(); } inline void SetSortColumn (GtkWidget *widget, SortColumn *data) { gtk_clist_set_sort_column (GTK_CLIST (data->clist), data->column); gtk_clist_sort (GTK_CLIST (data->clist)); } inline void GUIEventAdd (GUIEventType type, void (*func)(void)) { GUIEvent *event = g_malloc (sizeof (GUIEvent)); event->type = type; event->func = func; guiEvents = g_slist_append (guiEvents, event); } bool GUIEventRemove (GUIEventType type, void (*func)(void)) { GUIEvent event; GSList *list; event.type = type; event.func = func; list = g_slist_find (guiEvents, &event); if (list) { g_print ("Nasiel som\n"); guiEvents = g_slist_remove_link (guiEvents, list); g_slist_free_1 (list); return (TRUE); } return (FALSE); } static inline void CallEvent (gpointer data, gpointer user_data) { GUIEvent *event = (GUIEvent *) data; if (event->type == GPOINTER_TO_INT (user_data)) event->func (); } inline void GUIEventSend (GUIEventType type) { g_slist_foreach (guiEvents, CallEvent, GINT_TO_POINTER (type)); }