/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
- * xscreensaver, Copyright (c) 1993-1999 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2001 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
#endif /* HAVE_UNAME */
#include <stdio.h>
+#include <sys/stat.h>
#include <X11/Xproto.h> /* for CARD32 */
#include <X11/Xatom.h> /* for XA_INTEGER */
# include "xmu.h"
#endif
-
-
#include <gtk/gtk.h>
-extern Display *gdk_display;
+#ifdef HAVE_CRAPPLET
+# include <gnome.h>
+# include <capplet-widget.h>
+#endif
+
+#include <gdk/gdkx.h>
#include "version.h"
#include "prefs.h"
#include "remote.h" /* for xscreensaver_command() */
#include "usleep.h"
+#include "logo-50.xpm"
+#include "logo-180.xpm"
+
#include "demo-Gtk-widgets.h"
#include <stdio.h>
char *progclass = "XScreenSaver";
XrmDatabase db;
+static Bool crapplet_p = False;
+static Bool initializing_p;
+static GtkWidget *toplevel_widget;
+
typedef struct {
saver_preferences *a, *b;
} prefs_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);
+static void await_xscreensaver (GtkWidget *widget);
\f
/* Some random utility functions
static GtkWidget *
name_to_widget (GtkWidget *widget, const char *name)
{
- while (1)
- {
- GtkWidget *parent = (GTK_IS_MENU (widget)
- ? gtk_menu_get_attach_widget (GTK_MENU (widget))
- : widget->parent);
- if (parent)
- widget = parent;
- else
- break;
- }
- return (GtkWidget *) gtk_object_get_data (GTK_OBJECT (widget), name);
+ return (GtkWidget *) gtk_object_get_data (GTK_OBJECT(toplevel_widget), name);
}
-
/* Why this behavior isn't automatic in *either* toolkit, I'll never know.
Takes a scroller, viewport, or list as an argument.
*/
kids; kids = kids->next)
nkids++;
- adj = gtk_scrolled_window_get_vadjustment (scroller);
+ adj = gtk_scrolled_window_get_vadjustment (scroller);
gdk_window_get_geometry (GTK_WIDGET(vp)->window,
&ignore, &ignore, &ignore, &parent_h, &ignore);
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))
{
}
}
-
static void
-warning_dialog_dismiss_cb (GtkButton *button, gpointer user_data)
+warning_dialog_dismiss_cb (GtkWidget *widget, gpointer user_data)
{
GtkWidget *shell = GTK_WIDGET (user_data);
while (shell->parent)
}
+void restart_menu_cb (GtkWidget *widget, gpointer user_data);
+
+static void warning_dialog_restart_cb (GtkWidget *widget, gpointer user_data)
+{
+ restart_menu_cb (widget, user_data);
+ warning_dialog_dismiss_cb (widget, user_data);
+}
+
static void
-warning_dialog (GtkWidget *parent, const char *message, int center)
+warning_dialog (GtkWidget *parent, const char *message,
+ Boolean restart_button_p, int center)
{
char *msg = strdup (message);
char *head;
GtkWidget *dialog = gtk_dialog_new ();
GtkWidget *label = 0;
GtkWidget *ok = 0;
+ GtkWidget *cancel = 0;
int i = 0;
while (parent->parent)
parent = parent->parent;
+ if (!GTK_WIDGET (parent)->window) /* too early to pop up transient dialogs */
+ return;
+
head = msg;
while (head)
{
sprintf (name, "label%d", i++);
{
- char buf[255];
label = gtk_label_new (head);
- sprintf (buf, "warning_dialog.%s.font", name);
- GTK_WIDGET (label)->style = gtk_style_copy (GTK_WIDGET (label)->style);
- GTK_WIDGET (label)->style->font =
- gdk_font_load (get_string_resource (buf, "Dialog.Label.Font"));
+
+ if (i == 1)
+ {
+ GTK_WIDGET (label)->style =
+ gtk_style_copy (GTK_WIDGET (label)->style);
+ GTK_WIDGET (label)->style->font =
+ gdk_font_load (get_string_resource("warning_dialog.headingFont",
+ "Dialog.Font"));
+ gtk_widget_set_style (GTK_WIDGET (label),
+ GTK_WIDGET (label)->style);
+ }
+
if (center <= 0)
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
ok = gtk_button_new_with_label ("OK");
gtk_container_add (GTK_CONTAINER (label), ok);
+ if (restart_button_p)
+ {
+ cancel = gtk_button_new_with_label ("Cancel");
+ gtk_container_add (GTK_CONTAINER (label), cancel);
+ }
+
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
gtk_container_set_border_width (GTK_CONTAINER (dialog), 10);
gtk_window_set_title (GTK_WINDOW (dialog), progclass);
gtk_widget_show (ok);
+ if (cancel)
+ gtk_widget_show (cancel);
gtk_widget_show (label);
gtk_widget_show (dialog);
/* gtk_window_set_default (GTK_WINDOW (dialog), ok);*/
- gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
- GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb),
- (gpointer) dialog);
+ if (restart_button_p)
+ {
+ gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+ GTK_SIGNAL_FUNC (warning_dialog_restart_cb),
+ (gpointer) dialog);
+ gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",
+ GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb),
+ (gpointer) dialog);
+ }
+ else
+ {
+ gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+ GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb),
+ (gpointer) dialog);
+ }
+
gdk_window_set_transient_for (GTK_WIDGET (dialog)->window,
GTK_WIDGET (parent)->window);
int status;
apply_changes_and_save (widget);
- status = xscreensaver_command (gdk_display, command, arg, False, &err);
+ status = xscreensaver_command (GDK_DISPLAY(), command, arg, False, &err);
if (status < 0)
{
char buf [255];
sprintf (buf, "Error:\n\n%s", err);
else
strcpy (buf, "Unknown error!");
- warning_dialog (widget, buf, 100);
+ warning_dialog (widget, buf, False, 100);
}
if (err) free (err);
}
else
{
char *s = 0;
- xscreensaver_command (gdk_display, XA_DEMO, which + 1, False, &s);
+ xscreensaver_command (GDK_DISPLAY(), XA_DEMO, which + 1, False, &s);
if (s) free (s);
}
}
/* #### */
warning_dialog (GTK_WIDGET (menuitem),
"Error:\n\n"
- "cut unimplemented\n", 1);
+ "cut unimplemented\n", False, 1);
}
/* #### */
warning_dialog (GTK_WIDGET (menuitem),
"Error:\n\n"
- "copy unimplemented\n", 1);
+ "copy unimplemented\n", False, 1);
}
/* #### */
warning_dialog (GTK_WIDGET (menuitem),
"Error:\n\n"
- "paste unimplemented\n", 1);
+ "paste unimplemented\n", False, 1);
}
void
about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
{
- char buf [2048];
- char *s = strdup (screensaver_id + 4);
- char *s2;
+ char msg [2048];
+ char *vers = strdup (screensaver_id + 4);
+ char *s;
+ char copy[1024];
+ char *desc = "For updates, check http://www.jwz.org/xscreensaver/";
- s2 = strchr (s, ',');
- *s2 = 0;
- s2 += 2;
+ s = strchr (vers, ',');
+ *s = 0;
+ s += 2;
+
+ sprintf(copy, "Copyright \251 1991-2001 %s", s);
+
+ sprintf (msg, "%s\n\n%s", copy, desc);
- sprintf (buf, "%s\n%s\n\n"
- "For updates, check http://www.jwz.org/xscreensaver/",
- s, s2);
- free (s);
+ /* I can't make gnome_about_new() work here -- it starts dying in
+ gdk_imlib_get_visual() under gnome_about_new(). If this worked,
+ then this might be the thing to do:
- warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+ #ifdef HAVE_CRAPPLET
+ {
+ const gchar *auth[] = { 0 };
+ GtkWidget *about = gnome_about_new (progclass, vers, "", auth, desc,
+ "xscreensaver.xpm");
+ gtk_widget_show (about);
+ }
+ #else / * GTK but not GNOME * /
+ ...
+ */
+ {
+ GdkColormap *colormap;
+ GdkPixmap *gdkpixmap;
+ GdkBitmap *mask;
+
+ GtkWidget *dialog = gtk_dialog_new ();
+ GtkWidget *hbox, *icon, *vbox, *label1, *label2, *hb, *ok;
+ GtkWidget *parent = GTK_WIDGET (menuitem);
+ while (parent->parent)
+ parent = parent->parent;
+
+ hbox = gtk_hbox_new (FALSE, 20);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ hbox, TRUE, TRUE, 0);
+
+ colormap = gtk_widget_get_colormap (parent);
+ gdkpixmap =
+ gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask, NULL,
+ (gchar **) logo_180_xpm);
+ icon = gtk_pixmap_new (gdkpixmap, mask);
+ gtk_misc_set_padding (GTK_MISC (icon), 10, 10);
+
+ gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+
+ label1 = gtk_label_new (vers);
+ gtk_box_pack_start (GTK_BOX (vbox), label1, TRUE, TRUE, 0);
+ gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_alignment (GTK_MISC (label1), 0.0, 0.75);
+
+ GTK_WIDGET (label1)->style = gtk_style_copy (GTK_WIDGET (label1)->style);
+ GTK_WIDGET (label1)->style->font =
+ gdk_font_load (get_string_resource ("about.headingFont","Dialog.Font"));
+ gtk_widget_set_style (GTK_WIDGET (label1), GTK_WIDGET (label1)->style);
+
+ label2 = gtk_label_new (msg);
+ gtk_box_pack_start (GTK_BOX (vbox), label2, TRUE, TRUE, 0);
+ gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_alignment (GTK_MISC (label2), 0.0, 0.25);
+
+ GTK_WIDGET (label2)->style = gtk_style_copy (GTK_WIDGET (label2)->style);
+ GTK_WIDGET (label2)->style->font =
+ gdk_font_load (get_string_resource ("about.bodyFont","Dialog.Font"));
+ gtk_widget_set_style (GTK_WIDGET (label2), GTK_WIDGET (label2)->style);
+
+ hb = gtk_hbutton_box_new ();
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
+ hb, TRUE, TRUE, 0);
+
+ ok = gtk_button_new_with_label ("OK");
+ gtk_container_add (GTK_CONTAINER (hb), ok);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 10);
+ gtk_window_set_title (GTK_WINDOW (dialog), progclass);
+
+ gtk_widget_show (hbox);
+ gtk_widget_show (icon);
+ gtk_widget_show (vbox);
+ gtk_widget_show (label1);
+ gtk_widget_show (label2);
+ gtk_widget_show (hb);
+ gtk_widget_show (ok);
+ gtk_widget_show (dialog);
+
+ gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+ GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb),
+ (gpointer) dialog);
+ gdk_window_set_transient_for (GTK_WIDGET (dialog)->window,
+ GTK_WIDGET (parent)->window);
+ gdk_window_show (GTK_WIDGET (dialog)->window);
+ gdk_window_raise (GTK_WIDGET (dialog)->window);
+ }
}
{
warning_dialog (GTK_WIDGET (menuitem),
"Error:\n\n"
- "No Help URL has been specified.\n", 100);
+ "No Help URL has been specified.\n", False, 100);
return;
}
void
-restart_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+restart_menu_cb (GtkWidget *widget, gpointer user_data)
{
#if 0
- run_cmd (GTK_WIDGET (menuitem), XA_RESTART, 0);
+ run_cmd (GTK_WIDGET (widget), XA_RESTART, 0);
#else
- apply_changes_and_save (GTK_WIDGET (menuitem));
- xscreensaver_command (gdk_display, XA_EXIT, 0, False, NULL);
+ apply_changes_and_save (GTK_WIDGET (widget));
+ xscreensaver_command (GDK_DISPLAY(), XA_EXIT, 0, False, NULL);
sleep (1);
system ("xscreensaver -nosplash &");
#endif
+
+ await_xscreensaver (GTK_WIDGET (widget));
+}
+
+static void
+await_xscreensaver (GtkWidget *widget)
+{
+ int countdown = 5;
+
+ Display *dpy = GDK_DISPLAY();
+ /* GtkWidget *dialog = 0;*/
+ char *rversion = 0;
+
+ while (!rversion && (--countdown > 0))
+ {
+ /* Check for the version of the running xscreensaver... */
+ server_xscreensaver_version (dpy, &rversion, 0, 0);
+
+ /* If it's not there yet, wait a second... */
+ sleep (1);
+ }
+
+/* if (dialog) gtk_widget_destroy (dialog);*/
+
+ if (rversion)
+ {
+ /* Got it. */
+ free (rversion);
+ }
+ else
+ {
+ /* Timed out, no screensaver running. */
+
+ char buf [1024];
+ Bool root_p = (geteuid () == 0);
+
+ strcpy (buf,
+ "Error:\n\n"
+ "The xscreensaver daemon did not start up properly.\n"
+ "\n");
+
+ if (root_p)
+ strcat (buf,
+ "You are running as root. This usually means that xscreensaver\n"
+ "was unable to contact your X server because access control is\n"
+ "turned on. Try running this command:\n"
+ "\n"
+ " xhost +localhost\n"
+ "\n"
+ "and then selecting `File / Restart Daemon'.\n"
+ "\n"
+ "Note that turning off access control will allow anyone logged\n"
+ "on to this machine to access your screen, which might be\n"
+ "considered a security problem. Please read the xscreensaver\n"
+ "manual and FAQ for more information.\n"
+ "\n"
+ "You shouldn't run X as root. Instead, you should log in as a\n"
+ "normal user, and `su' as necessary.");
+ else
+ strcat (buf, "Please check your $PATH and permissions.");
+
+ warning_dialog (widget, buf, False, 1);
+ }
}
if (!f || !*f)
warning_dialog (widget,
"Error:\n\nCouldn't determine init file name!\n",
- 100);
+ False, 100);
else
{
char *b = (char *) malloc (strlen(f) + 1024);
sprintf (b, "Error:\n\nCouldn't write %s\n", f);
- warning_dialog (widget, b, 100);
+ warning_dialog (widget, b, False, 100);
free (b);
}
return -1;
static int
-apply_changes_and_save (GtkWidget *widget)
+apply_changes_and_save_1 (GtkWidget *widget)
{
/* prefs_pair *pair = (prefs_pair *) client_data; */
prefs_pair *pair = global_prefs_pair; /* I hate C so much... */
return 0;
}
+void prefs_ok_cb (GtkButton *button, gpointer user_data);
+
+static int
+apply_changes_and_save (GtkWidget *widget)
+{
+ prefs_ok_cb ((GtkButton *) widget, 0);
+ return apply_changes_and_save_1 (widget);
+}
+
+
void
run_this_cb (GtkButton *button, gpointer user_data)
{
{
warning_dialog (GTK_WIDGET (button),
"Error:\n\nno `manualCommand' resource set.",
- 100);
+ False, 100);
}
free (name);
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)
{
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, False, 100);
+ }
else
*store = value;
}
}
+static Bool
+directory_p (const char *path)
+{
+ struct stat st;
+ if (!path || !*path)
+ return False;
+ else if (stat (path, &st))
+ return False;
+ else if (!S_ISDIR (st.st_mode))
+ return False;
+ else
+ return True;
+}
+
+static char *
+normalize_directory (const char *path)
+{
+ int L;
+ char *p2, *s;
+ if (!path) return 0;
+ L = strlen (path);;
+ p2 = (char *) malloc (L + 2);
+ strcpy (p2, path);
+ if (p2[L-1] == '/') /* remove trailing slash */
+ p2[--L] = 0;
+
+ for (s = p2; s && *s; s++)
+ {
+ if (*s == '/' &&
+ (!strncmp (s, "/../", 4) || /* delete "XYZ/../" */
+ !strncmp (s, "/..\000", 4))) /* delete "XYZ/..$" */
+ {
+ char *s0 = s;
+ while (s0 > p2 && s0[-1] != '/')
+ s0--;
+ if (s0 > p2)
+ {
+ s0--;
+ s += 3;
+ strcpy (s0, s);
+ s = s0-1;
+ }
+ }
+ else if (*s == '/' && !strncmp (s, "/./", 3)) /* delete "/./" */
+ strcpy (s, s+2), s--;
+ else if (*s == '/' && !strncmp (s, "/.\000", 3)) /* delete "/.$" */
+ *s = 0, s--;
+ }
+
+ for (s = p2; s && *s; s++) /* normalize consecutive slashes */
+ while (s[0] == '/' && s[1] == '/')
+ strcpy (s, s+1);
+
+ return p2;
+}
+
+
void
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)
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, False, 100); \
+ } \
else \
*(field) = value; \
} while(0)
+# define PATHNAME(field, name) do { \
+ char *line = gtk_entry_get_text (\
+ GTK_ENTRY (name_to_widget (GTK_WIDGET(button), (name)))); \
+ if (! *line) \
+ ; \
+ else if (!directory_p (line)) \
+ { \
+ char b[255]; \
+ sprintf (b, "Error:\n\n" "Directory does not exist: \"%s\"\n", line); \
+ warning_dialog (GTK_WIDGET (button), b, False, 100); \
+ if ((field)) free ((field)); \
+ (field) = strdup(line); \
+ } \
+ else { \
+ if ((field)) free ((field)); \
+ (field) = strdup(line); \
+ } \
+ } while(0)
+
# define CHECKBOX(field, name) \
field = gtk_toggle_button_get_active (\
GTK_TOGGLE_BUTTON (name_to_widget (GTK_WIDGET(button), (name))))
- MINUTES (&p2->timeout, "timeout_text");
- MINUTES (&p2->cycle, "cycle_text");
- SECONDS (&p2->fade_seconds, "fade_text");
- INTEGER (&p2->fade_ticks, "ticks_text");
- MINUTES (&p2->lock_timeout, "lock_text");
- SECONDS (&p2->passwd_timeout, "pass_text");
- CHECKBOX (p2->verbose_p, "verbose_button");
- CHECKBOX (p2->install_cmap_p, "install_button");
- CHECKBOX (p2->fade_p, "fade_button");
- CHECKBOX (p2->unfade_p, "unfade_button");
- CHECKBOX (p2->lock_p, "lock_button");
+ MINUTES (&p2->timeout, "timeout_text");
+ MINUTES (&p2->cycle, "cycle_text");
+ CHECKBOX (p2->lock_p, "lock_button");
+ MINUTES (&p2->lock_timeout, "lock_text");
+
+ CHECKBOX (p2->dpms_enabled_p, "dpms_button");
+ MINUTES (&p2->dpms_standby, "dpms_standby_text");
+ MINUTES (&p2->dpms_suspend, "dpms_suspend_text");
+ MINUTES (&p2->dpms_off, "dpms_off_text");
+
+ CHECKBOX (p2->grab_desktop_p, "grab_desk_button");
+ CHECKBOX (p2->grab_video_p, "grab_video_button");
+ CHECKBOX (p2->random_image_p, "grab_image_button");
+ PATHNAME (p2->image_directory, "image_text");
+
+ CHECKBOX (p2->verbose_p, "verbose_button");
+ CHECKBOX (p2->capture_stderr_p, "capture_button");
+ CHECKBOX (p2->splash_p, "splash_button");
+
+ CHECKBOX (p2->install_cmap_p, "install_button");
+ CHECKBOX (p2->fade_p, "fade_button");
+ CHECKBOX (p2->unfade_p, "unfade_button");
+ SECONDS (&p2->fade_seconds, "fade_text");
# undef SECONDS
# undef MINUTES
# undef INTEGER
+# undef PATHNAME
# undef CHECKBOX
# define COPY(field) \
COPY(timeout);
COPY(cycle);
+ COPY(lock_p);
COPY(lock_timeout);
- COPY(passwd_timeout);
- COPY(fade_seconds);
- COPY(fade_ticks);
+
+ COPY(dpms_enabled_p);
+ COPY(dpms_standby);
+ COPY(dpms_suspend);
+ COPY(dpms_off);
+
+ COPY (grab_desktop_p);
+ COPY (grab_video_p);
+ COPY (random_image_p);
+
+ if (!p->image_directory ||
+ !p2->image_directory ||
+ strcmp(p->image_directory, p2->image_directory))
+ changed = True;
+ if (p->image_directory && p->image_directory != p2->image_directory)
+ free (p->image_directory);
+ p->image_directory = normalize_directory (p2->image_directory);
+ if (p2->image_directory) free (p2->image_directory);
+ p2->image_directory = 0;
+
COPY(verbose_p);
+ COPY(capture_stderr_p);
+ COPY(splash_p);
+
COPY(install_cmap_p);
COPY(fade_p);
COPY(unfade_p);
- COPY(lock_p);
+ COPY(fade_seconds);
# undef COPY
populate_prefs_page (GTK_WIDGET (button), pair);
if (changed)
- demo_write_init_file (GTK_WIDGET (button), p);
+ {
+ Display *dpy = GDK_DISPLAY();
+ sync_server_dpms_settings (dpy, p->dpms_enabled_p,
+ p->dpms_standby / 1000,
+ p->dpms_suspend / 1000,
+ p->dpms_off / 1000,
+ False);
+
+ demo_write_init_file (GTK_WIDGET (button), p);
+ }
}
}
+void
+pref_changed_cb (GtkButton *button, gpointer user_data)
+{
+ if (! initializing_p)
+ apply_changes_and_save (GTK_WIDGET (button));
+}
+
+
static gint
list_doubleclick_cb (GtkWidget *button, GdkEventButton *event,
gpointer client_data)
populate_demo_window (GTK_WIDGET (list), -1, pair);
}
+
+static int updating_enabled_cb = 0; /* kludge to make sure that enabled_cb
+ is only run by user action, not by
+ program action. */
+
+/* Called when the checkboxes that are in the left column of the
+ scrolling list are clicked. This both populates the right pane
+ (just as clicking on the label (really, listitem) does) and
+ also syncs this checkbox with the right pane Enabled checkbox.
+ */
+static void
+list_checkbox_cb (GtkWidget *cb, gpointer client_data)
+{
+ prefs_pair *pair = (prefs_pair *) client_data;
+
+ GtkWidget *line_hbox = GTK_WIDGET (cb)->parent;
+ GtkWidget *line = GTK_WIDGET (line_hbox)->parent;
+
+ GtkList *list = GTK_LIST (GTK_WIDGET (line)->parent);
+ GtkViewport *vp = GTK_VIEWPORT (GTK_WIDGET (list)->parent);
+ GtkScrolledWindow *scroller = GTK_SCROLLED_WINDOW (GTK_WIDGET (vp)->parent);
+ GtkAdjustment *adj;
+ double scroll_top;
+
+ GtkToggleButton *enabled =
+ GTK_TOGGLE_BUTTON (name_to_widget (cb, "enabled"));
+
+ int which = gtk_list_child_position (list, line);
+
+ /* remember previous scroll position of the top of the list */
+ adj = gtk_scrolled_window_get_vadjustment (scroller);
+ scroll_top = adj->value;
+
+ apply_changes_and_save (GTK_WIDGET (list));
+ gtk_list_select_item (list, which);
+ /* ensure_selected_item_visible (GTK_WIDGET (list)); */
+ populate_demo_window (GTK_WIDGET (list), which, pair);
+
+ updating_enabled_cb++;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enabled),
+ GTK_TOGGLE_BUTTON (cb)->active);
+ updating_enabled_cb--;
+
+ /* restore the previous scroll position of the top of the list.
+ this is weak, but I don't really know why it's moving... */
+ gtk_adjustment_set_value (adj, scroll_top);
+}
+
+
+/* Called when the right pane Enabled checkbox is clicked. This syncs
+ the corresponding checkbox inside the scrolling list to the state
+ of this checkbox.
+ */
+void
+enabled_cb (GtkWidget *cb, gpointer client_data)
+{
+ int which = selected_hack_number (cb);
+
+ if (updating_enabled_cb) return;
+
+ if (which != -1)
+ {
+ GtkList *list = GTK_LIST (name_to_widget (cb, "list"));
+ GList *kids = GTK_LIST (list)->children;
+ GtkWidget *line = GTK_WIDGET (g_list_nth_data (kids, which));
+ GtkWidget *line_hbox = GTK_WIDGET (GTK_BIN (line)->child);
+ GtkWidget *line_check =
+ GTK_WIDGET (gtk_container_children (GTK_CONTAINER (line_hbox))->data);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (line_check),
+ GTK_TOGGLE_BUTTON (cb)->active);
+ }
+}
+
+
+
+typedef struct {
+ prefs_pair *pair;
+ GtkFileSelection *widget;
+} file_selection_data;
+
+
+
+static void
+store_image_directory (GtkWidget *button, gpointer user_data)
+{
+ file_selection_data *fsd = (file_selection_data *) user_data;
+ prefs_pair *pair = fsd->pair;
+ GtkFileSelection *selector = fsd->widget;
+ GtkWidget *top = toplevel_widget;
+ saver_preferences *p = pair->a;
+ char *path = gtk_file_selection_get_filename (selector);
+
+ if (p->image_directory && !strcmp(p->image_directory, path))
+ return; /* no change */
+
+ if (!directory_p (path))
+ {
+ char b[255];
+ sprintf (b, "Error:\n\n" "Directory does not exist: \"%s\"\n", path);
+ warning_dialog (GTK_WIDGET (top), b, False, 100);
+ return;
+ }
+
+ if (p->image_directory) free (p->image_directory);
+ p->image_directory = normalize_directory (path);
+
+ gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "image_text")),
+ (p->image_directory ? p->image_directory : ""));
+ demo_write_init_file (GTK_WIDGET (top), p);
+}
+
+
+static void
+browse_image_dir_cancel (GtkWidget *button, gpointer user_data)
+{
+ file_selection_data *fsd = (file_selection_data *) user_data;
+ gtk_widget_hide (GTK_WIDGET (fsd->widget));
+}
+
+static void
+browse_image_dir_ok (GtkWidget *button, gpointer user_data)
+{
+ browse_image_dir_cancel (button, user_data);
+ store_image_directory (button, user_data);
+}
+
+static void
+browse_image_dir_close (GtkWidget *widget, GdkEvent *event, gpointer user_data)
+{
+ browse_image_dir_cancel (widget, user_data);
+}
+
+
+void
+browse_image_dir_cb (GtkButton *button, gpointer user_data)
+{
+ /* prefs_pair *pair = (prefs_pair *) client_data; */
+ prefs_pair *pair = global_prefs_pair; /* I hate C so much... */
+ saver_preferences *p = pair->a;
+ static file_selection_data *fsd = 0;
+
+ GtkFileSelection *selector = GTK_FILE_SELECTION(
+ gtk_file_selection_new ("Please select the image directory."));
+
+ if (!fsd)
+ fsd = (file_selection_data *) malloc (sizeof (*fsd));
+
+ fsd->widget = selector;
+ fsd->pair = pair;
+
+ if (p->image_directory && *p->image_directory)
+ gtk_file_selection_set_filename (selector, p->image_directory);
+
+ gtk_signal_connect (GTK_OBJECT (selector->ok_button),
+ "clicked", GTK_SIGNAL_FUNC (browse_image_dir_ok),
+ (gpointer *) fsd);
+ gtk_signal_connect (GTK_OBJECT (selector->cancel_button),
+ "clicked", GTK_SIGNAL_FUNC (browse_image_dir_cancel),
+ (gpointer *) fsd);
+ gtk_signal_connect (GTK_OBJECT (selector), "delete_event",
+ GTK_SIGNAL_FUNC (browse_image_dir_close),
+ (gpointer *) fsd);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (selector->file_list), False);
+
+ gtk_window_set_modal (GTK_WINDOW (selector), True);
+ gtk_widget_show (GTK_WIDGET (selector));
+}
+
+
\f
/* Populating the various widgets
*/
}
-static char *
-make_pretty_name (const char *shell_command)
-{
- char *s = strdup (shell_command);
- char *s2;
- char res_name[255];
-
- for (s2 = s; *s2; s2++) /* truncate at first whitespace */
- if (isspace (*s2))
- {
- *s2 = 0;
- break;
- }
-
- s2 = strrchr (s, '/'); /* if pathname, take last component */
- if (s2)
- {
- s2 = strdup (s2+1);
- free (s);
- s = s2;
- }
-
- if (strlen (s) > 50) /* 51 is hereby defined as "unreasonable" */
- s[50] = 0;
-
- sprintf (res_name, "hacks.%s.name", s); /* resource? */
- s2 = get_string_resource (res_name, res_name);
- if (s2)
- return s2;
-
- for (s2 = s; *s2; s2++) /* if it has any capitals, return it */
- if (*s2 >= 'A' && *s2 <= 'Z')
- return s;
-
- if (s[0] >= 'a' && s[0] <= 'z') /* else cap it */
- s[0] -= 'a'-'A';
- if (s[0] == 'X' && s[1] >= 'a' && s[1] <= 'z') /* (magic leading X) */
- s[1] -= 'a'-'A';
- return s;
-}
-
-
/* Finds the number of the last hack to run, and makes that item be
selected by default.
*/
static void
scroll_to_current_hack (GtkWidget *toplevel, prefs_pair *pair)
{
+ saver_preferences *p = pair->a;
Atom type;
int format;
unsigned long nitems, bytesafter;
CARD32 *data = 0;
- Display *dpy = gdk_display;
+ Display *dpy = GDK_DISPLAY();
int which = 0;
GtkList *list;
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);
+ }
}
screenhack **hacks = p->screenhacks;
screenhack **h;
- for (h = hacks; *h; h++)
+ for (h = hacks; h && *h; h++)
{
+ /* A GtkList must contain only GtkListItems, but those can contain
+ an arbitrary widget. We add an Hbox, and inside that, a Checkbox
+ and a Label. We handle single and double click events on the
+ line itself, for clicking on the text, but the interior checkbox
+ also handles its own events.
+ */
GtkWidget *line;
+ GtkWidget *line_hbox;
+ GtkWidget *line_check;
+ GtkWidget *line_label;
+
char *pretty_name = (h[0]->name
? strdup (h[0]->name)
- : make_pretty_name (h[0]->command));
+ : make_hack_name (h[0]->command));
+
+ line = gtk_list_item_new ();
+ line_hbox = gtk_hbox_new (FALSE, 0);
+ line_check = gtk_check_button_new ();
+ line_label = gtk_label_new (pretty_name);
+
+ gtk_container_add (GTK_CONTAINER (line), line_hbox);
+ gtk_box_pack_start (GTK_BOX (line_hbox), line_check, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (line_hbox), line_label, FALSE, FALSE, 0);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (line_check),
+ h[0]->enabled_p);
+ gtk_label_set_justify (GTK_LABEL (line_label), GTK_JUSTIFY_LEFT);
+
+ gtk_widget_show (line_check);
+ gtk_widget_show (line_label);
+ gtk_widget_show (line_hbox);
+ gtk_widget_show (line);
- line = gtk_list_item_new_with_label (pretty_name);
free (pretty_name);
gtk_container_add (GTK_CONTAINER (list), line);
gtk_signal_connect (GTK_OBJECT (line), "button_press_event",
GTK_SIGNAL_FUNC (list_doubleclick_cb),
(gpointer) pair);
+
+ gtk_signal_connect (GTK_OBJECT (line_check), "toggled",
+ GTK_SIGNAL_FUNC (list_checkbox_cb),
+ (gpointer) pair);
+
#if 0 /* #### */
GTK_WIDGET (GTK_BIN(line)->child)->style =
gtk_style_copy (GTK_WIDGET (text_line)->style);
gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "cycle_text")), s);
format_time (s, p->lock_timeout);
gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "lock_text")), s);
- format_time (s, p->passwd_timeout);
- gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "pass_text")), s);
+
+ format_time (s, p->dpms_standby);
+ gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "dpms_standby_text")),s);
+ format_time (s, p->dpms_suspend);
+ gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "dpms_suspend_text")),s);
+ format_time (s, p->dpms_off);
+ gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "dpms_off_text")), s);
+
format_time (s, p->fade_seconds);
gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "fade_text")), s);
- sprintf (s, "%u", p->fade_ticks);
- gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "ticks_text")), s);
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget (top, "lock_button")),
+ p->lock_p);
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON (name_to_widget (top, "verbose_button")),
p->verbose_p);
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget (top, "capture_button")),
+ p->capture_stderr_p);
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget (top, "splash_button")),
+ p->splash_p);
+
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget (top, "dpms_button")),
+ p->dpms_enabled_p);
+
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget (top,"grab_desk_button")),
+ p->grab_desktop_p);
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget(top,"grab_video_button")),
+ p->grab_video_p);
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (name_to_widget(top,"grab_image_button")),
+ p->random_image_p);
+ gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "image_text")),
+ (p->image_directory ? p->image_directory : ""));
+ gtk_widget_set_sensitive (GTK_WIDGET (name_to_widget (top, "image_text")),
+ p->random_image_p);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top,"image_browse_button")),
+ p->random_image_p);
+
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON (name_to_widget (top, "install_button")),
p->install_cmap_p);
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON (name_to_widget (top, "unfade_button")),
p->unfade_p);
- gtk_toggle_button_set_active (
- GTK_TOGGLE_BUTTON (name_to_widget (top, "lock_button")),
- p->lock_p);
{
Bool found_any_writable_cells = False;
- Display *dpy = gdk_display;
+ Bool dpms_supported = False;
+
+ Display *dpy = GDK_DISPLAY();
int nscreens = ScreenCount(dpy);
int i;
for (i = 0; i < nscreens; i++)
}
}
+#ifdef HAVE_XF86VMODE_GAMMA
+ found_any_writable_cells = True; /* if we can gamma fade, go for it */
+#endif
+
+#ifdef HAVE_DPMS_EXTENSION
+ {
+ int op = 0, event = 0, error = 0;
+ if (XQueryExtension (dpy, "DPMS", &op, &event, &error))
+ dpms_supported = True;
+ }
+#endif /* HAVE_DPMS_EXTENSION */
+
+
+ /* Blanking and Locking
+ */
gtk_widget_set_sensitive (
- GTK_WIDGET (name_to_widget (top, "fade_label")),
- found_any_writable_cells);
+ GTK_WIDGET (name_to_widget (top, "lock_label")),
+ p->lock_p);
gtk_widget_set_sensitive (
- GTK_WIDGET (name_to_widget (top, "ticks_label")),
- found_any_writable_cells);
+ GTK_WIDGET (name_to_widget (top, "lock_text")),
+ p->lock_p);
+
+ /* DPMS
+ */
gtk_widget_set_sensitive (
- GTK_WIDGET (name_to_widget (top, "fade_text")),
- found_any_writable_cells);
+ GTK_WIDGET (name_to_widget (top, "dpms_frame")),
+ dpms_supported);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "dpms_button")),
+ dpms_supported);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "dpms_standby_label")),
+ dpms_supported && p->dpms_enabled_p);
gtk_widget_set_sensitive (
- GTK_WIDGET (name_to_widget (top, "ticks_text")),
+ GTK_WIDGET (name_to_widget (top, "dpms_standby_text")),
+ dpms_supported && p->dpms_enabled_p);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "dpms_suspend_label")),
+ dpms_supported && p->dpms_enabled_p);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "dpms_suspend_text")),
+ dpms_supported && p->dpms_enabled_p);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "dpms_off_label")),
+ dpms_supported && p->dpms_enabled_p);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "dpms_off_text")),
+ dpms_supported && p->dpms_enabled_p);
+
+ /* Colormaps
+ */
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "cmap_frame")),
found_any_writable_cells);
gtk_widget_set_sensitive (
GTK_WIDGET (name_to_widget (top, "install_button")),
gtk_widget_set_sensitive (
GTK_WIDGET (name_to_widget (top, "unfade_button")),
found_any_writable_cells);
+
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "fade_label")),
+ (found_any_writable_cells &&
+ (p->fade_p || p->unfade_p)));
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (name_to_widget (top, "fade_text")),
+ (found_any_writable_cells &&
+ (p->fade_p || p->unfade_p)));
}
}
static void
fix_text_entry_sizes (GtkWidget *toplevel)
{
- const char *names[] = { "timeout_text", "cycle_text", "fade_text",
- "ticks_text", "lock_text", "pass_text" };
+ const char *names[] = { "timeout_text", "cycle_text", "lock_text",
+ "dpms_standby_text", "dpms_suspend_text",
+ "dpms_off_text", "fade_text" };
int i;
int width = 0;
GtkWidget *w;
width = gdk_text_width (w->style->font, "PseudoColor___", 14);
gtk_widget_set_usize (w, width, -2);
+ /* Now fix the size of the file entry text.
+ */
+ w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "image_text"));
+ width = gdk_text_width (w->style->font, "MMMMMMMMMMMMMM", 14);
+ gtk_widget_set_usize (w, width, -2);
+
#if 0
/* Now fix the size of the list.
*/
};
static void
-pixmapify_buttons (GtkWidget *toplevel)
+pixmapify_button (GtkWidget *toplevel, int down_p)
{
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
GtkWidget *w;
- w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "next"));
+ w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel),
+ (down_p ? "next" : "prev")));
style = gtk_widget_get_style (w);
mask = 0;
pixmap = gdk_pixmap_create_from_xpm_d (w->window, &mask,
&style->bg[GTK_STATE_NORMAL],
- (gchar **) down_arrow_xpm);
+ (down_p
+ ? (gchar **) down_arrow_xpm
+ : (gchar **) up_arrow_xpm));
pixmapwid = gtk_pixmap_new (pixmap, mask);
gtk_widget_show (pixmapwid);
gtk_container_remove (GTK_CONTAINER (w), GTK_BIN (w)->child);
gtk_container_add (GTK_CONTAINER (w), pixmapwid);
+}
- w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "prev"));
- style = gtk_widget_get_style (w);
- mask = 0;
- pixmap = gdk_pixmap_create_from_xpm_d (w->window, &mask,
- &style->bg[GTK_STATE_NORMAL],
- (gchar **) up_arrow_xpm);
- pixmapwid = gtk_pixmap_new (pixmap, mask);
- gtk_widget_show (pixmapwid);
- gtk_container_remove (GTK_CONTAINER (w), GTK_BIN (w)->child);
- gtk_container_add (GTK_CONTAINER (w), pixmapwid);
+static void
+map_next_button_cb (GtkWidget *w, gpointer user_data)
+{
+ pixmapify_button (w, 1);
+}
+
+static void
+map_prev_button_cb (GtkWidget *w, gpointer user_data)
+{
+ pixmapify_button (w, 0);
}
char *prog_name = strdup (hack->command);
char *pretty_name = (hack->name
? strdup (hack->name)
- : make_pretty_name (hack->command));
+ : make_hack_name (hack->command));
char doc_name[255], doc_class[255];
char *s, *s2;
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"));
char *pretty_name = (hack
? (hack->name
? strdup (hack->name)
- : make_pretty_name (hack->command))
+ : make_hack_name (hack->command))
: 0);
char *doc_string = hack ? get_hack_blurb (hack) : 0;
gtk_label_set_text (doc, (doc_string ? doc_string : ""));
gtk_entry_set_text (cmd, (hack ? hack->command : ""));
gtk_entry_set_position (cmd, 0);
+
+ updating_enabled_cb++;
gtk_toggle_button_set_active (enabled, (hack ? hack->enabled_p : False));
+ updating_enabled_cb--;
+
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry),
(hack
? (hack->visual && *hack->visual
"Warning:\n\n"
"file \"%s\" has changed, reloading.\n",
f);
- warning_dialog (widget, b, 100);
+ warning_dialog (widget, b, False, 100);
free (b);
load_init_file (p);
}
+\f
+/* Setting window manager icon
+ */
+
+static void
+init_icon (GdkWindow *window)
+{
+ GdkBitmap *mask = 0;
+ GdkColor transp;
+ GdkPixmap *pixmap =
+ gdk_pixmap_create_from_xpm_d (window, &mask, &transp,
+ (gchar **) logo_50_xpm);
+ if (pixmap)
+ gdk_window_set_icon (window, 0, pixmap, mask);
+}
+
\f
/* The main demo-mode command loop.
*/
static void
the_network_is_not_the_computer (GtkWidget *parent)
{
- Display *dpy = gdk_display;
+ Display *dpy = GDK_DISPLAY();
char *rversion, *ruser, *rhost;
char *luser, *lhost;
char *msg = 0;
sprintf (msg,
"Warning:\n\n"
"The XScreenSaver daemon doesn't seem to be running\n"
- "on display \"%s\". You can launch it by selecting\n"
- "`Restart Daemon' from the File menu, or by typing\n"
- "\"xscreensaver &\" in a shell.",
+ "on display \"%s\". Launch it now?",
d);
}
else if (p && ruser && *ruser && !!strcmp (ruser, p->pw_name))
"the same ~/.xscreensaver file, so %s isn't\n"
"going to work right.\n"
"\n"
- "Either re-run %s as \"%s\", or re-run\n"
- "xscreensaver as \"%s\" (which you can do by\n"
- "selecting `Restart Daemon' from the File menu.)\n",
+ "You should either re-run %s as \"%s\", or re-run\n"
+ "xscreensaver as \"%s\".\n"
+ "\n"
+ "Restart the xscreensaver daemon now?\n",
progname, luser, lhost,
d,
(ruser ? ruser : "???"), (rhost ? rhost : "???"),
"if they don't see the same ~%s/.xscreensaver file) then\n"
"%s won't work right.\n"
"\n"
- "You can restart the daemon on \"%s\" as \"%s\" by\n"
- "selecting `Restart Daemon' from the File menu.)",
+ "Restart the daemon on \"%s\" as \"%s\" now?\n",
progname, luser, lhost,
d,
(ruser ? ruser : "???"), (rhost ? rhost : "???"),
"Warning:\n\n"
"This is %s version %s.\n"
"But the xscreensaver managing display \"%s\"\n"
- "is version %s. This could cause problems.",
+ "is version %s. This could cause problems.\n"
+ "\n"
+ "Restart the xscreensaver daemon now?\n",
progname, short_version,
d,
rversion);
if (*msg)
- warning_dialog (parent, msg, 1);
+ warning_dialog (parent, msg, True, 1);
free (msg);
}
0
};
+#if 0
+#ifdef HAVE_CRAPPLET
+static struct poptOption crapplet_options[] = {
+ {NULL, '\0', 0, NULL, 0}
+};
+#endif /* HAVE_CRAPPLET */
+#endif /* 0 */
+
+#define USAGE() \
+ fprintf (stderr, "usage: %s [ -display dpy-string ] [ -prefs ]\n", \
+ real_progname)
+
+
+static void
+map_window_cb (GtkWidget *w, gpointer user_data)
+{
+ Boolean oi = initializing_p;
+ initializing_p = True;
+ eschew_gtk_lossage (w);
+ ensure_selected_item_visible (GTK_WIDGET(name_to_widget(w, "list")));
+ initializing_p = oi;
+}
+
+
int
main (int argc, char **argv)
{
char *real_progname = argv[0];
char *s;
+ initializing_p = True;
+
s = strrchr (real_progname, '/');
if (s) real_progname = s+1;
!strncmp(argv[i], "-display", strlen(argv[i])))
argv[i] = "--display";
+
+ /* We need to parse this arg really early... Sigh. */
+ for (i = 1; i < argc; i++)
+ if (argv[i] &&
+ (!strcmp(argv[i], "--crapplet") ||
+ !strcmp(argv[i], "--capplet")))
+ {
+# ifdef HAVE_CRAPPLET
+ int j;
+ crapplet_p = True;
+ for (j = i; j < argc; j++) /* remove it from the list */
+ argv[j] = argv[j+1];
+ argc--;
+
+# else /* !HAVE_CRAPPLET */
+ fprintf (stderr, "%s: not compiled with --crapplet support\n",
+ real_progname);
+ USAGE ();
+ exit (1);
+# endif /* !HAVE_CRAPPLET */
+ }
+
/* Let Gtk open the X connection, then initialize Xt to use that
- same connection. Doctor Frankenstein would be proud. */
- gtk_init (&argc, &argv);
+ same connection. Doctor Frankenstein would be proud.
+ */
+# ifdef HAVE_CRAPPLET
+ if (crapplet_p)
+ {
+ GnomeClient *client;
+ GnomeClientFlags flags = 0;
+
+ int init_results = gnome_capplet_init ("screensaver-properties",
+ short_version,
+ argc, argv, NULL, 0, NULL);
+ /* init_results is:
+ 0 upon successful initialization;
+ 1 if --init-session-settings was passed on the cmdline;
+ 2 if --ignore was passed on the cmdline;
+ -1 on error.
+
+ So the 1 signifies just to init the settings, and quit, basically.
+ (Meaning launch the xscreensaver daemon.)
+ */
+
+ if (init_results < 0)
+ {
+# if 0
+ g_error ("An initialization error occurred while "
+ "starting xscreensaver-capplet.\n");
+# else /* !0 */
+ fprintf (stderr, "%s: gnome_capplet_init failed: %d\n",
+ real_progname, init_results);
+ exit (1);
+# endif /* !0 */
+ }
+
+ client = gnome_master_client ();
+
+ if (client)
+ flags = gnome_client_get_flags (client);
+
+ if (flags & GNOME_CLIENT_IS_CONNECTED)
+ {
+ int token =
+ gnome_startup_acquire_token ("GNOME_SCREENSAVER_PROPERTIES",
+ gnome_client_get_id (client));
+ if (token)
+ {
+ char *session_args[20];
+ int i = 0;
+ session_args[i++] = real_progname;
+ session_args[i++] = "--capplet";
+ session_args[i++] = "--init-session-settings";
+ session_args[i] = 0;
+ gnome_client_set_priority (client, 20);
+ gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY);
+ gnome_client_set_restart_command (client, i, session_args);
+ }
+ else
+ {
+ gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
+ }
+
+ gnome_client_flush (client);
+ }
+
+ if (init_results == 1)
+ {
+ system ("xscreensaver -nosplash &");
+ return 0;
+ }
+
+ }
+ else
+# endif /* HAVE_CRAPPLET */
+ {
+ gtk_init (&argc, &argv);
+ }
/* We must read exactly the same resources as xscreensaver.
*/
XtToolkitInitialize ();
app = XtCreateApplicationContext ();
- dpy = gdk_display;
+ dpy = GDK_DISPLAY();
XtAppSetFallbackResources (app, defaults);
XtDisplayInitialize (app, dpy, progname, progclass, 0, 0, &argc, argv);
toplevel_shell = XtAppCreateShell (progname, progclass,
s++;
if (!strcmp (s, "-prefs"))
prefs = True;
+ else if (crapplet_p)
+ /* There are lots of random args that we don't care about when we're
+ started as a crapplet, so just ignore unknown args in that case. */
+ ;
else
{
- fprintf (stderr, "usage: %s [ -display dpy-string ] [ -prefs ]\n",
- real_progname);
- exit (1);
+ fprintf (stderr, "%s: unknown option: %s\n", real_progname, argv[i]);
+ USAGE ();
+ exit (1);
}
}
/* Create the window and all its widgets.
*/
gtk_window = create_xscreensaver_demo ();
+ toplevel_widget = gtk_window;
/* Set the window's title. */
{
sensitize_demo_widgets (gtk_window, False);
fix_text_entry_sizes (gtk_window);
scroll_to_current_hack (gtk_window, pair);
- gtk_widget_show (gtk_window);
- /* The next three calls must come after gtk_widget_show(). */
- pixmapify_buttons (gtk_window);
- eschew_gtk_lossage (gtk_window);
- ensure_selected_item_visible (GTK_WIDGET(name_to_widget(gtk_window,"list")));
+ gtk_signal_connect (
+ GTK_OBJECT (name_to_widget (GTK_WIDGET (gtk_window), "list")),
+ "map", GTK_SIGNAL_FUNC(map_window_cb), 0);
+ gtk_signal_connect (
+ GTK_OBJECT (name_to_widget (GTK_WIDGET (gtk_window), "prev")),
+ "map", GTK_SIGNAL_FUNC(map_prev_button_cb), 0);
+ gtk_signal_connect (
+ GTK_OBJECT (name_to_widget (GTK_WIDGET (gtk_window), "next")),
+ "map", GTK_SIGNAL_FUNC(map_next_button_cb), 0);
+
/* Handle the -prefs command-line argument. */
if (prefs)
gtk_notebook_set_page (notebook, 1);
}
- /* Issue any warnings about the running xscreensaver daemon. */
- the_network_is_not_the_computer (gtk_window);
+# ifdef HAVE_CRAPPLET
+ if (crapplet_p)
+ {
+ GtkWidget *capplet;
+ GtkWidget *top_vbox;
+
+ capplet = capplet_widget_new ();
+
+ top_vbox = GTK_BIN (gtk_window)->child;
+
+ gtk_widget_ref (top_vbox);
+ gtk_container_remove (GTK_CONTAINER (gtk_window), top_vbox);
+ GTK_OBJECT_SET_FLAGS (top_vbox, GTK_FLOATING);
+
+ /* In crapplet-mode, take off the menubar. */
+ gtk_widget_hide (name_to_widget (gtk_window, "menubar"));
+
+ gtk_container_add (GTK_CONTAINER (capplet), top_vbox);
+ gtk_widget_show (capplet);
+ gtk_widget_hide (gtk_window);
+
+ /* Hook up the Control Center's redundant Help button, too. */
+ gtk_signal_connect (GTK_OBJECT (capplet), "help",
+ GTK_SIGNAL_FUNC (doc_menu_cb), 0);
+
+ /* Issue any warnings about the running xscreensaver daemon. */
+ the_network_is_not_the_computer (top_vbox);
+ }
+ else
+# endif /* HAVE_CRAPPLET */
+ {
+ gtk_widget_show (gtk_window);
+ init_icon (GTK_WIDGET(gtk_window)->window);
+
+ /* Issue any warnings about the running xscreensaver daemon. */
+ the_network_is_not_the_computer (gtk_window);
+ }
/* Run the Gtk event loop, and not the Xt event loop. This means that
if there were Xt timers or fds registered, they would never get serviced,
Xt so that we could process the command line and use the X resource
manager.
*/
- gtk_main ();
+ initializing_p = False;
+
+# ifdef HAVE_CRAPPLET
+ if (crapplet_p)
+ capplet_gtk_main ();
+ else
+# endif /* HAVE_CRAPPLET */
+ gtk_main ();
+
exit (0);
}