X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=driver%2Fdemo-Gtk.c;h=298860a7e130a07dfb0cd4f4c0a9cd5435e8b27c;hp=715ca3934f55a472ed8a2b8300177e391a65d9b3;hb=ffd8c0873576a9e3065696a624dce6b766b77062;hpb=6a1da724858673ac40aa13a9612340d8bed8c7b9 diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c index 715ca393..298860a7 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-2003 Jamie Zawinski + * xscreensaver, Copyright (c) 1993-2004 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 @@ -116,6 +116,9 @@ #include "logo-50.xpm" #include "logo-180.xpm" +#undef dgettext /* else these are defined twice... */ +#undef dcgettext + #include "demo-Gtk-widgets.h" #include "demo-Gtk-support.h" #include "demo-Gtk-conf.h" @@ -135,6 +138,8 @@ enum { /* from exec.c */ extern void exec_command (const char *shell, const char *command, int nice); +static void hack_subproc_environment (Window preview_window_id, Bool debug_p); + #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -211,7 +216,7 @@ static int maybe_reload_init_file (state *); static void await_xscreensaver (state *); static void schedule_preview (state *, const char *cmd); -static void kill_preview_subproc (state *); +static void kill_preview_subproc (state *, Bool reset_p); static void schedule_preview_check (state *); @@ -572,6 +577,11 @@ run_cmd (state *s, Atom command, int arg) flush_dialog_changes_and_save (s); status = xscreensaver_command (GDK_DISPLAY(), command, arg, False, &err); + + /* Kludge: ignore the spurious "window unexpectedly deleted" errors... */ + if (status < 0 && err && strstr (err, "unexpectedly deleted")) + status = 0; + if (status < 0) { char buf [255]; @@ -615,7 +625,7 @@ exit_menu_cb (GtkMenuItem *menuitem, gpointer user_data) { state *s = global_state_kludge; /* I hate C so much... */ flush_dialog_changes_and_save (s); - kill_preview_subproc (s); + kill_preview_subproc (s, False); gtk_main_quit (); } @@ -648,9 +658,9 @@ about_menu_cb (GtkMenuItem *menuitem, gpointer user_data) look as good in the plain-old default Latin1 "C" locale.) */ #ifdef HAVE_GTK2 - sprintf(copy, ("Copyright \xC2\xA9 1991-2003 %s"), s); + sprintf(copy, ("Copyright \xC2\xA9 1991-2004 %s"), s); #else /* !HAVE_GTK2 */ - sprintf(copy, ("Copyright \251 1991-2003 %s"), s); + sprintf(copy, ("Copyright \251 1991-2004 %s"), s); #endif /* !HAVE_GTK2 */ sprintf (msg, "%s\n\n%s", copy, desc); @@ -1576,7 +1586,6 @@ mode_menu_item_cb (GtkWidget *widget, gpointer user_data) GList *menu_items = gtk_container_children (GTK_CONTAINER (widget->parent)); int menu_index = 0; saver_mode new_mode; - int old_selected = p->selected_hack; while (menu_items) { @@ -1590,17 +1599,12 @@ mode_menu_item_cb (GtkWidget *widget, gpointer user_data) new_mode = mode_menu_order[menu_index]; /* Keep the same list element displayed as before; except if we're - switching *to* "one screensaver" mode from any other mode, scroll - to and select "the one". + switching *to* "one screensaver" mode from any other mode, set + "the one" to be that which is currently selected. */ - list_elt = -1; + list_elt = selected_list_element (s); if (new_mode == ONE_HACK) - list_elt = (p->selected_hack >= 0 - ? s->hack_number_to_list_elt[p->selected_hack] - : -1); - - if (list_elt < 0) - list_elt = selected_list_element (s); + p->selected_hack = s->list_elt_to_hack_number[list_elt]; { saver_mode old_mode = p->mode; @@ -1611,9 +1615,6 @@ mode_menu_item_cb (GtkWidget *widget, gpointer user_data) } pref_changed_cb (widget, user_data); - - if (old_selected != p->selected_hack) - abort(); /* dammit, not again... */ } @@ -2013,7 +2014,7 @@ server_current_hack (void) Atom type; int format; unsigned long nitems, bytesafter; - CARD32 *data = 0; + unsigned char *dataP = 0; Display *dpy = GDK_DISPLAY(); int hack_number = -1; @@ -2021,14 +2022,17 @@ server_current_hack (void) XA_SCREENSAVER_STATUS, 0, 3, False, XA_INTEGER, &type, &format, &nitems, &bytesafter, - (unsigned char **) &data) + &dataP) == Success && type == XA_INTEGER && nitems >= 3 - && data) - hack_number = (int) data[2] - 1; + && dataP) + { + CARD32 *data = (CARD32 *) dataP; + hack_number = (int) data[2] - 1; + } - if (data) free (data); + if (dataP) XFree (dataP); return hack_number; } @@ -2372,7 +2376,7 @@ populate_prefs_page (state *s) # define THROTTLE(NAME) if (p->NAME != 0 && p->NAME < 60000) p->NAME = 60000 THROTTLE (timeout); THROTTLE (cycle); - THROTTLE (passwd_timeout); + /* THROTTLE (passwd_timeout); */ /* GUI doesn't set this; leave it alone */ # undef THROTTLE # define FMT_MINUTES(NAME,N) \ @@ -2840,15 +2844,15 @@ populate_demo_window (state *s, int list_elt) if (!pretty_name) pretty_name = strdup (_("Preview")); - gtk_frame_set_label (frame1, pretty_name); - gtk_frame_set_label (frame2, pretty_name); + gtk_frame_set_label (frame1, _(pretty_name)); + gtk_frame_set_label (frame2, _(pretty_name)); gtk_entry_set_text (cmd, (hack ? hack->command : "")); gtk_entry_set_position (cmd, 0); { char title[255]; - sprintf (title, "%s: %.100s Settings", + sprintf (title, _("%s: %.100s Settings"), progclass, (pretty_name ? pretty_name : "???")); gtk_window_set_title (GTK_WINDOW (s->popup_widget), title); } @@ -3114,6 +3118,32 @@ clear_preview_window (state *s) } +static void +reset_preview_window (state *s) +{ + /* On some systems (most recently, MacOS X) OpenGL programs get confused + when you kill one and re-start another on the same window. So maybe + it's best to just always destroy and recreate the preview window + when changing hacks, instead of always trying to reuse the same one? + */ + GtkWidget *pr = name_to_widget (s, "preview"); + if (GTK_WIDGET_REALIZED (pr)) + { + Window oid = (pr->window ? GDK_WINDOW_XWINDOW (pr->window) : 0); + Window id; + gtk_widget_hide (pr); + gtk_widget_unrealize (pr); + gtk_widget_realize (pr); + gtk_widget_show (pr); + id = (pr->window ? GDK_WINDOW_XWINDOW (pr->window) : 0); + if (s->debug_p) + fprintf (stderr, "%s: window id 0x%X -> 0x%X\n", blurb(), + (unsigned int) oid, + (unsigned int) id); + } +} + + static void fix_preview_visual (state *s) { @@ -3328,7 +3358,7 @@ get_best_gl_visual (state *s) static void -kill_preview_subproc (state *s) +kill_preview_subproc (state *s, Bool reset_p) { s->running_preview_error_p = False; @@ -3374,6 +3404,12 @@ kill_preview_subproc (state *s) } reap_zombies (s); + + if (reset_p) + { + reset_preview_window (s); + clear_preview_window (s); + } } @@ -3390,13 +3426,17 @@ launch_preview_subproc (state *s) const char *cmd = s->desired_preview_cmd; GtkWidget *pr = name_to_widget (s, "preview"); - GdkWindow *window = pr->window; + GdkWindow *window; + + reset_preview_window (s); + + window = pr->window; s->running_preview_error_p = False; if (s->preview_suppressed_p) { - kill_preview_subproc (s); + kill_preview_subproc (s, False); goto DONE; } @@ -3416,7 +3456,7 @@ launch_preview_subproc (state *s) (unsigned int) id); } - kill_preview_subproc (s); + kill_preview_subproc (s, False); if (! new_cmd) { s->running_preview_error_p = True; @@ -3439,6 +3479,8 @@ launch_preview_subproc (state *s) { close (ConnectionNumber (GDK_DISPLAY())); + hack_subproc_environment (id, s->debug_p); + usleep (250000); /* pause for 1/4th second before launching, to give the previous program time to die and flush its X buffer, so we don't get leftover turds on the @@ -3529,6 +3571,29 @@ hack_environment (state *s) } +static void +hack_subproc_environment (Window preview_window_id, Bool debug_p) +{ + /* Store a window ID in $XSCREENSAVER_WINDOW -- this isn't strictly + necessary yet, but it will make programs work if we had invoked + them with "-root" and not with "-window-id" -- which, of course, + doesn't happen. + */ + char *nssw = (char *) malloc (40); + sprintf (nssw, "XSCREENSAVER_WINDOW=0x%X", (unsigned int) preview_window_id); + + /* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems + any more, right? It's not Posix, but everyone seems to have it. */ + if (putenv (nssw)) + abort (); + + if (debug_p) + fprintf (stderr, "%s: %s\n", blurb(), nssw); + + /* do not free(nssw) -- see above */ +} + + /* Called from a timer: Launches the currently-chosen subprocess, if it's not already running. If there's a different process running, kills it. @@ -3538,7 +3603,7 @@ update_subproc_timer (gpointer data) { state *s = (state *) data; if (! s->desired_preview_cmd) - kill_preview_subproc (s); + kill_preview_subproc (s, True); else if (!s->running_preview_cmd || !!strcmp (s->desired_preview_cmd, s->running_preview_cmd)) launch_preview_subproc (s); @@ -3661,7 +3726,7 @@ screen_blanked_p (void) Atom type; int format; unsigned long nitems, bytesafter; - CARD32 *data = 0; + unsigned char *dataP = 0; Display *dpy = GDK_DISPLAY(); Bool blanked_p = False; @@ -3669,14 +3734,17 @@ screen_blanked_p (void) XA_SCREENSAVER_STATUS, 0, 3, False, XA_INTEGER, &type, &format, &nitems, &bytesafter, - (unsigned char **) &data) + &dataP) == Success && type == XA_INTEGER && nitems >= 3 - && data) - blanked_p = (data[0] == XA_BLANK || data[0] == XA_LOCK); + && dataP) + { + Atom *data = (Atom *) dataP; + blanked_p = (data[0] == XA_BLANK || data[0] == XA_LOCK); + } - if (data) free (data); + if (dataP) XFree (dataP); return blanked_p; } @@ -3694,7 +3762,7 @@ check_blanked_timer (gpointer data) { if (s->debug_p) fprintf (stderr, "%s: screen is blanked: killing preview\n", blurb()); - kill_preview_subproc (s); + kill_preview_subproc (s, True); } return True; /* re-execute timer */ @@ -3875,7 +3943,7 @@ demo_ehandler (Display *dpy, XErrorEvent *error) state *s = global_state_kludge; /* I hate C so much... */ fprintf (stderr, "\nX error in %s:\n", blurb()); XmuPrintDefaultErrorMessage (dpy, error, stderr); - kill_preview_subproc (s); + kill_preview_subproc (s, False); exit (-1); return 0; } @@ -4034,6 +4102,7 @@ main (int argc, char **argv) Widget toplevel_shell; char *real_progname = argv[0]; char *window_title; + char *geom = 0; Bool crapplet_p = False; char *str; @@ -4128,6 +4197,21 @@ main (int argc, char **argv) argc--; i--; } + else if (argv[i] && + argc > i+1 && + *argv[i+1] && + (!strcmp(argv[i], "-geometry") || + !strcmp(argv[i], "-geom") || + !strcmp(argv[i], "-geo") || + !strcmp(argv[i], "-g"))) + { + int j; + geom = argv[i+1]; + for (j = i; j < argc; j++) /* remove them from the list */ + argv[j] = argv[j+2]; + argc -= 2; + i -= 2; + } else if (argv[i] && argc > i+1 && *argv[i+1] && @@ -4285,7 +4369,8 @@ main (int argc, char **argv) ; else { - fprintf (stderr, _("%s: unknown option: %s\n"), real_progname, argv[i]); + fprintf (stderr, _("%s: unknown option: %s\n"), real_progname, + argv[i]); fprintf (stderr, "%s: %s\n", real_progname, usage); exit (1); } @@ -4496,6 +4581,11 @@ main (int argc, char **argv) free (window_title); window_title = 0; +#ifdef HAVE_GTK2 + /* After picking the default size, allow -geometry to override it. */ + if (geom) + gtk_window_parse_geometry (GTK_WINDOW (s->toplevel_widget), geom); +#endif gtk_widget_show (s->toplevel_widget); init_icon (GTK_WIDGET (s->toplevel_widget)->window); /* after `show' */ @@ -4555,7 +4645,7 @@ main (int argc, char **argv) # endif /* HAVE_CRAPPLET */ gtk_main (); - kill_preview_subproc (s); + kill_preview_subproc (s, False); exit (0); }