diff options
-rwxr-xr-x | configure | 161 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | driver/XScreenSaver.ad.in | 10 | ||||
-rw-r--r-- | driver/dpms.c | 23 | ||||
-rw-r--r-- | driver/prefs.c | 8 | ||||
-rw-r--r-- | driver/prefs.h | 2 | ||||
-rw-r--r-- | driver/subprocs.c | 62 | ||||
-rw-r--r-- | driver/timers.c | 15 | ||||
-rw-r--r-- | driver/types.h | 6 | ||||
-rw-r--r-- | driver/windows.c | 75 | ||||
-rw-r--r-- | driver/xscreensaver.c | 12 | ||||
-rw-r--r-- | driver/xscreensaver.h | 2 |
12 files changed, 336 insertions, 44 deletions
@@ -804,6 +804,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -919,6 +920,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1171,6 +1173,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1308,7 +1319,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1430,9 +1441,7 @@ VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. - Configuration: - -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages @@ -1458,13 +1467,18 @@ For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR + --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] @@ -1513,6 +1527,8 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pthread Enables POSIX threads, for SMP support. + --with-x use the X Window System + Installation options: --with-hackdir=DIR Where to install the hundreds of demo executables. @@ -1671,7 +1687,7 @@ fi ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -rf conftest.$ac_objext + rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; @@ -1709,7 +1725,7 @@ fi ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -rf conftest.$ac_objext conftest$ac_exeext + rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; @@ -1875,7 +1891,7 @@ if ac_fn_c_try_cpp "$LINENO"; then : else ac_header_preproc=no fi -rm -rf conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -3303,7 +3319,7 @@ $as_echo "$ac_try_echo"; } >&5 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi - rm -rf conftest.er1 conftest.err + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -3441,11 +3457,11 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi -rm -rf conftest conftest$ac_cv_exeext +rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } -rm -rf conftest.$ac_ext +rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3505,7 +3521,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } -rm -rf conftest.$ac_ext conftest$ac_cv_exeext conftest.out +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } @@ -3523,7 +3539,7 @@ main () return 0; } _ACEOF -rm -rf conftest.o conftest.obj +rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; @@ -3552,7 +3568,7 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi -rm -rf conftest.$ac_cv_objext conftest.$ac_ext +rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } @@ -3742,7 +3758,7 @@ fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done -rm -rf conftest.$ac_ext +rm -f conftest.$ac_ext CC=$ac_save_CC fi @@ -4588,7 +4604,7 @@ else # Broken: fails on valid input. continue fi -rm -rf conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4604,11 +4620,11 @@ else ac_preproc_ok=: break fi -rm -rf conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -rf conftest.i conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -4647,7 +4663,7 @@ else # Broken: fails on valid input. continue fi -rm -rf conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4663,11 +4679,11 @@ else ac_preproc_ok=: break fi -rm -rf conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -rf conftest.i conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else @@ -4989,7 +5005,7 @@ case `${MAKE-make} -f conftest.make 2>/dev/null` in *) eval ac_cv_prog_make_${ac_make}_set=no;; esac -rm -rf conftest.make +rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -5053,7 +5069,7 @@ case `"$ac_path_GREP" --version 2>&1` in # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done - rm -rf conftest.in conftest.tmp conftest.nl conftest.out;; + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 @@ -5119,7 +5135,7 @@ case `"$ac_path_EGREP" --version 2>&1` in # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done - rm -rf conftest.in conftest.tmp conftest.nl conftest.out;; + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 @@ -5181,7 +5197,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -rf conftest* +rm -f conftest* fi @@ -5198,7 +5214,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -rf conftest* +rm -f conftest* fi @@ -5670,7 +5686,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -5694,7 +5710,7 @@ rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC - rm -rf conftest.$ac_ext + rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 @@ -5716,7 +5732,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -5740,7 +5756,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -5785,7 +5801,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -5809,7 +5825,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -6289,7 +6305,7 @@ else fi done fi -rm -rf conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then @@ -9050,6 +9066,73 @@ $as_echo "not found ($d: no such directory)" >&6; } esac + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverQueryInfo in -lXss" >&5 +$as_echo_n "checking for XScreenSaverQueryInfo in -lXss... " >&6; } +if ${ac_cv_lib_Xss_XScreenSaverQueryInfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXss -lXss -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XScreenSaverQueryInfo (); +int +main () +{ +return XScreenSaverQueryInfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xss_XScreenSaverQueryInfo=yes +else + ac_cv_lib_Xss_XScreenSaverQueryInfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xss_XScreenSaverQueryInfo" >&5 +$as_echo "$ac_cv_lib_Xss_XScreenSaverQueryInfo" >&6; } +if test "x$ac_cv_lib_Xss_XScreenSaverQueryInfo" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lXss" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + if test "$with_xinerama" = yes; then # first check for Xinerama.h @@ -10266,7 +10349,7 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -rm -rf conftest* +rm -f conftest* CPPFLAGS="$ac_save_CPPFLAGS" @@ -12782,7 +12865,7 @@ fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lesstif_version_string" >&5 $as_echo "$ac_cv_lesstif_version_string" >&6; } - rm -rf conftest-lt + rm -f conftest-lt lesstif_version=$ac_cv_lesstif_version lesstif_version_string=$ac_cv_lesstif_version_string @@ -12837,7 +12920,7 @@ fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_motif_version_string" >&5 $as_echo "$ac_cv_motif_version_string" >&6; } - rm -rf conftest-mt + rm -f conftest-mt motif_version=$ac_cv_motif_version motif_version_string=$ac_cv_motif_version_string @@ -13140,7 +13223,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Mesa|MESA" >/dev/null 2>&1; then : ac_cv_have_mesa_gl=yes fi -rm -rf conftest* +rm -f conftest* CPPFLAGS="$ac_save_CPPFLAGS" fi @@ -13411,7 +13494,7 @@ if ${ac_cv_mesagl_version_string+:} false; then : $as_echo_n "(cached) " >&6 else cat > conftest.$ac_ext <<EOF -#line 13418 "configure" +#line 13497 "configure" #include "confdefs.h" #include <GL/gl.h> #ifndef MESA_MAJOR_VERSION @@ -13457,7 +13540,7 @@ EOF 's/^configure: *\([0-9][0-9]*\) *\([0-9].*\)$/\1.\2/p'` - rm -rf conftest.$ac_ext + rm -f conftest.$ac_ext CPPFLAGS="$ac_save_CPPFLAGS" diff --git a/configure.in b/configure.in index 20fb0f7..a2e943e 100644 --- a/configure.in +++ b/configure.in @@ -1635,6 +1635,10 @@ AC_ARG_WITH(xinerama-ext, HANDLE_X_PATH_ARG(with_xinerama, --with-xinerama-ext, XINERAMA) +AC_CHECK_X_LIB(Xss, XScreenSaverQueryInfo, [X_EXTRA_LIBS="$X_EXTRA_LIBS -lXss"], [true], + -lXss -lX11) + + if test "$with_xinerama" = yes; then # first check for Xinerama.h diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index cfdd1a2..0b51f0c 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -38,6 +38,7 @@ *dpmsStandby: 2:00:00 *dpmsSuspend: 2:00:00 *dpmsOff: 4:00:00 +*dpmsFullThrottle: False *grabDesktopImages: True *grabVideoFrames: False *chooseRandomImages: @DEFAULT_IMAGES_P@ @@ -142,6 +143,15 @@ @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: + + ! Change these at your peril: ! XScreenSaver.pointerPollTime: 0:00:05 diff --git a/driver/dpms.c b/driver/dpms.c index a0dd7b8..3a8803c 100644 --- a/driver/dpms.c +++ b/driver/dpms.c @@ -86,8 +86,12 @@ #ifdef HAVE_DPMS_EXTENSION +#define CLAMP_DOWN(var,val,mi) do { int old = (var); (var) -= (val); if ((var) < (mi) || (var) > old) (var) = (mi); } while (0) + static Bool error_handler_hit_p = False; +static int idle_offset = 0; + static int ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) { @@ -95,6 +99,12 @@ ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) return 0; } +void +store_dpms_offset(int offset) +{ + idle_offset = offset < 15 ? 0 : offset; +} + void sync_server_dpms_settings (Display *dpy, Bool enabled_p, Bool dpms_quickoff_p, @@ -125,6 +135,13 @@ sync_server_dpms_settings (Display *dpy, Bool enabled_p, Bool dpms_quickoff_p, if (bogus_p) enabled_p = False; + if (idle_offset != 0) + { + CLAMP_DOWN (standby_secs, idle_offset, 10); + CLAMP_DOWN (suspend_secs, idle_offset, 10); + CLAMP_DOWN (off_secs, idle_offset, 10); + } + /* X protocol sends these values in a CARD16, so truncate them to 16 bits. This means that the maximum timeout is 18:12:15. */ @@ -280,6 +297,12 @@ monitor_power_on (saver_info *si, Bool on_p) #else /* !HAVE_DPMS_EXTENSION */ void +store_dpms_offset(Display *dpy, Bool reset_p) +{ +} + + +void sync_server_dpms_settings (Display *dpy, Bool enabled_p, Bool dpms_quickoff_p, int standby_secs, int suspend_secs, int off_secs, diff --git a/driver/prefs.c b/driver/prefs.c index 94e7a0c..e5762ff 100644 --- a/driver/prefs.c +++ b/driver/prefs.c @@ -270,6 +270,7 @@ static const char * const prefs[] = { "helpURL", /* not saved */ "loadURL", /* not saved */ "newLoginCommand", /* not saved */ + "externalUngrabCommand", /* not saved */ "nice", "memoryLimit", "fade", @@ -286,6 +287,7 @@ static const char * const prefs[] = { "dpmsStandby", "dpmsSuspend", "dpmsOff", + "dpmsFullThrottle", "grabDesktopImages", "grabVideoFrames", "chooseRandomImages", @@ -810,6 +812,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; @@ -829,6 +832,7 @@ write_init_file (Display *dpy, CHECK("dpmsStandby") type = pref_time, t = p->dpms_standby; CHECK("dpmsSuspend") type = pref_time, t = p->dpms_suspend; CHECK("dpmsOff") type = pref_time, t = p->dpms_off; + CHECK("dpmsFullThrottle") continue; /* don't save */ CHECK("grabDesktopImages") type =pref_bool, b = p->grab_desktop_p; CHECK("grabVideoFrames") type =pref_bool, b = p->grab_video_p; @@ -1087,6 +1091,7 @@ load_init_file (Display *dpy, saver_preferences *p) p->dpms_standby = 1000 * get_minutes_resource (dpy, "dpmsStandby", "Time"); p->dpms_suspend = 1000 * get_minutes_resource (dpy, "dpmsSuspend", "Time"); p->dpms_off = 1000 * get_minutes_resource (dpy, "dpmsOff", "Time"); + p->dpms_full_throttle_p = get_boolean_resource (dpy, "dpmsFullThrottle", "Boolean"); p->grab_desktop_p = get_boolean_resource (dpy, "grabDesktopImages", "Boolean"); p->grab_video_p = get_boolean_resource (dpy, "grabVideoFrames", "Boolean"); @@ -1109,6 +1114,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/prefs.h b/driver/prefs.h index cd1016d..c494eaf 100644 --- a/driver/prefs.h +++ b/driver/prefs.h @@ -34,4 +34,6 @@ extern void sync_server_dpms_settings (Display *, Bool enabled_p, int off_secs, Bool verbose_p); +extern void store_dpms_offset(int offset); + #endif /* __XSCREENSAVER_PREFS_H__ */ diff --git a/driver/subprocs.c b/driver/subprocs.c index e251842..6cb96d3 100644 --- a/driver/subprocs.c +++ b/driver/subprocs.c @@ -928,6 +928,66 @@ fork_and_exec_1 (saver_info *si, 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) { @@ -935,7 +995,7 @@ spawn_screenhack (saver_screen_info *ssi) saver_preferences *p = &si->prefs; XFlush (si->dpy); - if (!monitor_powered_on_p (si)) + if (!p->dpms_full_throttle_p && !monitor_powered_on_p (si)) { if (si->prefs.verbose_p) fprintf (stderr, diff --git a/driver/timers.c b/driver/timers.c index 5aa568c..b096000 100644 --- a/driver/timers.c +++ b/driver/timers.c @@ -695,6 +695,19 @@ swallow_unlock_typeahead_events (saver_info *si, XEvent *e) memset (buf, 0, sizeof(buf)); } +void +flush_events (saver_info *si) +{ + int i; + XEvent xe; + for (i = 0; i < 10; ++i) { + while (XtAppPending (si->app) & XtIMXEvent) { + XtAppNextEvent (si->app, &xe); + dispatch_event (si, &xe); + } + usleep(5000); + } +} /* methods of detecting idleness: @@ -1663,7 +1676,7 @@ watchdog_timer (XtPointer closure, XtIntervalId *id) raise_window (si, True, True, running_p); } - if (screenhack_running_p (si) && + if (!p->dpms_full_throttle_p && screenhack_running_p (si) && !monitor_powered_on_p (si)) { int i; diff --git a/driver/types.h b/driver/types.h index ebea9e0..705750b 100644 --- a/driver/types.h +++ b/driver/types.h @@ -137,6 +137,7 @@ struct saver_preferences { Time dpms_standby; /* how long until monitor goes black */ Time dpms_suspend; /* how long until monitor power-saves */ Time dpms_off; /* how long until monitor powers down */ + Bool dpms_full_throttle_p; /* Never kill or suspend hack when screen is off */ Bool grab_desktop_p; /* These are not used by "xscreensaver" */ Bool grab_video_p; /* itself: they are used by the external */ @@ -164,6 +165,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 9e47c45..5854c49 100644 --- a/driver/windows.c +++ b/driver/windows.c @@ -35,6 +35,7 @@ #include <X11/Xutil.h> /* for XSetClassHint() */ #include <X11/Xatom.h> #include <X11/Xos.h> /* for time() */ +#include <X11/extensions/scrnsaver.h> #include <signal.h> /* for the signal names */ #include <time.h> #include <sys/time.h> @@ -235,7 +236,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 +321,32 @@ 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); + if (ret) { + /* The external command might have generated some x/input events */ + flush_events (si); + } + } + return ret; +} + + int move_mouse_grab (saver_info *si, Window to, Cursor cursor, int to_screen_no) { @@ -1639,6 +1666,17 @@ mouse_screen (saver_info *si) return 0; } +static int +get_idle_time (saver_info *si) +{ + int ret = 0; + XScreenSaverInfo *info; + info = XScreenSaverAllocInfo (); + if (info != NULL && XScreenSaverQueryInfo (si->dpy, DefaultRootWindow (si->dpy), info)) + ret = info->idle / 1000; + XFree (info); + return ret; +} Bool blank_screen (saver_info *si) @@ -1647,7 +1685,16 @@ blank_screen (saver_info *si) Bool ok; Window w; int mscreen; + int idle_s = 0; + Bool screen_on = True; + const char *euc = si->prefs.external_ungrab_command; + if (euc && *euc) + { + screen_on = monitor_powered_on_p (si); + if (screen_on) + idle_s = get_idle_time(si); + } /* 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. @@ -1679,6 +1726,31 @@ blank_screen (saver_info *si) if (!ok) return False; + if (euc && *euc) + { + /* ungrab hooks might have messed up idle time -- account for that. + this might look like the math is backwards, but this handles both + cases -- ungrab hook did mess up idle time, and ungrab hook + did *not* mess up idle time. In the latter case the value will be + zero or negative, so it gets clamped to zero. + */ + if (screen_on) + { + saver_preferences *p = &si->prefs; + store_dpms_offset (idle_s - get_idle_time(si)); + sync_server_dpms_settings (si->dpy, + (p->dpms_enabled_p && + p->mode != DONT_BLANK), + p->dpms_quickoff_p, + p->dpms_standby / 1000, + p->dpms_suspend / 1000, + p->dpms_off / 1000, + False); + } + else /* screen was off before, might have been turned on by fake events */ + monitor_power_on (si, False); + } + for (i = 0; i < si->nscreens; i++) { saver_screen_info *ssi = &si->screens[i]; @@ -1719,6 +1791,7 @@ unblank_screen (saver_info *si) Bool unfade_p = (si->fading_possible_p && p->unfade_p); int i; + store_dpms_offset (0); monitor_power_on (si, True); reset_watchdog_timer (si, False); diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index 40f8207..b9c54f1 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -1399,8 +1399,16 @@ main_loop (saver_info *si) was_locked = True; si->dbox_up_p = True; - for (i = 0; i < si->nscreens; i++) - suspend_screenhack (&si->screens[i], True); /* suspend */ + if (p->dpms_full_throttle_p) + { + for (i = 0; i < si->nscreens; i++) + if (si->screens[i].pid == 0) + spawn_screenhack (&si->screens[i]); + usleep(100000); + } + else + for (i = 0; i < si->nscreens; i++) + suspend_screenhack (&si->screens[i], True); /* suspend */ XUndefineCursor (si->dpy, ssi->screensaver_window); ok_to_unblank = unlock_p (si); diff --git a/driver/xscreensaver.h b/driver/xscreensaver.h index bed6537..fe84d20 100644 --- a/driver/xscreensaver.h +++ b/driver/xscreensaver.h @@ -129,6 +129,7 @@ extern void activate_lock_timer (XtPointer si, XtIntervalId *id); extern void reset_watchdog_timer (saver_info *si, Bool on_p); extern void idle_timer (XtPointer si, XtIntervalId *id); extern void de_race_timer (XtPointer si, XtIntervalId *id); +void flush_events (saver_info *si); extern void sleep_until_idle (saver_info *si, Bool until_idle_p); extern void reset_timers (saver_info *si); extern void schedule_wakeup_event (saver_info *si, Time when, Bool verbose_p); @@ -159,6 +160,7 @@ extern void spawn_screenhack (saver_screen_info *ssi); extern pid_t fork_and_exec (saver_screen_info *ssi, const char *command); extern pid_t fork_and_exec_1 (saver_info *si, 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); int kill_job (saver_info *si, pid_t pid, int signal); extern void suspend_screenhack (saver_screen_info *ssi, Bool suspend_p); |