X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fxscreensaver.c;h=dd27cae56f679727d5b42ab9679266c120692942;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=d2dbeb9227759a4c14478579357a0b3914f33d39;hpb=d5186197bc394e10a4402f7f6d23fbb14103bc50;p=xscreensaver diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index d2dbeb92..dd27cae5 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1991-2013 Jamie Zawinski +/* xscreensaver, Copyright (c) 1991-2017 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -93,6 +93,14 @@ * subwindows. It is an incredible misdesign that one client can make * another client malfunction in this way. * + * But here's a new kink that started showing up in late 2014: GNOME programs + * don't actually select for or receive KeyPress events! They do it behind + * the scenes through some kind of Input Method magic, even when running in + * an en_US locale. However, in that case, those applications *do* seem to + * update the _NET_WM_USER_TIME on their own windows every time they have + * received a secret KeyPress, so we *also* monitor that property on every + * window, and treat changes to it as identical to KeyPress. + * * To detect mouse motion, we periodically wake up and poll the mouse * position and button/modifier state, and notice when something has * changed. We make this check every five seconds by default, and since the @@ -297,7 +305,7 @@ xscreensaver %s, copyright (c) 1991-%s by Jamie Zawinski \n\ \n\ For updates, online manual, and FAQ, please see the web page:\n\ \n\ - http://www.jwz.org/xscreensaver/\n\ + https://www.jwz.org/xscreensaver/\n\ \n"); fflush (stdout); @@ -309,7 +317,7 @@ xscreensaver %s, copyright (c) 1991-%s by Jamie Zawinski \n\ Bool in_signal_handler_p = 0; /* I hate C so much... */ char * -timestring (void) +timestring (time_t when) { if (in_signal_handler_p) { @@ -322,9 +330,10 @@ timestring (void) } else { - time_t now = time ((time_t *) 0); - char *str = (char *) ctime (&now); - char *nl = (char *) strchr (str, '\n'); + char *str, *nl; + if (! when) when = time ((time_t *) 0); + str = (char *) ctime (&when); + nl = (char *) strchr (str, '\n'); if (nl) *nl = 0; /* take off that dang newline */ return str; } @@ -340,7 +349,7 @@ blurb (void) else { static char buf[255]; - char *ct = timestring(); + char *ct = timestring(0); int n = strlen(progname); if (n > 100) n = 99; strncpy(buf, progname, n); @@ -416,7 +425,7 @@ saver_ehandler (Display *dpy, XErrorEvent *error) " won't work. A \"log.txt\" file will also be written. Please *do*\n" " include the complete \"log.txt\" file with your bug report.\n" "\n" - " http://www.jwz.org/xscreensaver/bugs.html explains how to create\n" + " https://www.jwz.org/xscreensaver/bugs.html explains how to create\n" " the most useful bug reports, and how to examine core files.\n" "\n" " The more information you can provide, the better. But please\n" @@ -486,8 +495,8 @@ startup_ehandler (String name, String type, String class, } fprintf (stderr, "\n" - " http://www.jwz.org/xscreensaver/faq.html\n" - " http://www.jwz.org/xscreensaver/man.html\n" + " https://www.jwz.org/xscreensaver/faq.html\n" + " https://www.jwz.org/xscreensaver/man.html\n" "\n"); fflush (stderr); @@ -521,7 +530,7 @@ set_version_string (saver_info *si, int *argc, char **argv) *s = '_'; } - si->version = (char *) malloc (5); + si->version = (char *) malloc (32); memcpy (si->version, screensaver_id + 17, 4); si->version [4] = 0; } @@ -600,6 +609,16 @@ lock_initialization (saver_info *si, int *argc, char **argv) } } + /* Like MacOS, locking under Wayland's embedded X11 server does not work. + (X11 grabs don't work because the Wayland window manager lives at a + higher level than the X11 emulation layer.) + */ + if (!si->locking_disabled_p && getenv ("WAYLAND_DISPLAY")) + { + si->locking_disabled_p = True; + si->nolock_reason = "Cannot lock securely under Wayland"; + } + if (si->prefs.debug_p) /* But allow locking anyway in debug mode. */ si->locking_disabled_p = False; @@ -659,6 +678,7 @@ connect_to_server (saver_info *si, int *argc, char **argv) XA_XSETROOT_ID = XInternAtom (si->dpy, "_XSETROOT_ID", False); XA_ESETROOT_PMAP_ID = XInternAtom (si->dpy, "ESETROOT_PMAP_ID", False); XA_XROOTPMAP_ID = XInternAtom (si->dpy, "_XROOTPMAP_ID", False); + XA_NET_WM_USER_TIME = XInternAtom (si->dpy, "_NET_WM_USER_TIME", False); XA_ACTIVATE = XInternAtom (si->dpy, "ACTIVATE", False); XA_DEACTIVATE = XInternAtom (si->dpy, "DEACTIVATE", False); XA_RESTART = XInternAtom (si->dpy, "RESTART", False); @@ -730,7 +750,7 @@ process_command_line (saver_info *si, int *argc, char **argv) You control a running xscreensaver process by sending it messages\n\ with `xscreensaver-demo' or `xscreensaver-command'.\n\ . See the man pages for details, or check the web page:\n\ - http://www.jwz.org/xscreensaver/\n\n"); + https://www.jwz.org/xscreensaver/\n\n"); } exit (1); @@ -784,12 +804,12 @@ print_banner (saver_info *si) "\n", blurb()); - if (p->verbose_p && senescent_p ()) + if (p->verbose_p && decrepit_p ()) fprintf (stderr, "\n" "*************************************" "**************************************\n" "%s: Warning: this version of xscreensaver is VERY OLD!\n" - "%s: Please upgrade! http://www.jwz.org/xscreensaver/\n" + "%s: Please upgrade! https://www.jwz.org/xscreensaver/\n" "*************************************" "**************************************\n" "\n", @@ -1178,10 +1198,10 @@ main_loop (saver_info *si) { if (si->demoing_p) fprintf (stderr, "%s: demoing %d at %s.\n", blurb(), - si->selection_mode, timestring()); + si->selection_mode, timestring(0)); else fprintf (stderr, "%s: blanking screen at %s.\n", blurb(), - timestring()); + timestring(0)); } maybe_reload_init_file (si); @@ -1190,7 +1210,7 @@ main_loop (saver_info *si) { if (p->verbose_p) fprintf (stderr, "%s: idle with blanking disabled at %s.\n", - blurb(), timestring()); + blurb(), timestring(0)); /* Go around the loop and wait for the next bout of idleness, or for the init file to change, or for a remote command to @@ -1256,6 +1276,12 @@ main_loop (saver_info *si) "%s: unable to grab keyboard or mouse! Blanking aborted.\n", blurb()); + /* Since we were unable to blank, clearly we're not locked, + but we might have been prematurely marked as locked by + the LOCK ClientMessage. */ + if (si->locked_p) + set_locked_p (si, False); + schedule_wakeup_event (si, retry, p->debug_p); continue; } @@ -1386,7 +1412,7 @@ main_loop (saver_info *si) if (p->verbose_p) fprintf (stderr, "%s: unblanking screen at %s.\n", - blurb(), timestring ()); + blurb(), timestring (0)); /* Kill before unblanking, to stop drawing as soon as possible. */ for (i = 0; i < si->nscreens; i++) @@ -2044,7 +2070,16 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) : "locking."); sprintf (buf, "LOCK ClientMessage received; %s", response); clientmessage_response (si, window, False, buf, response); + + /* Note that this leaves things in a slightly inconsistent state: + we are blanked but not locked. And blanking might actually + fail if we can't get the grab. */ set_locked_p (si, True); + + /* Have to set the time or xscreensaver-command doesn't + report the LOCK state change. */ + si->blank_time = time ((time_t *) 0); + si->selection_mode = 0; si->demoing_p = False; @@ -2289,7 +2324,6 @@ analyze_display (saver_info *si) char buf [255]; int maj = 0, min = 0; int dummy1, dummy2, dummy3; - int j; /* Most of the extension version functions take 3 args, writing results into args 2 and 3, but some take more. @@ -2302,7 +2336,6 @@ analyze_display (saver_info *si) if (!XQueryExtension (si->dpy, exts[i].name, &op, &event, &error)) continue; sprintf (buf, "%s: ", blurb()); - j = strlen (buf); strcat (buf, exts[i].desc); if (!version_fn_2)