1 /*
2 * Callback functions for Xdialog.
3 */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <stdio.h>
10 #ifdef STDC_HEADERS
11 # include <stdlib.h>
12 # include <string.h>
13 #endif
14 #ifdef HAVE_UNISTD_H
15 # include <unistd.h>
16 #endif
17 #include <time.h>
18
19 #include <gtk/gtk.h>
20 #include <gdk/gdkkeysyms.h>
21
22 #include "callbacks.h"
23 #include "interface.h"
24 #include "support.h"
25
26 extern Xdialog_data Xdialog;
27
28 /* This function is called when a "delete_event" is received from the window
29 * manager. It is used to trigger a "destroy" event by returning FALSE
30 * (provided the "--no-close" option was not given).
31 */
delete_event(gpointer object,GdkEventAny * event,gpointer data)32 gboolean delete_event(gpointer object, GdkEventAny *event, gpointer data)
33 {
34 return Xdialog.no_close;
35 }
36
37 /* This function is called when a "destroy" event is received
38 * by the top level window.
39 */
destroy_event(gpointer object,GdkEventAny * event,gpointer data)40 gboolean destroy_event(gpointer object, GdkEventAny *event, gpointer data)
41 {
42 if (Xdialog.timer != 0) {
43 gtk_timeout_remove(Xdialog.timer);
44 Xdialog.timer = 0;
45 }
46 if (Xdialog.timer2 != 0) {
47 gtk_timeout_remove(Xdialog.timer2);
48 Xdialog.timer2 = 0;
49 }
50 gtk_main_quit();
51 Xdialog.window = Xdialog.widget1 = Xdialog.widget2 = Xdialog.widget3 = NULL;
52
53 if (Xdialog.file != NULL) {
54 if (Xdialog.file != stdin)
55 fclose(Xdialog.file);
56 Xdialog.file = NULL;
57 }
58 if (Xdialog.array != NULL) {
59 g_free(Xdialog.array);
60 Xdialog.array = NULL;
61 }
62
63 if (Xdialog.beep & BEEP_AFTER && Xdialog.exit_code != 2)
64 gdk_beep();
65
66 return FALSE;
67 }
68
69 /* These are the normal termination callback routines that are used by the
70 * OK, Cancel and Help buttons. They set the exit_code global variable (for
71 * use as the exit() parameter by main.c), and then call the destroy_event
72 * function that will cleanup everything, destroy the top level window and
73 * set the gtk main loop exit flag. They are used "as is" by most Xdialog
74 * widgets but care must be taken that they are connected with the
75 * gtk_signal_connect_after() function so that any other signal callbacks
76 * are executed BEFORE them (after them, the widget does not exists anymore).
77 */
exit_ok(gpointer object,gpointer data)78 gboolean exit_ok(gpointer object, gpointer data)
79 {
80 if (Xdialog.check) {
81 if (Xdialog.checked)
82 fprintf(Xdialog.output, "checked\n");
83 else
84 fprintf(Xdialog.output, "unchecked\n");
85 }
86 gtk_widget_destroy(Xdialog.window);
87 Xdialog.exit_code = 0;
88 return FALSE;
89 }
90
exit_cancel(gpointer object,gpointer data)91 gboolean exit_cancel(gpointer object, gpointer data)
92 {
93 Xdialog.exit_code = 1;
94 gtk_widget_destroy(Xdialog.window);
95 return FALSE;
96 }
97
exit_keypress(gpointer object,GdkEventKey * event,gpointer data)98 gint exit_keypress(gpointer object, GdkEventKey *event, gpointer data)
99 {
100 if (event->type == GDK_KEY_PRESS && (event->keyval == GDK_Escape)) {
101 return exit_cancel(object, data);
102 }
103 return TRUE;
104 }
105
exit_help(gpointer object,gpointer data)106 gboolean exit_help(gpointer object, gpointer data)
107 {
108 Xdialog.exit_code = 2;
109 gtk_widget_destroy(Xdialog.window);
110 return FALSE;
111 }
112
exit_previous(gpointer object,gpointer data)113 gboolean exit_previous(gpointer object, gpointer data)
114 {
115 Xdialog.exit_code = 3;
116 gtk_widget_destroy(Xdialog.window);
117 return FALSE;
118 }
119
checked(GtkObject * button,gpointer data)120 gboolean checked(GtkObject *button, gpointer data)
121 {
122 Xdialog.checked = GTK_TOGGLE_BUTTON(button)->active;
123 return TRUE;
124 }
125
timeout_exit(gpointer data)126 gboolean timeout_exit(gpointer data)
127 {
128 Xdialog.exit_code = 255;
129 gtk_widget_destroy(Xdialog.window);
130 return FALSE;
131 }
132
133 /* This function is called within the timeout functions so to force
134 * the processing of all queued GTK events.
135 */
empty_gtk_queue(void)136 gboolean empty_gtk_queue(void)
137 {
138 while(gtk_events_pending()) {
139 gtk_main_iteration();
140 /* If the timeout function has been removed, return immediately */
141 if (Xdialog.timer == 0)
142 return FALSE;
143 }
144 /* All events have been taken into account... */
145 return TRUE;
146 }
147
148 /* infobox callbacks: the infobox_timeout_exit() is responsible for
149 * closing the infobox once the timeout is over (it therefore calls
150 * exit_ok()). The infobox_timeout() function is responsible for
151 * reading the stdin and changing the infobox label and/or exiting the
152 * infobox by calling exit_ok().
153 */
154
infobox_timeout_exit(gpointer data)155 gboolean infobox_timeout_exit(gpointer data)
156 {
157 return exit_ok(NULL, NULL);
158 }
159
infobox_timeout(gpointer data)160 gboolean infobox_timeout(gpointer data)
161 {
162 char temp[256];
163 int ret;
164
165 if (!empty_gtk_queue())
166 return FALSE;
167
168 /* Read the the data from stdin */
169 #ifdef USE_SCANF
170 ret = scanf("%255s", temp);
171 #else
172 ret = my_scanf(temp);
173 #endif
174 if ((ret == EOF && !Xdialog.ignore_eof) || (strcmp(temp, "XXXX") == 0))
175 return exit_ok(NULL, NULL);
176 if (ret != 1)
177 return TRUE;
178
179 if (strcmp(temp, "XXX") == 0) {
180 /* If this is a new label delimiter, then check to see if it's the
181 * start or the end of the label. */
182 if (Xdialog.new_label) {
183 gtk_label_set_text(GTK_LABEL(Xdialog.widget1),
184 Xdialog.label_text);
185 Xdialog.label_text[0] = 0 ;
186 Xdialog.new_label = FALSE;
187 } else {
188 Xdialog.new_label = TRUE;
189 }
190 } else {
191 /* Add this text to the new label text */
192 if (strlen(Xdialog.label_text)+strlen(temp)+2 < MAX_LABEL_LENGTH) {
193 if (strcmp(temp, "\\n") == 0) {
194 strcat(Xdialog.label_text, "\n");
195 } else {
196 strcat(Xdialog.label_text, " ");
197 strcat(Xdialog.label_text, temp);
198 }
199 }
200 }
201
202 /* As this is a timeout function, return TRUE so that it
203 * continues to get called */
204 return TRUE;
205 }
206
207 /* gauge timeout callback */
208
gauge_timeout(gpointer data)209 gboolean gauge_timeout(gpointer data)
210 {
211 gfloat new_val;
212 GtkAdjustment *adj;
213 char temp[256];
214 int ret;
215
216 if (!empty_gtk_queue())
217 return FALSE;
218
219 /* Read the new progress bar value or the new label from stdin */
220 #ifdef USE_SCANF
221 ret = scanf("%255s", temp);
222 #else
223 ret = my_scanf(temp);
224 #endif
225 if (ret == EOF && !Xdialog.ignore_eof)
226 return exit_ok(NULL, NULL);
227 if (ret != 1)
228 return TRUE;
229
230 if (!Xdialog.new_label && strcmp(temp, "XXX")) {
231 /* Try to convert the string into an integer for use as the new
232 * progress bar value... */
233 new_val = (gfloat) atoi(temp);
234 adj = GTK_PROGRESS(Xdialog.widget1)->adjustment;
235 if ((new_val > adj->upper) || (new_val < adj->lower))
236 return exit_ok(NULL, NULL);
237 /* Set the new value */
238 gtk_progress_set_value(GTK_PROGRESS(Xdialog.widget1), new_val);
239 } else {
240 if (strcmp(temp, "XXX") == 0) {
241 /* If this is a new label delimiter, then check to see if it's the
242 * start or the end of the label. */
243 if (Xdialog.new_label) {
244 gtk_label_set_text(GTK_LABEL(Xdialog.widget2),
245 Xdialog.label_text);
246 Xdialog.label_text[0] = 0 ;
247 Xdialog.new_label = FALSE;
248 } else {
249 Xdialog.new_label = TRUE;
250 }
251 } else {
252 /* Add this text to the new label text */
253 if (strlen(Xdialog.label_text)+strlen(temp)+2 < MAX_LABEL_LENGTH) {
254 if (strcmp(temp, "\\n") == 0) {
255 strcat(Xdialog.label_text, "\n");
256 } else {
257 strcat(Xdialog.label_text, " ");
258 strcat(Xdialog.label_text, temp);
259 }
260 }
261 }
262 }
263
264 /* As this is a timeout function, return TRUE so that it
265 * continues to get called */
266 return TRUE;
267 }
268
269 /* progress timeout callback */
270
progress_timeout(gpointer data)271 gboolean progress_timeout(gpointer data)
272 {
273 gfloat new_val;
274 GtkAdjustment *adj;
275 char temp[256];
276 int ret;
277
278 if (!empty_gtk_queue())
279 return FALSE;
280
281 adj = GTK_PROGRESS(Xdialog.widget1)->adjustment;
282
283 temp[255] = '\0';
284
285 /* Read the new progress bar value or the new "dot" from stdin,
286 * skipping any control character.
287 */
288 do {
289 ret = fgetc(stdin);
290 if (ret == EOF)
291 return exit_ok(NULL, NULL);
292 temp[0] = (char) ret;
293 } while (temp[0] <= ' ');
294
295 if (temp[0] >= '0' && temp[0] <= '9') {
296 /* Get and convert a string into an integer for use as
297 * the new progress bar value... */
298 ret = scanf("%254s", temp + 1);
299 if (ret == EOF)
300 return exit_ok(NULL, NULL);
301 if (ret != 1)
302 return TRUE;
303 new_val = (gfloat) atoi(temp);
304 } else {
305 /* Increment the number of "dots" */
306 new_val = adj->value + 1;
307 }
308
309 if ((new_val > adj->upper) || (new_val < adj->lower))
310 return exit_ok(NULL, NULL);
311 /* Set the new value */
312 gtk_progress_set_value(GTK_PROGRESS(Xdialog.widget1), new_val);
313
314 /* As this is a timeout function, return TRUE so that it
315 * continues to get called */
316 return TRUE;
317 }
318
319 /* tailbox and logbox callbacks */
320
321 #ifdef USE_GTK2
tailbox_timeout(gpointer data)322 gboolean tailbox_timeout(gpointer data)
323 {
324 gchar buffer[1024];
325 int nchars = 0;
326 GtkTextIter end_iter;
327
328 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(Xdialog.widget1));
329
330 do {
331 if (!empty_gtk_queue() && (Xdialog.file_init_size <= 0))
332 return FALSE;
333
334 nchars = fread(buffer, sizeof(gchar), 1024, Xdialog.file);
335 if (nchars == 0)
336 break;
337
338 gtk_text_buffer_get_end_iter(text_buffer, &end_iter);
339 gtk_text_buffer_insert(text_buffer, &end_iter, buffer, nchars);
340
341 if (Xdialog.file_init_size > 0)
342 Xdialog.file_init_size -= nchars;
343 } while (nchars == 1024);
344
345 if (nchars > 0) {
346 GtkTextMark *mark;
347 gtk_text_buffer_get_end_iter(text_buffer, &end_iter);
348
349 mark = gtk_text_buffer_create_mark(text_buffer, "end",
350 &end_iter, TRUE);
351
352 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(Xdialog.widget1),
353 mark, 0, FALSE, 0, 0);
354 }
355
356 return TRUE;
357 }
358 #else
tailbox_timeout(gpointer data)359 gboolean tailbox_timeout(gpointer data)
360 {
361 GtkAdjustment *adj;
362 gchar buffer[1024];
363 int nchars;
364 gboolean flag = FALSE;
365
366 adj = GTK_TEXT(Xdialog.widget1)->vadj;
367
368 if (Xdialog.file_init_size > 0)
369 gtk_text_freeze(GTK_TEXT(Xdialog.widget1));
370
371 do {
372 if (!empty_gtk_queue() && (Xdialog.file_init_size <= 0))
373 return FALSE;
374
375 nchars = fread(buffer, sizeof(gchar), 1024, Xdialog.file);
376
377 if (nchars == 0)
378 break;
379
380 if (Xdialog.file_init_size > 0) {
381 Xdialog.file_init_size -= nchars;
382 if (Xdialog.file_init_size <= 0)
383 flag = TRUE;
384 } else {
385 if (!Xdialog.smooth)
386 gtk_text_freeze(GTK_TEXT(Xdialog.widget1));
387 }
388
389 gtk_text_insert(GTK_TEXT(Xdialog.widget1), NULL, NULL,
390 NULL, buffer, nchars);
391
392 if ((!Xdialog.smooth || flag) && Xdialog.file_init_size <= 0) {
393 gtk_text_thaw(GTK_TEXT(Xdialog.widget1));
394 flag = FALSE;
395 }
396
397 gtk_adjustment_set_value(adj, adj->upper);
398
399 } while (nchars == 1024);
400
401 return TRUE;
402 }
403 #endif
404
tailbox_keypress(GtkObject * text,GdkEventKey * event,gpointer data)405 gint tailbox_keypress(GtkObject *text, GdkEventKey *event,
406 gpointer data)
407 {
408 if (event->type == GDK_KEY_PRESS && (event->keyval == GDK_Return ||
409 event->keyval == GDK_KP_Enter)) {
410 if (Xdialog.default_no)
411 Xdialog.exit_code = 1;
412 else
413 Xdialog.exit_code = 0;
414
415 return(FALSE);
416 }
417 return(TRUE);
418 }
419
420 #ifdef HAVE_STRSTR
421
vt_to_gdk_color(gint color,GdkColor ** fgcolor,GdkColor ** bgcolor)422 static void vt_to_gdk_color(gint color, GdkColor **fgcolor, GdkColor **bgcolor)
423 {
424 static const GdkColor BLACK = { 0, 0x0000, 0x0000, 0x0000 };
425 static const GdkColor RED = { 0, 0xffff, 0x0000, 0x0000 };
426 static const GdkColor GREEN = { 0, 0x0000, 0xffff, 0x0000 };
427 static const GdkColor BLUE = { 0, 0x0000, 0x0000, 0xffff };
428 static const GdkColor MAGENTA = { 0, 0xffff, 0x0000, 0xffff };
429 static const GdkColor YELLOW = { 0, 0xffff, 0xffff, 0x0000 };
430 static const GdkColor CYAN = { 0, 0x0000, 0xffff, 0xffff };
431 static const GdkColor WHITE = { 0, 0xffff, 0xffff, 0xffff };
432
433 switch (color) {
434 case 30:
435 *fgcolor = (GdkColor *) &BLACK;
436 break;
437 case 31:
438 *fgcolor = (GdkColor *) &RED;
439 break;
440 case 32:
441 *fgcolor = (GdkColor *) &GREEN;
442 break;
443 case 33:
444 *fgcolor = (GdkColor *) &YELLOW;
445 break;
446 case 34:
447 *fgcolor = (GdkColor *) &BLUE;
448 break;
449 case 35:
450 *fgcolor = (GdkColor *) &MAGENTA;
451 break;
452 case 36:
453 *fgcolor = (GdkColor *) &CYAN;
454 break;
455 case 37:
456 *fgcolor = (GdkColor *) &WHITE;
457 break;
458 case 38:
459 *fgcolor = NULL;
460 break;
461 case 40:
462 *bgcolor = (GdkColor *) &BLACK;
463 break;
464 case 41:
465 *bgcolor = (GdkColor *) &RED;
466 break;
467 case 42:
468 *bgcolor = (GdkColor *) &GREEN;
469 break;
470 case 43:
471 *bgcolor = (GdkColor *) &YELLOW;
472 break;
473 case 44:
474 *bgcolor = (GdkColor *) &BLUE;
475 break;
476 case 45:
477 *bgcolor = (GdkColor *) &MAGENTA;
478 break;
479 case 46:
480 *bgcolor = (GdkColor *) &CYAN;
481 break;
482 case 47:
483 *bgcolor = (GdkColor *) &WHITE;
484 break;
485 case 48:
486 *bgcolor = NULL;
487 break;
488 }
489 }
490
remove_vt_sequences(char * str)491 static void remove_vt_sequences(char *str)
492 {
493 char *p, *q;
494
495 while ((p = strstr(str, "\033[")) != NULL) {
496 q = p;
497 while (++p < str + strlen(str)) {
498 if (*p == 'm')
499 break;
500 }
501 strcpy(q, ++p);
502 }
503 }
504
505 static GdkColor *old_fgcolor = NULL;
506 static GdkColor *old_bgcolor = NULL;
507
logbox_timeout(gpointer data)508 gboolean logbox_timeout(gpointer data)
509 {
510 GtkCList *clist = GTK_CLIST(Xdialog.widget1);
511 GdkColor *fgcolor, *bgcolor;
512 gchar buffer[MAX_LABEL_LENGTH], *p;
513 static gchar *null_single_row[] = { NULL };
514 static gchar *null_double_row[] = { NULL, NULL };
515 gint rownum;
516 int color, len;
517 struct tm *localdate = NULL;
518 time_t curr_time;
519 gboolean flag = FALSE;
520
521 if (!Xdialog.smooth && (Xdialog.file_init_size > 0))
522 gtk_clist_freeze(clist);
523 else {
524 if (!empty_gtk_queue())
525 return FALSE;
526 }
527
528 while (fgets(buffer, MAX_LABEL_LENGTH, Xdialog.file) != NULL) {
529
530 len = strlen(buffer);
531
532 if (Xdialog.file_init_size > 0) {
533 Xdialog.file_init_size -= len;
534 if (Xdialog.file_init_size <= 0)
535 flag = TRUE;
536 }
537
538 if ((len > 0) && (buffer[len - 1] == '\n'))
539 buffer[--len] = 0;
540
541 if (Xdialog.time_stamp) {
542 time(&curr_time);
543 localdate = localtime(&curr_time);
544 }
545
546 if (Xdialog.keep_colors) {
547 fgcolor = old_fgcolor;
548 bgcolor = old_bgcolor;
549 } else
550 fgcolor = bgcolor = NULL;
551
552 if ((p = strstr(buffer, "\033[1;")) != NULL) {
553 p += 4;
554 color = atoi(p);
555 vt_to_gdk_color(color, &fgcolor, &bgcolor);
556
557 while (++p < buffer + len) {
558 if (*p == ';') {
559 color = atoi(++p);
560 vt_to_gdk_color(color, &fgcolor, &bgcolor);
561 p += 2;
562 }
563 if (*p == 'm')
564 break;
565 }
566
567 if (Xdialog.keep_colors) {
568 old_fgcolor = fgcolor;
569 old_bgcolor = bgcolor;
570 }
571
572 remove_vt_sequences(buffer);
573 }
574
575 if (Xdialog.reverse)
576 rownum = gtk_clist_prepend(clist,
577 Xdialog.time_stamp ? null_double_row : null_single_row);
578 else
579 rownum = gtk_clist_append(clist,
580 Xdialog.time_stamp ? null_double_row : null_single_row);
581 gtk_clist_set_selectable(clist, rownum, FALSE);
582 if (fgcolor != NULL)
583 gtk_clist_set_foreground(clist, rownum, fgcolor);
584 if (bgcolor != NULL)
585 gtk_clist_set_background(clist, rownum, bgcolor);
586 if (Xdialog.time_stamp) {
587 gtk_clist_set_text(clist, rownum, 1, buffer);
588 if (Xdialog.date_stamp)
589 sprintf(buffer, "%02d/%02d/%d %02d:%02d:%02d ",
590 localdate->tm_mday, localdate->tm_mon+1, localdate->tm_year+1900,
591 localdate->tm_hour, localdate->tm_min, localdate->tm_sec);
592 else
593 sprintf(buffer, "%02d:%02d:%02d",
594 localdate->tm_hour, localdate->tm_min, localdate->tm_sec);
595 gtk_clist_set_text(clist, rownum, 0, buffer);
596 } else
597 gtk_clist_set_text(clist, rownum, 0, buffer);
598 gtk_clist_columns_autosize(clist);
599
600 if ((Xdialog.file_init_size <= 0) || Xdialog.smooth) {
601 if (flag) {
602 gtk_clist_thaw(clist);
603 flag = FALSE;
604 }
605
606 if (Xdialog.reverse)
607 gtk_clist_moveto(clist, rownum, 0, 0.0, 0.0);
608 else
609 gtk_clist_moveto(clist, rownum, 0, 1.0, 0.0);
610 }
611
612 if (!empty_gtk_queue())
613 return FALSE;
614 }
615
616 return TRUE;
617 }
618
619 #else
620 #error strstr() function is needed by Xdialog !
621 #endif
622
623 /* Here are the callback functions for the inputboxes and combobox (OK button
624 * callback and entry RETURN/ENTER keypress callback).
625 */
inputbox_ok(gpointer object,gpointer data)626 gint inputbox_ok(gpointer object, gpointer data)
627 {
628 fprintf(Xdialog.output, "%s",
629 gtk_entry_get_text(GTK_ENTRY(Xdialog.widget1)));
630 if (Xdialog.widget2 != NULL)
631 fprintf(Xdialog.output, "%s%s", Xdialog.separator,
632 gtk_entry_get_text(GTK_ENTRY(Xdialog.widget2)));
633 if (Xdialog.widget3 != NULL)
634 fprintf(Xdialog.output, "%s%s", Xdialog.separator,
635 gtk_entry_get_text(GTK_ENTRY(Xdialog.widget3)));
636 fprintf(Xdialog.output, "\n");
637
638 return TRUE;
639 }
640
inputbox_timeout(gpointer data)641 gboolean inputbox_timeout(gpointer data)
642 {
643 return inputbox_ok(NULL, NULL);
644 }
645
646
input_keypress(GtkObject * entry,GdkEventKey * event,gpointer data)647 gint input_keypress(GtkObject *entry, GdkEventKey *event, gpointer data)
648 {
649 if (event->type == GDK_KEY_PRESS && (event->keyval == GDK_Return ||
650 event->keyval == GDK_KP_Enter)) {
651 if (Xdialog.default_no) {
652 Xdialog.exit_code = 1;
653 } else {
654 inputbox_ok(NULL, NULL);
655 Xdialog.exit_code = 0;
656 }
657 if (Xdialog.check) {
658 if (Xdialog.checked)
659 fprintf(Xdialog.output, "checked\n");
660 else
661 fprintf(Xdialog.output, "unchecked\n");
662 }
663 gtk_widget_destroy(Xdialog.window);
664 return FALSE;
665 }
666 return TRUE;
667 }
668
hide_passwords(GtkObject * button,gpointer data)669 gboolean hide_passwords(GtkObject *button, gpointer data)
670 {
671 gint entries;
672 gboolean visible;
673
674 entries = 1 + (Xdialog.widget2 != NULL ? 1 : 0) + (Xdialog.widget3 != NULL ? 1 : 0);
675
676 visible = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == FALSE);
677
678 if ((Xdialog.passwd < 10 && Xdialog.passwd >= entries) || Xdialog.passwd == 11)
679 gtk_entry_set_visibility(GTK_ENTRY(Xdialog.widget1), visible);
680 if (entries > 1 && ((Xdialog.passwd < 10 && Xdialog.passwd >= entries-1) || Xdialog.passwd == 12))
681 gtk_entry_set_visibility(GTK_ENTRY(Xdialog.widget2), visible);
682 if (entries > 2 && ((Xdialog.passwd < 10 && Xdialog.passwd > 0) || Xdialog.passwd == 13))
683 gtk_entry_set_visibility(GTK_ENTRY(Xdialog.widget3), visible);
684
685 return TRUE;
686 }
687
688 /* editbox callback */
689
690 #ifdef USE_GTK2
editbox_ok(gpointer object,gpointer data)691 gboolean editbox_ok(gpointer object, gpointer data)
692 {
693 GtkTextIter start_iter, end_iter;
694
695 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(Xdialog.widget1));
696 gtk_text_buffer_get_bounds(text_buffer, &start_iter, &end_iter);
697 fputs(gtk_text_buffer_get_text(text_buffer, &start_iter, &end_iter,
698 FALSE), Xdialog.output);
699
700 return TRUE;
701 }
702 #else
editbox_ok(gpointer object,gpointer data)703 gboolean editbox_ok(gpointer object, gpointer data)
704 {
705 int length, i;
706
707 length = gtk_text_get_length(GTK_TEXT(Xdialog.widget1));
708 for (i = 0; i < length; i++)
709 fputc(GTK_TEXT_INDEX(GTK_TEXT(Xdialog.widget1), i),
710 Xdialog.output);
711
712 return TRUE;
713 }
714 #endif
715
716 /* The print button callback (used by editbox, textbox and tailbox) */
717
718 #ifdef USE_GTK2
print_text(gpointer object,gpointer data)719 gboolean print_text(gpointer object, gpointer data)
720 {
721 gint length;
722 char cmd[MAX_PRTCMD_LENGTH];
723 FILE * temp;
724 GtkTextIter start_iter, end_iter;
725 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(Xdialog.widget1));
726
727 gtk_text_buffer_get_bounds(text_buffer, &start_iter, &end_iter);
728
729 strcpysafe(cmd, PRINTER_CMD, MAX_PRTCMD_LENGTH);
730 if (strlen(Xdialog.printer) != 0) {
731 strcatsafe(cmd, " "PRINTER_CMD_OPTION, MAX_PRTCMD_LENGTH);
732 strcatsafe(cmd, Xdialog.printer, MAX_PRTCMD_LENGTH);
733 }
734
735 length = gtk_text_buffer_get_char_count(text_buffer);
736
737 temp = popen(cmd, "w");
738 if (temp != NULL) {
739 fwrite(gtk_text_buffer_get_text(text_buffer, &start_iter,
740 &end_iter, FALSE), sizeof(gchar), length, temp);
741 pclose(temp);
742 }
743
744 return TRUE;
745 }
746 #else
print_text(gpointer object,gpointer data)747 gboolean print_text(gpointer object, gpointer data)
748 {
749 int length, i;
750 gchar * buffer;
751 char cmd[MAX_PRTCMD_LENGTH];
752 FILE * temp;
753
754 strcpysafe(cmd, PRINTER_CMD, MAX_PRTCMD_LENGTH);
755 if (strlen(Xdialog.printer) != 0) {
756 strcatsafe(cmd, " "PRINTER_CMD_OPTION, MAX_PRTCMD_LENGTH);
757 strcatsafe(cmd, Xdialog.printer, MAX_PRTCMD_LENGTH);
758 }
759
760 length = gtk_text_get_length(GTK_TEXT(Xdialog.widget1));
761 buffer = g_malloc((length+1)*sizeof(gchar));
762 for (i = 0; i < length; i++)
763 buffer[i] = GTK_TEXT_INDEX(GTK_TEXT(Xdialog.widget1), i);
764
765 temp = popen(cmd, "w");
766 if (temp != NULL) {
767 i = fwrite(buffer, sizeof(gchar), length, temp);
768 pclose(temp);
769 }
770 g_free(buffer);
771
772 return TRUE;
773 }
774 #endif
775
776 /* rangebox callbacks */
777
rangebox_exit(GtkButton * button,gpointer data)778 gboolean rangebox_exit(GtkButton *button, gpointer data)
779 {
780 GtkAdjustment *adj;
781
782 adj = GTK_ADJUSTMENT((GtkObject *) Xdialog.widget1);
783 fprintf(Xdialog.output, "%d", (gint) adj->value);
784 if (Xdialog.widget2 != NULL) {
785 adj = GTK_ADJUSTMENT((GtkObject *) Xdialog.widget2);
786 fprintf(Xdialog.output, "%s%d", Xdialog.separator,
787 (gint) adj->value);
788 }
789 if (Xdialog.widget3 != NULL) {
790 adj = GTK_ADJUSTMENT((GtkObject *) Xdialog.widget3);
791 fprintf(Xdialog.output, "%s%d", Xdialog.separator,
792 (gint) adj->value);
793 }
794 fprintf(Xdialog.output, "\n");
795
796 return TRUE;
797 }
798
799
rangebox_timeout(gpointer data)800 gboolean rangebox_timeout(gpointer data)
801 {
802 return rangebox_exit(NULL, NULL);
803 }
804
805 /* spin boxes callbacks */
806
spinbox_exit(GtkButton * button,gpointer data)807 gboolean spinbox_exit(GtkButton *button, gpointer data)
808 {
809 fprintf(Xdialog.output, "%d",
810 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(Xdialog.widget1)));
811
812 if (Xdialog.widget2 != NULL)
813 fprintf(Xdialog.output, "%s%d", Xdialog.separator,
814 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(Xdialog.widget2)));
815
816 if (Xdialog.widget3 != NULL)
817 fprintf(Xdialog.output, "%s%d", Xdialog.separator,
818 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(Xdialog.widget3)));
819
820 fprintf(Xdialog.output, "\n");
821
822 return TRUE;
823 }
824
spinbox_timeout(gpointer data)825 gboolean spinbox_timeout(gpointer data)
826 {
827 return spinbox_exit(NULL, NULL);
828 }
829
830 /* Double-click event is processed as a button click in menubox, radiolist and
831 * checklist... The button widget is to be passed as "data".
832 */
double_click_event(GtkObject * object,GdkEventButton * event,gpointer data)833 gint double_click_event(GtkObject *object, GdkEventButton *event,
834 gpointer data)
835 {
836 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
837 gtk_signal_emit_by_name(GTK_OBJECT(data), "clicked");
838
839 return FALSE;
840 }
841
842 /* radiolist and checklist callbacks */
843
item_toggle(GtkObject * item,int i)844 void item_toggle(GtkObject *item, int i)
845 {
846 if (GTK_TOGGLE_BUTTON(item)->active) {
847 Xdialog.array[i].state = 1;
848 } else
849 Xdialog.array[i].state = 0;
850 }
851
print_items(GtkButton * button,gpointer data)852 gboolean print_items(GtkButton *button, gpointer data)
853 {
854 int i;
855 gboolean flag = FALSE;
856
857 for (i = 0 ; Xdialog.array[i].state != -1 ; i++) {
858 if (Xdialog.array[i].state) {
859 if (flag)
860 fprintf(Xdialog.output, "%s", Xdialog.separator);
861 fprintf(Xdialog.output, "%s", Xdialog.array[i].tag);
862 flag = TRUE;
863 }
864 }
865 if (flag)
866 fprintf(Xdialog.output, "\n");
867
868 return TRUE;
869 }
870
itemlist_timeout(gpointer data)871 gboolean itemlist_timeout(gpointer data)
872 {
873 return print_items(NULL, NULL);
874 }
875
876 /* menubox callback */
877
item_select(GtkObject * clist,gint row,gint column,GdkEventButton * event,gpointer data)878 void item_select(GtkObject *clist, gint row, gint column,
879 GdkEventButton *event, gpointer data)
880 {
881 /* If the tag is empty, then this is an unavailable item:
882 * select back the last selected row and exit.
883 */
884 if (strlen(Xdialog.array[row].tag) == 0) {
885 gtk_clist_select_row(GTK_CLIST(clist), Xdialog.array[0].state, 0);
886 return;
887 }
888
889 /* Just remember which row was last selected (we use the first
890 * row status variable IOT do so)...
891 */
892 Xdialog.array[0].state = row;
893
894 if (Xdialog.tips == 1) {
895 gtk_statusbar_pop(GTK_STATUSBAR(Xdialog.widget1), Xdialog.status_id);
896 gtk_statusbar_push(GTK_STATUSBAR(Xdialog.widget1), Xdialog.status_id,
897 Xdialog.array[row].tips);
898 }
899 }
900
901 /* menubox and treeview callback */
902
print_selection(GtkButton * button,gpointer data)903 gboolean print_selection(GtkButton *button, gpointer data)
904 {
905 if ( Xdialog.array[0].state >= 0) {
906 fprintf(Xdialog.output, "%s\n", Xdialog.array[Xdialog.array[0].state].tag);
907 return TRUE;
908 } else
909 return FALSE;
910 }
911
912 #ifdef USE_GTK2
print_tree_selection(GtkButton * button,gpointer data)913 gboolean print_tree_selection(GtkButton *button, gpointer data)
914 {
915 int i = 0;
916 for (i = 0 ; Xdialog.array[i].state != -1 ; i++) {
917 if (Xdialog.array[i].state > 0) {
918 fprintf(Xdialog.output, "%s\n", Xdialog.array[i].tag);
919 return TRUE;
920 }
921 }
922 return FALSE;
923 }
924 #endif
925
menu_timeout(gpointer data)926 gboolean menu_timeout(gpointer data)
927 {
928 return print_selection(NULL, NULL);
929 }
930
move_to_row_timeout(gpointer data)931 gboolean move_to_row_timeout(gpointer data)
932 {
933 gtk_clist_moveto(GTK_CLIST(Xdialog.widget2),
934 Xdialog.array[0].state, 0, 0.5, 0.0);
935
936 /* Run this timeout function only once ! */
937 return FALSE;
938 }
939
940 #ifdef USE_GTK2
cb_selection_changed(GtkObject * tree)941 void cb_selection_changed(GtkObject *tree)
942 {
943 GtkTreeIter tree_iter;
944 GtkTreeModel *model;
945 GtkTreeSelection* selection;
946 gchar *name, *tag;
947 int i = 0;
948
949 model = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget1));
950 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(Xdialog.widget1));
951
952 if (gtk_tree_selection_get_selected(selection, &model, &tree_iter))
953 gtk_tree_model_get(model, &tree_iter, 0, &name, 1, &tag, -1);
954
955 for (i = 0 ; Xdialog.array[i].state != -1 ; i++) {
956 if (!strncmp(Xdialog.array[i].name, name, strlen(name)))
957 Xdialog.array[i].state = 1;
958 else
959 Xdialog.array[i].state = 0;
960 }
961
962 g_free(name);
963 g_free(tag);
964 }
965 #else
cb_selection_changed(GtkObject * tree)966 void cb_selection_changed(GtkObject *tree)
967 {
968 GList *list;
969 GtkWidget *item;
970 int i;
971
972 list = GTK_TREE_SELECTION(tree);
973 if (list != NULL) {
974 item = GTK_WIDGET(list->data);
975 for (i = 0 ; Xdialog.array[i].state != -1 ; i++) {
976 if (Xdialog.array[i].widget == item) {
977 Xdialog.array[0].state = i;
978 break;
979 }
980 }
981 }
982 }
983 #endif
984
985 /* buildlist callbacks */
986
987 /* the following function is to be called after each glist update so to
988 * set the proper (in)sensitive status onto the Add/Remove buttons.
989 */
990 #ifdef USE_GTK2
sensitive_buttons(void)991 void sensitive_buttons(void)
992 {
993 GtkTreeIter tree_iter;
994 GtkTreeModel *model;
995
996 model = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget1));
997
998 if (gtk_tree_model_get_iter_first(model, &tree_iter)) {
999 gtk_widget_set_sensitive(Xdialog.widget3, TRUE);
1000 } else {
1001 gtk_widget_set_sensitive(Xdialog.widget3, FALSE);
1002 }
1003
1004 model = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget2));
1005
1006 if (gtk_tree_model_get_iter_first(model, &tree_iter)) {
1007 gtk_widget_set_sensitive(Xdialog.widget4, TRUE);
1008 } else {
1009 gtk_widget_set_sensitive(Xdialog.widget4, FALSE);
1010 }
1011 }
1012 #else
sensitive_buttons(void)1013 void sensitive_buttons(void)
1014 {
1015 gtk_widget_set_sensitive(Xdialog.widget3,
1016 g_list_length(GTK_LIST(Xdialog.widget1)->children) != 0);
1017 gtk_widget_set_sensitive(Xdialog.widget4,
1018 g_list_length(GTK_LIST(Xdialog.widget2)->children) != 0);
1019 }
1020 #endif
1021
1022 #ifdef USE_GTK2
add_to_list(GtkButton * button,gpointer data)1023 gboolean add_to_list(GtkButton *button, gpointer data)
1024 {
1025 GtkTreeIter tree_iter1, tree_iter2;
1026 GtkTreeModel *model1, *model2;
1027 GtkTreeSelection* selection1;
1028
1029 model1 = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget1));
1030 selection1 = gtk_tree_view_get_selection(GTK_TREE_VIEW(Xdialog.widget1));
1031 model2 = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget2));
1032
1033 if (gtk_tree_selection_get_selected(selection1, &model1, &tree_iter1)) {
1034 gchar *name, *tag;
1035 gtk_tree_model_get(model1, &tree_iter1, 0, &name, 1, &tag, -1);
1036
1037 gtk_list_store_append(GTK_LIST_STORE(model2), &tree_iter2);
1038 gtk_list_store_set(GTK_LIST_STORE(model2), &tree_iter2, 0,
1039 name, 1, tag, -1);
1040 gtk_list_store_remove(GTK_LIST_STORE(model1), &tree_iter1);
1041
1042 g_free(name);
1043 g_free(tag);
1044 }
1045
1046 sensitive_buttons();
1047
1048 return TRUE;
1049 }
1050 #else
add_to_list(GtkButton * button,gpointer data)1051 gboolean add_to_list(GtkButton *button, gpointer data)
1052 {
1053 GList *selected;
1054
1055 selected = g_list_copy(GTK_LIST(Xdialog.widget1)->selection);
1056 gtk_list_remove_items_no_unref(GTK_LIST(Xdialog.widget1), selected);
1057 gtk_list_append_items(GTK_LIST(Xdialog.widget2), selected);
1058
1059 sensitive_buttons();
1060
1061 return TRUE;
1062 }
1063 #endif
1064
1065 #ifdef USE_GTK2
remove_from_list(GtkButton * button,gpointer data)1066 gboolean remove_from_list(GtkButton *button, gpointer data)
1067 {
1068 GtkTreeIter tree_iter1, tree_iter2;
1069 GtkTreeModel *model1, *model2;
1070 GtkTreeSelection* selection2;
1071
1072 model1 = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget1));
1073 model2 = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget2));
1074 selection2 = gtk_tree_view_get_selection(GTK_TREE_VIEW(Xdialog.widget2));
1075
1076 if (gtk_tree_selection_get_selected(selection2, &model2, &tree_iter2)) {
1077 gchar *name, *tag;
1078 gtk_tree_model_get(model2, &tree_iter2, 0, &name, 1, &tag, -1);
1079
1080 gtk_list_store_append(GTK_LIST_STORE(model1), &tree_iter1);
1081 gtk_list_store_set(GTK_LIST_STORE(model1), &tree_iter1, 0, name, 1, tag, -1);
1082 gtk_list_store_remove(GTK_LIST_STORE(model2), &tree_iter2);
1083
1084 g_free(name);
1085 g_free(tag);
1086 }
1087
1088 sensitive_buttons();
1089
1090 return TRUE;
1091 }
1092 #else
remove_from_list(GtkButton * button,gpointer data)1093 gboolean remove_from_list(GtkButton *button, gpointer data)
1094 {
1095 GList *selected;
1096
1097 selected = g_list_copy(GTK_LIST(Xdialog.widget2)->selection);
1098 gtk_list_remove_items_no_unref(GTK_LIST(Xdialog.widget2), selected);
1099 gtk_list_append_items(GTK_LIST(Xdialog.widget1), selected);
1100
1101 sensitive_buttons();
1102
1103 return TRUE;
1104 }
1105 #endif
1106
1107 #ifdef USE_GTK2
print_list(GtkButton * button,gpointer data)1108 gboolean print_list(GtkButton *button, gpointer data)
1109 {
1110 GtkTreeModel *model;
1111 GtkTreeIter iter;
1112 gboolean valid;
1113 gboolean flag = FALSE;
1114
1115 model = gtk_tree_view_get_model(GTK_TREE_VIEW(Xdialog.widget2));
1116 valid = gtk_tree_model_get_iter_first(model, &iter);
1117
1118 while (valid) {
1119 gchar *name_data, *tag_data;
1120
1121 gtk_tree_model_get(model, &iter, 0, &name_data, 1, &tag_data, -1);
1122
1123 if (flag)
1124 fprintf(Xdialog.output, "%s", Xdialog.separator);
1125
1126 fprintf(Xdialog.output, "%s", tag_data);
1127 flag = TRUE;
1128
1129 g_free(name_data);
1130 g_free(tag_data);
1131
1132 valid = gtk_tree_model_iter_next(model, &iter);
1133 }
1134
1135 if (flag)
1136 fprintf(Xdialog.output, "\n");
1137
1138 return TRUE;
1139 }
1140 #else
print_list(GtkButton * button,gpointer data)1141 gboolean print_list(GtkButton *button, gpointer data)
1142 {
1143 GList *children;
1144 int i;
1145 gboolean flag = FALSE;
1146
1147 children = GTK_LIST(Xdialog.widget2)->children;
1148 while (children != NULL) {
1149 for (i = 0 ; Xdialog.array[i].state != -1 ; i++) {
1150 if (Xdialog.array[i].widget == children->data) {
1151 if (flag)
1152 fprintf(Xdialog.output, "%s", Xdialog.separator);
1153 fprintf(Xdialog.output, "%s", Xdialog.array[i].tag);
1154 flag = TRUE;
1155 break;
1156 }
1157 }
1158 children = g_list_next(children);
1159 }
1160 if (flag)
1161 fprintf(Xdialog.output, "\n");
1162
1163 return TRUE;
1164 }
1165 #endif
1166
buildlist_timeout(gpointer data)1167 gboolean buildlist_timeout(gpointer data)
1168 {
1169 return print_list(NULL, NULL);
1170 }
1171
1172 /* fselect and dselect callback */
1173
filesel_exit(GtkObject * filesel,gpointer client_data)1174 gboolean filesel_exit(GtkObject *filesel, gpointer client_data)
1175 {
1176 fprintf(Xdialog.output, "%s\n",
1177 gtk_file_selection_get_filename(GTK_FILE_SELECTION(client_data)));
1178 return exit_ok(NULL, NULL);
1179 }
1180
1181 /* colorsel callback */
1182
colorsel_exit(GtkObject * colorsel,gpointer client_data)1183 gboolean colorsel_exit(GtkObject *colorsel, gpointer client_data)
1184 {
1185 gdouble colors[4];
1186
1187 gtk_color_selection_get_color(GTK_COLOR_SELECTION(client_data), colors);
1188 fprintf(Xdialog.output, "%d %d %d\n",
1189 (int) (255.0 * colors[0]), (int) (255.0 * colors[1]), (int) (255.0 * colors[2]));
1190 return exit_ok(NULL, NULL);
1191 }
1192
1193 /* fontsel callback */
1194
fontsel_exit(GtkObject * fontsel,gpointer client_data)1195 gboolean fontsel_exit(GtkObject *fontsel, gpointer client_data)
1196 {
1197 fprintf(Xdialog.output, "%s\n",
1198 gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(client_data)));
1199 return exit_ok(NULL, NULL);
1200 }
1201
1202 /* calendar callbacks */
1203
calendar_exit(gpointer object,gpointer data)1204 gboolean calendar_exit(gpointer object, gpointer data)
1205 {
1206 gint day, month, year;
1207
1208 gtk_calendar_get_date(GTK_CALENDAR(Xdialog.widget1), &year, &month, &day);
1209 fprintf(Xdialog.output, "%02d/%02d/%d\n", day, month+1, year);
1210
1211 return TRUE;
1212 }
1213
calendar_timeout(gpointer data)1214 gboolean calendar_timeout(gpointer data)
1215 {
1216 return calendar_exit(NULL, NULL);
1217 }
1218
1219 /* timebox callbacks */
1220
timebox_exit(gpointer object,gpointer data)1221 gboolean timebox_exit(gpointer object, gpointer data)
1222 {
1223 fprintf(Xdialog.output, "%02d:%02d:%02d\n",
1224 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(Xdialog.widget1)),
1225 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(Xdialog.widget2)),
1226 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(Xdialog.widget3)));
1227
1228 return TRUE;
1229 }
1230
timebox_timeout(gpointer data)1231 gboolean timebox_timeout(gpointer data)
1232 {
1233 return timebox_exit(NULL, NULL);
1234 }
1235