/* 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 <capplet-widget.h>
#endif
-extern Display *gdk_display;
+#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>
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
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);
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),
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];
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);
}
}
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 (buf, "%s\n%s\n\n"
- "For updates, check http://www.jwz.org/xscreensaver/",
- s, s2);
- free (s);
+ sprintf (msg, "%s\n\n%s", copy, desc);
- warning_dialog (GTK_WIDGET (menuitem), buf, False, 100);
+ /* 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:
+
+ #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);
+ }
}
run_cmd (GTK_WIDGET (widget), XA_RESTART, 0);
#else
apply_changes_and_save (GTK_WIDGET (widget));
- xscreensaver_command (gdk_display, XA_EXIT, 0, False, NULL);
+ 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);
+ }
}
}
+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)
{
*(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);
+ }
}
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.
*/
int format;
unsigned long nitems, bytesafter;
CARD32 *data = 0;
- Display *dpy = gdk_display;
+ Display *dpy = GDK_DISPLAY();
int which = 0;
GtkList *list;
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, "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, "ticks_text")),
+ 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;
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
}
+\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;
{
Boolean oi = initializing_p;
initializing_p = True;
- pixmapify_buttons (w);
eschew_gtk_lossage (w);
ensure_selected_item_visible (GTK_WIDGET(name_to_widget(w, "list")));
initializing_p = oi;
main (int argc, char **argv)
{
XtAppContext app;
-# ifdef HAVE_CRAPPLET
- GnomeClient *client;
- GnomeClientFlags flags;
- int init_results;
-# endif /* HAVE_CRAPPLET */
prefs_pair Pair, *pair;
saver_preferences P, P2, *p, *p2;
Bool prefs = False;
# else /* !HAVE_CRAPPLET */
fprintf (stderr, "%s: not compiled with --crapplet support\n",
- real_progname[i]);
+ real_progname);
USAGE ();
exit (1);
# endif /* !HAVE_CRAPPLET */
# ifdef HAVE_CRAPPLET
if (crapplet_p)
{
- init_results = gnome_capplet_init ("screensaver-properties",
- short_version,
- argc, argv, NULL, 0, NULL);
+ 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 (client)
flags = gnome_client_get_flags (client);
- else
- flags = 0;
if (flags & GNOME_CLIENT_IS_CONNECTED)
{
- gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
+ 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 */
*/
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,
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. */
gtk_container_remove (GTK_CONTAINER (gtk_window), top_vbox);
GTK_OBJECT_SET_FLAGS (top_vbox, GTK_FLOATING);
- /* This is a crock, but otherwise, the Control Center expands to
- be as tall as the screen. */
- gtk_window_set_default_size (GTK_WINDOW (top_vbox), 600, 400);
-
/* In crapplet-mode, take off the menubar. */
gtk_widget_hide (name_to_widget (gtk_window, "menubar"));
# 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);