From 541cb14f1cf2d77f76b6cec665466a1685ff9b65 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:21:16 +0200 Subject: Add ungrab command, respawn hack before password prompt --- driver/XScreenSaver.ad.in | 9 +++++++ driver/XScreenSaver_ad.h | 13 +++++----- driver/prefs.c | 5 ++++ driver/subprocs.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ driver/types.h | 5 ++++ driver/windows.c | 24 ++++++++++++++++++- driver/xscreensaver.c | 5 ++++ driver/xscreensaver.h | 1 + 8 files changed, 115 insertions(+), 7 deletions(-) diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index f4e29d4..e365486 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -139,6 +139,15 @@ GetViewPortIsFullOfLies: False @NEW_LOGIN_COMMAND_P@*newLoginCommand: @NEW_LOGIN_COMMAND@ +! External command used to help xscreensaver aquire the mouse/keyboard +! grab. (I.e. some script that makes VMware release it). +! This is called before xscreensaver tries to aquire the grab with +! "pre" as parameter, and again with "post" after xscreensaver is done +! (trying to) aquire the grab. +! +*externalUngrabCommand: + + ! Turning on "installColormap" on 8-bit systems interacts erratically with ! certain jurassic window managers. If your screen turns some color other ! than black, the window manager is buggy, and you need to set this resource diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h index cd4976e..345bca9 100644 --- a/driver/XScreenSaver_ad.h +++ b/driver/XScreenSaver_ad.h @@ -14,7 +14,7 @@ "*grabDesktopImages: True", "*grabVideoFrames: False", "*chooseRandomImages: True", -"*imageDirectory: /Library/Desktop Pictures/", +"*imageDirectory: /usr/share/wallpapers/", "*nice: 10", "*memoryLimit: 0", "*lock: False", @@ -32,7 +32,7 @@ "*authWarningSlack: 20", "*textMode: file", "*textLiteral: XScreenSaver", -"*textFile: ", +"*textFile: /usr/share/doc/xserver-common/copyright", "*textProgram: fortune", "*textURL: https://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss", "*overlayTextForeground: #FFFF00", @@ -47,10 +47,11 @@ "*demoCommand: xscreensaver-demo", "*prefsCommand: xscreensaver-demo -prefs", "*helpURL: https://www.jwz.org/xscreensaver/man.html", -"*loadURL: firefox '%s' || mozilla '%s' || netscape '%s'", -"*manualCommand: xterm -sb -fg black -bg gray75 -T '%s manual' \ - -e /bin/sh -c 'man \"%s\" ; read foo'", +"*loadURL: gnome-open '%s'", +"*manualCommand: gnome-terminal --title '%s manual' \ + --command '/bin/sh -c \"man %s; read foo\"'", "*dateFormat: %d-%b-%y (%a); %I:%M %p", +"*newLoginCommand: dm-tool switch-to-greeter", "*installColormap: True", "*programs: \ maze -root \\n\ @@ -127,7 +128,7 @@ compass -root \\n\ deluxe -root \\n\ - demon -root \\n\ - GL: extrusion -root \\n\ +- GL: extrusion -root \\n\ - loop -root \\n\ penetrate -root \\n\ petri -root \\n\ diff --git a/driver/prefs.c b/driver/prefs.c index 8fb029e..6965ad9 100644 --- a/driver/prefs.c +++ b/driver/prefs.c @@ -265,6 +265,7 @@ static const char * const prefs[] = { "helpURL", /* not saved */ "loadURL", /* not saved */ "newLoginCommand", /* not saved */ + "externalUngrabCommand", /* not saved */ "nice", "memoryLimit", "fade", @@ -805,6 +806,7 @@ write_init_file (Display *dpy, CHECK("loadURL") continue; /* don't save */ /* CHECK("newLoginCommand") type = pref_str, s = p->new_login_command; */ CHECK("newLoginCommand") continue; /* don't save */ + CHECK("externalUngrabCommand") continue; /* don't save */ CHECK("nice") type = pref_int, i = p->nice_inferior; CHECK("memoryLimit") type = pref_byte, i = p->inferior_memory_limit; CHECK("fade") type = pref_bool, b = p->fade_p; @@ -1104,6 +1106,9 @@ load_init_file (Display *dpy, saver_preferences *p) p->new_login_command = get_string_resource(dpy, "newLoginCommand", "NewLoginCommand"); + p->external_ungrab_command = get_string_resource(dpy, + "externalUngrabCommand", + "ExternalUngrabCommand"); p->auth_warning_slack = get_integer_resource(dpy, "authWarningSlack", "Integer"); diff --git a/driver/subprocs.c b/driver/subprocs.c index 4f327e9..13b47a4 100644 --- a/driver/subprocs.c +++ b/driver/subprocs.c @@ -916,6 +916,66 @@ fork_and_exec (saver_screen_info *ssi, const char *command) } +/* Execute command in another process and wait for it to + * finish. Return exit code of process, or -1 on error + * with fork() or exec(). + */ +int +exec_and_wait (saver_info *si, const char *command) +{ + pid_t forked; + saver_preferences *p = &si->prefs; + + switch ((int) (forked = fork ())) + { + case -1: + { + char buf [255]; + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + return -1; + } + + case 0: + close (ConnectionNumber (si->dpy)); /* close display fd */ + limit_subproc_memory (p->inferior_memory_limit, p->verbose_p); + + if (p->verbose_p) + fprintf (stderr, "%s: spawning \"%s\" in pid %lu.\n", + blurb(), command, + (unsigned long) getpid ()); + + exec_command (p->shell, command, 0); + + /* If that returned, we were unable to exec the subprocess. + Print an error message, if desired. + */ + print_path_error (command); + + exit (-1); /* exits child fork */ + break; + + default: /* parent */ + { + pid_t retpid; + int wstatus; + while ((retpid = waitpid (forked, &wstatus, 0)) == -1) { + if (errno == EINTR) + continue; + perror ("Could not waitpid for child."); + return -1; + } + if (WIFEXITED(wstatus)) + return WEXITSTATUS(wstatus); + if (WIFSIGNALED(wstatus)) + return WTERMSIG(wstatus) + 128; + return -1; + } + } + return -1; +} + + void spawn_screenhack (saver_screen_info *ssi) { diff --git a/driver/types.h b/driver/types.h index f1630b0..8ecef71 100644 --- a/driver/types.h +++ b/driver/types.h @@ -164,6 +164,11 @@ struct saver_preferences { char *help_url; /* Where the help document resides. */ char *load_url_command; /* How one loads URLs. */ char *new_login_command; /* Command for the "New Login" button. */ + char *external_ungrab_command; /* Command that's supposed to make sure + nobody is holding the keyboard or + mouse grab. Called with params + "pre" and "post" before and after + trying to get the grab. */ int auth_warning_slack; /* Don't warn about login failures if they all happen within this many seconds of diff --git a/driver/windows.c b/driver/windows.c index 9b2bf84..c54f15e 100644 --- a/driver/windows.c +++ b/driver/windows.c @@ -235,7 +235,7 @@ ungrab_keyboard_and_mouse (saver_info *si) static Bool -grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, +grab_keyboard_and_mouse_real (saver_info *si, Window window, Cursor cursor, int screen_no) { Status mstatus = 0, kstatus = 0; @@ -320,6 +320,28 @@ grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, } +static Bool +grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, + int screen_no) +{ + Bool ret; + char *euc = si->prefs.external_ungrab_command; + char cmd[200]; + if (euc && *euc) + { + snprintf (cmd, sizeof(cmd), "%s %s", euc, "pre"); + exec_and_wait (si, cmd); + } + ret = grab_keyboard_and_mouse_real (si, window, cursor, screen_no); + if (euc && *euc) + { + snprintf (cmd, sizeof(cmd), "%s %s", euc, "post"); + exec_and_wait (si, cmd); + } + return ret; +} + + int move_mouse_grab (saver_info *si, Window to, Cursor cursor, int to_screen_no) { diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index f5f65dc..03d2d91 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -1380,6 +1380,11 @@ main_loop (saver_info *si) was_locked = True; si->dbox_up_p = True; + /* bwlp: make sure saver is running */ + for (i = 0; i < si->nscreens; i++) + if (si->screens[i].pid == 0) + spawn_screenhack (&si->screens[i]); + /* -- */ for (i = 0; i < si->nscreens; i++) suspend_screenhack (&si->screens[i], True); /* suspend */ XUndefineCursor (si->dpy, ssi->screensaver_window); diff --git a/driver/xscreensaver.h b/driver/xscreensaver.h index 42cf794..c5b5644 100644 --- a/driver/xscreensaver.h +++ b/driver/xscreensaver.h @@ -157,6 +157,7 @@ extern void hack_subproc_environment (Screen *, Window saver_window); extern void init_sigchld (void); extern void spawn_screenhack (saver_screen_info *ssi); extern pid_t fork_and_exec (saver_screen_info *ssi, const char *command); +extern int exec_and_wait (saver_info *si, const char *command); extern void kill_screenhack (saver_screen_info *ssi); extern void suspend_screenhack (saver_screen_info *ssi, Bool suspend_p); extern Bool screenhack_running_p (saver_info *si); -- cgit v1.2.3-55-g7522