summaryrefslogtreecommitdiffstats
path: root/driver/demo-Gtk.c
diff options
context:
space:
mode:
authorSimon Rettberg2021-04-06 14:23:46 +0200
committerSimon Rettberg2021-04-06 14:23:46 +0200
commit26b6e4255d4b9ff79a6dca10de5bec7bfc8691f9 (patch)
treea51e1637554bcd84e63cccb1cb220c898a2c4ee8 /driver/demo-Gtk.c
parent5.44 (diff)
downloadxscreensaver-26b6e4255d4b9ff79a6dca10de5bec7bfc8691f9.tar.gz
xscreensaver-26b6e4255d4b9ff79a6dca10de5bec7bfc8691f9.tar.xz
xscreensaver-26b6e4255d4b9ff79a6dca10de5bec7bfc8691f9.zip
xscreensaver 6.00
Diffstat (limited to 'driver/demo-Gtk.c')
-rw-r--r--driver/demo-Gtk.c535
1 files changed, 274 insertions, 261 deletions
diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c
index da98c53..b5e82e2 100644
--- a/driver/demo-Gtk.c
+++ b/driver/demo-Gtk.c
@@ -1,5 +1,5 @@
/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
- * xscreensaver, Copyright (c) 1993-2020 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright © 1993-2021 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
@@ -16,6 +16,8 @@
#ifdef HAVE_GTK /* whole file */
+#include "blurb.h"
+
#include <xscreensaver-intl.h>
#include <stdlib.h>
@@ -35,18 +37,13 @@
# include <locale.h>
#endif /* ENABLE_NLS */
-#ifndef VMS
-# include <pwd.h> /* for getpwuid() */
-#else /* VMS */
-# include "vms-pwd.h"
-#endif /* VMS */
-
#ifdef HAVE_UNAME
# include <sys/utsname.h> /* for uname() */
#endif /* HAVE_UNAME */
#include <stdio.h>
#include <time.h>
+#include <pwd.h> /* for getpwuid() */
#include <sys/stat.h>
#include <sys/time.h>
@@ -68,20 +65,19 @@
#include <X11/IntrinsicP.h>
#include <X11/ShellP.h>
-#ifdef HAVE_XMU
-# ifndef VMS
-# include <X11/Xmu/Error.h>
-# else /* VMS */
-# include <Xmu/Error.h>
-# endif
-#else
-# include "xmu.h"
-#endif
-
#ifdef HAVE_XINERAMA
# include <X11/extensions/Xinerama.h>
#endif /* HAVE_XINERAMA */
+#if (__GNUC__ >= 4) /* Ignore useless warnings generated by gtk.h */
+# undef inline
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wstrict-prototypes"
+# pragma GCC diagnostic ignored "-Wlong-long"
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
#include <gtk/gtk.h>
#ifdef HAVE_CRAPPLET
@@ -92,38 +88,36 @@
#include <gdk/gdkx.h>
#ifdef HAVE_GTK2
-# include <glade/glade-xml.h>
# include <gmodule.h>
#else /* !HAVE_GTK2 */
# define G_MODULE_EXPORT /**/
#endif /* !HAVE_GTK2 */
-#if defined(DEFAULT_ICONDIR) && !defined(GLADE_DIR)
-# define GLADE_DIR DEFAULT_ICONDIR
-#endif
-#if !defined(DEFAULT_ICONDIR) && defined(GLADE_DIR)
-# define DEFAULT_ICONDIR GLADE_DIR
-#endif
-
#ifndef HAVE_XML
/* Kludge: this is defined in demo-Gtk-conf.c when HAVE_XML.
It is unused otherwise, so in that case, stub it out. */
static const char *hack_configuration_path = 0;
#endif
+#if (__GNUC__ >= 4)
+# pragma GCC diagnostic pop
+#endif
#include "version.h"
-#include "prefs.h"
+#include "types.h"
#include "resources.h" /* for parse_time() */
-#include "visual.h" /* for has_writable_cells() */
#include "remote.h" /* for xscreensaver_command() */
+#include "visual.h"
+#include "atoms.h"
#include "usleep.h"
+#include "xmu.h"
#include "logo-50.xpm"
#include "logo-180.xpm"
#include "demo-Gtk-conf.h"
+#include "atoms.h"
#include <stdio.h>
#include <string.h>
@@ -182,14 +176,6 @@ static void hack_subproc_environment (Window preview_window_id, Bool debug_p);
#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;
@@ -208,7 +194,7 @@ typedef struct {
conf_data *cdata; /* private data for per-hack configuration */
#ifdef HAVE_GTK2
- GladeXML *glade_ui; /* Glade UI file */
+ GtkBuilder *gtk_ui; /* UI file */
#endif /* HAVE_GTK2 */
Bool debug_p; /* whether to print diagnostics */
@@ -247,13 +233,6 @@ typedef struct {
a closure object of our own down into the various widget callbacks. */
static state *global_state_kludge;
-Atom XA_VROOT;
-Atom XA_SCREENSAVER, XA_SCREENSAVER_RESPONSE, XA_SCREENSAVER_VERSION;
-Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO;
-Atom XA_ACTIVATE, XA_SUSPEND, XA_BLANK, XA_LOCK, XA_RESTART, XA_EXIT;
-Atom XA_NEXT, XA_PREV;
-
-
static void populate_demo_window (state *, int list_elt);
static void populate_prefs_page (state *);
static void populate_popup_window (state *);
@@ -272,16 +251,15 @@ static void kill_preview_subproc (state *, Bool reset_p);
static void schedule_preview_check (state *);
-/* Prototypes of functions used by the Glade-generated code,
- to avoid warnings.
+/* Prototypes of functions used by the Gtk-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 exit_menu_cb (GtkAction *, gpointer user_data);
+void about_menu_cb (GtkAction *, gpointer user_data);
+void doc_menu_cb (GtkAction *, gpointer user_data);
+void file_menu_cb (GtkAction *, gpointer user_data);
+void activate_menu_cb (GtkAction *, gpointer user_data);
+void lock_menu_cb (GtkAction *, gpointer user_data);
+void kill_menu_cb (GtkAction *, 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);
@@ -303,33 +281,14 @@ 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);
+void preview_theme_cb (GtkWidget *, gpointer user_data);
static void kill_gnome_screensaver (void);
static void kill_kde_screensaver (void);
-
/* Some random utility functions
*/
-const char *blurb (void);
-
-const char *
-blurb (void)
-{
- time_t now = time ((time_t *) 0);
- char *ct = (char *) ctime (&now);
- static char buf[255];
- int n = strlen(progname);
- if (n > 100) n = 99;
- strncpy(buf, progname, n);
- buf[n++] = ':';
- buf[n++] = ' ';
- strncpy(buf+n, ct+11, 8);
- strcpy(buf+n+9, ": ");
- return buf;
-}
-
-
static GtkWidget *
name_to_widget (state *s, const char *name)
{
@@ -339,38 +298,49 @@ name_to_widget (state *s, const char *name)
if (!*name) abort();
#ifdef HAVE_GTK2
- if (!s->glade_ui)
+ if (!s->gtk_ui)
{
- /* First try to load the Glade file from the current directory;
+ /* First try to load the UI file from the current directory;
if there isn't one there, check the installed directory.
*/
-# define GLADE_FILE_NAME "xscreensaver-demo.glade2"
- const char * const files[] = { GLADE_FILE_NAME,
- GLADE_DIR "/" GLADE_FILE_NAME };
+# define UI_FILE "xscreensaver.ui"
+ const char * const files[] = { UI_FILE,
+ DEFAULT_ICONDIR "/" UI_FILE };
int i;
+
+ s->gtk_ui = gtk_builder_new ();
+
for (i = 0; i < countof (files); i++)
{
struct stat st;
if (!stat (files[i], &st))
{
- s->glade_ui = glade_xml_new (files[i], NULL, NULL);
- break;
+ GError* error = NULL;
+
+ if (gtk_builder_add_from_file (s->gtk_ui, files[i], &error))
+ break;
+ else
+ {
+ g_warning ("Couldn't load builder file %s: %s",
+ files[i], error->message);
+ g_error_free (error);
+ }
}
}
- if (!s->glade_ui)
+ if (i >= countof (files))
{
fprintf (stderr,
- "%s: could not load \"" GLADE_FILE_NAME "\"\n"
- "\tfrom " GLADE_DIR "/ or current directory.\n",
+ "%s: could not load \"" UI_FILE "\"\n"
+ "\tfrom " DEFAULT_ICONDIR "/ or current directory.\n",
blurb());
exit (-1);
}
-# undef GLADE_FILE_NAME
+# undef UI_FILE
- glade_xml_signal_autoconnect (s->glade_ui);
+ gtk_builder_connect_signals (s->gtk_ui, NULL);
}
- w = glade_xml_get_widget (s->glade_ui, name);
+ w = GTK_WIDGET (gtk_builder_get_object (s->gtk_ui, name));
#else /* !HAVE_GTK2 */
@@ -382,7 +352,7 @@ name_to_widget (state *s, const char *name)
#endif /* HAVE_GTK2 */
if (w) return w;
- fprintf (stderr, "%s: no widget \"%s\" (wrong Glade file?)\n",
+ fprintf (stderr, "%s: no widget \"%s\" (wrong UI file?)\n",
blurb(), name);
abort();
}
@@ -774,12 +744,12 @@ run_hack (state *s, int list_elt, Bool report_errors_p)
/* Button callbacks
According to Eric Lassauge, this G_MODULE_EXPORT crud is needed to make
- libglade work on Cygwin; apparently all Glade callbacks need this magic
- extra declaration. I do not pretend to understand.
+ GTK work on Cygwin; apparently all GTK callbacks need this magic extra
+ declaration. I do not pretend to understand.
*/
G_MODULE_EXPORT void
-exit_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+exit_menu_cb (GtkAction *menu_action, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
flush_dialog_changes_and_save (s);
@@ -798,28 +768,27 @@ wm_toplevel_close_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
G_MODULE_EXPORT void
-about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+about_menu_cb (GtkAction *menu_action, gpointer user_data)
{
+#if 1
+ /* Let's just pop up the splash dialog instead. */
+ preview_theme_cb (NULL, user_data);
+#else
char msg [2048];
- char *vers = strdup (screensaver_id + 4);
- char *s, *s2;
char copy[1024];
- char year[5];
char *desc = _("For updates, check https://www.jwz.org/xscreensaver/");
- s = strchr (vers, ',');
+ char *version = strdup (screensaver_id + 17);
+ char *year = strchr (version, '-');
+ char *s = strchr (version, ' ');
+ *s = 0;
+ year = strchr (year+1, '-') + 1;
+ s = strchr (year, ')');
*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
+ (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
@@ -837,7 +806,7 @@ about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
#ifdef HAVE_CRAPPLET
{
const gchar *auth[] = { 0 };
- GtkWidget *about = gnome_about_new (progclass, vers, "", auth, desc,
+ GtkWidget *about = gnome_about_new (progclass, version, "", auth, desc,
"xscreensaver.xpm");
gtk_widget_show (about);
}
@@ -851,7 +820,8 @@ about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
GtkWidget *dialog = gtk_dialog_new ();
GtkWidget *hbox, *icon, *vbox, *label1, *label2, *hb, *ok;
- GtkWidget *parent = GTK_WIDGET (menuitem);
+ GSList *proxies = gtk_action_get_proxies (menu_action);
+ GtkWidget *parent = GTK_WIDGET (proxies->data);
while (GET_PARENT (parent))
parent = GET_PARENT (parent);
@@ -871,7 +841,7 @@ about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
vbox = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
- label1 = gtk_label_new (vers);
+ label1 = gtk_label_new (version);
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);
@@ -928,11 +898,12 @@ about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
gdk_window_show (GET_WINDOW (GTK_WIDGET (dialog)));
gdk_window_raise (GET_WINDOW (GTK_WIDGET (dialog)));
}
+#endif /* 0 */
}
G_MODULE_EXPORT void
-doc_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+doc_menu_cb (GtkAction *menu_action, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
saver_preferences *p = &s->prefs;
@@ -947,11 +918,11 @@ doc_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
}
help_command = (char *) malloc (strlen (p->load_url_command) +
- (strlen (p->help_url) * 4) + 20);
+ (strlen (p->help_url) * 5) + 20);
strcpy (help_command, "( ");
sprintf (help_command + strlen(help_command),
p->load_url_command,
- p->help_url, p->help_url, p->help_url, p->help_url);
+ p->help_url, p->help_url, p->help_url, p->help_url, p->help_url);
strcat (help_command, " ) &");
if (system (help_command) < 0)
fprintf (stderr, "%s: fork error\n", blurb());
@@ -960,7 +931,7 @@ doc_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
G_MODULE_EXPORT void
-file_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+file_menu_cb (GtkAction *menu_action, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
sensitize_menu_items (s, False);
@@ -968,7 +939,7 @@ file_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
G_MODULE_EXPORT void
-activate_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+activate_menu_cb (GtkAction *menu_action, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
run_cmd (s, XA_ACTIVATE, 0);
@@ -976,7 +947,7 @@ activate_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
G_MODULE_EXPORT void
-lock_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+lock_menu_cb (GtkAction *menu_action, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
run_cmd (s, XA_LOCK, 0);
@@ -984,7 +955,7 @@ lock_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
G_MODULE_EXPORT void
-kill_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+kill_menu_cb (GtkAction *menu_action, gpointer user_data)
{
state *s = global_state_kludge; /* I hate C so much... */
run_cmd (s, XA_EXIT, 0);
@@ -998,7 +969,7 @@ restart_menu_cb (GtkWidget *widget, gpointer user_data)
flush_dialog_changes_and_save (s);
xscreensaver_command (GDK_DISPLAY(), XA_EXIT, 0, False, NULL);
sleep (1);
- if (system ("xscreensaver -nosplash &") < 0)
+ if (system ("xscreensaver -splash &") < 0)
fprintf (stderr, "%s: fork error\n", blurb());
await_xscreensaver (s);
@@ -1084,12 +1055,6 @@ demo_write_init_file (state *s, saver_preferences *p)
{
Display *dpy = GDK_DISPLAY();
-#if 0
- /* #### try to figure out why shit keeps getting reordered... */
- if (strcmp (s->prefs.screenhacks[0]->name, "DNA Lounge Slideshow"))
- abort();
-#endif
-
if (!write_init_file (dpy, p, s->short_version, False))
{
if (s->debug_p)
@@ -1191,7 +1156,7 @@ force_list_select_item (state *s, GtkWidget *list, int list_elt, Bool scroll_p)
if (!was) gtk_widget_set_sensitive (parent, True);
#ifdef HAVE_GTK2
model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
- g_assert (model);
+ if (!model) abort();
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, list_elt))
{
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
@@ -1485,6 +1450,25 @@ flush_checkbox (GtkTreeModel *model,
#endif /* HAVE_GTK2 */
+
+static char *
+theme_name_strip (const char *s)
+{
+ const char *in = s;
+ char *s2 = strdup(s);
+ char *out = s2;
+ for (; *in; in++)
+ if (*in >= 'A' && *in <= 'Z')
+ *out++ = *in + ('a'-'A');
+ else if (*in == ' ' || *in == '\t')
+ ;
+ else
+ *out++ = *in;
+ *out = 0;
+ return s2;
+}
+
+
/* Flush out any changes made in the main dialog window (where changes
take place immediately: clicking on a checkbox causes the init file
to be written right away.)
@@ -1492,6 +1476,7 @@ flush_checkbox (GtkTreeModel *model,
static Bool
flush_dialog_changes_and_save (state *s)
{
+ Display *dpy = GDK_DISPLAY();
saver_preferences *p = &s->prefs;
saver_preferences P2, *p2 = &P2;
#ifdef HAVE_GTK2
@@ -1578,7 +1563,6 @@ flush_dialog_changes_and_save (state *s)
#if 0
CHECKBOX (p2->verbose_p, "verbose_button");
- CHECKBOX (p2->capture_stderr_p, "capture_button");
CHECKBOX (p2->splash_p, "splash_button");
#endif
@@ -1596,7 +1580,6 @@ flush_dialog_changes_and_save (state *s)
TEXT (p2->text_url, "text_url_entry");
}
- CHECKBOX (p2->install_cmap_p, "install_button");
CHECKBOX (p2->fade_p, "fade_button");
CHECKBOX (p2->unfade_p, "unfade_button");
SECONDS (&p2->fade_seconds, "fade_spinbutton");
@@ -1610,12 +1593,13 @@ flush_dialog_changes_and_save (state *s)
/* 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://
+ - image directory is not a URL
*/
if (p2->image_directory &&
*p2->image_directory &&
!directory_p (p2->image_directory) &&
- strncmp(p2->image_directory, "http://", 6) &&
+ strncmp(p2->image_directory, "http://", 7) &&
+ strncmp(p2->image_directory, "https://", 8) &&
( !already_warned_about_missing_image_directory ||
( p->image_directory &&
*p->image_directory &&
@@ -1634,11 +1618,8 @@ flush_dialog_changes_and_save (state *s)
/* Map the mode menu to `saver_mode' enum values. */
{
- GtkOptionMenu *opt = GTK_OPTION_MENU (name_to_widget (s, "mode_menu"));
- GtkMenu *menu = GTK_MENU (gtk_option_menu_get_menu (opt));
- GtkWidget *selected = gtk_menu_get_active (menu);
- GList *kids = gtk_container_children (GTK_CONTAINER (menu));
- int menu_elt = g_list_index (kids, (gpointer) selected);
+ GtkComboBox *opt = GTK_COMBO_BOX (name_to_widget (s, "mode_menu"));
+ int menu_elt = gtk_combo_box_get_active (opt);
if (menu_elt < 0 || menu_elt >= countof(mode_menu_order)) abort();
p2->mode = mode_menu_order[menu_elt];
}
@@ -1651,11 +1632,33 @@ flush_dialog_changes_and_save (state *s)
: -1);
}
+ /* Theme menu. */
+ {
+ GtkComboBox *cbox = GTK_COMBO_BOX (name_to_widget (s, "theme_menu"));
+ char *themes = get_string_resource (dpy, "themeNames", "ThemeNames");
+ int menu_index = gtk_combo_box_get_active (cbox);
+ char *token = themes;
+ char *name, *last;
+ int i = 0;
+ while ((name = strtok_r (token, ",", &last)))
+ {
+ token = 0;
+ if (i == menu_index)
+ {
+ char *name2 = theme_name_strip (name);
+ if (p->dialog_theme) free (p->dialog_theme);
+ p2->dialog_theme = name2;
+ }
+ i++;
+ }
+ }
+
# define COPY(field, name) \
if (p->field != p2->field) { \
changed = True; \
if (s->debug_p) \
- fprintf (stderr, "%s: %s => %d\n", blurb(), name, (int) p2->field); \
+ fprintf (stderr, "%s: %s => %ld\n", blurb(), \
+ name, (unsigned long) p2->field); \
} \
p->field = p2->field
@@ -1675,7 +1678,6 @@ flush_dialog_changes_and_save (state *s)
#if 0
COPY(verbose_p, "verbose_p");
- COPY(capture_stderr_p, "capture_stderr_p");
COPY(splash_p, "splash_p");
#endif
@@ -1690,6 +1692,7 @@ flush_dialog_changes_and_save (state *s)
COPY(grab_video_p, "grab_video_p");
COPY(random_image_p, "random_image_p");
+ COPY(dialog_theme, "dialog_theme");
# undef COPY
# define COPYSTR(FIELD,NAME) \
@@ -1717,14 +1720,7 @@ flush_dialog_changes_and_save (state *s)
if (changed)
{
- Display *dpy = GDK_DISPLAY();
- Bool enabled_p = (p->dpms_enabled_p && p->mode != DONT_BLANK);
- sync_server_dpms_settings (dpy, enabled_p, p->dpms_quickoff_p,
- p->dpms_standby / 1000,
- p->dpms_suspend / 1000,
- p->dpms_off / 1000,
- False);
-
+ sync_server_dpms_settings (GDK_DISPLAY(), p);
changed = demo_write_init_file (s, p);
}
@@ -1744,9 +1740,10 @@ flush_popup_changes_and_save (state *s)
int list_elt = selected_list_element (s);
GtkEntry *cmd = GTK_ENTRY (name_to_widget (s, "cmd_text"));
- GtkCombo *vis = GTK_COMBO (name_to_widget (s, "visual_combo"));
+ GtkComboBoxEntry *vis = GTK_COMBO_BOX_ENTRY (name_to_widget (s, "visual_combo"));
+ GtkEntry *visent = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (vis)));
- const char *visual = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (vis)->entry));
+ const char *visual = gtk_entry_get_text (visent);
const char *command = gtk_entry_get_text (cmd);
char c;
@@ -1791,7 +1788,7 @@ flush_popup_changes_and_save (state *s)
{
gdk_beep (); /* unparsable */
visual = "";
- gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry), _("Any"));
+ gtk_entry_set_text (visent, _("Any"));
}
changed = flush_changes (s, list_elt, -1, command, visual);
@@ -1839,21 +1836,8 @@ mode_menu_item_cb (GtkWidget *widget, gpointer user_data)
GtkWidget *list = name_to_widget (s, "list");
int list_elt;
- GList *menu_items =
- gtk_container_children (GTK_CONTAINER (GET_PARENT (widget)));
- int menu_index = 0;
- saver_mode new_mode;
-
- while (menu_items)
- {
- if (menu_items->data == widget)
- break;
- menu_index++;
- menu_items = menu_items->next;
- }
- if (!menu_items) abort();
-
- new_mode = mode_menu_order[menu_index];
+ int menu_index = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+ saver_mode new_mode = mode_menu_order[menu_index];
/* Keep the same list element displayed as before; except if we're
switching *to* "one screensaver" mode from any other mode, set
@@ -1901,7 +1885,7 @@ list_activated_cb (GtkTreeView *list,
char *str;
int list_elt;
- g_return_if_fail (!gdk_pointer_is_grabbed ());
+ if (gdk_pointer_is_grabbed()) return;
str = gtk_tree_path_to_string (path);
list_elt = strtol (str, NULL, 10);
@@ -2305,7 +2289,12 @@ browse_text_program_cb (GtkButton *button, gpointer user_data)
}
-
+G_MODULE_EXPORT void
+preview_theme_cb (GtkWidget *w, gpointer user_data)
+{
+ if (system ("xscreensaver-auth --splash &") < 0)
+ fprintf (stderr, "%s: splash exec failed\n", blurb());
+}
G_MODULE_EXPORT void
@@ -2761,6 +2750,7 @@ update_list_sensitivity (state *s)
static void
populate_prefs_page (state *s)
{
+ Display *dpy = GDK_DISPLAY();
saver_preferences *p = &s->prefs;
Bool can_lock_p = True;
@@ -2813,7 +2803,6 @@ populate_prefs_page (state *s)
TOGGLE_ACTIVE ("lock_button", p->lock_p);
#if 0
TOGGLE_ACTIVE ("verbose_button", p->verbose_p);
- TOGGLE_ACTIVE ("capture_button", p->capture_stderr_p);
TOGGLE_ACTIVE ("splash_button", p->splash_p);
#endif
TOGGLE_ACTIVE ("dpms_button", p->dpms_enabled_p);
@@ -2821,7 +2810,6 @@ populate_prefs_page (state *s)
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);
- TOGGLE_ACTIVE ("install_button", p->install_cmap_p);
TOGGLE_ACTIVE ("fade_button", p->fade_p);
TOGGLE_ACTIVE ("unfade_button", p->unfade_p);
@@ -2866,40 +2854,73 @@ populate_prefs_page (state *s)
p->tmode == TEXT_URL);
+ /* Theme menu */
+ {
+ GtkComboBox *cbox = GTK_COMBO_BOX (name_to_widget (s, "theme_menu"));
+
+ /* Without this, pref_changed_cb gets called an exponentially-increasing
+ number of times on the themes menu, despite the call to
+ gtk_list_store_clear(). */
+ static Bool done_once = False;
+
+ if (cbox && !done_once)
+ {
+ char *themes = get_string_resource (dpy, "themeNames", "ThemeNames");
+ char *token = themes;
+ char *name, *name2, *last;
+ GtkListStore *model;
+ GtkTreeIter iter;
+ int i = 0;
+ done_once = True;
+
+ g_object_get (G_OBJECT (cbox), "model", &model, NULL);
+ if (!model) abort();
+ gtk_list_store_clear (model);
+
+ gtk_signal_connect (GTK_OBJECT (cbox), "changed",
+ GTK_SIGNAL_FUNC (pref_changed_cb), (gpointer) s);
+
+ while ((name = strtok_r (token, ",", &last)))
+ {
+ int L;
+ token = 0;
+
+ /* Strip leading and trailing whitespace */
+ while (*name == ' ' || *name == '\t' || *name == '\n')
+ name++;
+ L = strlen(name);
+ while (L && (name[L-1] == ' ' || name[L-1] == '\t' ||
+ name[L-1] == '\n'))
+ name[--L] = 0;
+
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter, 0, name, -1);
+
+ name2 = theme_name_strip (name);
+ if (!strcmp (p->dialog_theme, name2))
+ gtk_combo_box_set_active (cbox, i);
+ free (name2);
+ i++;
+ }
+ }
+ }
+
+
/* Map the `saver_mode' enum to mode menu to values. */
{
- GtkOptionMenu *opt = GTK_OPTION_MENU (name_to_widget (s, "mode_menu"));
+ GtkComboBox *opt = GTK_COMBO_BOX (name_to_widget (s, "mode_menu"));
int i;
for (i = 0; i < countof(mode_menu_order); i++)
if (mode_menu_order[i] == p->mode)
break;
- gtk_option_menu_set_history (opt, i);
+ gtk_combo_box_set_active (opt, i);
update_list_sensitivity (s);
}
{
- Bool found_any_writable_cells = False;
- Bool fading_possible = False;
Bool dpms_supported = False;
-
Display *dpy = GDK_DISPLAY();
- int nscreens = ScreenCount(dpy); /* real screens, not Xinerama */
- int i;
- for (i = 0; i < nscreens; i++)
- {
- Screen *s = ScreenOfDisplay (dpy, i);
- if (has_writable_cells (s, DefaultVisualOfScreen (s)))
- {
- found_any_writable_cells = True;
- break;
- }
- }
-
- fading_possible = found_any_writable_cells;
-#ifdef HAVE_XF86VMODE_GAMMA
- fading_possible = True;
-#endif
#ifdef HAVE_DPMS_EXTENSION
{
@@ -2923,7 +2944,6 @@ populate_prefs_page (state *s)
*/
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);
@@ -2934,24 +2954,26 @@ populate_prefs_page (state *s)
SENSITIZE ("dpms_off_label", dpms_supported && p->dpms_enabled_p);
SENSITIZE ("dpms_off_mlabel", dpms_supported && p->dpms_enabled_p);
SENSITIZE ("dpms_off_spinbutton", dpms_supported && p->dpms_enabled_p);
+ SENSITIZE ("dpms_quickoff_button", dpms_supported);
- /* Colormaps
- */
- SENSITIZE ("cmap_frame", found_any_writable_cells || fading_possible);
- SENSITIZE ("install_button", found_any_writable_cells);
- SENSITIZE ("fade_button", fading_possible);
- SENSITIZE ("unfade_button", fading_possible);
-
- SENSITIZE ("fade_label", (fading_possible &&
- (p->fade_p || p->unfade_p)));
- SENSITIZE ("fade_spinbutton", (fading_possible &&
- (p->fade_p || p->unfade_p)));
+ SENSITIZE ("fade_label", (p->fade_p || p->unfade_p));
+ SENSITIZE ("fade_spinbutton", (p->fade_p || p->unfade_p));
# undef SENSITIZE
}
}
+/* Allow the documentation label to re-flow when the text is changed.
+ http://blog.borovsak.si/2009/05/wrapping-adn-resizing-gtklabel.html
+ */
+static void
+cb_allocate (GtkWidget *label, GtkAllocation *allocation, gpointer data)
+{
+ gtk_widget_set_size_request (label, allocation->width - 8, -1);
+}
+
+
static void
populate_popup_window (state *s)
{
@@ -2962,6 +2984,9 @@ populate_popup_window (state *s)
gtk_label_set_selectable (doc);
*/
+ g_signal_connect (G_OBJECT (doc), "size-allocate",
+ G_CALLBACK (cb_allocate), NULL);
+
# ifdef HAVE_XML
if (s->cdata)
{
@@ -2998,6 +3023,14 @@ populate_popup_window (state *s)
gtk_label_set_text (doc, (doc_string
? _(doc_string)
: _("No description available.")));
+
+ {
+ GtkWidget *w = name_to_widget (s, "dialog_vbox");
+ gtk_widget_hide (w);
+ gtk_widget_unrealize (w);
+ gtk_widget_realize (w);
+ gtk_widget_show (w);
+ }
}
@@ -3022,7 +3055,7 @@ sensitize_menu_items (state *s, Bool force_p)
static Bool running_p = False;
static time_t last_checked = 0;
time_t now = time ((time_t *) 0);
- const char *names[] = { "activate_menu", "lock_menu", "kill_menu",
+ const char *names[] = { "activate_action", "lock_action", "kill_action",
/* "demo" */ };
int i;
@@ -3034,8 +3067,8 @@ sensitize_menu_items (state *s, Bool force_p)
for (i = 0; i < countof(names); i++)
{
- GtkWidget *w = name_to_widget (s, names[i]);
- gtk_widget_set_sensitive (GTK_WIDGET(w), running_p);
+ GtkAction *a = GTK_ACTION (gtk_builder_get_object (s->gtk_ui, names[i]));
+ gtk_action_set_sensitive (a, running_p);
}
}
@@ -3107,7 +3140,7 @@ fix_text_entry_sizes (state *s)
/* Now fix the width of the combo box.
*/
w = GTK_WIDGET (name_to_widget (s, "visual_combo"));
- w = GTK_COMBO (w)->entry;
+ w = GTK_COMBO_BOX_ENTRY (w)->entry;
width = gdk_string_width (w->style->font, "PseudoColor___");
gtk_widget_set_usize (w, width, -2);
@@ -3313,7 +3346,7 @@ populate_demo_window (state *s, int list_elt)
GtkFrame *frame1 = GTK_FRAME (name_to_widget (s, "preview_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"));
+ GtkComboBoxEntry *vis = GTK_COMBO_BOX_ENTRY (name_to_widget (s, "visual_combo"));
GtkWidget *list = GTK_WIDGET (name_to_widget (s, "list"));
if (p->mode == BLANK_ONLY)
@@ -3363,7 +3396,7 @@ populate_demo_window (state *s, int list_elt)
gtk_window_set_title (GTK_WINDOW (s->popup_widget), title);
}
- gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry),
+ gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (vis))),
(hack
? (hack->visual && *hack->visual
? hack->visual
@@ -3471,10 +3504,11 @@ initialize_sort_map (state *s)
char *name = (hack->name && *hack->name
? strdup (hack->name)
: make_hack_name (dpy, hack->command));
- char *str;
- for (str = name; *str; str++)
- *str = tolower(*str);
- sort_hack_cmp_names_kludge[i] = name;
+ gchar *s2 = g_str_to_ascii (name, 0); /* Sort "Möbius" properly */
+ gchar *s3 = g_ascii_strdown (s2, -1);
+ free (name);
+ free (s2);
+ sort_hack_cmp_names_kludge[i] = s3;
}
/* Sort list->hack map alphabetically
@@ -3782,7 +3816,7 @@ get_best_gl_visual (state *s)
char *av[10];
int ac = 0;
- av[ac++] = "xscreensaver-gl-helper";
+ av[ac++] = "xscreensaver-gl-visual";
av[ac] = 0;
if (pipe (fds))
@@ -4395,7 +4429,9 @@ gnome_screensaver_window (Screen *screen)
&bytesafter, &name)
== Success
&& type != None
- && !strcmp ((char *) name, "gnome-screensaver"))
+ && (!strcmp ((char *) name, "gnome-screensaver") ||
+ !strcmp ((char *) name, "mate-screensaver") ||
+ !strcmp ((char *) name, "cinnamon-screensaver")))
{
gnome_window = kids[i];
break;
@@ -4464,11 +4500,9 @@ the_network_is_not_the_computer (state *s)
lhost = "<UNKNOWN>";
else
lhost = uts.nodename;
-# elif defined(VMS)
- strcpy (lhost, getenv("SYS$NODE"));
-# else /* !HAVE_UNAME && !VMS */
+# else /* !HAVE_UNAME */
strcat (lhost, "<UNKNOWN>");
-# endif /* !HAVE_UNAME && !VMS */
+# endif /* !HAVE_UNAME */
if (p && p->pw_name)
luser = p->pw_name;
@@ -4791,10 +4825,7 @@ main (int argc, char **argv)
progname = real_progname;
- s->short_version = (char *) malloc (5);
- memcpy (s->short_version, screensaver_id + 17, 4);
- s->short_version [4] = 0;
-
+ s->short_version = XSCREENSAVER_VERSION;
/* Register our error message logger for every ``log domain'' known.
There's no way to do this globally, so I grepped the Gtk/Gdk sources
@@ -5007,7 +5038,7 @@ main (int argc, char **argv)
dpy = XtDisplay (toplevel_shell);
db = XtDatabase (dpy);
- XtGetApplicationNameAndClass (dpy, &progname, &progclass);
+ XtGetApplicationNameAndClass (dpy, (char **) &progname, &progclass);
XSetErrorHandler (demo_ehandler);
/* Let's just ignore these. They seem to confuse Irix Gtk... */
@@ -5046,6 +5077,7 @@ main (int argc, char **argv)
p->db = db;
s->nscreens = screen_count (dpy);
+ init_xscreensaver_atoms (dpy);
hack_environment (s); /* must be before initialize_sort_map() */
load_init_file (dpy, p);
@@ -5069,26 +5101,7 @@ main (int argc, char **argv)
}
#endif
-
- /* Intern the atoms that xscreensaver_command() needs.
- */
- XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False);
- XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False);
- XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False);
- XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False);
- XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False);
- XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False);
- XA_SELECT = XInternAtom (dpy, "SELECT", False);
- XA_DEMO = XInternAtom (dpy, "DEMO", False);
- XA_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False);
- XA_SUSPEND = XInternAtom (dpy, "SUSPEND", False);
- XA_BLANK = XInternAtom (dpy, "BLANK", False);
- XA_LOCK = XInternAtom (dpy, "LOCK", False);
- XA_NEXT = XInternAtom (dpy, "NEXT", False);
- XA_PREV = XInternAtom (dpy, "PREV", False);
- XA_EXIT = XInternAtom (dpy, "EXIT", False);
- XA_RESTART = XInternAtom (dpy, "RESTART", False);
-
+ init_xscreensaver_atoms (dpy);
/* Create the window and all its widgets.
*/
@@ -5171,31 +5184,32 @@ main (int argc, char **argv)
#endif /* !HAVE_GTK2 */
/* Hook up callbacks to the items on the mode menu. */
- {
- GtkOptionMenu *opt = GTK_OPTION_MENU (name_to_widget (s, "mode_menu"));
- GtkMenu *menu = GTK_MENU (gtk_option_menu_get_menu (opt));
- GList *kids = gtk_container_children (GTK_CONTAINER (menu));
- int i;
- for (i = 0; kids; kids = kids->next, i++)
- {
- gtk_signal_connect (GTK_OBJECT (kids->data), "activate",
- GTK_SIGNAL_FUNC (mode_menu_item_cb),
- (gpointer) s);
-
- /* The "random-same" mode menu item does not appear unless
- there are multple screens.
- */
- if (s->nscreens <= 1 &&
- mode_menu_order[i] == RANDOM_HACKS_SAME)
- gtk_widget_hide (GTK_WIDGET (kids->data));
- }
+ gtk_signal_connect (GTK_OBJECT (name_to_widget (s, "mode_menu")),
+ "changed", GTK_SIGNAL_FUNC (mode_menu_item_cb),
+ (gpointer) s);
+ if (s->nscreens <= 1)
+ {
+ GtkComboBox *opt = GTK_COMBO_BOX (name_to_widget (s, "mode_menu"));
+ GtkTreeModel *list = gtk_combo_box_get_model (opt);
+ unsigned int i;
+ for (i = 0; i < countof(mode_menu_order); i++)
+ {
+ /* The "random-same" mode menu item does not appear unless
+ there are multiple screens.
+ */
+ if (mode_menu_order[i] == RANDOM_HACKS_SAME)
+ {
+ GtkTreeIter iter;
+ gtk_tree_model_iter_nth_child (list, &iter, NULL, i);
+ gtk_list_store_remove (GTK_LIST_STORE (list), &iter);
+ break;
+ }
+ }
- if (s->nscreens <= 1) /* recompute option-menu size */
- {
- gtk_widget_unrealize (GTK_WIDGET (menu));
- gtk_widget_realize (GTK_WIDGET (menu));
- }
- }
+ /* recompute option-menu size */
+ gtk_widget_unrealize (GTK_WIDGET (opt));
+ gtk_widget_realize (GTK_WIDGET (opt));
+ }
/* Handle the -prefs command-line argument. */
@@ -5299,7 +5313,7 @@ main (int argc, char **argv)
the_network_is_not_the_computer (s);
- if (senesculent_p())
+ if (time ((time_t *) 0) - XSCREENSAVER_RELEASED > 60*60*24*30*17)
warning_dialog (s->toplevel_widget,
_("Warning:\n\n"
"This version of xscreensaver is VERY OLD!\n"
@@ -5312,7 +5326,6 @@ main (int argc, char **argv)
),
D_NONE, 7);
-
/* 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,
and if there were any Xt widgets, they would never have events delivered.