summaryrefslogtreecommitdiffstats
path: root/driver/xscreensaver-auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/xscreensaver-auth.c')
-rw-r--r--driver/xscreensaver-auth.c92
1 files changed, 82 insertions, 10 deletions
diff --git a/driver/xscreensaver-auth.c b/driver/xscreensaver-auth.c
index 4344d20..a65cc0d 100644
--- a/driver/xscreensaver-auth.c
+++ b/driver/xscreensaver-auth.c
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright © 1991-2021 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 1991-2022 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
@@ -167,6 +167,66 @@ oom_assassin_immunity (void)
#endif /* HAVE_PROC_OOM */
+#ifndef HAVE_DPMS_EXTENSION
+# define dpms_init (dpy) /** */
+
+#else /* HAVE_DPMS_EXTENSION */
+
+# include <X11/Xproto.h>
+# include <X11/extensions/dpms.h>
+
+static int
+ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
+{
+ return 0;
+}
+
+/* When XScreenSaver first launches, power on the monitor and disable DPMS.
+ The DPMS settings will be re-written when 'xscreensaver-gfx' launches for
+ the first time to blank the screen, and will be re-enabled if that is what
+ is configured in ~/.xscreensaver.
+
+ Without this, if the server's default DPMS timeouts are different than, and
+ less than, the .xscreensaver file's 'timeout' and 'dpmsStandby' the monitor
+ will already be powered down when 'xscreensaver-gfx' launches for the first
+ time, and it will never change them, as it can't touch those settings if
+ the monitor is already powered off.
+
+ It would be better for us to call sync_server_dpms_settings() here, but
+ that requires a full 'saver_preferences' struct. Once 'xscreensaver-gfx'
+ is launched, it will correct things.
+
+ The only way this behaves oddly is if the user has set their 'dpmsStandby'
+ to less than their 'timeout', but that would be weird, right? That
+ probably shouldn't even be permitted (though currently it is).
+
+ This is in 'xscreensaver-auth' because that's run at startup with either
+ --splash or --init, long before 'xscreensaver-gfx' is run for the first
+ time; and putting this code into 'xscreensaver' would violate the principle
+ of linking only the bare minimum into the daemon itself.
+ */
+static void
+dpms_init (Display *dpy)
+{
+ int ev, err;
+ XErrorHandler old_handler;
+ XSync (dpy, False);
+ old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
+ XSync (dpy, False);
+
+ if (DPMSQueryExtension (dpy, &ev, &err))
+ {
+ DPMSForceLevel (dpy, DPMSModeOn);
+ DPMSDisable (dpy);
+ }
+ XSetScreenSaver (dpy, 0, 0, 0, 0);
+
+ XSync (dpy, False);
+ XSetErrorHandler (old_handler);
+}
+#endif /* HAVE_DPMS_EXTENSION */
+
+
int
main (int argc, char **argv)
{
@@ -175,7 +235,7 @@ main (int argc, char **argv)
Widget root_widget;
char *dpy_str = getenv ("DISPLAY");
Bool xsync_p = False;
- Bool splash_p = False;
+ int splash_p = 0;
Bool init_p = False;
int i;
@@ -225,13 +285,20 @@ main (int argc, char **argv)
dpy_str = argv[++i];
if (!dpy_str) goto HELP;
}
+ else if (!strcmp (argv[i], "-ver") ||
+ !strcmp (argv[i], "-vers") ||
+ !strcmp (argv[i], "-version"))
+ {
+ fprintf (stderr, "%s\n", screensaver_id+4);
+ exit (1);
+ }
else if (!strcmp (argv[i], "-sync") ||
!strcmp (argv[i], "-synch") ||
!strcmp (argv[i], "-synchronize") ||
!strcmp (argv[i], "-synchronise"))
xsync_p = True;
else if (!strcmp (argv[i], "-splash"))
- splash_p = True;
+ splash_p++; /* 0, 1 or 2 */
else if (!strcmp (argv[i], "-init"))
init_p = True;
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "-help"))
@@ -266,19 +333,16 @@ main (int argc, char **argv)
}
# ifdef HAVE_PROC_OOM
- if (splash_p || init_p)
+ if (splash_p == 1 || init_p)
oom_assassin_immunity ();
# endif
if (!splash_p && !init_p)
lock_priv_init ();
- if (!splash_p && init_p)
- exit (0);
-
disavow_privileges ();
- if (!splash_p)
+ if (!splash_p && !init_p)
lock_init ();
/* Setting the locale is necessary for XLookupString to return multi-byte
@@ -316,9 +380,17 @@ main (int argc, char **argv)
if (xsync_p) XSynchronize (dpy, True);
init_xscreensaver_atoms (dpy);
- if (splash_p)
+ if (splash_p == 1 || init_p)
+ dpms_init (dpy);
+
+ if (!splash_p && init_p)
+ {
+ exit (0);
+ }
+ else if (splash_p)
{
- xscreensaver_splash (root_widget);
+ /* Settings button is disabled with --splash --splash */
+ xscreensaver_splash (root_widget, splash_p > 1);
exit (0);
}
else if (xscreensaver_auth ((void *) root_widget,