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);
sprintf (name, "label%d", i++);
{
+#if 0
char buf[255];
+#endif
label = gtk_label_new (head);
+#if 0
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"));
+#endif
if (center <= 0)
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
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);
+ }
}
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);
+ }
+}
+
\f
/* Populating the various widgets
*/
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));
- line = gtk_list_item_new_with_label (pretty_name);
+ 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);
+
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);
};
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);
}
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
{
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;
# 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 */
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"));