1 /*
2
3 $Id$
4
5 X G N O K I I
6
7 A Linux/Unix GUI for the mobile phones.
8
9 This file is part of gnokii.
10
11 Gnokii is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 Gnokii is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with gnokii; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25 Copyright (C) 1999 Pavel Janik ml., Hugh Blemings
26 & 1999-2005 Jan Derfinak.
27
28 */
29
30 #include "config.h"
31
32 #ifndef WIN32
33 # include <unistd.h>
34 # include <sys/types.h>
35 # include <sys/wait.h>
36 # include <signal.h>
37 #endif
38 #include <string.h>
39 #include <gtk/gtk.h>
40 #include "misc.h" /* for _() */
41 #include "xgnokii_common.h"
42 #include "xgnokii.h"
43 #include "xpm/quest.xpm"
44 #include "xpm/stop.xpm"
45 #include "xpm/info.xpm"
46
47
48 typedef struct {
49 GUIEventType type;
50 void (*func) (void);
51 } GUIEvent;
52
53 static GSList *guiEvents = NULL;
54
55
DeleteEvent(const GtkWidget * widget,const GdkEvent * event,const gpointer data)56 inline void DeleteEvent(const GtkWidget * widget, const GdkEvent * event, const gpointer data)
57 {
58 gtk_widget_hide(GTK_WIDGET(widget));
59 }
60
61
CancelDialog(const GtkWidget * widget,const gpointer data)62 inline void CancelDialog(const GtkWidget * widget, const gpointer data)
63 {
64 gtk_widget_hide(GTK_WIDGET(data));
65 }
66
67
CreateErrorDialog(ErrorDialog * errorDialog,GtkWidget * window)68 void CreateErrorDialog(ErrorDialog * errorDialog, GtkWidget * window)
69 {
70 GtkWidget *button, *hbox, *pixmap;
71
72 errorDialog->dialog = gtk_dialog_new();
73 gtk_window_set_title(GTK_WINDOW(errorDialog->dialog), _("Error"));
74 gtk_window_set_modal(GTK_WINDOW(errorDialog->dialog), TRUE);
75 gtk_window_position(GTK_WINDOW(errorDialog->dialog), GTK_WIN_POS_MOUSE);
76 gtk_container_set_border_width(GTK_CONTAINER(errorDialog->dialog), 5);
77 gtk_signal_connect(GTK_OBJECT(errorDialog->dialog), "delete_event",
78 GTK_SIGNAL_FUNC(DeleteEvent), NULL);
79
80 button = gtk_button_new_with_label(_("Cancel"));
81 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(errorDialog->dialog)->action_area),
82 button, FALSE, FALSE, 0);
83 gtk_signal_connect(GTK_OBJECT(button), "clicked",
84 GTK_SIGNAL_FUNC(CancelDialog), (gpointer) errorDialog->dialog);
85 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
86 gtk_widget_grab_default(button);
87 gtk_widget_show(button);
88
89 hbox = gtk_hbox_new(FALSE, 0);
90 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(errorDialog->dialog)->vbox), hbox);
91 gtk_widget_show(hbox);
92
93 if (window) {
94 pixmap = NewPixmap(stop_xpm, window->window, &window->style->bg[GTK_STATE_NORMAL]);
95 gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, FALSE, 10);
96 gtk_widget_show(pixmap);
97 }
98
99 errorDialog->text = gtk_label_new("");
100 gtk_box_pack_start(GTK_BOX(hbox), errorDialog->text, FALSE, FALSE, 10);
101 gtk_widget_show(errorDialog->text);
102 }
103
104
CreateInfoDialog(InfoDialog * infoDialog,GtkWidget * window)105 void CreateInfoDialog(InfoDialog * infoDialog, GtkWidget * window)
106 {
107 GtkWidget *hbox, *pixmap;
108
109 infoDialog->dialog = gtk_dialog_new();
110 gtk_window_set_title(GTK_WINDOW(infoDialog->dialog), _("Info"));
111 gtk_window_set_modal(GTK_WINDOW(infoDialog->dialog), TRUE);
112 gtk_window_position(GTK_WINDOW(infoDialog->dialog), GTK_WIN_POS_MOUSE);
113 gtk_container_set_border_width(GTK_CONTAINER(infoDialog->dialog), 5);
114 gtk_signal_connect(GTK_OBJECT(infoDialog->dialog), "delete_event",
115 GTK_SIGNAL_FUNC(DeleteEvent), NULL);
116
117 hbox = gtk_hbox_new(FALSE, 0);
118 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(infoDialog->dialog)->vbox), hbox);
119 gtk_widget_show_now(hbox);
120
121 if (window) {
122 pixmap = NewPixmap(info_xpm, window->window, &window->style->bg[GTK_STATE_NORMAL]);
123 gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, FALSE, 10);
124 gtk_widget_show_now(pixmap);
125 }
126
127 infoDialog->text = gtk_label_new("");
128 gtk_box_pack_start(GTK_BOX(hbox), infoDialog->text, FALSE, FALSE, 10);
129 gtk_widget_show_now(infoDialog->text);
130 }
131
132
CreateYesNoDialog(YesNoDialog * yesNoDialog,const GtkSignalFunc yesFunc,const GtkSignalFunc noFunc,GtkWidget * window)133 void CreateYesNoDialog(YesNoDialog * yesNoDialog, const GtkSignalFunc yesFunc,
134 const GtkSignalFunc noFunc, GtkWidget * window)
135 {
136 GtkWidget *button, *hbox, *pixmap;
137
138 yesNoDialog->dialog = gtk_dialog_new();
139 gtk_window_position(GTK_WINDOW(yesNoDialog->dialog), GTK_WIN_POS_MOUSE);
140 gtk_window_set_modal(GTK_WINDOW(yesNoDialog->dialog), TRUE);
141 gtk_container_set_border_width(GTK_CONTAINER(yesNoDialog->dialog), 5);
142 gtk_signal_connect(GTK_OBJECT(yesNoDialog->dialog), "delete_event",
143 GTK_SIGNAL_FUNC(DeleteEvent), NULL);
144
145
146 button = gtk_button_new_with_label(_("Yes"));
147 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yesNoDialog->dialog)->action_area),
148 button, FALSE, TRUE, 0);
149 gtk_signal_connect(GTK_OBJECT(button), "clicked",
150 GTK_SIGNAL_FUNC(yesFunc), (gpointer) yesNoDialog->dialog);
151 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
152 gtk_widget_grab_default(button);
153 gtk_widget_show(button);
154
155 button = gtk_button_new_with_label(_("No"));
156 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yesNoDialog->dialog)->action_area),
157 button, FALSE, TRUE, 0);
158 gtk_signal_connect(GTK_OBJECT(button), "clicked",
159 GTK_SIGNAL_FUNC(noFunc), (gpointer) yesNoDialog->dialog);
160 gtk_widget_show(button);
161
162 button = gtk_button_new_with_label(_("Cancel"));
163 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yesNoDialog->dialog)->action_area),
164 button, FALSE, TRUE, 0);
165 gtk_signal_connect(GTK_OBJECT(button), "clicked",
166 GTK_SIGNAL_FUNC(CancelDialog), (gpointer) yesNoDialog->dialog);
167 gtk_widget_show(button);
168
169 hbox = gtk_hbox_new(FALSE, 0);
170 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(yesNoDialog->dialog)->vbox), hbox);
171 gtk_widget_show(hbox);
172
173 if (window) {
174 pixmap = NewPixmap(quest_xpm, window->window, &window->style->bg[GTK_STATE_NORMAL]);
175 gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, FALSE, 10);
176 gtk_widget_show(pixmap);
177 }
178
179 yesNoDialog->text = gtk_label_new("");
180 gtk_box_pack_start(GTK_BOX(hbox), yesNoDialog->text, FALSE, FALSE, 10);
181 gtk_widget_show(yesNoDialog->text);
182 }
183
184
NewPixmap(gchar ** data,GdkWindow * window,GdkColor * background)185 GtkWidget *NewPixmap(gchar ** data, GdkWindow * window, GdkColor * background)
186 {
187 GtkWidget *wpixmap;
188 GdkPixmap *pixmap;
189 GdkBitmap *mask;
190
191 pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, background, data);
192
193 wpixmap = gtk_pixmap_new(pixmap, mask);
194
195 return wpixmap;
196 }
197
198
LaunchProcess(const gchar * p,const gchar * arg,const gint infile,const gint outfile,const gint errfile)199 gint LaunchProcess(const gchar * p, const gchar * arg, const gint infile,
200 const gint outfile, const gint errfile)
201 {
202 pid_t pid;
203
204 if (p == 0)
205 return (1);
206 pid = fork();
207 if (pid == -1)
208 return (-1);
209 if (pid == 0) {
210 pid = getpid();
211 setpgid(pid, pid);
212 if (getuid() != geteuid())
213 seteuid(getuid());
214
215 signal(SIGINT, SIG_DFL);
216 signal(SIGQUIT, SIG_DFL);
217 signal(SIGTSTP, SIG_DFL);
218 signal(SIGTTIN, SIG_DFL);
219 signal(SIGTTOU, SIG_DFL);
220 signal(SIGCHLD, SIG_DFL);
221
222 if (infile != STDIN_FILENO) {
223 dup2(infile, STDIN_FILENO);
224 close(infile);
225 }
226 if (outfile != STDOUT_FILENO) {
227 dup2(outfile, STDOUT_FILENO);
228 close(outfile);
229 }
230 if (errfile != STDERR_FILENO) {
231 dup2(errfile, STDERR_FILENO);
232 close(errfile);
233 }
234
235 execlp(p, p, arg, NULL);
236 g_print(_("Can't exec %s\n"), p);
237 execlp("/bin/false", p, NULL);
238 return (-1);
239 }
240
241 setpgid(pid, pid);
242 return (0);
243 }
244
245
RemoveZombie(const gint sign)246 void RemoveZombie(const gint sign)
247 {
248 gint status;
249
250 wait(&status);
251 }
252
253
strrncmp(const gchar * const s1,const gchar * const s2,size_t n)254 inline gint strrncmp(const gchar * const s1, const gchar * const s2, size_t n)
255 {
256 gint l1 = strlen(s1);
257 gint l2 = strlen(s2);
258
259 if (l1 == 0 && l2 != 0)
260 return (-1);
261 else if (l1 != 0 && l2 == 0)
262 return (1);
263
264 while (l1-- > 0 && l2-- > 0 && n-- > 0) {
265 if (s1[l1] < s2[l2])
266 return (-1);
267 else if (s1[l1] > s2[l2])
268 return (1);
269 }
270
271 return (0);
272 }
273
274
GUI_Refresh(void)275 inline void GUI_Refresh(void)
276 {
277 while (gtk_events_pending())
278 gtk_main_iteration();
279 }
280
281
SetSortColumn(GtkWidget * widget,SortColumn * data)282 inline void SetSortColumn(GtkWidget * widget, SortColumn * data)
283 {
284 gtk_clist_set_sort_column(GTK_CLIST(data->clist), data->column);
285 gtk_clist_sort(GTK_CLIST(data->clist));
286 }
287
288
GUIEventAdd(GUIEventType type,void (* func)(void))289 inline void GUIEventAdd(GUIEventType type, void (*func) (void))
290 {
291 GUIEvent *event = g_malloc(sizeof(GUIEvent));
292
293 event->type = type;
294 event->func = func;
295
296 guiEvents = g_slist_append(guiEvents, event);
297 }
298
299
GUIEventRemove(GUIEventType type,void (* func)(void))300 bool GUIEventRemove(GUIEventType type, void (*func) (void))
301 {
302 GUIEvent event;
303 GSList *list;
304
305 event.type = type;
306 event.func = func;
307
308 list = g_slist_find(guiEvents, &event);
309 if (list) {
310 g_print("Nasiel som\n");
311 guiEvents = g_slist_remove_link(guiEvents, list);
312 g_slist_free_1(list);
313 return (TRUE);
314 }
315
316 return (FALSE);
317 }
318
CallEvent(gpointer data,gpointer user_data)319 static inline void CallEvent(gpointer data, gpointer user_data)
320 {
321 GUIEvent *event = (GUIEvent *) data;
322
323 if (event->type == GPOINTER_TO_INT(user_data))
324 event->func();
325 }
326
GUIEventSend(GUIEventType type)327 inline void GUIEventSend(GUIEventType type)
328 {
329 g_slist_foreach(guiEvents, CallEvent, GINT_TO_POINTER(type));
330 }
331