summaryrefslogtreecommitdiff
path: root/Xext/saver.c
diff options
context:
space:
mode:
authorFredrik Höglund <fredrik@kde.org>2006-03-31 18:49:38 +0000
committerFredrik Höglund <fredrik@kde.org>2006-03-31 18:49:38 +0000
commit7ea30b507f4ce5ce20fbfaca80f7d5b53a99eb1d (patch)
treebd9ab6c21ffb47e8e8d30598ac96a460fde26cf8 /Xext/saver.c
parentacca49b1a5a6c034f3b9d51d9016b8a7d43da809 (diff)
Move the screensaver extension from module to builtins.
Add the server side implementation of the ScreenSaverSuspend request. Require scrnsaverproto >= 1.1, and change the linking order of the Xorg static libs.
Diffstat (limited to 'Xext/saver.c')
-rw-r--r--Xext/saver.c153
1 files changed, 150 insertions, 3 deletions
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