X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fdemo-Gtk.c;h=0ff66e9382ae0a7bcbb721edff8ad66b1cb439c4;hb=de041722414a2e31c1c04caa10aaec9d6952e9b4;hp=11c64d8985de896a76f8c47856559f4da3c80aae;hpb=0316d74da7982288abddd34e7a62698eb7f79965;p=xscreensaver diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c index 11c64d89..0ff66e93 100644 --- a/driver/demo-Gtk.c +++ b/driver/demo-Gtk.c @@ -109,6 +109,7 @@ static void populate_demo_window (GtkWidget *toplevel, 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); /* Some random utility functions @@ -171,7 +172,7 @@ ensure_selected_item_visible (GtkWidget *widget) 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); @@ -257,12 +258,16 @@ warning_dialog (GtkWidget *parent, const char *message, 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), @@ -497,6 +502,69 @@ restart_menu_cb (GtkWidget *widget, gpointer user_data) 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); + } } @@ -915,6 +983,80 @@ list_unselect_cb (GtkList *list, GtkWidget *child) 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); + } +} + /* Populating the various widgets */ @@ -1036,18 +1178,50 @@ populate_hack_list (GtkWidget *toplevel, prefs_pair *pair) 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); @@ -1268,7 +1442,7 @@ static char *down_arrow_xpm[] = { }; static void -pixmapify_buttons (GtkWidget *toplevel) +pixmapify_button (GtkWidget *toplevel, int down_p) { GdkPixmap *pixmap; GdkBitmap *mask; @@ -1276,27 +1450,31 @@ pixmapify_buttons (GtkWidget *toplevel) 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); } @@ -1466,7 +1644,11 @@ populate_demo_window (GtkWidget *toplevel, int which, prefs_pair *pair) 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 @@ -1764,7 +1946,6 @@ map_window_cb (GtkWidget *w, gpointer user_data) { 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; @@ -1775,11 +1956,6 @@ int 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; @@ -1858,9 +2034,21 @@ main (int argc, char **argv) # 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) { @@ -1878,14 +2066,38 @@ main (int argc, char **argv) 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 */ @@ -2022,6 +2234,12 @@ main (int argc, char **argv) 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. */ @@ -2046,10 +2264,6 @@ main (int argc, char **argv) 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"));