diff --git a/config.d/x11.m4 b/config.d/x11.m4 index ee521f296..23f950087 100644 --- a/config.d/x11.m4 +++ b/config.d/x11.m4 @@ -35,6 +35,27 @@ if test "x$HAVE_VIDMODE" != xno; then fi AC_SUBST(VIDMODE_LIBS) +dnl Check for XScreenSaver support +AC_ARG_ENABLE(xi2, + AS_HELP_STRING([--disable-xss], [do not use Xorg XScreenSaver extension]), + HAVE_XSS=$enable_xi2, HAVE_XSS=auto) +if test "x$HAVE_XSS" != xno; then + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$X_CFLAGS $CPPFLAGS" + AC_CHECK_HEADER(X11/extensions/scrnsaver.h, + dnl Make sure the library works + [AC_CHECK_LIB(Xss, XScreenSaverQueryExtension, + AC_DEFINE(HAVE_XSS, 1, [Define if you have the Xorg XScreenSaver extension]) + HAVE_XSS=yes + XSS_LIBS="-lXss",, + [$X_LIBS -lXext -lX11 $X_EXTRA_LIBS] + )],, + [#include <X11/Xlib.h>] + ) + CPPFLAGS="$save_CPPFLAGS" +fi +AC_SUBST(XSS_LIBS) + dnl Check for XInput2 support AC_ARG_ENABLE(xi2, AS_HELP_STRING([--disable-xi2], [do not use Xorg XInput2 extension]), diff --git a/include/context_x11.h b/include/context_x11.h index 1dd9e67d3..f9fc66964 100644 --- a/include/context_x11.h +++ b/include/context_x11.h @@ -64,6 +64,7 @@ extern bool x_have_focus; bool X11_AddEvent (int event, void (*event_handler)(XEvent *)); bool X11_RemoveEvent (int event, void (*event_handler)(XEvent *)); bool X11_SetGamma (double); +void X11_SetScreenSaver (void); void X11_CloseDisplay (void); void X11_CreateNullCursor (void); void X11_CreateWindow (int, int); @@ -74,6 +75,7 @@ void X11_OpenDisplay (void); void X11_ProcessEvent (void); void X11_ProcessEvents (void); void X11_RestoreGamma (void); +void X11_RestoreScreenSaver (void); void X11_RestoreVidMode (void); void X11_SetCaption (const char *); void X11_SetVidMode (int, int); diff --git a/libs/video/targets/context_x11.c b/libs/video/targets/context_x11.c index 5b8237257..8aabf434a 100644 --- a/libs/video/targets/context_x11.c +++ b/libs/video/targets/context_x11.c @@ -44,18 +44,13 @@ # include <unistd.h> #endif -#include <stdlib.h> -#include <sys/ipc.h> -#include <sys/shm.h> #include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <X11/keysym.h> -#include <X11/extensions/XShm.h> - #ifdef HAVE_VIDMODE # include <X11/extensions/xf86vmode.h> #endif +#ifdef HAVE_XSS +# include <X11/extensions/scrnsaver.h> +#endif #include "QF/cmd.h" #include "QF/cvar.h" @@ -78,8 +73,9 @@ bool oktodraw = false; int x_shmeventtype; static int x_disp_ref_count = 0; +static bool x_have_xss = false; -Display *x_disp = NULL; +Display *x_disp = nullptr; int x_screen; int x_width; int x_height; @@ -99,8 +95,8 @@ static XF86VidModeModeInfo **vidmodes; static int nummodes; static int original_mode = 0; static vec3_t x_gamma = {-1, -1, -1}; -static bool vidmode_avail = false; #endif +static bool vidmode_avail = false; static bool vidmode_active = false; @@ -205,7 +201,7 @@ X11_RemoveEvent (int event, void (*event_handler) (XEvent *)) if (event_handlers[event] != event_handler) return false; - event_handlers[event] = NULL; + event_handlers[event] = nullptr; return true; } @@ -252,34 +248,72 @@ X11_ProcessEvents (void) X11_ProcessEvent (); } -#ifdef HAVE_VIDMODE -static void +void X11_SetScreenSaver (void) { - XGetScreenSaver (x_disp, &xss_timeout, &xss_interval, &xss_blanking, - &xss_exposures); - XSetScreenSaver (x_disp, 0, xss_interval, xss_blanking, xss_exposures); + if (x_have_xss) { +#ifdef HAVE_XSS + XScreenSaverSuspend (x_disp, true); +#endif + } else { +#ifdef HAVE_VIDMODE + XGetScreenSaver (x_disp, &xss_timeout, &xss_interval, &xss_blanking, + &xss_exposures); + XSetScreenSaver (x_disp, 0, xss_interval, xss_blanking, xss_exposures); +#endif + } +} + +void +X11_RestoreScreenSaver (void) +{ + if (x_have_xss) { +#ifdef HAVE_XSS + XScreenSaverSuspend (x_disp, false); +#endif + } else { +#ifdef HAVE_VIDMODE + XSetScreenSaver (x_disp, xss_timeout, xss_interval, xss_blanking, + xss_exposures); +#endif + } } static void -X11_RestoreScreenSaver (void) +X11_CheckScreenSaver (void) { - XSetScreenSaver (x_disp, xss_timeout, xss_interval, xss_blanking, - xss_exposures); -} +#ifdef HAVE_XSS + int ev_base, err_base; + int maj_ver, min_ver; + if (!XScreenSaverQueryExtension (x_disp, &ev_base, &err_base)) { + Sys_MaskPrintf (SYS_vid, "XSS not supported\n"); + return; + } + if (!XScreenSaverQueryVersion (x_disp, &maj_ver, &min_ver)) { + Sys_MaskPrintf (SYS_vid, "XScreenSaver version query failed\n"); + return; + } + Sys_MaskPrintf (SYS_vid, "XSS supperted: version %d.%d (ev:%d, err:%d)\n", + maj_ver, min_ver, ev_base, err_base); + x_have_xss = true; +#else + Sys_MaskPrintf (SYS_vid, "X11: XScreenSaver support not compiled in\n"); #endif +} void X11_OpenDisplay (void) { qfZoneScoped (true); if (!x_disp) { - x_disp = XOpenDisplay (NULL); + x_disp = XOpenDisplay (nullptr); if (!x_disp) { Sys_Error ("X11_OpenDisplay: Could not open display [%s]", - XDisplayName (NULL)); + XDisplayName (nullptr)); } + X11_CheckScreenSaver (); + x_net_state = XInternAtom (x_disp, "_NET_WM_STATE", False); x_net_fullscreen = XInternAtom (x_disp, "_NET_WM_STATE_FULLSCREEN", False); @@ -304,6 +338,7 @@ X11_CloseDisplay (void) X11_RestoreVidMode (); X11_RestoreGamma (); + X11_RestoreScreenSaver (); if (x_nullcursor != None) { XFreeCursor (x_disp, x_nullcursor); @@ -363,11 +398,11 @@ X11_GetGamma (void) (*temp)[2] = xgamma.blue; return temp; } - return NULL; + return nullptr; } } vid_gamma_avail = false; - return NULL; + return nullptr; } #endif @@ -393,7 +428,7 @@ X11_SetVidMode (int width, int height) static int initialized = 0; if (!vidmode_avail) - vidmode_avail = VID_CheckVMode (x_disp, NULL, NULL); + vidmode_avail = VID_CheckVMode (x_disp, nullptr, nullptr); if (!initialized && vidmode_avail) { vec3_t *temp; @@ -461,7 +496,6 @@ X11_SetVidMode (int width, int height) vidmodes[best_mode]); } vidmode_active = true; - X11_SetScreenSaver (); } else { Sys_Printf ("VID: Mode %dx%d can't go fullscreen.\n", viddef.width, viddef.height); @@ -569,14 +603,13 @@ X11_CreateWindow (int width, int height) void X11_RestoreVidMode (void) { -#ifdef HAVE_VIDMODE if (vidmode_active) { - X11_RestoreScreenSaver (); +#ifdef HAVE_VIDMODE //XF86VidModeSwitchToMode (x_disp, x_screen, vidmodes[original_mode]); XFree (vidmodes); vidmode_active = false; - } #endif + } } void diff --git a/libs/video/targets/in_x11.c b/libs/video/targets/in_x11.c index 02badd3af..60032d413 100644 --- a/libs/video/targets/in_x11.c +++ b/libs/video/targets/in_x11.c @@ -1143,6 +1143,7 @@ event_focusout (XEvent *event) CDAudio_Pause (); } X11_RestoreGamma (); + X11_RestoreScreenSaver (); } } @@ -1162,6 +1163,10 @@ event_focusin (XEvent *event) #endif } VID_UpdateGamma (); + // The assumption is that kb+mouse will generate enough input it doesn't + // matter, and that if the game is in focus, then assume a controller + // (which does not generate X11 events) might be in use. + X11_SetScreenSaver (); } static void diff --git a/nq/source/Makemodule.am b/nq/source/Makemodule.am index 0670d205d..48e4cb274 100644 --- a/nq/source/Makemodule.am +++ b/nq/source/Makemodule.am @@ -93,8 +93,8 @@ nq_x11_libs= \ $(nq_client_LIBS) nq_x11_SOURCES= nq/source/sys_unix.c $(tracy_src) $(tracyvk_src) nq_x11_LDADD= $(nq_x11_libs) \ - $(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(X_LIBS) \ - -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(DL_LIBS) + $(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(XSS_LIBS) \ + $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(DL_LIBS) nq_x11_LDFLAGS= $(common_ldflags) nq_x11_DEPENDENCIES= $(nq_x11_libs) diff --git a/qw/source/Makemodule.am b/qw/source/Makemodule.am index a061b74a4..58e40a2a4 100644 --- a/qw/source/Makemodule.am +++ b/qw/source/Makemodule.am @@ -118,9 +118,9 @@ qw_client_x11_libs= \ $(qw_client_LIBS) qw_client_x11_SOURCES= qw/source/cl_sys_unix.c $(tracy_src) $(tracyvk_src) qw_client_x11_LDADD= $(qw_client_x11_libs) \ - $(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(X_LIBS) \ - -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(LIBCURL_LIBS) \ - $(DL_LIBS) + $(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(XSS_LIBS) \ + $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) \ + $(LIBCURL_LIBS) $(DL_LIBS) qw_client_x11_LDFLAGS= $(common_ldflags) qw_client_x11_DEPENDENCIES= $(qw_client_x11_libs) diff --git a/ruamoko/qwaq/Makemodule.am b/ruamoko/qwaq/Makemodule.am index 225d7953b..8de33c572 100644 --- a/ruamoko/qwaq/Makemodule.am +++ b/ruamoko/qwaq/Makemodule.am @@ -124,8 +124,9 @@ ruamoko_qwaq_qwaq_x11_SOURCES= \ ruamoko/qwaq/builtins/qwaq-graphics.c \ ruamoko/qwaq/builtins/graphics.c $(tracy_src) $(tracyvk_src) ruamoko_qwaq_qwaq_x11_LDADD= $(qwaq_x11_libs) $(QWAQ_LIBS) \ - $(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(X_LIBS) \ - -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(PTHREAD_LDFLAGS) $(DL_LIBS) + $(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(XSS_LIBS)\ + $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(PTHREAD_LDFLAGS) \ + $(DL_LIBS) ruamoko_qwaq_qwaq_x11_LDFLAGS= ruamoko_qwaq_qwaq_x11_DEPENDENCIES= $(qwaq_x11_libs) $(QWAQ_DEPS)