/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
- * xscreensaver, Copyright (c) 1993-2006 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2013 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 "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"
#include <stdio.h>
};
#endif /* HAVE_GTK2 */
+/* Deal with deprecation of direct access to struct fields on the way to GTK3
+ See http://live.gnome.org/GnomeGoals/UseGseal
+ */
+#if GTK_CHECK_VERSION(2,14,0)
+# define GET_PARENT(w) gtk_widget_get_parent (w)
+# define GET_WINDOW(w) gtk_widget_get_window (w)
+# define GET_ACTION_AREA(d) gtk_dialog_get_action_area (d)
+# define GET_CONTENT_AREA(d) gtk_dialog_get_content_area (d)
+# define GET_ADJ_VALUE(a) gtk_adjustment_get_value (a)
+# define SET_ADJ_VALUE(a,v) gtk_adjustment_set_value (a, v)
+# define SET_ADJ_UPPER(a,v) gtk_adjustment_set_upper (a, v)
+#else
+# define GET_PARENT(w) ((w)->parent)
+# define GET_WINDOW(w) ((w)->window)
+# define GET_ACTION_AREA(d) ((d)->action_area)
+# define GET_CONTENT_AREA(d) ((d)->vbox)
+# define GET_ADJ_VALUE(a) ((a)->value)
+# define SET_ADJ_VALUE(a,v) (a)->value = v
+# define SET_ADJ_UPPER(a,v) (a)->upper = v
+#endif
+
+#if GTK_CHECK_VERSION(2,18,0)
+# define SET_CAN_DEFAULT(w) gtk_widget_set_can_default ((w), TRUE)
+# define GET_SENSITIVE(w) gtk_widget_get_sensitive (w)
+#else
+# define SET_CAN_DEFAULT(w) GTK_WIDGET_SET_FLAGS ((w), GTK_CAN_DEFAULT)
+# define GET_SENSITIVE(w) GTK_WIDGET_IS_SENSITIVE (w)
+#endif
+
+#if GTK_CHECK_VERSION(2,20,0)
+# define GET_REALIZED(w) gtk_widget_get_realized (w)
+#else
+# define GET_REALIZED(w) GTK_WIDGET_REALIZED (w)
+#endif
+
/* from exec.c */
extern void exec_command (const char *shell, const char *command, int nice);
extern int on_path_p (const char *program);
#define countof(x) (sizeof((x))/sizeof((*x)))
+/* You might think that to read an array of 32-bit quantities out of a
+ server-side property, you would pass an array of 32-bit data quantities
+ into XGetWindowProperty(). You would be wrong. You have to use an array
+ of longs, even if long is 64 bits (using 32 of each 64.)
+ */
+typedef long PROP32;
+
char *progname = 0;
char *progclass = "XScreenSaver";
XrmDatabase db;
static void kill_preview_subproc (state *, Bool reset_p);
static void schedule_preview_check (state *);
+\f
+/* Prototypes of functions used by the Glade-generated code,
+ to avoid warnings.
+ */
+void exit_menu_cb (GtkMenuItem *, gpointer user_data);
+void about_menu_cb (GtkMenuItem *, gpointer user_data);
+void doc_menu_cb (GtkMenuItem *, gpointer user_data);
+void file_menu_cb (GtkMenuItem *, gpointer user_data);
+void activate_menu_cb (GtkMenuItem *, gpointer user_data);
+void lock_menu_cb (GtkMenuItem *, gpointer user_data);
+void kill_menu_cb (GtkMenuItem *, gpointer user_data);
+void restart_menu_cb (GtkWidget *, gpointer user_data);
+void run_this_cb (GtkButton *, gpointer user_data);
+void manual_cb (GtkButton *, gpointer user_data);
+void run_next_cb (GtkButton *, gpointer user_data);
+void run_prev_cb (GtkButton *, gpointer user_data);
+void pref_changed_cb (GtkWidget *, gpointer user_data);
+gboolean pref_changed_event_cb (GtkWidget *, GdkEvent *, gpointer user_data);
+void mode_menu_item_cb (GtkWidget *, gpointer user_data);
+void switch_page_cb (GtkNotebook *, GtkNotebookPage *,
+ gint page_num, gpointer user_data);
+void browse_image_dir_cb (GtkButton *, gpointer user_data);
+void browse_text_file_cb (GtkButton *, gpointer user_data);
+void browse_text_program_cb (GtkButton *, gpointer user_data);
+void settings_cb (GtkButton *, gpointer user_data);
+void settings_adv_cb (GtkButton *, gpointer user_data);
+void settings_std_cb (GtkButton *, gpointer user_data);
+void settings_reset_cb (GtkButton *, gpointer user_data);
+void settings_switch_page_cb (GtkNotebook *, GtkNotebookPage *,
+ gint page_num, gpointer user_data);
+void settings_cancel_cb (GtkButton *, gpointer user_data);
+void settings_ok_cb (GtkButton *, gpointer user_data);
+
+static void kill_gnome_screensaver (void);
+static void kill_kde_screensaver (void);
\f
/* Some random utility functions
*/
+const char *blurb (void);
+
const char *
blurb (void)
{
adj = gtk_scrolled_window_get_vadjustment (scroller);
- gdk_window_get_geometry (GTK_WIDGET(vp)->window,
+ gdk_window_get_geometry (GET_WINDOW (GTK_WIDGET (vp)),
&ignore, &ignore, &ignore, &parent_h, &ignore);
- gdk_window_get_geometry (GTK_WIDGET(selected)->window,
+ gdk_window_get_geometry (GET_WINDOW (GTK_WIDGET (selected)),
&ignore, &child_y, &ignore, &child_h, &ignore);
children_h = nkids * child_h;
warning_dialog_dismiss_cb (GtkWidget *widget, gpointer user_data)
{
GtkWidget *shell = GTK_WIDGET (user_data);
- while (shell->parent)
- shell = shell->parent;
+ while (GET_PARENT (shell))
+ shell = GET_PARENT (shell);
gtk_widget_destroy (GTK_WIDGET (shell));
}
warning_dialog_dismiss_cb (widget, user_data);
}
-static void
+static void warning_dialog_killg_cb (GtkWidget *widget, gpointer user_data)
+{
+ kill_gnome_screensaver ();
+ warning_dialog_dismiss_cb (widget, user_data);
+}
+
+static void warning_dialog_killk_cb (GtkWidget *widget, gpointer user_data)
+{
+ kill_kde_screensaver ();
+ warning_dialog_dismiss_cb (widget, user_data);
+}
+
+typedef enum { D_NONE, D_LAUNCH, D_GNOME, D_KDE } dialog_button;
+
+static Bool
warning_dialog (GtkWidget *parent, const char *message,
- Boolean restart_button_p, int center)
+ dialog_button button_type, int center)
{
char *msg = strdup (message);
char *head;
GtkWidget *cancel = 0;
int i = 0;
- while (parent && !parent->window)
- parent = parent->parent;
+ while (parent && !GET_WINDOW (parent))
+ parent = GET_PARENT (parent);
if (!parent ||
- !GTK_WIDGET (parent)->window) /* too early to pop up transient dialogs */
+ !GET_WINDOW (parent)) /* too early to pop up transient dialogs */
{
fprintf (stderr, "%s: too early for dialog?\n", progname);
- return;
+ free(msg);
+ return False;
}
head = msg;
#endif /* !HAVE_GTK2 */
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_box_pack_start (GTK_BOX (GET_CONTENT_AREA (GTK_DIALOG (dialog))),
label, TRUE, TRUE, 0);
gtk_widget_show (label);
}
}
label = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (GET_CONTENT_AREA (GTK_DIALOG (dialog))),
label, TRUE, TRUE, 0);
gtk_widget_show (label);
label = gtk_hbutton_box_new ();
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
+ gtk_box_pack_start (GTK_BOX (GET_ACTION_AREA (GTK_DIALOG (dialog))),
label, TRUE, TRUE, 0);
#ifdef HAVE_GTK2
- if (restart_button_p)
+ if (button_type != D_NONE)
{
cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
gtk_container_add (GTK_CONTAINER (label), cancel);
ok = gtk_button_new_with_label ("OK");
gtk_container_add (GTK_CONTAINER (label), ok);
- if (restart_button_p)
+ if (button_type != D_NONE)
{
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);
- STFU GTK_WIDGET_SET_FLAGS (ok, GTK_CAN_DEFAULT);
+ SET_CAN_DEFAULT (ok);
gtk_widget_show (ok);
gtk_widget_grab_focus (ok);
if (cancel)
{
- STFU GTK_WIDGET_SET_FLAGS (cancel, GTK_CAN_DEFAULT);
+ SET_CAN_DEFAULT (cancel);
gtk_widget_show (cancel);
}
gtk_widget_show (label);
gtk_widget_show (dialog);
- if (restart_button_p)
+ if (button_type != D_NONE)
{
- gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
- GTK_SIGNAL_FUNC (warning_dialog_restart_cb),
+ GtkSignalFunc fn;
+ switch (button_type) {
+ case D_LAUNCH: fn = GTK_SIGNAL_FUNC (warning_dialog_restart_cb); break;
+ case D_GNOME: fn = GTK_SIGNAL_FUNC (warning_dialog_killg_cb); break;
+ case D_KDE: fn = GTK_SIGNAL_FUNC (warning_dialog_killk_cb); break;
+ default: abort(); break;
+ }
+ gtk_signal_connect_object (GTK_OBJECT (ok), "clicked", fn,
(gpointer) dialog);
gtk_signal_connect_object (GTK_OBJECT (cancel), "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_set_transient_for (GET_WINDOW (GTK_WIDGET (dialog)),
+ GET_WINDOW (GTK_WIDGET (parent)));
#ifdef HAVE_GTK2
gtk_window_present (GTK_WINDOW (dialog));
#endif /* !HAVE_GTK2 */
free (msg);
+ return True;
}
sprintf (buf, "Error:\n\n%s", err);
else
strcpy (buf, "Unknown error!");
- warning_dialog (s->toplevel_widget, buf, False, 100);
+ warning_dialog (s->toplevel_widget, buf, D_NONE, 100);
}
if (err) free (err);
sprintf (buf, "Error:\n\n%s", err);
else
strcpy (buf, "Unknown error!");
- warning_dialog (s->toplevel_widget, buf, False, 100);
+ warning_dialog (s->toplevel_widget, buf, D_NONE, 100);
}
}
else
"The XScreenSaver daemon doesn't seem to be running\n"
"on display \"%s\". Launch it now?"),
d);
- warning_dialog (s->toplevel_widget, msg, True, 1);
+ warning_dialog (s->toplevel_widget, msg, D_LAUNCH, 1);
}
}
{
char msg [2048];
char *vers = strdup (screensaver_id + 4);
- char *s;
+ char *s, *s2;
char copy[1024];
+ char year[5];
char *desc = _("For updates, check http://www.jwz.org/xscreensaver/");
s = strchr (vers, ',');
*s = 0;
s += 2;
+ s2 = vers;
+ s2 = strrchr (vers, '-');
+ s2++;
+ strncpy (year, s2, 4);
+ year[4] = 0;
+
/* Ole Laursen <olau@hardworking.dk> says "don't use _() here because
non-ASCII characters aren't allowed in localizable string keys."
(I don't want to just use (c) instead of © because that doesn't
look as good in the plain-old default Latin1 "C" locale.)
*/
#ifdef HAVE_GTK2
- sprintf(copy, ("Copyright \xC2\xA9 1991-2005 %s"), s);
+ sprintf(copy, ("Copyright \xC2\xA9 1991-%s %s"), year, s);
#else /* !HAVE_GTK2 */
- sprintf(copy, ("Copyright \251 1991-2005 %s"), s);
+ sprintf(copy, ("Copyright \251 1991-%s %s"), year, s);
#endif /* !HAVE_GTK2 */
sprintf (msg, "%s\n\n%s", copy, desc);
GtkWidget *dialog = gtk_dialog_new ();
GtkWidget *hbox, *icon, *vbox, *label1, *label2, *hb, *ok;
GtkWidget *parent = GTK_WIDGET (menuitem);
- while (parent->parent)
- parent = parent->parent;
+ while (GET_PARENT (parent))
+ parent = GET_PARENT (parent);
hbox = gtk_hbox_new (FALSE, 20);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (GET_CONTENT_AREA (GTK_DIALOG (dialog))),
hbox, TRUE, TRUE, 0);
colormap = gtk_widget_get_colormap (parent);
hb = gtk_hbutton_box_new ();
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
+ gtk_box_pack_start (GTK_BOX (GET_ACTION_AREA (GTK_DIALOG (dialog))),
hb, TRUE, TRUE, 0);
#ifdef HAVE_GTK2
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);
+ gdk_window_set_transient_for (GET_WINDOW (GTK_WIDGET (dialog)),
+ GET_WINDOW (GTK_WIDGET (parent)));
+ gdk_window_show (GET_WINDOW (GTK_WIDGET (dialog)));
+ gdk_window_raise (GET_WINDOW (GTK_WIDGET (dialog)));
}
}
{
warning_dialog (s->toplevel_widget,
_("Error:\n\n"
- "No Help URL has been specified.\n"), False, 100);
+ "No Help URL has been specified.\n"), D_NONE, 100);
return;
}
the length ISO C89 compilers are required to
support" in the following expression... */
# endif
- strcat (buf,
+ strcat (buf, STFU
_("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"
else
strcat (buf, _("Please check your $PATH and permissions."));
- warning_dialog (s->toplevel_widget, buf, False, 1);
+ warning_dialog (s->toplevel_widget, buf, D_NONE, 1);
}
force_dialog_repaint (s);
static int
demo_write_init_file (state *s, saver_preferences *p)
{
+ Display *dpy = GDK_DISPLAY();
#if 0
/* #### try to figure out why shit keeps getting reordered... */
abort();
#endif
- if (!write_init_file (p, s->short_version, False))
+ if (!write_init_file (dpy, p, s->short_version, False))
{
if (s->debug_p)
fprintf (stderr, "%s: wrote %s\n", blurb(), init_file_name());
if (!f || !*f)
warning_dialog (s->toplevel_widget,
_("Error:\n\nCouldn't determine init file name!\n"),
- False, 100);
+ D_NONE, 100);
else
{
char *b = (char *) malloc (strlen(f) + 1024);
sprintf (b, _("Error:\n\nCouldn't write %s\n"), f);
- warning_dialog (s->toplevel_widget, b, False, 100);
+ warning_dialog (s->toplevel_widget, b, D_NONE, 100);
free (b);
}
return -1;
G_MODULE_EXPORT void
manual_cb (GtkButton *button, gpointer user_data)
{
+ Display *dpy = GDK_DISPLAY();
state *s = global_state_kludge; /* I hate C so much... */
saver_preferences *p = &s->prefs;
GtkWidget *list_widget = name_to_widget (s, "list");
while (*str && !isspace (*str)) str++;
*str = 0;
str = strrchr (name2, '/');
- if (str) name = str+1;
+ if (str) name2 = str+1;
- cmd = get_string_resource ("manualCommand", "ManualCommand");
+ cmd = get_string_resource (dpy, "manualCommand", "ManualCommand");
if (cmd)
{
char *cmd2 = (char *) malloc (strlen (cmd) + (strlen (name2) * 4) + 100);
{
warning_dialog (GTK_WIDGET (button),
_("Error:\n\nno `manualCommand' resource set."),
- False, 100);
+ D_NONE, 100);
}
free (oname);
force_list_select_item (state *s, GtkWidget *list, int list_elt, Bool scroll_p)
{
GtkWidget *parent = name_to_widget (s, "scroller");
- Bool was = GTK_WIDGET_IS_SENSITIVE (parent);
+ gboolean was = GET_SENSITIVE (parent);
#ifdef HAVE_GTK2
GtkTreeIter iter;
GtkTreeModel *model;
if (!was) gtk_widget_set_sensitive (parent, True);
#ifdef HAVE_GTK2
model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
- STFU g_assert (model);
+ g_assert (model);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, list_elt))
{
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
_("Error:\n\n"
"Unparsable time format: \"%s\"\n"),
line);
- warning_dialog (s->toplevel_widget, b, False, 100);
+ warning_dialog (s->toplevel_widget, b, D_NONE, 100);
}
else
*store = value;
{
s0--;
s += 3;
- strcpy (s0, s);
+ /* strcpy (s0, s); */
+ memmove(s0, s, strlen(s) + 1);
s = s0-1;
}
}
- else if (*s == '/' && !strncmp (s, "/./", 3)) /* delete "/./" */
- strcpy (s, s+2), s--;
+ else if (*s == '/' && !strncmp (s, "/./", 3)) { /* delete "/./" */
+ /* strcpy (s, s+2), s--; */
+ memmove(s, s+2, strlen(s+2) + 1);
+ 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);
+ /*
+ Normalize consecutive slashes.
+ Ignore doubled slashes after ":" to avoid mangling URLs.
+ */
+
+ for (s = p2; s && *s; s++){
+ if (*s == ':') continue;
+ if (!s[1] || !s[2]) continue;
+ while (s[1] == '/' && s[2] == '/')
+ /* strcpy (s+1, s+2); */
+ memmove (s+1, s+2, strlen(s+2) + 1);
+ }
/* and strip trailing whitespace for good measure. */
L = strlen(p2);
GList *kids = gtk_container_children (GTK_CONTAINER (list_widget));
int i;
#endif /* !HAVE_GTK2 */
+ static Bool already_warned_about_missing_image_directory = False; /* very long name... */
Bool changed = False;
GtkWidget *w;
CHECKBOX (p2->lock_p, "lock_button");
MINUTES (&p2->lock_timeout, "lock_spinbutton");
- CHECKBOX (p2->dpms_enabled_p, "dpms_button");
+ CHECKBOX (p2->dpms_enabled_p, "dpms_button");
+ CHECKBOX (p2->dpms_quickoff_p, "dpms_quickoff_button");
MINUTES (&p2->dpms_standby, "dpms_standby_spinbutton");
MINUTES (&p2->dpms_suspend, "dpms_suspend_spinbutton");
MINUTES (&p2->dpms_off, "dpms_off_spinbutton");
# undef PATHNAME
# undef TEXT
- /* Warn if the image directory doesn't exist.
+ /* Warn if the image directory doesn't exist, when:
+ - not being warned before
+ - image directory is changed and the directory doesn't exist
+ - image directory does not begin with http://
*/
if (p2->image_directory &&
*p2->image_directory &&
- !directory_p (p2->image_directory))
+ !directory_p (p2->image_directory) &&
+ strncmp(p2->image_directory, "http://", 6) &&
+ ( !already_warned_about_missing_image_directory ||
+ ( p->image_directory &&
+ *p->image_directory &&
+ strcmp(p->image_directory, p2->image_directory)
+ )
+ )
+ )
{
char b[255];
- sprintf (b, "Error:\n\n" "Directory does not exist: \"%s\"\n",
+ sprintf (b, "Warning:\n\n" "Directory does not exist: \"%s\"\n",
p2->image_directory);
- warning_dialog (s->toplevel_widget, b, False, 100);
+ if (warning_dialog (s->toplevel_widget, b, D_NONE, 100))
+ already_warned_about_missing_image_directory = True;
}
COPY(lock_p, "lock_p");
COPY(lock_timeout, "lock_timeout");
- COPY(dpms_enabled_p, "dpms_enabled_p");
- COPY(dpms_standby, "dpms_standby");
- COPY(dpms_suspend, "dpms_suspend");
- COPY(dpms_off, "dpms_off");
+ COPY(dpms_enabled_p, "dpms_enabled_p");
+ COPY(dpms_quickoff_p, "dpms_quickoff_enabled_p");
+ COPY(dpms_standby, "dpms_standby");
+ COPY(dpms_suspend, "dpms_suspend");
+ COPY(dpms_off, "dpms_off");
#if 0
COPY(verbose_p, "verbose_p");
{
Display *dpy = GDK_DISPLAY();
Bool enabled_p = (p->dpms_enabled_p && p->mode != DONT_BLANK);
- sync_server_dpms_settings (dpy, enabled_p,
+ sync_server_dpms_settings (dpy, enabled_p, p->dpms_quickoff_p,
p->dpms_standby / 1000,
p->dpms_suspend / 1000,
p->dpms_off / 1000,
/* Callback on menu items in the "mode" options menu.
*/
-void
+G_MODULE_EXPORT void
mode_menu_item_cb (GtkWidget *widget, gpointer user_data)
{
state *s = (state *) user_data;
GtkWidget *list = name_to_widget (s, "list");
int list_elt;
- GList *menu_items = gtk_container_children (GTK_CONTAINER (widget->parent));
+ GList *menu_items =
+ gtk_container_children (GTK_CONTAINER (GET_PARENT (widget)));
int menu_index = 0;
saver_mode new_mode;
char *str;
int list_elt;
- STFU g_return_if_fail (!gdk_pointer_is_grabbed ());
+ g_return_if_fail (!gdk_pointer_is_grabbed ());
str = gtk_tree_path_to_string (path);
list_elt = strtol (str, NULL, 10);
/* remember previous scroll position of the top of the list */
adj = gtk_scrolled_window_get_vadjustment (scroller);
- scroll_top = adj->value;
+ scroll_top = GET_ADJ_VALUE (adj);
flush_dialog_changes_and_save (s);
force_list_select_item (s, GTK_WIDGET (list), list_elt, False);
if (p->image_directory && !strcmp(p->image_directory, path))
return; /* no change */
- if (!directory_p (path))
+ /* No warning for URLs. */
+ if ((!directory_p (path)) && strncmp(path, "http://", 6))
{
char b[255];
sprintf (b, _("Error:\n\n" "Directory does not exist: \"%s\"\n"), path);
- warning_dialog (GTK_WIDGET (top), b, False, 100);
+ warning_dialog (GTK_WIDGET (top), b, D_NONE, 100);
return;
}
{
char b[255];
sprintf (b, _("Error:\n\n" "File does not exist: \"%s\"\n"), path);
- warning_dialog (GTK_WIDGET (top), b, False, 100);
+ warning_dialog (GTK_WIDGET (top), b, D_NONE, 100);
return;
}
{
char b[255];
sprintf (b, _("Error:\n\n" "File does not exist: \"%s\"\n"), path);
- warning_dialog (GTK_WIDGET (top), b, False, 100);
+ warning_dialog (GTK_WIDGET (top), b, D_NONE, 100);
return;
}
# endif
-G_MODULE_EXPORT void
+G_MODULE_EXPORT void
settings_cb (GtkButton *button, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
{
# ifdef HAVE_XML
GtkWidget *cmd = GTK_WIDGET (name_to_widget (s, "cmd_text"));
- char *cmd_line = get_configurator_command_line (s->cdata);
+ char *cmd_line = get_configurator_command_line (s->cdata, False);
gtk_entry_set_text (GTK_ENTRY (cmd), cmd_line);
gtk_entry_set_position (GTK_ENTRY (cmd), strlen (cmd_line));
free (cmd_line);
gtk_notebook_set_page (notebook, 0);
}
+G_MODULE_EXPORT void
+settings_reset_cb (GtkButton *button, gpointer user_data)
+{
+# ifdef HAVE_XML
+ state *s = global_state_kludge; /* I hate C so much... */
+ GtkWidget *cmd = GTK_WIDGET (name_to_widget (s, "cmd_text"));
+ char *cmd_line = get_configurator_command_line (s->cdata, True);
+ gtk_entry_set_text (GTK_ENTRY (cmd), cmd_line);
+ gtk_entry_set_position (GTK_ENTRY (cmd), strlen (cmd_line));
+ free (cmd_line);
+ populate_popup_window (s);
+# endif /* HAVE_XML */
+}
+
G_MODULE_EXPORT void
settings_switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page,
gint page_num, gpointer user_data)
&& nitems >= 3
&& dataP)
{
- CARD32 *data = (CARD32 *) dataP;
+ PROP32 *data = (PROP32 *) dataP;
hack_number = (int) data[2] - 1;
}
static void
populate_hack_list (state *s)
{
+ Display *dpy = GDK_DISPLAY();
#ifdef HAVE_GTK2
saver_preferences *p = &s->prefs;
GtkTreeView *list = GTK_TREE_VIEW (name_to_widget (s, "list"));
pretty_name = (hack->name
? strdup (hack->name)
- : make_hack_name (hack->command));
+ : make_hack_name (dpy, hack->command));
if (!available_p)
{
(but don't actually make it be insensitive, since we still
want to be able to click on it.)
*/
- GtkStyle *style = GTK_WIDGET (list)->style;
+ GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (list));
GdkColor *fg = &style->fg[GTK_STATE_INSENSITIVE];
/* GdkColor *bg = &style->bg[GTK_STATE_INSENSITIVE]; */
char *buf = (char *) malloc (strlen (pretty_name) + 100);
TOGGLE_ACTIVE ("splash_button", p->splash_p);
#endif
TOGGLE_ACTIVE ("dpms_button", p->dpms_enabled_p);
+ TOGGLE_ACTIVE ("dpms_quickoff_button", p->dpms_quickoff_p);
TOGGLE_ACTIVE ("grab_desk_button", p->grab_desktop_p);
TOGGLE_ACTIVE ("grab_video_button", p->grab_video_p);
TOGGLE_ACTIVE ("grab_image_button", p->random_image_p);
/* DPMS
*/
+dpms_supported=1;
SENSITIZE ("dpms_frame", dpms_supported);
SENSITIZE ("dpms_button", dpms_supported);
+ SENSITIZE ("dpms_quickoff_button", dpms_supported);
+
SENSITIZE ("dpms_standby_label", dpms_supported && p->dpms_enabled_p);
SENSITIZE ("dpms_standby_mlabel", dpms_supported && p->dpms_enabled_p);
SENSITIZE ("dpms_standby_spinbutton", dpms_supported && p->dpms_enabled_p);
#if 1
/* Tell GDK to invalidate and repaint the whole window.
*/
- GdkWindow *w = s->toplevel_widget->window;
+ GdkWindow *w = GET_WINDOW (s->toplevel_widget);
GdkRegion *region = gdk_region_new ();
GdkRectangle rect;
rect.x = rect.y = 0;
#ifdef HAVE_GTK2
PangoFontMetrics *pain =
pango_context_get_metrics (gtk_widget_get_pango_context (w),
- w->style->font_desc,
+ gtk_widget_get_style (w)->font_desc,
gtk_get_default_language ());
height = PANGO_PIXELS (pango_font_metrics_get_ascent (pain) +
pango_font_metrics_get_descent (pain));
static void
populate_demo_window (state *s, int list_elt)
{
+ Display *dpy = GDK_DISPLAY();
saver_preferences *p = &s->prefs;
screenhack *hack;
char *pretty_name;
GtkFrame *frame1 = GTK_FRAME (name_to_widget (s, "preview_frame"));
- GtkFrame *frame2 = GTK_FRAME (name_to_widget (s, "doc_frame"));
+ GtkFrame *frame2 = GTK_FRAME (name_to_widget (s, "opt_frame"));
GtkEntry *cmd = GTK_ENTRY (name_to_widget (s, "cmd_text"));
GtkCombo *vis = GTK_COMBO (name_to_widget (s, "visual_combo"));
GtkWidget *list = GTK_WIDGET (name_to_widget (s, "list"));
pretty_name = (hack
? (hack->name
? strdup (hack->name)
- : make_hack_name (hack->command))
+ : make_hack_name (dpy, hack->command))
: 0);
if (hack)
static void
initialize_sort_map (state *s)
{
+ Display *dpy = GDK_DISPLAY();
saver_preferences *p = &s->prefs;
int i, j;
screenhack *hack = p->screenhacks[i];
char *name = (hack->name && *hack->name
? strdup (hack->name)
- : make_hack_name (hack->command));
+ : make_hack_name (dpy, hack->command));
char *str;
for (str = name; *str; str++)
*str = tolower(*str);
static int
maybe_reload_init_file (state *s)
{
+ Display *dpy = GDK_DISPLAY();
saver_preferences *p = &s->prefs;
int status = 0;
_("Warning:\n\n"
"file \"%s\" has changed, reloading.\n"),
f);
- warning_dialog (s->toplevel_widget, b, False, 100);
+ warning_dialog (s->toplevel_widget, b, D_NONE, 100);
free (b);
- load_init_file (p);
+ load_init_file (dpy, p);
initialize_sort_map (s);
list_elt = selected_list_element (s);
{
GtkWidget *p;
GdkWindow *window;
+ GtkStyle *style;
if (!s->toplevel_widget) return; /* very early */
p = name_to_widget (s, "preview");
- window = p->window;
+ window = GET_WINDOW (p);
if (!window) return;
/* Flush the widget background down into the window, in case a subproc
has changed it. */
- gdk_window_set_background (window, &p->style->bg[GTK_STATE_NORMAL]);
+ style = gtk_widget_get_style (p);
+ gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]);
gdk_window_clear (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))
+ if (GET_REALIZED (pr))
{
- Window oid = (pr->window ? GDK_WINDOW_XWINDOW (pr->window) : 0);
+ GdkWindow *window = GET_WINDOW (pr);
+ Window oid = (window ? GDK_WINDOW_XWINDOW (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);
+ id = (window ? GDK_WINDOW_XWINDOW (window) : 0);
if (s->debug_p)
fprintf (stderr, "%s: window id 0x%X -> 0x%X\n", blurb(),
(unsigned int) oid,
(visual == dvisual ? "default" : "non-default"),
(xvisual ? (unsigned long) xvisual->visualid : 0L));
- if (!GTK_WIDGET_REALIZED (widget) ||
+ if (!GET_REALIZED (widget) ||
gtk_widget_get_visual (widget) != visual)
{
gtk_widget_unrealize (widget);
/* Set the Widget colors to be white-on-black. */
{
- GdkWindow *window = widget->window;
- GtkStyle *style = gtk_style_copy (widget->style);
+ GdkWindow *window = GET_WINDOW (widget);
+ GtkStyle *style = gtk_style_copy (gtk_widget_get_style (widget));
GdkColormap *cmap = gtk_widget_get_colormap (widget);
GdkColor *fg = &style->fg[GTK_STATE_NORMAL];
GdkColor *bg = &style->bg[GTK_STATE_NORMAL];
perror (buf);
}
}
- else if (s->debug_p)
- fprintf (stderr, "%s: killed pid %lu (%s)\n", blurb(),
- (unsigned long) s->running_preview_pid, ss);
+ else {
+ int endstatus;
+ waitpid(s->running_preview_pid, &endstatus, 0);
+ if (s->debug_p)
+ fprintf (stderr, "%s: killed pid %lu (%s)\n", blurb(),
+ (unsigned long) s->running_preview_pid, ss);
+ }
free (ss);
s->running_preview_pid = 0;
reset_preview_window (s);
- window = pr->window;
+ window = GET_WINDOW (pr);
s->running_preview_error_p = False;
return FALSE; /* do not re-execute timer */
}
+static int
+settings_timer (gpointer data)
+{
+ settings_cb (0, 0);
+ return FALSE;
+}
+
/* Call this when you think you might want a preview process running.
It will set a timer that will actually launch that program a second
init_icon (GdkWindow *window)
{
GdkBitmap *mask = 0;
- GdkColor transp;
GdkPixmap *pixmap =
- gdk_pixmap_create_from_xpm_d (window, &mask, &transp,
+ gdk_pixmap_create_from_xpm_d (window, &mask, 0,
(gchar **) logo_50_xpm);
if (pixmap)
gdk_window_set_icon (window, 0, pixmap, mask);
#endif
+static Window
+gnome_screensaver_window (Screen *screen)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ Window root = RootWindowOfScreen (screen);
+ Window parent, *kids;
+ unsigned int nkids;
+ Window gnome_window = 0;
+ int i;
+
+ if (! XQueryTree (dpy, root, &root, &parent, &kids, &nkids))
+ abort ();
+ for (i = 0; i < nkids; i++)
+ {
+ Atom type;
+ int format;
+ unsigned long nitems, bytesafter;
+ unsigned char *name;
+ if (XGetWindowProperty (dpy, kids[i], XA_WM_COMMAND, 0, 128,
+ False, XA_STRING, &type, &format, &nitems,
+ &bytesafter, &name)
+ == Success
+ && type != None
+ && !strcmp ((char *) name, "gnome-screensaver"))
+ {
+ gnome_window = kids[i];
+ break;
+ }
+ }
+
+ if (kids) XFree ((char *) kids);
+ return gnome_window;
+}
+
+static Bool
+gnome_screensaver_active_p (void)
+{
+ Display *dpy = GDK_DISPLAY();
+ Window w = gnome_screensaver_window (DefaultScreenOfDisplay (dpy));
+ return (w ? True : False);
+}
+
+static void
+kill_gnome_screensaver (void)
+{
+ Display *dpy = GDK_DISPLAY();
+ Window w = gnome_screensaver_window (DefaultScreenOfDisplay (dpy));
+ if (w) XKillClient (dpy, (XID) w);
+}
+
+static Bool
+kde_screensaver_active_p (void)
+{
+ FILE *p = popen ("dcop kdesktop KScreensaverIface isEnabled 2>/dev/null",
+ "r");
+ char buf[255];
+ fgets (buf, sizeof(buf)-1, p);
+ pclose (p);
+ if (!strcmp (buf, "true\n"))
+ return True;
+ else
+ return False;
+}
+
+static void
+kill_kde_screensaver (void)
+{
+ system ("dcop kdesktop KScreensaverIface enable false");
+}
+
+
static void
the_network_is_not_the_computer (state *s)
{
if (*msg)
- warning_dialog (s->toplevel_widget, msg, True, 1);
+ warning_dialog (s->toplevel_widget, msg, D_LAUNCH, 1);
if (rversion) free (rversion);
if (ruser) free (ruser);
if (rhost) free (rhost);
free (msg);
+ msg = 0;
+
+ /* Note: since these dialogs are not modal, they will stack up.
+ So we do this check *after* popping up the "xscreensaver is not
+ running" dialog so that these are on top. Good enough.
+ */
+
+ if (gnome_screensaver_active_p ())
+ warning_dialog (s->toplevel_widget,
+ _("Warning:\n\n"
+ "The GNOME screensaver daemon appears to be running.\n"
+ "It must be stopped for XScreenSaver to work properly.\n"
+ "\n"
+ "Stop the GNOME screen saver daemon now?\n"),
+ D_GNOME, 1);
+
+ if (kde_screensaver_active_p ())
+ warning_dialog (s->toplevel_widget,
+ _("Warning:\n\n"
+ "The KDE screen saver daemon appears to be running.\n"
+ "It must be stopped for XScreenSaver to work properly.\n"
+ "\n"
+ "Stop the KDE screen saver daemon now?\n"),
+ D_KDE, 1);
}
the .ad file... */
#endif
+STFU
static char *defaults[] = {
#include "XScreenSaver_ad.h"
0
#endif /* HAVE_CRAPPLET */
#endif /* 0 */
-const char *usage = "[--display dpy] [--prefs]"
+const char *usage = "[--display dpy] [--prefs | --settings]"
# ifdef HAVE_CRAPPLET
" [--crapplet]"
# endif
#ifdef HAVE_GTK2
-GtkWidget *
+static GtkWidget *
create_xscreensaver_demo (void)
{
GtkWidget *nb;
return name_to_widget (global_state_kludge, "xscreensaver_demo");
}
-GtkWidget *
+static GtkWidget *
create_xscreensaver_settings_dialog (void)
{
GtkWidget *w, *box;
XtAppContext app;
state S, *s;
saver_preferences *p;
- Bool prefs = False;
+ Bool prefs_p = False;
+ Bool settings_p = False;
int i;
Display *dpy;
Widget toplevel_shell;
if (str[0] == '-' && str[1] == '-')
str++;
if (!strcmp (str, "-prefs"))
- prefs = True;
+ prefs_p = True;
+ else if (!strcmp (str, "-settings"))
+ settings_p = 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. */
hack_environment (s); /* must be before initialize_sort_map() */
- load_init_file (p);
+ load_init_file (dpy, p);
initialize_sort_map (s);
/* Now that Xt has been initialized, and the resources have been read,
gtk_widget_set_sensitive (std, False);
std = GTK_WIDGET (name_to_widget (s, "adv_button"));
gtk_widget_hide (std);
+ std = GTK_WIDGET (name_to_widget (s, "reset_button"));
+ gtk_widget_hide (std);
page = 1;
# endif /* !HAVE_XML */
/* Handle the -prefs command-line argument. */
- if (prefs)
+ if (prefs_p)
{
GtkNotebook *notebook =
GTK_NOTEBOOK (name_to_widget (s, "notebook"));
{
GtkWidget *window = capplet;
while (window && !GTK_IS_WINDOW (window))
- window = window->parent;
+ window = GET_PARENT (window);
if (window)
{
gtk_window_set_title (GTK_WINDOW (window), window_title);
#endif
gtk_widget_show (s->toplevel_widget);
- init_icon (GTK_WIDGET (s->toplevel_widget)->window); /* after `show' */
+ init_icon (GET_WINDOW (GTK_WIDGET (s->toplevel_widget))); /* after `show' */
fix_preview_visual (s);
/* Realize page zero, so that we can diddle the scrollbar when the
gtk_timeout_add (60 * 1000, check_blanked_timer, s);
+ /* Handle the --settings command-line argument. */
+ if (settings_p)
+ gtk_timeout_add (500, settings_timer, 0);
+
+
/* Issue any warnings about the running xscreensaver daemon. */
- the_network_is_not_the_computer (s);
+ if (! s->debug_p)
+ the_network_is_not_the_computer (s);
+
+
+ if (senescent_p())
+ warning_dialog (s->toplevel_widget,
+ _("Warning:\n\n"
+ "This version of xscreensaver is VERY OLD!\n"
+ "Please upgrade!\n"
+ "\n"
+ "http://www.jwz.org/xscreensaver/\n"
+ "\n"
+ "(If this is the latest version that your distro ships, then\n"
+ "your distro is doing you a disservice. Build from source.)\n"
+ ),
+ D_NONE, 7);
/* Run the Gtk event loop, and not the Xt event loop. This means that
gtk_timeout_add (500, delayed_scroll_kludge, s);
-#if 0
+#if 1
/* Load every configurator in turn, to scan them for errors all at once. */
- {
- int i;
- for (i = 0; i < p->screenhacks_count; i++)
- {
- screenhack *hack = p->screenhacks[i];
- conf_data *d = load_configurator (hack->command, False);
- if (d) free_conf_data (d);
- }
- }
+ if (s->debug_p)
+ {
+ int i;
+ for (i = 0; i < p->screenhacks_count; i++)
+ {
+ screenhack *hack = p->screenhacks[i];
+ conf_data *d = load_configurator (hack->command, s->debug_p);
+ if (d) free_conf_data (d);
+ }
+ }
#endif