-/* xscreensaver, Copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* window exposed.
* - If you run your debugger under XEmacs, try M-ESC (x-grab-keyboard)
* to keep your emacs window alive even when xscreensaver has grabbed.
- * - Go read the code related to -DDEBUG.
+ * - Go read the code related to `debug_p'.
* - You probably can't set breakpoints in functions that are called on
* the other side of a call to fork() -- if your clients are dying
* with signal 5, Trace/BPT Trap, you're losing in this way.
XrmDatabase db = 0;
-static Atom XA_SCREENSAVER;
static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV;
static Atom XA_EXIT, XA_RESTART, XA_DEMO, XA_LOCK;
static XrmOptionDescRec options [] = {
{ "-timeout", ".timeout", XrmoptionSepArg, 0 },
{ "-cycle", ".cycle", XrmoptionSepArg, 0 },
- { "-idelay", ".initialDelay", XrmoptionSepArg, 0 },
- { "-nice", ".nice", XrmoptionSepArg, 0 },
- { "-visual", ".visualID", XrmoptionSepArg, 0 },
+ { "-lock-mode", ".lock", XrmoptionNoArg, "on" },
+ { "-no-lock-mode", ".lock", XrmoptionNoArg, "off" },
{ "-lock-timeout", ".lockTimeout", XrmoptionSepArg, 0 },
+ { "-visual", ".visualID", XrmoptionSepArg, 0 },
{ "-install", ".installColormap", XrmoptionNoArg, "on" },
{ "-no-install", ".installColormap", XrmoptionNoArg, "off" },
{ "-verbose", ".verbose", XrmoptionNoArg, "on" },
{ "-no-mit-extension", ".mitSaverExtension",XrmoptionNoArg, "off" },
{ "-sgi-extension", ".sgiSaverExtension",XrmoptionNoArg, "on" },
{ "-no-sgi-extension", ".sgiSaverExtension",XrmoptionNoArg, "off" },
- { "-lock", ".lock", XrmoptionNoArg, "on" },
- { "-no-lock", ".lock", XrmoptionNoArg, "off" }
+ { "-idelay", ".initialDelay", XrmoptionSepArg, 0 },
+ { "-nice", ".nice", XrmoptionSepArg, 0 }
};
static char *defaults[] = {
do_help (saver_info *si)
{
printf ("\
-xscreensaver %s, copyright (c) 1991-1997 by Jamie Zawinski <jwz@netscape.com>\n\
+xscreensaver %s, copyright (c) 1991-1998 by Jamie Zawinski <jwz@netscape.com>\n\
The standard Xt command-line options are accepted; other options include:\n\
\n\
-timeout <minutes> When the screensaver should activate.\n\
-cycle <minutes> How long to let each hack run.\n\
- -idelay <seconds> How long to sleep before startup.\n\
+ -lock-mode Require a password before deactivating.\n\
+ -no-lock-mode Don't.\n\
+ -lock-timeout <minutes> Grace period before locking; default 0.\n\
-visual <id-or-class> Which X visual to run on.\n\
- -demo Enter interactive demo mode on startup.\n\
-install Install a private colormap.\n\
-no-install Don't.\n\
-verbose Be loud.\n\
-silent Don't.\n\
- -xidle-extension Use the R5 XIdle server extension.\n\
- -no-xidle-extension Don't.\n\
-mit-extension Use the R6 MIT_SCREEN_SAVER server extension.\n\
-no-mit-extension Don't.\n\
-sgi-extension Use the SGI SCREEN-SAVER server extension.\n\
-no-sgi-extension Don't.\n\
- -lock Require a password before deactivating.\n\
- -no-lock Don't.\n\
- -lock-timeout <minutes> Grace period before locking; default 0.\n\
+ -xidle-extension Use the R5 XIdle server extension.\n\
+ -no-xidle-extension Don't.\n\
-help This message.\n\
\n\
-Use the `xscreensaver-command' program to control a running screensaver.\n\
+The `xscreensaver' program should be left running in the background.\n\
+Use the `xscreensaver-command' program to manipulate a running xscreensaver.\n\
+\n\
+The `*programs' resource controls which graphics demos will be launched by\n\
+the screensaver. See `man xscreensaver' or the web page for more details.\n\
\n\
-The *programs resource controls which graphics demos will be launched by the\n\
-screensaver. See the man page for more details. For updates, check\n\
-http://people.netscape.com/jwz/xscreensaver/\n\n",
+For updates, check http://people.netscape.com/jwz/xscreensaver/\n\n",
si->version);
#ifdef NO_LOCKING
{
fprintf (stderr,
"%s: the `monoPrograms' and `colorPrograms' resources are obsolete;\n\
- see the manual for details.\n", progname);
+ see the manual for details.\n", blurb());
free(d);
}
d = get_string_resource ("programs", "Programs");
- size = strlen (d);
+ size = d ? strlen (d) : 0;
p->screenhacks = (char **) malloc (sizeof (char *) * hacks_size);
p->screenhacks_count = 0;
}
+static Bool blurb_timestamp_p = False; /* kludge */
+
+
static void
get_resources (saver_info *si)
{
saver_preferences *p = &si->prefs;
p->verbose_p = get_boolean_resource ("verbose", "Boolean");
+ p->timestamp_p = get_boolean_resource ("timestamp", "Boolean");
p->lock_p = get_boolean_resource ("lock", "Boolean");
p->fade_p = get_boolean_resource ("fade", "Boolean");
p->unfade_p = get_boolean_resource ("unfade", "Boolean");
{
p->lock_p = False;
fprintf (stderr, "%s: not compiled with support for locking.\n",
- progname);
+ blurb());
}
#else /* ! NO_LOCKING */
if (p->lock_p && si->locking_disabled_p)
{
- fprintf (stderr, "%s: locking is disabled (%s).\n", progname,
+ fprintf (stderr, "%s: locking is disabled (%s).\n", blurb(),
si->nolock_reason);
p->lock_p = False;
}
get_screenhacks (si);
-#ifdef DEBUG
if (p->debug_p)
{
XSynchronize(si->dpy, True);
p->verbose_p = True;
+ p->timestamp_p = True;
p->initial_delay = 0;
}
-#endif /* DEBUG */
+
+ blurb_timestamp_p = p->timestamp_p;
}
{
saver_info *si = global_si_kludge; /* I hate C so much... */
- fprintf (real_stderr, "\nX error in %s:\n", progname);
+ fprintf (real_stderr, "\nX error in %s:\n", blurb());
if (XmuPrintDefaultErrorMessage (dpy, error, real_stderr))
saver_exit (si, -1);
else
return 0;
}
+
+const char *
+blurb (void)
+{
+ if (!blurb_timestamp_p)
+ return progname;
+ else
+ {
+ static char buf[255];
+ time_t now = time ((time_t *) 0);
+ char *ct = (char *) ctime (&now);
+ 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 void
initialize_connection (saver_info *si, int argc, char **argv)
{
int i;
- Widget toplevel_shell = XtAppInitialize (&si->app, progclass,
- options, XtNumber (options),
- &argc, argv, defaults, 0, 0);
+ Widget toplevel_shell;
+
+ /* The X resource database blows up if argv[0] has a "." in it. */
+ {
+ char *s = argv[0];
+ while ((s = strchr (s, '.')))
+ *s = '_';
+ }
+
+ toplevel_shell = XtAppInitialize (&si->app, progclass,
+ options, XtNumber (options),
+ &argc, argv, defaults, 0, 0);
si->dpy = XtDisplay (toplevel_shell);
si->db = XtDatabase (si->dpy);
XtGetApplicationNameAndClass (si->dpy, &progname, &progclass);
+ if(strlen(progname) > 100) progname [99] = 0; /* keep it short. */
+
db = si->db; /* resources.c needs this */
if (argc == 2 && !strcmp (argv[1], "-help"))
do_help (si);
-#ifdef DEBUG
+
else if (argc == 2 && !strcmp (argv[1], "-debug"))
si->prefs.debug_p = True; /* no resource for this one, out of paranoia. */
-#endif /* DEBUG */
+
else if (argc > 1)
{
- fprintf (stderr, "%s: unknown option %s\n", progname, argv [1]);
+ const char *s = argv[1];
+ fprintf (stderr, "%s: unknown option \"%s\". Try \"-help\".\n",
+ blurb(), s);
+
+ if (s[0] == '-' && s[1] == '-') s++;
+ if (!strcmp (s, "-activate") ||
+ !strcmp (s, "-deactivate") ||
+ !strcmp (s, "-cycle") ||
+ !strcmp (s, "-next") ||
+ !strcmp (s, "-prev") ||
+ !strcmp (s, "-exit") ||
+ !strcmp (s, "-restart") ||
+ !strcmp (s, "-demo") ||
+ !strcmp (s, "-lock") ||
+ !strcmp (s, "-version") ||
+ !strcmp (s, "-time"))
+ {
+ fprintf (stderr, "\n\
+ However, %s is an option to the `xscreensaver-command' program.\n\
+ The `xscreensaver' program is a daemon that runs in the background.\n\
+ You control a running xscreensaver process by sending it messages\n\
+ with `xscreensaver-command'. See the man pages for details,\n\
+ or check the web page: http://people.netscape.com/jwz/xscreensaver/\n\n",
+ s);
+
+ /* Since version 1.21 renamed the "-lock" option to "-lock-mode",
+ suggest that explicitly. */
+ if (!strcmp (s, "-lock"))
+ fprintf (stderr, "\
+ Or perhaps you meant either the \"-lock-mode\" or the\n\
+ \"-lock-timeout <minutes>\" options to xscreensaver?\n\n");
+ }
+
exit (1);
}
get_resources (si);
si->version [4] = 0;
progname = argv[0]; /* reset later; this is for the benefit of lock_init() */
+ if(strlen(progname) > 100) progname[99] = 0; /* keep it short. */
+
#ifdef NO_LOCKING
si->locking_disabled_p = True;
si->nolock_reason = "not compiled with locking support";
-#else
+#else /* !NO_LOCKING */
si->locking_disabled_p = False;
-#ifdef SCO
+# ifdef SCO
set_auth_parameters(argc, argv);
-#endif
+# endif /* SCO */
if (! lock_init (argc, argv)) /* before hack_uid() for proper permissions */
{
si->locking_disabled_p = True;
si->nolock_reason = "error getting password";
}
-#endif
+#endif /* !NO_LOCKING */
#ifndef NO_SETUID
hack_uid (si);
-#endif
+#endif /* NO_SETUID */
progclass = "XScreenSaver";
- /* remove -demo switch before saving argv */
+ /* remove -initial-demo-mode switch before saving argv */
for (i = 1; i < argc; i++)
- while (!strcmp ("-demo", argv [i]))
+ while (!strcmp ("-initial-demo-mode", argv [i]))
{
int j;
initial_demo_mode_p = True;
if (p->verbose_p)
printf ("\
-%s %s, copyright (c) 1991-1997 by Jamie Zawinski <jwz@netscape.com>\n\
+%s %s, copyright (c) 1991-1998 by Jamie Zawinski <jwz@netscape.com>\n\
pid = %d.\n", progname, si->version, (int) getpid ());
for (i = 0; i < si->nscreens; i++)
- ensure_no_screensaver_running (si->dpy, si->screens[i].screen);
+ if (ensure_no_screensaver_running (si->dpy, si->screens[i].screen))
+ exit (1);
+
+ hack_environment (si);
si->demo_mode_p = initial_demo_mode_p;
srandom ((int) time ((time_t *) 0));
{
fprintf (stderr,
"%s: display %s does not support the SGI SCREEN_SAVER extension.\n",
- progname, DisplayString (si->dpy));
+ blurb(), DisplayString (si->dpy));
p->use_sgi_saver_extension = False;
}
else if (p->use_mit_saver_extension)
{
fprintf (stderr, "%s: SGI SCREEN_SAVER extension used instead\
of MIT-SCREEN-SAVER extension.\n",
- progname);
+ blurb());
p->use_mit_saver_extension = False;
}
else if (p->use_xidle_extension)
{
fprintf (stderr,
"%s: SGI SCREEN_SAVER extension used instead of XIDLE extension.\n",
- progname);
+ blurb());
p->use_xidle_extension = False;
}
#else /* !HAVE_MIT_SAVER_EXTENSION */
fprintf (stderr,
"%s: not compiled with support for the SGI SCREEN_SAVER extension.\n",
- progname);
+ blurb());
p->use_sgi_saver_extension = False;
#endif /* !HAVE_SGI_SAVER_EXTENSION */
}
{
fprintf (stderr,
"%s: display %s does not support the MIT-SCREEN-SAVER extension.\n",
- progname, DisplayString (si->dpy));
+ blurb(), DisplayString (si->dpy));
p->use_mit_saver_extension = False;
}
else if (p->use_xidle_extension)
{
fprintf (stderr,
"%s: MIT-SCREEN-SAVER extension used instead of XIDLE extension.\n",
- progname);
+ blurb());
p->use_xidle_extension = False;
}
#else /* !HAVE_MIT_SAVER_EXTENSION */
fprintf (stderr,
"%s: not compiled with support for the MIT-SCREEN-SAVER extension.\n",
- progname);
+ blurb());
p->use_mit_saver_extension = False;
#endif /* !HAVE_MIT_SAVER_EXTENSION */
}
{
fprintf (stderr,
"%s: display %s does not support the XIdle extension.\n",
- progname, DisplayString (si->dpy));
+ blurb(), DisplayString (si->dpy));
p->use_xidle_extension = False;
}
#else /* !HAVE_XIDLE_EXTENSION */
fprintf (stderr, "%s: not compiled with support for XIdle.\n",
- progname);
+ blurb());
p->use_xidle_extension = False;
#endif /* !HAVE_XIDLE_EXTENSION */
}
if (p->verbose_p && p->use_mit_saver_extension)
fprintf (stderr, "%s: using MIT-SCREEN-SAVER server extension.\n",
- progname);
+ blurb());
if (p->verbose_p && p->use_sgi_saver_extension)
fprintf (stderr, "%s: using SGI SCREEN_SAVER server extension.\n",
- progname);
+ blurb());
if (p->verbose_p && p->use_xidle_extension)
fprintf (stderr, "%s: using XIdle server extension.\n",
- progname);
+ blurb());
initialize_stderr (si);
XSetErrorHandler (saver_ehandler);
{
if (p->verbose_p)
{
- printf ("%s: waiting for %d second%s...", progname,
+ printf ("%s: waiting for %d second%s...", blurb(),
(int) p->initial_delay,
(p->initial_delay == 1 ? "" : "s"));
fflush (stdout);
}
if (p->verbose_p)
{
- printf ("%s: selecting events on extant windows...", progname);
+ printf ("%s: selecting events on extant windows...", blurb());
fflush (stdout);
}
if (si->demo_mode_p)
demo_mode (si);
else
-#endif
+#endif /* !NO_DEMO_MODE */
{
if (p->verbose_p)
- printf ("%s: user is idle; waking up at %s.\n", progname,
+ printf ("%s: user is idle; waking up at %s.\n", blurb(),
timestring());
blank_screen (si);
spawn_screenhack (si, True);
si->lock_id = XtAppAddTimeOut (si->app, p->lock_timeout,
activate_lock_timer,
(XtPointer) si);
-#endif
+#endif /* !NO_LOCKING */
PASSWD_INVALID:
just after the server is grabbed, closing this window
entirely.
*/
- /* ungrab_keyboard_and_mouse (); */
+ /* ungrab_keyboard_and_mouse (si); */
{
saver_screen_info *ssi = si->default_screen;
suspend_screenhack (si, True);
XUndefineCursor (si->dpy, ssi->screensaver_window);
if (p->verbose_p)
- printf ("%s: prompting for password.\n", progname);
+ printf ("%s: prompting for password.\n", blurb());
val = unlock_p (si);
if (p->verbose_p && val == False)
- printf ("%s: password incorrect!\n", progname);
+ printf ("%s: password incorrect!\n", blurb());
si->dbox_up_p = False;
XDefineCursor (si->dpy, ssi->screensaver_window, ssi->cursor);
suspend_screenhack (si, False);
/* I think this grab is now redundant, but it shouldn't hurt.
*/
if (!si->demo_mode_p)
- grab_keyboard_and_mouse (si->dpy, ssi->screensaver_window,
+ grab_keyboard_and_mouse (si, ssi->screensaver_window,
ssi->cursor);
}
goto PASSWD_INVALID;
si->locked_p = False;
}
-#endif
- unblank_screen (si);
+#endif /* !NO_LOCKING */
+
+ /* Let's kill it before unblanking, to get it to stop drawing as
+ soon as possible... */
kill_screenhack (si);
+ unblank_screen (si);
+
if (si->cycle_id)
{
XtRemoveTimeOut (si->cycle_id);
si->cycle_id = 0;
}
+
#ifndef NO_LOCKING
if (si->lock_id)
{
XtRemoveTimeOut (si->lock_id);
si->lock_id = 0;
}
-#endif
+#endif /* !NO_LOCKING */
+
if (p->verbose_p)
- printf ("%s: user is active; going to sleep at %s.\n", progname,
+ printf ("%s: user is active; going to sleep at %s.\n", blurb(),
timestring ());
}
}
char *str;
str = XGetAtomName (si->dpy, event->xclient.message_type);
fprintf (stderr, "%s: unrecognised ClientMessage type %s received\n",
- progname, (str ? str : "(null)"));
+ blurb(), (str ? str : "(null)"));
if (str) XFree (str);
return False;
}
if (event->xclient.format != 32)
{
fprintf (stderr, "%s: ClientMessage of format %d received, not 32\n",
- progname, event->xclient.format);
+ blurb(), event->xclient.format);
return False;
}
if (until_idle_p)
{
if (p->verbose_p)
- printf ("%s: ACTIVATE ClientMessage received.\n", progname);
+ printf ("%s: ACTIVATE ClientMessage received.\n", blurb());
if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
{
XForceScreenSaver (si->dpy, ScreenSaverActive);
}
fprintf (stderr,
"%s: ClientMessage ACTIVATE received while already active.\n",
- progname);
+ blurb());
}
else if (type == XA_DEACTIVATE)
{
if (! until_idle_p)
{
if (p->verbose_p)
- printf ("%s: DEACTIVATE ClientMessage received.\n", progname);
+ printf ("%s: DEACTIVATE ClientMessage received.\n", blurb());
if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
{
XForceScreenSaver (si->dpy, ScreenSaverReset);
}
fprintf (stderr,
"%s: ClientMessage DEACTIVATE received while inactive.\n",
- progname);
+ blurb());
}
else if (type == XA_CYCLE)
{
if (! until_idle_p)
{
if (p->verbose_p)
- printf ("%s: CYCLE ClientMessage received.\n", progname);
+ printf ("%s: CYCLE ClientMessage received.\n", blurb());
if (si->cycle_id)
XtRemoveTimeOut (si->cycle_id);
si->cycle_id = 0;
return False;
}
fprintf (stderr, "%s: ClientMessage CYCLE received while inactive.\n",
- progname);
+ blurb());
}
else if (type == XA_NEXT || type == XA_PREV)
{
if (p->verbose_p)
- printf ("%s: %s ClientMessage received.\n", progname,
+ printf ("%s: %s ClientMessage received.\n", blurb(),
(type == XA_NEXT ? "NEXT" : "PREV"));
si->next_mode_p = 1 + (type == XA_PREV);
if (until_idle_p || !si->locked_p)
{
if (p->verbose_p)
- printf ("%s: EXIT ClientMessage received.\n", progname);
+ printf ("%s: EXIT ClientMessage received.\n", blurb());
if (! until_idle_p)
{
unblank_screen (si);
}
else
fprintf (stderr, "%s: EXIT ClientMessage received while locked.\n",
- progname);
+ blurb());
}
else if (type == XA_RESTART)
{
if (until_idle_p || !si->locked_p)
{
if (p->verbose_p)
- printf ("%s: RESTART ClientMessage received.\n", progname);
+ printf ("%s: RESTART ClientMessage received.\n", blurb());
if (! until_idle_p)
{
unblank_screen (si);
}
else
fprintf(stderr, "%s: RESTART ClientMessage received while locked.\n",
- progname);
+ blurb());
}
else if (type == XA_DEMO)
{
#ifdef NO_DEMO_MODE
fprintf (stderr, "%s: not compiled with support for DEMO mode\n",
- progname);
+ blurb());
#else
if (until_idle_p)
{
if (p->verbose_p)
- printf ("%s: DEMO ClientMessage received.\n", progname);
+ printf ("%s: DEMO ClientMessage received.\n", blurb());
si->demo_mode_p = True;
return True;
}
fprintf (stderr,
- "%s: DEMO ClientMessage received while active.\n", progname);
+ "%s: DEMO ClientMessage received while active.\n", blurb());
#endif
}
else if (type == XA_LOCK)
{
#ifdef NO_LOCKING
fprintf (stderr, "%s: not compiled with support for LOCK mode\n",
- progname);
+ blurb());
#else
if (si->locking_disabled_p)
fprintf (stderr,
"%s: LOCK ClientMessage received, but locking is disabled.\n",
- progname);
+ blurb());
else if (si->locked_p)
fprintf (stderr,
"%s: LOCK ClientMessage received while already locked.\n",
- progname);
+ blurb());
else
{
si->locked_p = True;
if (p->verbose_p)
printf ("%s: LOCK ClientMessage received;%s locking.\n",
- progname, until_idle_p ? " activating and" : "");
+ blurb(), until_idle_p ? " activating and" : "");
if (si->lock_id) /* we're doing it now, so lose the timeout */
{
if (str)
fprintf (stderr,
"%s: unrecognised screensaver ClientMessage %s received\n",
- progname, str);
+ blurb(), str);
else
fprintf (stderr,
"%s: unrecognised screensaver ClientMessage 0x%x received\n",
- progname, (unsigned int) event->xclient.data.l[0]);
+ blurb(), (unsigned int) event->xclient.data.l[0]);
if (str) XFree (str);
}
return False;