diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | Xext/Makefile.am | 2 | ||||
-rw-r--r-- | Xext/saver.c | 153 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | os/WaitFor.c | 14 |
5 files changed, 181 insertions, 6 deletions
@@ -1,3 +1,17 @@ +2006-03-31 Fredrik Höglund <fredrik@kde.org> + + * Xext/Makefile.am: + Move the screensaver extension from module to builtins. + + * Xext/saver.c (ScreenSaverExtensionInit), (ScreenSaverFreeSuspend), + (ProcScreenSaverSuspend), (SProcScreenSaverSuspend): + * os/WaitFor.c (SetScreenSaverTimer): + Add the server side implementation of the ScreenSaverSuspend request. + + * configure.ac: + Require scrnsaverproto >= 1.1, and change the linking order of the + Xorg static libs. + Fri Mar 31 12:37:16 2006 Søren Sandmann <sandmann@redhat.com> * dix/window.c: Fix copyright statement diff --git a/Xext/Makefile.am b/Xext/Makefile.am index 8ab4c8640..2e573c139 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -59,7 +59,7 @@ endif # MIT ScreenSaver extension SCREENSAVER_SRCS = saver.c if SCREENSAVER -MODULE_SRCS += $(SCREENSAVER_SRCS) +BUILTIN_SRCS += $(SCREENSAVER_SRCS) endif # Xinerama extension: making multiple video devices act as one virtual screen diff --git a/Xext/saver.c b/Xext/saver.c index dff1f14fe..f2c2fdf01 100644 --- a/Xext/saver.c +++ b/Xext/saver.c @@ -1,4 +1,4 @@ -/* $XdotOrg: xserver/xorg/Xext/saver.c,v 1.10 2005/07/03 08:53:36 daniels Exp $ */ +/* $XdotOrg: xserver/xorg/Xext/saver.c,v 1.11 2006/02/10 22:00:20 anholt Exp $ */ /* * $XConsortium: saver.c,v 1.12 94/04/17 20:59:36 dpw Exp $ * @@ -55,7 +55,10 @@ in this Software without prior written authorization from the X Consortium. #include "panoramiX.h" #include "panoramiXsrv.h" #endif - +#ifdef DPMSExtension +#define DPMS_SERVER +#include <X11/extensions/dpms.h> +#endif #include <stdio.h> @@ -72,12 +75,14 @@ static DISPATCH_PROC(ProcScreenSaverQueryVersion); static DISPATCH_PROC(ProcScreenSaverSelectInput); static DISPATCH_PROC(ProcScreenSaverSetAttributes); static DISPATCH_PROC(ProcScreenSaverUnsetAttributes); +static DISPATCH_PROC(ProcScreenSaverSuspend); static DISPATCH_PROC(SProcScreenSaverDispatch); static DISPATCH_PROC(SProcScreenSaverQueryInfo); static DISPATCH_PROC(SProcScreenSaverQueryVersion); static DISPATCH_PROC(SProcScreenSaverSelectInput); static DISPATCH_PROC(SProcScreenSaverSetAttributes); static DISPATCH_PROC(SProcScreenSaverUnsetAttributes); +static DISPATCH_PROC(SProcScreenSaverSuspend); static Bool ScreenSaverHandle ( ScreenPtr /* pScreen */, @@ -114,6 +119,34 @@ static void ScreenSaverResetProc ( ExtensionEntry * /* extEntry */ ); +static RESTYPE SuspendType; /* resource type for suspension records */ + +_X_EXPORT Bool screenSaverSuspended = FALSE; /* used in os/WaitFor.c */ + +typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; + +/* List of clients that are suspending the screensaver. */ +static ScreenSaverSuspensionPtr suspendingClients = NULL; + +/* + * clientResource is a resource ID that's added when the record is + * allocated, so the record is freed and the screensaver resumed when + * the client disconnects. count is the number of times the client has + * requested the screensaver be suspended. + */ +typedef struct _ScreenSaverSuspension +{ + ScreenSaverSuspensionPtr next; + ClientPtr pClient; + XID clientResource; + int count; +} ScreenSaverSuspensionRec; + +static int ScreenSaverFreeSuspend( + pointer /*value */, + XID /* id */ +); + /* * each screen has a list of clients requesting * ScreenSaverNotify events. Each client has a resource @@ -231,13 +264,15 @@ ScreenSaverExtensionInit(INITARGS) AttrType = CreateNewResourceType(ScreenSaverFreeAttr); EventType = CreateNewResourceType(ScreenSaverFreeEvents); + SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend); ScreenPrivateIndex = AllocateScreenPrivateIndex (); + for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; SetScreenPrivate (pScreen, NULL); } - if (AttrType && EventType && ScreenPrivateIndex != -1 && + if (AttrType && EventType && SuspendType && ScreenPrivateIndex != -1 && (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, ProcScreenSaverDispatch, SProcScreenSaverDispatch, ScreenSaverResetProc, StandardMinorOpcode))) @@ -431,6 +466,45 @@ ScreenSaverFreeAttr (value, id) return TRUE; } +static int +ScreenSaverFreeSuspend (pointer value, XID id) +{ + ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; + ScreenSaverSuspensionPtr *prev, this; + + /* Unlink and free the suspension record for the client */ + for (prev = &suspendingClients; (this = *prev); prev = &this->next) + { + if (this == data) + { + *prev = this->next; + xfree (this); + break; + } + } + + /* Reenable the screensaver if this was the last client suspending it. */ + if (screenSaverSuspended && suspendingClients == NULL) + { + screenSaverSuspended = FALSE; + + /* The screensaver could be active, since suspending it (by design) + doesn't prevent it from being forceably activated */ +#ifdef DPMSExtension + if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) +#else + if (screenIsSaved != SCREEN_SAVER_ON) +#endif + { + UpdateCurrentTimeIf(); + lastDeviceEventTime = currentTime; + SetScreenSaverTimer(); + } + } + + return Success; +} + static void SendScreenSaverNotify (pScreen, state, forced) ScreenPtr pScreen; @@ -1297,12 +1371,72 @@ ProcScreenSaverUnsetAttributes (ClientPtr client) return ScreenSaverUnsetAttributes(client); } +static int +ProcScreenSaverSuspend (ClientPtr client) +{ + ScreenSaverSuspensionPtr *prev, this; + + REQUEST(xScreenSaverSuspendReq); + REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); + + /* Check if this client is suspending the screensaver */ + for (prev = &suspendingClients; (this = *prev); prev = &this->next) + if (this->pClient == client) + break; + + if (this) + { + if (stuff->suspend == TRUE) + this->count++; + else if (--this->count == 0) + FreeResource (this->clientResource, RT_NONE); + + return Success; + } + + /* If we get to this point, this client isn't suspending the screensaver */ + if (stuff->suspend == FALSE) + return Success; + + /* + * Allocate a suspension record for the client, and stop the screensaver + * if it isn't already suspended by another client. We attach a resource ID + * to the record, so the screensaver will be reenabled and the record freed + * if the client disconnects without reenabling it first. + */ + this = (ScreenSaverSuspensionPtr) xalloc (sizeof (ScreenSaverSuspensionRec)); + + if (!this) + return BadAlloc; + + this->next = NULL; + this->pClient = client; + this->count = 1; + this->clientResource = FakeClientID (client->index); + + if (!AddResource (this->clientResource, SuspendType, (pointer) this)) + { + xfree (this); + return BadAlloc; + } + + *prev = this; + if (!screenSaverSuspended) + { + screenSaverSuspended = TRUE; + FreeScreenSaverTimer(); + } + + return (client->noClientException); +} + static DISPATCH_PROC((*NormalVector[])) = { ProcScreenSaverQueryVersion, ProcScreenSaverQueryInfo, ProcScreenSaverSelectInput, ProcScreenSaverSetAttributes, ProcScreenSaverUnsetAttributes, + ProcScreenSaverSuspend, }; #define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) @@ -1391,12 +1525,25 @@ SProcScreenSaverUnsetAttributes (client) return ProcScreenSaverUnsetAttributes (client); } +static int +SProcScreenSaverSuspend (ClientPtr client) +{ + int n; + REQUEST(xScreenSaverSuspendReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); + swapl(&stuff->suspend, n); + return ProcScreenSaverSuspend (client); +} + static DISPATCH_PROC((*SwappedVector[])) = { SProcScreenSaverQueryVersion, SProcScreenSaverQueryInfo, SProcScreenSaverSelectInput, SProcScreenSaverSetAttributes, SProcScreenSaverUnsetAttributes, + SProcScreenSaverSuspend, }; static int diff --git a/configure.ac b/configure.ac index 7eabf0271..ba35a70bf 100644 --- a/configure.ac +++ b/configure.ac @@ -492,7 +492,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la' XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' dnl Core modules for most extensions, et al. -REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto scrnsaverproto bigreqsproto resourceproto fontsproto inputproto xf86dgaproto" +REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto" REQUIRED_LIBS="xfont xau fontenc" AM_CONDITIONAL(XV, [test "x$XV" = xyes]) @@ -1029,7 +1029,7 @@ if test "x$XORG" = xyes -o "x$XGL" = xyes; then XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os' XORG_INCS="$XORG_DDXINCS $XORG_OSINCS" XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H" - XORG_LIBS="$MI_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $LBX_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB" + XORG_LIBS="$MI_LIB $FIXES_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $LBX_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB $XEXTXORG_LIB" AC_CHECK_LIB([dl], [dlopen], XORG_LIBS="$XORG_LIBS -ldl") diff --git a/os/WaitFor.c b/os/WaitFor.c index a2c2126e9..78101906f 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -669,6 +669,16 @@ FreeScreenSaverTimer(void) } } +#ifdef SCREENSAVER +/* + * When this variable is set a client has temporarily suspended the + * screensaver and DPMS, so SetScreenSaverTimer should be a noop. + * The screensaver extension is responsible for stopping and + * restarting the timer when suspension is enabled/disabled. + */ +extern Bool screenSaverSuspended; /* declared in Xext/saver.c */ +#endif /* SCREENSAVER */ + void SetScreenSaverTimer(void) { @@ -699,7 +709,11 @@ SetScreenSaverTimer(void) ScreenSaverTime; } +#ifdef SCREENSAVER + if (timeout && !screenSaverSuspended) { +#else if (timeout) { +#endif ScreenSaverTimer = TimerSet(ScreenSaverTimer, 0, timeout, ScreenSaverTimeoutExpire, NULL); } |