3 Copyright (c) 1992 X Consortium
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
26 * Author: Keith Packard, MIT X Consortium
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
34 #include <X11/Xproto.h>
37 #include "windowstr.h"
38 #include "scrnintstr.h"
39 #include "pixmapstr.h"
40 #include "extnsionst.h"
41 #include "dixstruct.h"
44 #include <X11/extensions/saverproto.h>
46 #include "cursorstr.h"
47 #include "colormapst.h"
51 #include "panoramiX.h"
52 #include "panoramiXsrv.h"
55 #include <X11/extensions/dpmsconst.h>
57 #include "protocol-versions.h"
63 static int ScreenSaverEventBase = 0;
65 static Bool ScreenSaverHandle(ScreenPtr /* pScreen */ ,
71 CreateSaverWindow(ScreenPtr /* pScreen */
75 DestroySaverWindow(ScreenPtr /* pScreen */
79 UninstallSaverColormap(ScreenPtr /* pScreen */
83 CheckScreenPrivate(ScreenPtr /* pScreen */
86 static void SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * /* from */ ,
87 xScreenSaverNotifyEvent * /* to */
90 static RESTYPE SuspendType; /* resource type for suspension records */
92 typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr;
94 /* List of clients that are suspending the screensaver. */
95 static ScreenSaverSuspensionPtr suspendingClients = NULL;
98 * clientResource is a resource ID that's added when the record is
99 * allocated, so the record is freed and the screensaver resumed when
100 * the client disconnects. count is the number of times the client has
101 * requested the screensaver be suspended.
103 typedef struct _ScreenSaverSuspension {
104 ScreenSaverSuspensionPtr next;
108 } ScreenSaverSuspensionRec;
110 static int ScreenSaverFreeSuspend(pointer /*value */ ,
115 * each screen has a list of clients requesting
116 * ScreenSaverNotify events. Each client has a resource
117 * for each screen it selects ScreenSaverNotify input for,
118 * this resource is used to delete the ScreenSaverNotifyRec
119 * entry from the per-screen queue.
122 static RESTYPE SaverEventType; /* resource type for event masks */
124 typedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
126 typedef struct _ScreenSaverEvent {
127 ScreenSaverEventPtr next;
132 } ScreenSaverEventRec;
134 static int ScreenSaverFreeEvents(pointer /* value */ ,
138 static Bool setEventMask(ScreenPtr /* pScreen */ ,
139 ClientPtr /* client */ ,
140 unsigned long /* mask */
143 static unsigned long getEventMask(ScreenPtr /* pScreen */ ,
144 ClientPtr /* client */
148 * when a client sets the screen saver attributes, a resource is
149 * kept to be freed when the client exits
152 static RESTYPE AttrType; /* resource type for attributes */
154 typedef struct _ScreenSaverAttr {
159 unsigned short width, height, borderWidth;
164 PixmapPtr pBackgroundPixmap;
165 PixmapPtr pBorderPixmap;
167 unsigned long mask; /* no pixmaps or cursors */
168 unsigned long *values;
169 } ScreenSaverAttrRec, *ScreenSaverAttrPtr;
171 static int ScreenSaverFreeAttr(pointer /* value */ ,
175 static void FreeAttrs(ScreenSaverAttrPtr /* pAttr */
178 static void FreeScreenAttr(ScreenSaverAttrPtr /* pAttr */
182 SendScreenSaverNotify(ScreenPtr /* pScreen */ ,
187 typedef struct _ScreenSaverScreenPrivate {
188 ScreenSaverEventPtr events;
189 ScreenSaverAttrPtr attr;
191 Colormap installedMap;
192 } ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
194 static ScreenSaverScreenPrivatePtr MakeScreenPrivate(ScreenPtr /* pScreen */
197 static DevPrivateKeyRec ScreenPrivateKeyRec;
199 #define ScreenPrivateKey (&ScreenPrivateKeyRec)
201 #define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
202 dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
203 #define SetScreenPrivate(s,v) \
204 dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v);
205 #define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
207 #define New(t) (malloc(sizeof (t)))
210 CheckScreenPrivate(ScreenPtr pScreen)
212 SetupScreen(pScreen);
216 if (!pPriv->attr && !pPriv->events &&
217 !pPriv->hasWindow && pPriv->installedMap == None) {
219 SetScreenPrivate(pScreen, NULL);
220 pScreen->screensaver.ExternalScreenSaver = NULL;
224 static ScreenSaverScreenPrivatePtr
225 MakeScreenPrivate(ScreenPtr pScreen)
227 SetupScreen(pScreen);
231 pPriv = New(ScreenSaverScreenPrivateRec);
236 pPriv->hasWindow = FALSE;
237 pPriv->installedMap = None;
238 SetScreenPrivate(pScreen, pPriv);
239 pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle;
244 getEventMask(ScreenPtr pScreen, ClientPtr client)
246 SetupScreen(pScreen);
247 ScreenSaverEventPtr pEv;
251 for (pEv = pPriv->events; pEv; pEv = pEv->next)
252 if (pEv->client == client)
258 setEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask)
260 SetupScreen(pScreen);
261 ScreenSaverEventPtr pEv, *pPrev;
263 if (getEventMask(pScreen, client) == mask)
266 pPriv = MakeScreenPrivate(pScreen);
270 for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
271 if (pEv->client == client)
274 FreeResource(pEv->resource, SaverEventType);
277 CheckScreenPrivate(pScreen);
281 pEv = New(ScreenSaverEventRec);
283 CheckScreenPrivate(pScreen);
288 pEv->client = client;
289 pEv->screen = pScreen;
290 pEv->resource = FakeClientID(client->index);
291 if (!AddResource(pEv->resource, SaverEventType, (pointer) pEv))
300 FreeAttrs(ScreenSaverAttrPtr pAttr)
305 if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
306 (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
307 if ((pPixmap = pAttr->pBorderPixmap) != 0)
308 (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
309 if ((pCursor = pAttr->pCursor) != 0)
310 FreeCursor(pCursor, (Cursor) 0);
314 FreeScreenAttr(ScreenSaverAttrPtr pAttr)
322 ScreenSaverFreeEvents(pointer value, XID id)
324 ScreenSaverEventPtr pOld = (ScreenSaverEventPtr) value;
325 ScreenPtr pScreen = pOld->screen;
327 SetupScreen(pScreen);
328 ScreenSaverEventPtr pEv, *pPrev;
332 for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
339 CheckScreenPrivate(pScreen);
344 ScreenSaverFreeAttr(pointer value, XID id)
346 ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr) value;
347 ScreenPtr pScreen = pOldAttr->screen;
349 SetupScreen(pScreen);
353 if (pPriv->attr != pOldAttr)
355 FreeScreenAttr(pOldAttr);
357 if (pPriv->hasWindow) {
358 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
359 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
361 CheckScreenPrivate(pScreen);
366 ScreenSaverFreeSuspend(pointer value, XID id)
368 ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
369 ScreenSaverSuspensionPtr *prev, this;
371 /* Unlink and free the suspension record for the client */
372 for (prev = &suspendingClients; (this = *prev); prev = &this->next) {
380 /* Reenable the screensaver if this was the last client suspending it. */
381 if (screenSaverSuspended && suspendingClients == NULL) {
382 screenSaverSuspended = FALSE;
384 /* The screensaver could be active, since suspending it (by design)
385 doesn't prevent it from being forceably activated */
387 if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn)
389 if (screenIsSaved != SCREEN_SAVER_ON)
393 UpdateCurrentTimeIf();
394 nt_list_for_each_entry(dev, inputInfo.devices, next)
395 lastDeviceEventTime[dev->id] = currentTime;
396 SetScreenSaverTimer();
404 SendScreenSaverNotify(ScreenPtr pScreen, int state, Bool forced)
406 ScreenSaverScreenPrivatePtr pPriv;
407 ScreenSaverEventPtr pEv;
411 UpdateCurrentTimeIf();
412 mask = ScreenSaverNotifyMask;
413 if (state == ScreenSaverCycle)
414 mask = ScreenSaverCycleMask;
415 pScreen = screenInfo.screens[pScreen->myNum];
416 pPriv = GetScreenPrivate(pScreen);
420 kind = ScreenSaverExternal;
421 else if (ScreenSaverBlanking != DontPreferBlanking)
422 kind = ScreenSaverBlanked;
424 kind = ScreenSaverInternal;
425 for (pEv = pPriv->events; pEv; pEv = pEv->next) {
426 if (pEv->mask & mask) {
427 xScreenSaverNotifyEvent ev = {
428 .type = ScreenSaverNotify + ScreenSaverEventBase,
430 .timestamp = currentTime.milliseconds,
431 .root = pScreen->root->drawable.id,
432 .window = pScreen->screensaver.wid,
436 WriteEventsToClient(pEv->client, 1, (xEvent *) &ev);
442 SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * from,
443 xScreenSaverNotifyEvent * to)
445 to->type = from->type;
446 to->state = from->state;
447 cpswaps(from->sequenceNumber, to->sequenceNumber);
448 cpswapl(from->timestamp, to->timestamp);
449 cpswapl(from->root, to->root);
450 cpswapl(from->window, to->window);
451 to->kind = from->kind;
452 to->forced = from->forced;
456 UninstallSaverColormap(ScreenPtr pScreen)
458 SetupScreen(pScreen);
462 if (pPriv && pPriv->installedMap != None) {
463 rc = dixLookupResourceByType((pointer *) &pCmap, pPriv->installedMap,
464 RT_COLORMAP, serverClient,
467 (*pCmap->pScreen->UninstallColormap) (pCmap);
468 pPriv->installedMap = None;
469 CheckScreenPrivate(pScreen);
474 CreateSaverWindow(ScreenPtr pScreen)
476 SetupScreen(pScreen);
477 ScreenSaverStuffPtr pSaver;
478 ScreenSaverAttrPtr pAttr;
482 Colormap *installedMaps;
488 pSaver = &pScreen->screensaver;
489 if (pSaver->pWindow) {
490 pSaver->pWindow = NullWindow;
491 FreeResource(pSaver->wid, RT_NONE);
493 UninstallSaverColormap(pScreen);
494 pPriv->hasWindow = FALSE;
495 CheckScreenPrivate(pScreen);
499 if (!pPriv || !(pAttr = pPriv->attr))
502 pPriv->installedMap = None;
504 if (GrabInProgress && GrabInProgress != pAttr->client->index)
507 pWin = CreateWindow(pSaver->wid, pScreen->root,
508 pAttr->x, pAttr->y, pAttr->width, pAttr->height,
509 pAttr->borderWidth, pAttr->class,
510 pAttr->mask, (XID *) pAttr->values,
511 pAttr->depth, serverClient, pAttr->visual, &result);
515 if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
519 if (pAttr->pBackgroundPixmap) {
520 pWin->backgroundState = BackgroundPixmap;
521 pWin->background.pixmap = pAttr->pBackgroundPixmap;
522 pAttr->pBackgroundPixmap->refcnt++;
523 mask |= CWBackPixmap;
525 if (pAttr->pBorderPixmap) {
526 pWin->borderIsPixel = FALSE;
527 pWin->border.pixmap = pAttr->pBorderPixmap;
528 pAttr->pBorderPixmap->refcnt++;
529 mask |= CWBorderPixmap;
531 if (pAttr->pCursor) {
533 if (!MakeWindowOptional(pWin)) {
534 FreeResource(pWin->drawable.id, RT_NONE);
537 pAttr->pCursor->refcnt++;
538 if (pWin->optional->cursor)
539 FreeCursor(pWin->optional->cursor, (Cursor) 0);
540 pWin->optional->cursor = pAttr->pCursor;
541 pWin->cursorIsNone = FALSE;
542 CheckWindowOptionalNeed(pWin);
546 (*pScreen->ChangeWindowAttributes) (pWin, mask);
548 if (pAttr->colormap != None)
549 (void) ChangeWindowAttributes(pWin, CWColormap, &pAttr->colormap,
552 MapWindow(pWin, serverClient);
554 pPriv->hasWindow = TRUE;
555 pSaver->pWindow = pWin;
557 /* check and install our own colormap if it isn't installed now */
558 wantMap = wColormap(pWin);
561 installedMaps = malloc(pScreen->maxInstalledCmaps * sizeof(Colormap));
562 numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps)
563 (pScreen, installedMaps);
564 for (i = 0; i < numInstalled; i++)
565 if (installedMaps[i] == wantMap)
568 free((char *) installedMaps);
570 if (i < numInstalled)
573 result = dixLookupResourceByType((pointer *) &pCmap, wantMap, RT_COLORMAP,
574 serverClient, DixInstallAccess);
575 if (result != Success)
578 pPriv->installedMap = wantMap;
580 (*pCmap->pScreen->InstallColormap) (pCmap);
586 DestroySaverWindow(ScreenPtr pScreen)
588 SetupScreen(pScreen);
589 ScreenSaverStuffPtr pSaver;
591 if (!pPriv || !pPriv->hasWindow)
594 pSaver = &pScreen->screensaver;
595 if (pSaver->pWindow) {
596 pSaver->pWindow = NullWindow;
597 FreeResource(pSaver->wid, RT_NONE);
599 pPriv->hasWindow = FALSE;
600 CheckScreenPrivate(pScreen);
601 UninstallSaverColormap(pScreen);
606 ScreenSaverHandle(ScreenPtr pScreen, int xstate, Bool force)
610 ScreenSaverScreenPrivatePtr pPriv;
613 case SCREEN_SAVER_ON:
614 state = ScreenSaverOn;
615 ret = CreateSaverWindow(pScreen);
617 case SCREEN_SAVER_OFF:
618 state = ScreenSaverOff;
619 ret = DestroySaverWindow(pScreen);
621 case SCREEN_SAVER_CYCLE:
622 state = ScreenSaverCycle;
623 pPriv = GetScreenPrivate(pScreen);
624 if (pPriv && pPriv->hasWindow)
629 if (noPanoramiXExtension || !pScreen->myNum)
631 SendScreenSaverNotify(pScreen, state, force);
636 ProcScreenSaverQueryVersion(ClientPtr client)
638 xScreenSaverQueryVersionReply rep = {
640 .sequenceNumber = client->sequence,
642 .majorVersion = SERVER_SAVER_MAJOR_VERSION,
643 .minorVersion = SERVER_SAVER_MINOR_VERSION
646 REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
648 if (client->swapped) {
649 swaps(&rep.sequenceNumber);
652 WriteToClient(client, sizeof(xScreenSaverQueryVersionReply), &rep);
657 ProcScreenSaverQueryInfo(ClientPtr client)
659 REQUEST(xScreenSaverQueryInfoReq);
660 xScreenSaverQueryInfoReply rep;
662 ScreenSaverStuffPtr pSaver;
665 ScreenSaverScreenPrivatePtr pPriv;
667 REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
668 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
672 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
677 pSaver = &pDraw->pScreen->screensaver;
678 pPriv = GetScreenPrivate(pDraw->pScreen);
681 lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
683 rep = (xScreenSaverQueryInfoReply) {
685 .sequenceNumber = client->sequence,
687 .window = pSaver->wid
689 if (screenIsSaved != SCREEN_SAVER_OFF) {
690 rep.state = ScreenSaverOn;
692 rep.tilOrSince = lastInput - ScreenSaverTime;
697 if (ScreenSaverTime) {
698 rep.state = ScreenSaverOff;
699 if (ScreenSaverTime < lastInput)
702 rep.tilOrSince = ScreenSaverTime - lastInput;
705 rep.state = ScreenSaverDisabled;
709 rep.idle = lastInput;
710 rep.eventMask = getEventMask(pDraw->pScreen, client);
711 if (pPriv && pPriv->attr)
712 rep.kind = ScreenSaverExternal;
713 else if (ScreenSaverBlanking != DontPreferBlanking)
714 rep.kind = ScreenSaverBlanked;
716 rep.kind = ScreenSaverInternal;
717 if (client->swapped) {
718 swaps(&rep.sequenceNumber);
721 swapl(&rep.tilOrSince);
723 swapl(&rep.eventMask);
725 WriteToClient(client, sizeof(xScreenSaverQueryInfoReply), &rep);
730 ProcScreenSaverSelectInput(ClientPtr client)
732 REQUEST(xScreenSaverSelectInputReq);
736 REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
737 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
742 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
747 if (!setEventMask(pDraw->pScreen, client, stuff->eventMask))
753 ScreenSaverSetAttributes(ClientPtr client)
755 REQUEST(xScreenSaverSetAttributesReq);
759 ScreenSaverScreenPrivatePtr pPriv = 0;
760 ScreenSaverAttrPtr pAttr = 0;
761 int ret, len, class, bw, depth;
762 unsigned long visual;
766 WindowOptPtr ancwopt;
767 unsigned int *pVlist;
768 unsigned long *values = 0;
769 unsigned long tmask, imask;
778 REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
779 ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
783 pScreen = pDraw->pScreen;
784 pParent = pScreen->root;
786 ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess);
790 len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
791 if (Ones(stuff->mask) != len)
793 if (!stuff->width || !stuff->height) {
794 client->errorValue = 0;
797 switch (class = stuff->c_class) {
803 client->errorValue = class;
806 bw = stuff->borderWidth;
807 depth = stuff->depth;
808 visual = stuff->visualID;
810 /* copied directly from CreateWindow */
812 if (class == CopyFromParent)
813 class = pParent->drawable.class;
815 if ((class != InputOutput) && (class != InputOnly)) {
816 client->errorValue = class;
820 if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
823 if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
826 if ((class == InputOutput) && (depth == 0))
827 depth = pParent->drawable.depth;
828 ancwopt = pParent->optional;
830 ancwopt = FindWindowWithOptional(pParent)->optional;
831 if (visual == CopyFromParent)
832 visual = ancwopt->visual;
834 /* Find out if the depth and visual are acceptable for this Screen */
835 if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
837 for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
838 pDepth = (DepthPtr) & pScreen->allowedDepths[idepth];
839 if ((depth == pDepth->depth) || (depth == 0)) {
840 for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
841 if (visual == pDepth->vids[ivisual]) {
852 if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
853 (class != InputOnly) && (depth != pParent->drawable.depth)) {
857 if (((stuff->mask & CWColormap) == 0) &&
858 (class != InputOnly) &&
859 ((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
863 /* end of errors from CreateWindow */
865 pPriv = GetScreenPrivate(pScreen);
866 if (pPriv && pPriv->attr) {
867 if (pPriv->attr->client != client)
871 pPriv = MakeScreenPrivate(pScreen);
875 pAttr = New(ScreenSaverAttrRec);
880 /* over allocate for override redirect */
881 pAttr->values = values = malloc((len + 1) * sizeof(unsigned long));
886 pAttr->screen = pScreen;
887 pAttr->client = client;
890 pAttr->width = stuff->width;
891 pAttr->height = stuff->height;
892 pAttr->borderWidth = stuff->borderWidth;
893 pAttr->class = stuff->c_class;
894 pAttr->depth = depth;
895 pAttr->visual = visual;
896 pAttr->colormap = None;
897 pAttr->pCursor = NullCursor;
898 pAttr->pBackgroundPixmap = NullPixmap;
899 pAttr->pBorderPixmap = NullPixmap;
901 * go through the mask, checking the values,
902 * looking up pixmaps and cursors and hold a reference
905 pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
906 pVlist = (unsigned int *) (stuff + 1);
908 imask = lowbit(tmask);
912 pixID = (Pixmap) * pVlist;
916 else if (pixID == ParentRelative) {
917 if (depth != pParent->drawable.depth) {
921 *values++ = ParentRelative;
925 dixLookupResourceByType((pointer *) &pPixmap, pixID,
926 RT_PIXMAP, client, DixReadAccess);
927 if (ret == Success) {
928 if ((pPixmap->drawable.depth != depth) ||
929 (pPixmap->drawable.pScreen != pScreen)) {
933 pAttr->pBackgroundPixmap = pPixmap;
935 pAttr->mask &= ~CWBackPixmap;
938 client->errorValue = pixID;
944 *values++ = (CARD32) *pVlist;
947 pixID = (Pixmap) * pVlist;
948 if (pixID == CopyFromParent) {
949 if (depth != pParent->drawable.depth) {
953 *values++ = CopyFromParent;
957 dixLookupResourceByType((pointer *) &pPixmap, pixID,
958 RT_PIXMAP, client, DixReadAccess);
959 if (ret == Success) {
960 if ((pPixmap->drawable.depth != depth) ||
961 (pPixmap->drawable.pScreen != pScreen)) {
965 pAttr->pBorderPixmap = pPixmap;
967 pAttr->mask &= ~CWBorderPixmap;
970 client->errorValue = pixID;
976 *values++ = (CARD32) *pVlist;
979 val = (CARD8) *pVlist;
980 if (val > StaticGravity) {
982 client->errorValue = val;
988 val = (CARD8) *pVlist;
989 if (val > StaticGravity) {
991 client->errorValue = val;
997 val = (CARD8) *pVlist;
998 if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
1000 client->errorValue = val;
1005 case CWBackingPlanes:
1006 *values++ = (CARD32) *pVlist;
1008 case CWBackingPixel:
1009 *values++ = (CARD32) *pVlist;
1012 val = (BOOL) * pVlist;
1013 if ((val != xTrue) && (val != xFalse)) {
1015 client->errorValue = val;
1021 *values++ = (CARD32) *pVlist;
1023 case CWDontPropagate:
1024 *values++ = (CARD32) *pVlist;
1026 case CWOverrideRedirect:
1027 if (!(stuff->mask & CWOverrideRedirect))
1030 val = (BOOL) * pVlist;
1031 if ((val != xTrue) && (val != xFalse)) {
1033 client->errorValue = val;
1040 cmap = (Colormap) * pVlist;
1041 ret = dixLookupResourceByType((pointer *) &pCmap, cmap, RT_COLORMAP,
1042 client, DixUseAccess);
1043 if (ret != Success) {
1044 client->errorValue = cmap;
1047 if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) {
1051 pAttr->colormap = cmap;
1052 pAttr->mask &= ~CWColormap;
1055 cursorID = (Cursor) * pVlist;
1056 if (cursorID == None) {
1060 ret = dixLookupResourceByType((pointer *) &pCursor, cursorID,
1061 RT_CURSOR, client, DixUseAccess);
1062 if (ret != Success) {
1063 client->errorValue = cursorID;
1067 pAttr->pCursor = pCursor;
1068 pAttr->mask &= ~CWCursor;
1073 client->errorValue = stuff->mask;
1079 FreeScreenAttr(pPriv->attr);
1080 pPriv->attr = pAttr;
1081 pAttr->resource = FakeClientID(client->index);
1082 if (!AddResource(pAttr->resource, AttrType, (pointer) pAttr))
1088 CheckScreenPrivate(pScreen);
1090 free(pAttr->values);
1096 ScreenSaverUnsetAttributes(ClientPtr client)
1098 REQUEST(xScreenSaverSetAttributesReq);
1100 ScreenSaverScreenPrivatePtr pPriv;
1103 REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
1104 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
1108 pPriv = GetScreenPrivate(pDraw->pScreen);
1109 if (pPriv && pPriv->attr && pPriv->attr->client == client) {
1110 FreeResource(pPriv->attr->resource, AttrType);
1111 FreeScreenAttr(pPriv->attr);
1113 CheckScreenPrivate(pDraw->pScreen);
1119 ProcScreenSaverSetAttributes(ClientPtr client)
1122 if (!noPanoramiXExtension) {
1123 REQUEST(xScreenSaverSetAttributesReq);
1125 PanoramiXRes *backPix = NULL;
1126 PanoramiXRes *bordPix = NULL;
1127 PanoramiXRes *cmap = NULL;
1129 int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
1130 XID orig_visual, tmp;
1132 REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
1134 status = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1135 XRC_DRAWABLE, client, DixWriteAccess);
1136 if (status != Success)
1137 return (status == BadValue) ? BadDrawable : status;
1141 bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
1142 if (Ones(stuff->mask) != len)
1145 if ((Mask) stuff->mask & CWBackPixmap) {
1146 pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1));
1147 tmp = *((CARD32 *) &stuff[1] + pback_offset);
1148 if ((tmp != None) && (tmp != ParentRelative)) {
1149 status = dixLookupResourceByType((pointer *) &backPix, tmp,
1152 if (status != Success)
1157 if ((Mask) stuff->mask & CWBorderPixmap) {
1158 pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1));
1159 tmp = *((CARD32 *) &stuff[1] + pbord_offset);
1160 if (tmp != CopyFromParent) {
1161 status = dixLookupResourceByType((pointer *) &bordPix, tmp,
1164 if (status != Success)
1169 if ((Mask) stuff->mask & CWColormap) {
1170 cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
1171 tmp = *((CARD32 *) &stuff[1] + cmap_offset);
1172 if ((tmp != CopyFromParent) && (tmp != None)) {
1173 status = dixLookupResourceByType((pointer *) &cmap, tmp,
1174 XRT_COLORMAP, client,
1176 if (status != Success)
1181 orig_visual = stuff->visualID;
1183 FOR_NSCREENS_BACKWARD(i) {
1184 stuff->drawable = draw->info[i].id;
1186 *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
1188 *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
1190 *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
1192 if (orig_visual != CopyFromParent)
1193 stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual);
1195 status = ScreenSaverSetAttributes(client);
1202 return ScreenSaverSetAttributes(client);
1206 ProcScreenSaverUnsetAttributes(ClientPtr client)
1209 if (!noPanoramiXExtension) {
1210 REQUEST(xScreenSaverUnsetAttributesReq);
1214 rc = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1215 XRC_DRAWABLE, client, DixWriteAccess);
1217 return (rc == BadValue) ? BadDrawable : rc;
1219 for (i = PanoramiXNumScreens - 1; i > 0; i--) {
1220 stuff->drawable = draw->info[i].id;
1221 ScreenSaverUnsetAttributes(client);
1224 stuff->drawable = draw->info[0].id;
1228 return ScreenSaverUnsetAttributes(client);
1232 ProcScreenSaverSuspend(ClientPtr client)
1234 ScreenSaverSuspensionPtr *prev, this;
1236 REQUEST(xScreenSaverSuspendReq);
1237 REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
1239 /* Check if this client is suspending the screensaver */
1240 for (prev = &suspendingClients; (this = *prev); prev = &this->next)
1241 if (this->pClient == client)
1245 if (stuff->suspend == TRUE)
1247 else if (--this->count == 0)
1248 FreeResource(this->clientResource, RT_NONE);
1253 /* If we get to this point, this client isn't suspending the screensaver */
1254 if (stuff->suspend == FALSE)
1258 * Allocate a suspension record for the client, and stop the screensaver
1259 * if it isn't already suspended by another client. We attach a resource ID
1260 * to the record, so the screensaver will be reenabled and the record freed
1261 * if the client disconnects without reenabling it first.
1263 this = malloc(sizeof(ScreenSaverSuspensionRec));
1269 this->pClient = client;
1271 this->clientResource = FakeClientID(client->index);
1273 if (!AddResource(this->clientResource, SuspendType, (pointer) this)) {
1279 if (!screenSaverSuspended) {
1280 screenSaverSuspended = TRUE;
1281 FreeScreenSaverTimer();
1287 static int (*NormalVector[]) (ClientPtr /* client */ ) = {
1288 ProcScreenSaverQueryVersion,
1289 ProcScreenSaverQueryInfo,
1290 ProcScreenSaverSelectInput,
1291 ProcScreenSaverSetAttributes,
1292 ProcScreenSaverUnsetAttributes, ProcScreenSaverSuspend,};
1294 #define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0]))
1297 ProcScreenSaverDispatch(ClientPtr client)
1301 if (stuff->data < NUM_REQUESTS)
1302 return (*NormalVector[stuff->data]) (client);
1307 SProcScreenSaverQueryVersion(ClientPtr client)
1309 REQUEST(xScreenSaverQueryVersionReq);
1310 swaps(&stuff->length);
1311 REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
1312 return ProcScreenSaverQueryVersion(client);
1316 SProcScreenSaverQueryInfo(ClientPtr client)
1318 REQUEST(xScreenSaverQueryInfoReq);
1319 swaps(&stuff->length);
1320 REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
1321 swapl(&stuff->drawable);
1322 return ProcScreenSaverQueryInfo(client);
1326 SProcScreenSaverSelectInput(ClientPtr client)
1328 REQUEST(xScreenSaverSelectInputReq);
1329 swaps(&stuff->length);
1330 REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
1331 swapl(&stuff->drawable);
1332 swapl(&stuff->eventMask);
1333 return ProcScreenSaverSelectInput(client);
1337 SProcScreenSaverSetAttributes(ClientPtr client)
1339 REQUEST(xScreenSaverSetAttributesReq);
1340 swaps(&stuff->length);
1341 REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
1342 swapl(&stuff->drawable);
1345 swaps(&stuff->width);
1346 swaps(&stuff->height);
1347 swaps(&stuff->borderWidth);
1348 swapl(&stuff->visualID);
1349 swapl(&stuff->mask);
1351 return ProcScreenSaverSetAttributes(client);
1355 SProcScreenSaverUnsetAttributes(ClientPtr client)
1357 REQUEST(xScreenSaverUnsetAttributesReq);
1358 swaps(&stuff->length);
1359 REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
1360 swapl(&stuff->drawable);
1361 return ProcScreenSaverUnsetAttributes(client);
1365 SProcScreenSaverSuspend(ClientPtr client)
1367 REQUEST(xScreenSaverSuspendReq);
1369 swaps(&stuff->length);
1370 REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
1371 return ProcScreenSaverSuspend(client);
1374 static int (*SwappedVector[]) (ClientPtr /* client */ ) = {
1375 SProcScreenSaverQueryVersion,
1376 SProcScreenSaverQueryInfo,
1377 SProcScreenSaverSelectInput,
1378 SProcScreenSaverSetAttributes,
1379 SProcScreenSaverUnsetAttributes, SProcScreenSaverSuspend,};
1382 SProcScreenSaverDispatch(ClientPtr client)
1386 if (stuff->data < NUM_REQUESTS)
1387 return (*SwappedVector[stuff->data]) (client);
1392 ScreenSaverExtensionInit(void)
1394 ExtensionEntry *extEntry;
1398 if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
1401 AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr");
1402 SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, "SaverEvent");
1403 SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, "SaverSuspend");
1405 for (i = 0; i < screenInfo.numScreens; i++) {
1406 pScreen = screenInfo.screens[i];
1407 SetScreenPrivate(pScreen, NULL);
1409 if (AttrType && SaverEventType && SuspendType &&
1410 (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
1411 ProcScreenSaverDispatch,
1412 SProcScreenSaverDispatch, NULL,
1413 StandardMinorOpcode))) {
1414 ScreenSaverEventBase = extEntry->eventBase;
1415 EventSwapVector[ScreenSaverEventBase] =
1416 (EventSwapPtr) SScreenSaverNotifyEvent;