/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
- * xscreensaver, Copyright (c) 1993-2004 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2005 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include <gdk/gdkx.h>
#ifdef HAVE_GTK2
-#include <glade/glade-xml.h>
-#endif /* HAVE_GTK2 */
+# include <glade/glade-xml.h>
+# include <gmodule.h>
+#else /* !HAVE_GTK2 */
+# define G_MODULE_EXPORT /**/
+#endif /* !HAVE_GTK2 */
#if defined(DEFAULT_ICONDIR) && !defined(GLADE_DIR)
# define GLADE_DIR DEFAULT_ICONDIR
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 *);
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];
\f
/* Button callbacks
+
+ According to Eric Lassauge, this G_MODULE_EXPORT crud is needed to make
+ libglade work on Cygwin; apparently all Glade callbacks need this magic
+ extra declaration. I do not pretend to understand.
*/
-void
+G_MODULE_EXPORT void
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 ();
}
}
-void
+G_MODULE_EXPORT void
about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
{
char msg [2048];
look as good in the plain-old default Latin1 "C" locale.)
*/
#ifdef HAVE_GTK2
- sprintf(copy, ("Copyright \xC2\xA9 1991-2004 %s"), s);
+ sprintf(copy, ("Copyright \xC2\xA9 1991-2005 %s"), s);
#else /* !HAVE_GTK2 */
- sprintf(copy, ("Copyright \251 1991-2004 %s"), s);
+ sprintf(copy, ("Copyright \251 1991-2005 %s"), s);
#endif /* !HAVE_GTK2 */
sprintf (msg, "%s\n\n%s", copy, desc);
}
-void
+G_MODULE_EXPORT void
doc_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
help_command = (char *) malloc (strlen (p->load_url_command) +
- (strlen (p->help_url) * 2) + 20);
+ (strlen (p->help_url) * 4) + 20);
strcpy (help_command, "( ");
sprintf (help_command + strlen(help_command),
- p->load_url_command, p->help_url, p->help_url);
+ p->load_url_command,
+ p->help_url, p->help_url, p->help_url, p->help_url);
strcat (help_command, " ) &");
system (help_command);
free (help_command);
}
-void
+G_MODULE_EXPORT void
activate_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
lock_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
kill_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
restart_menu_cb (GtkWidget *widget, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
run_this_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
manual_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
cmd = get_string_resource ("manualCommand", "ManualCommand");
if (cmd)
{
- char *cmd2 = (char *) malloc (strlen (cmd) + strlen (name2) + 100);
+ char *cmd2 = (char *) malloc (strlen (cmd) + (strlen (name2) * 4) + 100);
strcpy (cmd2, "( ");
sprintf (cmd2 + strlen (cmd2),
cmd,
}
-void
+G_MODULE_EXPORT void
run_next_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
run_prev_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
pref_changed_cb (GtkWidget *widget, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
}
-gboolean
+G_MODULE_EXPORT gboolean
pref_changed_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
pref_changed_cb (widget, user_data);
}
-void
+G_MODULE_EXPORT void
switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page,
gint page_num, gpointer user_data)
{
}
-void
+G_MODULE_EXPORT void
browse_image_dir_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
}
-void
+G_MODULE_EXPORT void
settings_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
# endif /* HAVE_XML */
}
-void
+G_MODULE_EXPORT void
settings_adv_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
gtk_notebook_set_page (notebook, 1);
}
-void
+G_MODULE_EXPORT void
settings_std_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
gtk_notebook_set_page (notebook, 0);
}
-void
+G_MODULE_EXPORT void
settings_switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page,
gint page_num, gpointer user_data)
{
-void
+G_MODULE_EXPORT void
settings_cancel_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
gtk_widget_hide (s->popup_widget);
}
-void
+G_MODULE_EXPORT void
settings_ok_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
Atom type;
int format;
unsigned long nitems, bytesafter;
- CARD32 *data = 0;
+ unsigned char *dataP = 0;
Display *dpy = GDK_DISPLAY();
int hack_number = -1;
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;
}
{
Bool found_any_writable_cells = False;
+ Bool fading_possible = False;
Bool dpms_supported = False;
Display *dpy = GDK_DISPLAY();
}
}
+ fading_possible = found_any_writable_cells;
#ifdef HAVE_XF86VMODE_GAMMA
- found_any_writable_cells = True; /* if we can gamma fade, go for it */
+ fading_possible = True;
#endif
#ifdef HAVE_DPMS_EXTENSION
/* Colormaps
*/
- SENSITIZE ("cmap_frame", found_any_writable_cells);
+ SENSITIZE ("cmap_frame", found_any_writable_cells || fading_possible);
SENSITIZE ("install_button", found_any_writable_cells);
- SENSITIZE ("fade_button", found_any_writable_cells);
- SENSITIZE ("unfade_button", found_any_writable_cells);
+ SENSITIZE ("fade_button", fading_possible);
+ SENSITIZE ("unfade_button", fading_possible);
- SENSITIZE ("fade_label", (found_any_writable_cells &&
+ SENSITIZE ("fade_label", (fading_possible &&
(p->fade_p || p->unfade_p)));
- SENSITIZE ("fade_spinbutton", (found_any_writable_cells &&
+ SENSITIZE ("fade_spinbutton", (fading_possible &&
(p->fade_p || p->unfade_p)));
# undef SENSITIZE
}
+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)
{
static void
-kill_preview_subproc (state *s)
+kill_preview_subproc (state *s, Bool reset_p)
{
s->running_preview_error_p = False;
}
reap_zombies (s);
+
+ if (reset_p)
+ {
+ reset_preview_window (s);
+ clear_preview_window (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;
}
(unsigned int) id);
}
- kill_preview_subproc (s);
+ kill_preview_subproc (s, False);
if (! new_cmd)
{
s->running_preview_error_p = True;
{
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);
Atom type;
int format;
unsigned long nitems, bytesafter;
- CARD32 *data = 0;
+ unsigned char *dataP = 0;
Display *dpy = GDK_DISPLAY();
Bool blanked_p = False;
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;
}
{
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 */
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;
}
# endif /* HAVE_CRAPPLET */
gtk_main ();
- kill_preview_subproc (s);
+ kill_preview_subproc (s, False);
exit (0);
}