summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure161
-rw-r--r--configure.in4
-rw-r--r--driver/XScreenSaver.ad.in10
-rw-r--r--driver/dpms.c23
-rw-r--r--driver/prefs.c8
-rw-r--r--driver/prefs.h2
-rw-r--r--driver/subprocs.c62
-rw-r--r--driver/timers.c15
-rw-r--r--driver/types.h6
-rw-r--r--driver/windows.c75
-rw-r--r--driver/xscreensaver.c12
-rw-r--r--driver/xscreensaver.h2
12 files changed, 336 insertions, 44 deletions
diff --git a/configure b/configure
index e566796..68e04e2 100755
--- a/configure
+++ b/configure
@@ -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);