# include "xmu.h"
#endif
-
-
#include <gtk/gtk.h>
+#ifdef HAVE_CRAPPLET
+# include <gnome.h>
+# include <capplet-widget.h>
+#endif
+
extern Display *gdk_display;
#include "version.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 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.
*/
}
}
-
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)
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);
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);
}
/* #### */
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);
}
s, s2);
free (s);
- warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+ warning_dialog (GTK_WIDGET (menuitem), buf, False, 100);
}
{
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));
+ apply_changes_and_save (GTK_WIDGET (widget));
xscreensaver_command (gdk_display, XA_EXIT, 0, False, NULL);
sleep (1);
system ("xscreensaver -nosplash &");
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);
"Error:\n\n"
"Unparsable time format: \"%s\"\n",
line);
- warning_dialog (widget, b, 100);
+ warning_dialog (widget, b, False, 100);
}
else
*store = value;
{ \
char b[255]; \
sprintf (b, "Error:\n\n" "Not an integer: \"%s\"\n", line); \
- warning_dialog (GTK_WIDGET (button), b, 100); \
+ warning_dialog (GTK_WIDGET (button), b, False, 100); \
} \
else \
*(field) = value; \
}
+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)
"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);
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;
+ pixmapify_buttons (w);
+ eschew_gtk_lossage (w);
+ ensure_selected_item_visible (GTK_WIDGET(name_to_widget(w, "list")));
+ initializing_p = oi;
+}
+
+
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;
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[i]);
+ 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)
+ {
+ init_results = gnome_capplet_init ("screensaver-properties",
+ short_version,
+ argc, argv, NULL, 0, NULL);
+
+ 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);
+ else
+ flags = 0;
+
+ if (flags & GNOME_CLIENT_IS_CONNECTED)
+ {
+ gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
+ gnome_client_flush (client);
+ }
+ }
+ else
+# endif /* HAVE_CRAPPLET */
+ {
+ gtk_init (&argc, &argv);
+ }
/* We must read exactly the same resources as xscreensaver.
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, "%s: unknown option: %s\n", real_progname, argv[i]);
- fprintf (stderr, "usage: %s [ -display dpy-string ] [ -prefs ]\n",
- real_progname);
- exit (1);
+ 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);
+
/* 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);
+
+ /* 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"));
+
+ 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);
+
+ /* 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);
}