/* windows.c --- turning the screen black; dealing with visuals, virtual roots.
- * xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
+ * xscreensaver, Copyright (c) 1991-1998 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
#ifdef VMS
# include <unixlib.h> /* for getpid() */
# include "vms-gtod.h" /* for gettimeofday() */
-# if !defined(HAVE_UNAME) && (__VMS_VER >= 70000000)
-# define HAVE_UNAME 1
-# endif /* !HAVE_UNAME */
#endif /* VMS */
# ifdef HAVE_UNAME
#include "visual.h"
#include "fade.h"
+
+#ifdef HAVE_VT_LOCKSWITCH
+# include <fcntl.h>
+# include <sys/ioctl.h>
+# include <sys/vt.h>
+ static void lock_vt (saver_info *si, Bool lock_p);
+#endif /* HAVE_VT_LOCKSWITCH */
+
+
extern int kill (pid_t, int); /* signal() is in sys/signal.h... */
Atom XA_VROOT, XA_XSETROOT_ID;
if (status == GrabSuccess)
si->keyboard_grab_window = w;
- if (p->debug_p)
- fprintf(stderr, "%s: XGrabKeyboard(... 0x%x ...) ==> %s\n",
- progname, (unsigned long) w,
+ if (p->verbose_p)
+ fprintf(stderr, "%s: grabbing keyboard on 0x%x... %s.\n",
+ blurb(), (unsigned long) w,
(status == GrabSuccess ? "GrabSuccess" :
status == AlreadyGrabbed ? "AlreadyGrabbed" :
status == GrabInvalidTime ? "GrabInvalidTime" :
if (status == GrabSuccess)
si->mouse_grab_window = w;
- if (p->debug_p)
- fprintf(stderr, "%s: XGrabPointer(... 0x%x, 0x%x ...) ==> %s\n",
- progname, (unsigned long) w, (unsigned long) cursor,
- grab_string(status));
+ if (p->verbose_p)
+ fprintf(stderr, "%s: grabbing mouse on 0x%x... %s.\n",
+ blurb(), (unsigned long) w, grab_string(status));
return status;
}
{
saver_preferences *p = &si->prefs;
XUngrabKeyboard(si->dpy, CurrentTime);
- if (p->debug_p)
- fprintf(stderr, "%s: XUngrabKeyboard (was 0x%x)\n", progname,
+ if (p->verbose_p)
+ fprintf(stderr, "%s: ungrabbing keyboard (was 0x%x).\n", blurb(),
(unsigned long) si->keyboard_grab_window);
si->keyboard_grab_window = 0;
}
{
saver_preferences *p = &si->prefs;
XUngrabPointer(si->dpy, CurrentTime);
- if (p->debug_p)
- fprintf(stderr, "%s: XUngrabPointer (was 0x%x)\n", progname,
+ if (p->verbose_p)
+ fprintf(stderr, "%s: ungrabbing mouse (was 0x%x).\n", blurb(),
(unsigned long) si->mouse_grab_window);
si->mouse_grab_window = 0;
}
status = grab_kbd (si, window);
if (status != GrabSuccess)
fprintf (stderr, "%s: couldn't grab keyboard! (%s)\n",
- progname, grab_string(status));
+ blurb(), grab_string(status));
}
status = grab_mouse (si, window, cursor);
status = grab_mouse (si, window, cursor);
if (status != GrabSuccess)
fprintf (stderr, "%s: couldn't grab pointer! (%s)\n",
- progname, grab_string(status));
+ blurb(), grab_string(status));
}
}
fprintf (stderr,
"%s: already running on display %s (window 0x%x)\n from process %s.\n",
- progname, DisplayString (dpy), (int) kids [i], id);
+ blurb(), DisplayString (dpy), (int) kids [i], id);
status = True;
}
}
#if 0
if (p->verbose_p)
fprintf (stderr,
- "%s: storing XA_VROOT = 0x%x (%s) = 0x%x (%s)\n", progname,
+ "%s: storing XA_VROOT = 0x%x (%s) = 0x%x (%s)\n", blurb(),
win,
(win == screensaver_window ? "ScreenSaver" :
(win == real_vroot ? "VRoot" :
{
#if 0
if (p->verbose_p)
- fprintf (stderr, "%s: removing XA_VROOT from 0x%x (%s)\n", progname, win,
+ fprintf (stderr, "%s: removing XA_VROOT from 0x%x (%s)\n", blurb(), win,
(win == screensaver_window ? "ScreenSaver" :
(win == real_vroot ? "VRoot" :
(win == real_vroot_value ? "Vroot_value" : "???"))));
nitems == 1 && bytesafter == 0)
{
if (verbose_p)
- printf ("%s: destroying xsetroot data (0x%lX).\n",
- progname, *dataP);
+ fprintf (stderr, "%s: destroying xsetroot data (0x%lX).\n",
+ blurb(), *dataP);
XKillClient (dpy, *dataP);
}
else
fprintf (stderr, "%s: deleted unrecognised _XSETROOT_ID property: \n\
%lu, %lu; type: %lu, format: %d, nitems: %lu, bytesafter %ld\n",
- progname, (unsigned long) dataP, (dataP ? *dataP : 0), type,
+ blurb(), (unsigned long) dataP, (dataP ? *dataP : 0), type,
format, nitems, bytesafter);
}
}
if (*vrootP == ssi->screensaver_window) abort ();
fprintf (stderr,
"%s: more than one virtual root window found (0x%x and 0x%x).\n",
- progname, (int) ssi->real_vroot, (int) kids [i]);
+ blurb(), (int) ssi->real_vroot, (int) kids [i]);
exit (1);
}
ssi->real_vroot = kids [i];
saver_info *si = ssi->global;
saver_preferences *p = &si->prefs;
if (p->verbose_p && ssi->real_vroot)
- printf ("%s: restoring __SWM_VROOT property on the real vroot (0x%lx).\n",
- progname, (unsigned long) ssi->real_vroot);
+ fprintf (stderr,
+ "%s: restoring __SWM_VROOT property on the real vroot (0x%lx).\n",
+ blurb(), (unsigned long) ssi->real_vroot);
remove_vroot_property (si->dpy, ssi->screensaver_window);
if (ssi->real_vroot)
{
signal (sig, SIG_DFL);
if (restore_real_vroot_1 (si))
fprintf (real_stderr, "\n%s: %s intercepted, vroot restored.\n",
- progname, signal_name(sig));
+ blurb(), signal_name(sig));
kill (getpid (), sig);
}
if (((long) signal (sig, restore_real_vroot_handler)) == -1L)
{
char buf [255];
- sprintf (buf, "%s: couldn't catch %s", progname, signal_name(sig));
+ sprintf (buf, "%s: couldn't catch %s", blurb(), signal_name(sig));
perror (buf);
- saver_exit (si, 1);
+ saver_exit (si, 1, 0);
}
}
}
handle_signals (saver_info *si, Bool on_p)
{
#if 0
- if (on_p) printf ("handling signals\n");
- else printf ("unhandling signals\n");
+ if (on_p) fprintf (stderr, "handling signals\n");
+ else fprintf (stderr, "unhandling signals\n");
#endif
catch_signal (si, SIGHUP, on_p);
}
void
-saver_exit (saver_info *si, int status)
+saver_exit (saver_info *si, int status, const char *dump_core_reason)
{
saver_preferences *p = &si->prefs;
static Bool exiting = False;
+ Bool bugp;
Bool vrs;
if (exiting)
emergency_kill_subproc (si);
if (vrs && (p->verbose_p || status != 0))
- fprintf (real_stderr, "%s: vroot restored, exiting.\n", progname);
+ fprintf (real_stderr, "%s: vroot restored, exiting.\n", blurb());
else if (p->verbose_p)
- fprintf (real_stderr, "%s: no vroot to restore; exiting.\n", progname);
+ fprintf (real_stderr, "%s: no vroot to restore; exiting.\n", blurb());
fflush(real_stdout);
else if (status == 1) status = -1;
#endif
- if (si->prefs.debug_p)
+ bugp = !!dump_core_reason;
+
+ if (si->prefs.debug_p && !dump_core_reason)
+ dump_core_reason = "because of -debug";
+
+ if (dump_core_reason)
{
- fprintf(real_stderr, "%s: dumping core (because of -debug)\n", progname);
+ /* Note that the Linux man page for setuid() says If uid is
+ different from the old effective uid, the process will be
+ forbidden from leaving core dumps.
+ */
+ char cwd[4096]; /* should really be PATH_MAX, but who cares. */
+ cwd[0] = 0;
+ fprintf(real_stderr, "%s: dumping core (%s)\n", blurb(),
+ dump_core_reason);
+
+ if (bugp)
+ fprintf(real_stderr,
+ "%s: see http://www.jwz.org/xscreensaver/bugs.html\n"
+ "\t\tfor bug reporting information.\n\n",
+ blurb());
+
+# if defined(HAVE_GETCWD)
+ if (!getcwd (cwd, sizeof(cwd)))
+# elif defined(HAVE_GETWD)
+ if (!getwd (cwd))
+# endif
+ strcpy(cwd, "unknown.");
+
+ fprintf (real_stderr, "%s: current directory is %s\n", blurb(), cwd);
+ describe_uids (si, real_stderr);
+
/* Do this to drop a core file, so that we can get a stack trace. */
abort();
}
{
saver_info *si = ssi->global;
saver_preferences *p = &si->prefs;
- Bool install_cmap_p = ssi->install_cmap_p;
+ Bool install_cmap_p = (ssi->install_cmap_p || p->install_cmap_p);
/* This resets the screensaver window as fully as possible, since there's
no way of knowing what some random client may have done to us in the
;
else if (ssi->current_visual == DefaultVisualOfScreen (ssi->screen))
{
- fprintf (stderr, "%s: using default visual ", progname);
- describe_visual (stderr, ssi->screen, ssi->current_visual);
+ fprintf (stderr, "%s: using default visual ", blurb());
+ describe_visual (stderr, ssi->screen, ssi->current_visual,
+ install_cmap_p);
}
else
{
- fprintf (stderr, "%s: using visual: ", progname);
- describe_visual (stderr, ssi->screen, ssi->current_visual);
- fprintf (stderr, "%s: default visual: ", progname);
+ fprintf (stderr, "%s: using visual: ", blurb());
+ describe_visual (stderr, ssi->screen, ssi->current_visual,
+ install_cmap_p);
+ fprintf (stderr, "%s: default visual: ", blurb());
describe_visual (stderr, ssi->screen,
- DefaultVisualOfScreen (ssi->screen));
+ DefaultVisualOfScreen (ssi->screen),
+ ssi->install_cmap_p);
}
printed_visual_info = True;
store_activate_time(si, True);
if (p->verbose_p)
fprintf (stderr, "%s: saver window is 0x%lx.\n",
- progname, (unsigned long) ssi->screensaver_window);
+ blurb(), (unsigned long) ssi->screensaver_window);
}
#ifdef HAVE_MIT_SAVER_EXTENSION
initialize_screensaver_window (si);
reset_watchdog_timer (si, True);
- if (p->fade_p && !inhibit_fade && !si->demo_mode_p)
+ if (p->fade_p && si->fading_possible_p && !inhibit_fade && !si->demo_mode_p)
{
- int grabbed = -1;
Window *current_windows = (Window *)
calloc(sizeof(Window), si->nscreens);
Colormap *current_maps = (Colormap *)
ssi->black_pixel);
}
- if (p->verbose_p) fprintf (stderr, "%s: fading... ", progname);
+ if (p->verbose_p) fprintf (stderr, "%s: fading...\n", blurb());
XGrabServer (si->dpy); /* ############ DANGER! */
/* Clear the stderr layer on each screen.
- Grab the mouse on the first screen on which the mouse is grabbable
- (if there are multiple heads, I think you might only be able to
- grab the mouse on the screen that currently has the mouse? Anyway,
- we only grab the mouse once, and don't try again after the grab
- has succeeded.) We grab the mouse on the root window of the screen,
- not on the screensaver window, since the screensaver window is not
- yet mapped.
*/
- for (i = 0; i < si->nscreens; i++)
- {
- saver_screen_info *ssi = &si->screens[i];
-
- /* grab and blacken mouse on the root window (saver not mapped yet)
- */
- if (grabbed != GrabSuccess)
- {
- Window root = RootWindowOfScreen(ssi->screen);
- grabbed = grab_mouse (si, root,
- (si->demo_mode_p ? 0 : ssi->cursor));
- }
-
- if (!dont_clear || ssi->stderr_overlay_window)
- /* Do this before the fade, since the stderr cmap won't fade
- even if we uninstall it (beats me...) */
- clear_stderr (ssi);
- }
+ if (!dont_clear)
+ for (i = 0; i < si->nscreens; i++)
+ {
+ saver_screen_info *ssi = &si->screens[i];
+ if (ssi->stderr_overlay_window)
+ /* Do this before the fade, since the stderr cmap won't fade
+ even if we uninstall it (beats me...) */
+ clear_stderr (ssi);
+ }
/* Note! The server is grabbed, and this will take several seconds
to complete! */
fade_screens (si->dpy, current_maps, current_windows,
- p->fade_seconds, p->fade_ticks, True, !dont_clear);
+ p->fade_seconds/1000, p->fade_ticks, True, !dont_clear);
free(current_maps);
free(current_windows);
current_maps = 0;
current_windows = 0;
- if (p->verbose_p) fprintf (stderr, "fading done.\n");
+ if (p->verbose_p) fprintf (stderr, "%s: fading done.\n", blurb());
#ifdef HAVE_MIT_SAVER_EXTENSION
for (i = 0; i < si->nscreens; i++)
}
#endif /* HAVE_MIT_SAVER_EXTENSION */
- /* If we had successfully grabbed the mouse, let it go now. */
- if (grabbed == GrabSuccess)
- ungrab_mouse (si);
-
XUngrabServer (si->dpy);
XSync (si->dpy, False); /* ###### (danger over) */
}
blank_screen (saver_info *si)
{
int i;
+
+ /* Note: we do our grabs on the root window, not on the screensaver window.
+ If we grabbed on the saver window, then the demo mode and lock dialog
+ boxes wouldn't get any events.
+ */
+ grab_keyboard_and_mouse (si,
+ /*si->screens[0].screensaver_window,*/
+ RootWindowOfScreen(si->screens[0].screen),
+ (si->demo_mode_p ? 0 : si->screens[0].cursor));
+
for (i = 0; i < si->nscreens; i++)
{
saver_screen_info *ssi = &si->screens[i];
store_activate_time (si, si->screen_blanked_p);
raise_window (si, False, False, False);
- /* Note: we do our grabs on the root window, not on the screensaver window.
- If we grabbed on the saver window, then the demo mode and lock dialog
- boxes wouldn't get any events.
- */
- grab_keyboard_and_mouse (si,
- /*si->screens[0].screensaver_window,*/
- RootWindowOfScreen(si->screens[0].screen),
- (si->demo_mode_p ? 0 : si->screens[0].cursor));
-
#ifdef HAVE_XHPDISABLERESET
if (si->locked_p && !hp_locked_p)
{
}
#endif
+#ifdef HAVE_VT_LOCKSWITCH
+ if (si->locked_p)
+ lock_vt (si, True); /* turn off C-Alt-Fn */
+#endif
+
si->screen_blanked_p = True;
}
store_activate_time (si, True);
reset_watchdog_timer (si, False);
- if (p->unfade_p && !si->demo_mode_p)
+ if (p->unfade_p && si->fading_possible_p && !si->demo_mode_p)
{
- int grabbed = -1;
Window *current_windows = (Window *)
calloc(sizeof(Window), si->nscreens);
ssi->black_pixel);
}
- if (p->verbose_p) fprintf (stderr, "%s: unfading... ", progname);
+ if (p->verbose_p) fprintf (stderr, "%s: unfading...\n", blurb());
XSync (si->dpy, False);
XSync (si->dpy, False);
/* Clear the stderr layer on each screen.
- Grab the mouse on the first screen on which the mouse is grabbable
- (if there are multiple heads, I think you might only be able to
- grab the mouse on the screen that currently has the mouse? Anyway,
- we only grab the mouse once, and don't try again after the grab
- has succeeded.)
*/
for (i = 0; i < si->nscreens; i++)
{
saver_screen_info *ssi = &si->screens[i];
- if (grabbed != GrabSuccess)
- grabbed = grab_mouse (si, RootWindowOfScreen (ssi->screen),
- 0);
clear_stderr (ssi);
}
fade_screens (si->dpy, 0, current_windows,
- p->fade_seconds, p->fade_ticks,
+ p->fade_seconds/1000, p->fade_ticks,
False, False);
free(current_windows);
current_windows = 0;
- if (p->verbose_p) fprintf (stderr, "unfading done.\n");
-
- /* If we had successfully grabbed the mouse, let it go now. */
- if (grabbed == GrabSuccess)
- ungrab_mouse (si);
+ if (p->verbose_p) fprintf (stderr, "%s: unfading done.\n", blurb());
}
else
{
}
#endif
+#ifdef HAVE_VT_LOCKSWITCH
+ lock_vt (si, False); /* turn C-Alt-Fn back on */
+#endif
+
/* Unmap the windows a second time, dammit -- just to avoid a race
with the screen-grabbing hacks. (I'm not sure if this is really
necessary; I'm stabbing in the dark now.)
if (p->verbose_p)
{
+ fprintf (stderr, "%s: switching to visual ", blurb());
+ describe_visual (stderr, ssi->screen, new_v, install_cmap_p);
#if 0
- fprintf (stderr, "%s: switching visuals\tfrom: ", progname);
- describe_visual (stderr, ssi->screen, ssi->current_visual);
- fprintf (stderr, "\t\t\t\tto: ");
- describe_visual (stderr, ssi->screen, new_v);
- fprintf (stderr, "\t\t\t\t install cmap: %s\n",
- (install_cmap_p ? "yes" : "no"));
-#else
- fprintf (stderr, "%s: switching to visual ", progname);
- describe_visual (stderr, ssi->screen, new_v);
+ fprintf (stderr, "%s: from ", blurb());
+ describe_visual (stderr, ssi->screen, ssi->current_visual,
+ was_installed_p);
#endif
}
ssi->screensaver_window = 0;
initialize_screensaver_window_1 (ssi);
+
+ /* stderr_overlay_window is a child of screensaver_window, so we need
+ to destroy that as well (actually, we just need to invalidate and
+ drop our pointers to it, but this will destroy it, which is ok so
+ long as it happens before old_w itself is destroyed.) */
+ reset_stderr (ssi);
+
raise_window (si, True, True, False);
store_vroot_property (si->dpy,
ssi->screensaver_window, ssi->screensaver_window);
if (p->verbose_p)
fprintf (stderr, "%s: destroyed old saver window 0x%lx.\n",
- progname, (unsigned long) old_w);
+ blurb(), (unsigned long) old_w);
if (old_c &&
old_c != DefaultColormapOfScreen (ssi->screen) &&
return got_it;
}
+
+\f
+/* VT locking */
+
+#ifdef HAVE_VT_LOCKSWITCH
+static void
+lock_vt (saver_info *si, Bool lock_p)
+{
+ saver_preferences *p = &si->prefs;
+ static Bool locked_p = False;
+ const char *dev_console = "/dev/console";
+ int fd;
+
+ if (lock_p == locked_p)
+ return;
+
+ if (lock_p && !p->lock_vt_p)
+ return;
+
+ fd = open (dev_console, O_RDWR);
+ if (fd < 0)
+ {
+ char buf [255];
+ sprintf (buf, "%s: couldn't %s VTs: %s", blurb(),
+ (lock_p ? "lock" : "unlock"),
+ dev_console);
+#if 0 /* #### doesn't work yet, so don't bother complaining */
+ perror (buf);
+#endif
+ return;
+ }
+
+ if (ioctl (fd, (lock_p ? VT_LOCKSWITCH : VT_UNLOCKSWITCH)) == 0)
+ {
+ locked_p = lock_p;
+
+ if (p->verbose_p)
+ fprintf (stderr, "%s: %s VTs\n", blurb(),
+ (lock_p ? "locked" : "unlocked"));
+ }
+ else
+ {
+ char buf [255];
+ sprintf (buf, "%s: couldn't %s VTs: ioctl", blurb(),
+ (lock_p ? "lock" : "unlock"));
+#if 0 /* #### doesn't work yet, so don't bother complaining */
+ perror (buf);
+#endif
+ }
+
+ close (fd);
+}
+#endif /* HAVE_VT_LOCKSWITCH */