X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fdemo-Gtk.c;h=e027622726179ec964043ce7a4009d6e2a588bb6;hb=06e9a7886a77cad92f9ddbc169d6d199a4d8b76d;hp=2b07ab0ce892fa2905e0b3c2b43d820d111b6e4b;hpb=0ed85ca0e4b0eae40a4f50a51d63f2f41e45373a;p=xscreensaver diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c index 2b07ab0c..e0276227 100644 --- a/driver/demo-Gtk.c +++ b/driver/demo-Gtk.c @@ -1,5 +1,5 @@ /* demo-Gtk.c --- implements the interactive demo-mode and options dialogs. - * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski + * xscreensaver, Copyright (c) 1993-1999 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -101,7 +101,7 @@ static void populate_demo_window (GtkWidget *toplevel, int which, prefs_pair *pair); static void populate_prefs_page (GtkWidget *top, prefs_pair *pair); static int apply_changes_and_save (GtkWidget *widget); - +static int maybe_reload_init_file (GtkWidget *widget, prefs_pair *pair); /* Some random utility functions @@ -186,6 +186,9 @@ ensure_selected_item_visible (GtkWidget *widget) ratio_t = ((double) child_y) / ((double) children_h); ratio_b = ((double) child_y + child_h) / ((double) children_h); + if (adj->upper == 0.0) /* no items in list */ + return; + if (ratio_t < (adj->value / adj->upper) || ratio_b > ((adj->value + adj->page_size) / adj->upper)) { @@ -279,9 +282,7 @@ warning_dialog (GtkWidget *parent, const char *message, int center) gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), label, TRUE, TRUE, 0); - ok = gtk_button_new_with_label ( - get_string_resource ("warning_dialog.ok.label", - "warning_dialog.Button.Label")); + ok = gtk_button_new_with_label ("OK"); gtk_container_add (GTK_CONTAINER (label), ok); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); @@ -332,7 +333,7 @@ run_hack (GtkWidget *widget, int which, Bool report_errors_p) if (which < 0) return; apply_changes_and_save (widget); if (report_errors_p) - run_cmd (widget, XA_ACTIVATE, 0); + run_cmd (widget, XA_DEMO, which + 1); else { char *s = 0; @@ -542,6 +543,9 @@ apply_changes_and_save (GtkWidget *widget) if (which < 0) return -1; + if (maybe_reload_init_file (widget, pair) != 0) + return 1; + /* Sanity-check and canonicalize whatever the user typed into the combo box. */ if (!strcasecmp (visual, "")) visual = ""; @@ -713,7 +717,7 @@ run_prev_cb (GtkButton *button, gpointer user_data) this parses the text, and does error checking. */ static void -hack_time_text (const char *line, Time *store, Bool sec_p) +hack_time_text (GtkWidget *widget, const char *line, Time *store, Bool sec_p) { if (*line) { @@ -721,7 +725,14 @@ hack_time_text (const char *line, Time *store, Bool sec_p) value = parse_time ((char *) line, sec_p, True); value *= 1000; /* Time measures in microseconds */ if (value < 0) - /* gdk_beep () */; + { + char b[255]; + sprintf (b, + "Error:\n\n" + "Unparsable time format: \"%s\"\n", + line); + warning_dialog (widget, b, 100); + } else *store = value; } @@ -739,13 +750,13 @@ prefs_ok_cb (GtkButton *button, gpointer user_data) Bool changed = False; # define SECONDS(field, name) \ - hack_time_text (gtk_entry_get_text (\ + hack_time_text (GTK_WIDGET(button), gtk_entry_get_text (\ GTK_ENTRY (name_to_widget (GTK_WIDGET(button), (name)))), \ (field), \ True) # define MINUTES(field, name) \ - hack_time_text (gtk_entry_get_text (\ + hack_time_text (GTK_WIDGET(button), gtk_entry_get_text (\ GTK_ENTRY (name_to_widget (GTK_WIDGET(button), (name)))), \ (field), \ False) @@ -758,7 +769,11 @@ prefs_ok_cb (GtkButton *button, gpointer user_data) if (! *line) \ ; \ else if (sscanf (line, "%u%c", &value, &c) != 1) \ - gdk_beep(); \ + { \ + char b[255]; \ + sprintf (b, "Error:\n\n" "Not an integer: \"%s\"\n", line); \ + warning_dialog (GTK_WIDGET (button), b, 100); \ + } \ else \ *(field) = value; \ } while(0) @@ -931,6 +946,7 @@ make_pretty_name (const char *shell_command) static void scroll_to_current_hack (GtkWidget *toplevel, prefs_pair *pair) { + saver_preferences *p = pair->a; Atom type; int format; unsigned long nitems, bytesafter; @@ -957,9 +973,12 @@ scroll_to_current_hack (GtkWidget *toplevel, prefs_pair *pair) list = GTK_LIST (name_to_widget (toplevel, "list")); apply_changes_and_save (toplevel); - gtk_list_select_item (list, which); - ensure_selected_item_visible (GTK_WIDGET (list)); - populate_demo_window (toplevel, which, pair); + if (which < p->screenhacks_count) + { + gtk_list_select_item (list, which); + ensure_selected_item_visible (GTK_WIDGET (list)); + populate_demo_window (toplevel, which, pair); + } } @@ -972,7 +991,7 @@ populate_hack_list (GtkWidget *toplevel, prefs_pair *pair) screenhack **hacks = p->screenhacks; screenhack **h; - for (h = hacks; *h; h++) + for (h = hacks; h && *h; h++) { GtkWidget *line; char *pretty_name = (h[0]->name @@ -1183,6 +1202,7 @@ static char *down_arrow_xpm[] = { "+ c #D6D6D6", "@ c #000000", + " ", " ------------- ", " -+++++++++++@ ", " -+++++++++@ ", @@ -1383,7 +1403,8 @@ static void populate_demo_window (GtkWidget *toplevel, int which, prefs_pair *pair) { saver_preferences *p = pair->a; - screenhack *hack = (which >= 0 ? p->screenhacks[which] : 0); + screenhack *hack = (which >= 0 && which < p->screenhacks_count + ? p->screenhacks[which] : 0); GtkFrame *frame = GTK_FRAME (name_to_widget (toplevel, "frame")); GtkLabel *doc = GTK_LABEL (name_to_widget (toplevel, "doc")); GtkEntry *cmd = GTK_ENTRY (name_to_widget (toplevel, "cmd_text")); @@ -1421,6 +1442,69 @@ populate_demo_window (GtkWidget *toplevel, int which, prefs_pair *pair) } +static void +widget_deleter (GtkWidget *widget, gpointer data) +{ + /* #### Well, I want to destroy these widgets, but if I do that, they get + referenced again, and eventually I get a SEGV. So instead of + destroying them, I'll just hide them, and leak a bunch of memory + every time the disk file changes. Go go go Gtk! + + #### Ok, that's a lie, I get a crash even if I just hide the widget + and don't ever delete it. Fuck! + */ +#if 0 + gtk_widget_destroy (widget); +#else + gtk_widget_hide (widget); +#endif +} + + +static int +maybe_reload_init_file (GtkWidget *widget, prefs_pair *pair) +{ + int status = 0; + saver_preferences *p = pair->a; + + static Bool reentrant_lock = False; + if (reentrant_lock) return 0; + reentrant_lock = True; + + if (init_file_changed_p (p)) + { + const char *f = init_file_name(); + char *b; + int which; + GtkList *list; + + if (!f || !*f) return 0; + b = (char *) malloc (strlen(f) + 1024); + sprintf (b, + "Warning:\n\n" + "file \"%s\" has changed, reloading.\n", + f); + warning_dialog (widget, b, 100); + free (b); + + load_init_file (p); + + which = selected_hack_number (widget); + list = GTK_LIST (name_to_widget (widget, "list")); + gtk_container_foreach (GTK_CONTAINER (list), widget_deleter, NULL); + populate_hack_list (widget, pair); + gtk_list_select_item (list, which); + populate_prefs_page (widget, pair); + populate_demo_window (widget, which, pair); + ensure_selected_item_visible (GTK_WIDGET (list)); + + status = 1; + } + + reentrant_lock = False; + return status; +} + /* The main demo-mode command loop. @@ -1714,6 +1798,7 @@ main (int argc, char **argv) prefs = True; else { + fprintf (stderr, "%s: unknown option: %s\n", real_progname, argv[i]); fprintf (stderr, "usage: %s [ -display dpy-string ] [ -prefs ]\n", real_progname); exit (1);