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 NoticeTime(dev
, 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
) {
534 if (!MakeWindowOptional(pWin
)) {
535 FreeResource(pWin
->drawable
.id
, RT_NONE
);
538 cursor
= RefCursor(pAttr
->pCursor
);
539 if (pWin
->optional
->cursor
)
540 FreeCursor(pWin
->optional
->cursor
, (Cursor
) 0);
541 pWin
->optional
->cursor
= cursor
;
542 pWin
->cursorIsNone
= FALSE
;
543 CheckWindowOptionalNeed(pWin
);
547 (*pScreen
->ChangeWindowAttributes
) (pWin
, mask
);
549 if (pAttr
->colormap
!= None
)
550 (void) ChangeWindowAttributes(pWin
, CWColormap
, &pAttr
->colormap
,
553 MapWindow(pWin
, serverClient
);
555 pPriv
->hasWindow
= TRUE
;
556 pSaver
->pWindow
= pWin
;
558 /* check and install our own colormap if it isn't installed now */
559 wantMap
= wColormap(pWin
);
562 installedMaps
= malloc(pScreen
->maxInstalledCmaps
* sizeof(Colormap
));
563 numInstalled
= (*pWin
->drawable
.pScreen
->ListInstalledColormaps
)
564 (pScreen
, installedMaps
);
565 for (i
= 0; i
< numInstalled
; i
++)
566 if (installedMaps
[i
] == wantMap
)
569 free((char *) installedMaps
);
571 if (i
< numInstalled
)
574 result
= dixLookupResourceByType((pointer
*) &pCmap
, wantMap
, RT_COLORMAP
,
575 serverClient
, DixInstallAccess
);
576 if (result
!= Success
)
579 pPriv
->installedMap
= wantMap
;
581 (*pCmap
->pScreen
->InstallColormap
) (pCmap
);
587 DestroySaverWindow(ScreenPtr pScreen
)
589 SetupScreen(pScreen
);
590 ScreenSaverStuffPtr pSaver
;
592 if (!pPriv
|| !pPriv
->hasWindow
)
595 pSaver
= &pScreen
->screensaver
;
596 if (pSaver
->pWindow
) {
597 pSaver
->pWindow
= NullWindow
;
598 FreeResource(pSaver
->wid
, RT_NONE
);
600 pPriv
->hasWindow
= FALSE
;
601 CheckScreenPrivate(pScreen
);
602 UninstallSaverColormap(pScreen
);
607 ScreenSaverHandle(ScreenPtr pScreen
, int xstate
, Bool force
)
611 ScreenSaverScreenPrivatePtr pPriv
;
614 case SCREEN_SAVER_ON
:
615 state
= ScreenSaverOn
;
616 ret
= CreateSaverWindow(pScreen
);
618 case SCREEN_SAVER_OFF
:
619 state
= ScreenSaverOff
;
620 ret
= DestroySaverWindow(pScreen
);
622 case SCREEN_SAVER_CYCLE
:
623 state
= ScreenSaverCycle
;
624 pPriv
= GetScreenPrivate(pScreen
);
625 if (pPriv
&& pPriv
->hasWindow
)
630 if (noPanoramiXExtension
|| !pScreen
->myNum
)
632 SendScreenSaverNotify(pScreen
, state
, force
);
637 ProcScreenSaverQueryVersion(ClientPtr client
)
639 xScreenSaverQueryVersionReply rep
= {
641 .sequenceNumber
= client
->sequence
,
643 .majorVersion
= SERVER_SAVER_MAJOR_VERSION
,
644 .minorVersion
= SERVER_SAVER_MINOR_VERSION
647 REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq
);
649 if (client
->swapped
) {
650 swaps(&rep
.sequenceNumber
);
653 WriteToClient(client
, sizeof(xScreenSaverQueryVersionReply
), &rep
);
658 ProcScreenSaverQueryInfo(ClientPtr client
)
660 REQUEST(xScreenSaverQueryInfoReq
);
661 xScreenSaverQueryInfoReply rep
;
663 ScreenSaverStuffPtr pSaver
;
666 ScreenSaverScreenPrivatePtr pPriv
;
668 REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq
);
669 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0,
673 rc
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, pDraw
->pScreen
,
678 pSaver
= &pDraw
->pScreen
->screensaver
;
679 pPriv
= GetScreenPrivate(pDraw
->pScreen
);
682 lastInput
= GetTimeInMillis() - LastEventTime(XIAllDevices
).milliseconds
;
684 rep
= (xScreenSaverQueryInfoReply
) {
686 .sequenceNumber
= client
->sequence
,
688 .window
= pSaver
->wid
690 if (screenIsSaved
!= SCREEN_SAVER_OFF
) {
691 rep
.state
= ScreenSaverOn
;
693 rep
.tilOrSince
= lastInput
- ScreenSaverTime
;
698 if (ScreenSaverTime
) {
699 rep
.state
= ScreenSaverOff
;
700 if (ScreenSaverTime
< lastInput
)
703 rep
.tilOrSince
= ScreenSaverTime
- lastInput
;
706 rep
.state
= ScreenSaverDisabled
;
710 rep
.idle
= lastInput
;
711 rep
.eventMask
= getEventMask(pDraw
->pScreen
, client
);
712 if (pPriv
&& pPriv
->attr
)
713 rep
.kind
= ScreenSaverExternal
;
714 else if (ScreenSaverBlanking
!= DontPreferBlanking
)
715 rep
.kind
= ScreenSaverBlanked
;
717 rep
.kind
= ScreenSaverInternal
;
718 if (client
->swapped
) {
719 swaps(&rep
.sequenceNumber
);
722 swapl(&rep
.tilOrSince
);
724 swapl(&rep
.eventMask
);
726 WriteToClient(client
, sizeof(xScreenSaverQueryInfoReply
), &rep
);
731 ProcScreenSaverSelectInput(ClientPtr client
)
733 REQUEST(xScreenSaverSelectInputReq
);
737 REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq
);
738 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0,
743 rc
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, pDraw
->pScreen
,
748 if (!setEventMask(pDraw
->pScreen
, client
, stuff
->eventMask
))
754 ScreenSaverSetAttributes(ClientPtr client
)
756 REQUEST(xScreenSaverSetAttributesReq
);
760 ScreenSaverScreenPrivatePtr pPriv
= 0;
761 ScreenSaverAttrPtr pAttr
= 0;
762 int ret
, len
, class, bw
, depth
;
763 unsigned long visual
;
767 WindowOptPtr ancwopt
;
768 unsigned int *pVlist
;
769 unsigned long *values
= 0;
770 unsigned long tmask
, imask
;
779 REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq
);
780 ret
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0,
784 pScreen
= pDraw
->pScreen
;
785 pParent
= pScreen
->root
;
787 ret
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, pScreen
, DixSetAttrAccess
);
791 len
= stuff
->length
- bytes_to_int32(sizeof(xScreenSaverSetAttributesReq
));
792 if (Ones(stuff
->mask
) != len
)
794 if (!stuff
->width
|| !stuff
->height
) {
795 client
->errorValue
= 0;
798 switch (class = stuff
->c_class
) {
804 client
->errorValue
= class;
807 bw
= stuff
->borderWidth
;
808 depth
= stuff
->depth
;
809 visual
= stuff
->visualID
;
811 /* copied directly from CreateWindow */
813 if (class == CopyFromParent
)
814 class = pParent
->drawable
.class;
816 if ((class != InputOutput
) && (class != InputOnly
)) {
817 client
->errorValue
= class;
821 if ((class != InputOnly
) && (pParent
->drawable
.class == InputOnly
))
824 if ((class == InputOnly
) && ((bw
!= 0) || (depth
!= 0)))
827 if ((class == InputOutput
) && (depth
== 0))
828 depth
= pParent
->drawable
.depth
;
829 ancwopt
= pParent
->optional
;
831 ancwopt
= FindWindowWithOptional(pParent
)->optional
;
832 if (visual
== CopyFromParent
)
833 visual
= ancwopt
->visual
;
835 /* Find out if the depth and visual are acceptable for this Screen */
836 if ((visual
!= ancwopt
->visual
) || (depth
!= pParent
->drawable
.depth
)) {
838 for (idepth
= 0; idepth
< pScreen
->numDepths
; idepth
++) {
839 pDepth
= (DepthPtr
) &pScreen
->allowedDepths
[idepth
];
840 if ((depth
== pDepth
->depth
) || (depth
== 0)) {
841 for (ivisual
= 0; ivisual
< pDepth
->numVids
; ivisual
++) {
842 if (visual
== pDepth
->vids
[ivisual
]) {
853 if (((stuff
->mask
& (CWBorderPixmap
| CWBorderPixel
)) == 0) &&
854 (class != InputOnly
) && (depth
!= pParent
->drawable
.depth
)) {
858 if (((stuff
->mask
& CWColormap
) == 0) &&
859 (class != InputOnly
) &&
860 ((visual
!= ancwopt
->visual
) || (ancwopt
->colormap
== None
))) {
864 /* end of errors from CreateWindow */
866 pPriv
= GetScreenPrivate(pScreen
);
867 if (pPriv
&& pPriv
->attr
) {
868 if (pPriv
->attr
->client
!= client
)
872 pPriv
= MakeScreenPrivate(pScreen
);
876 pAttr
= New(ScreenSaverAttrRec
);
881 /* over allocate for override redirect */
882 pAttr
->values
= values
= malloc((len
+ 1) * sizeof(unsigned long));
887 pAttr
->screen
= pScreen
;
888 pAttr
->client
= client
;
891 pAttr
->width
= stuff
->width
;
892 pAttr
->height
= stuff
->height
;
893 pAttr
->borderWidth
= stuff
->borderWidth
;
894 pAttr
->class = stuff
->c_class
;
895 pAttr
->depth
= depth
;
896 pAttr
->visual
= visual
;
897 pAttr
->colormap
= None
;
898 pAttr
->pCursor
= NullCursor
;
899 pAttr
->pBackgroundPixmap
= NullPixmap
;
900 pAttr
->pBorderPixmap
= NullPixmap
;
902 * go through the mask, checking the values,
903 * looking up pixmaps and cursors and hold a reference
906 pAttr
->mask
= tmask
= stuff
->mask
| CWOverrideRedirect
;
907 pVlist
= (unsigned int *) (stuff
+ 1);
909 imask
= lowbit(tmask
);
913 pixID
= (Pixmap
) * pVlist
;
917 else if (pixID
== ParentRelative
) {
918 if (depth
!= pParent
->drawable
.depth
) {
922 *values
++ = ParentRelative
;
926 dixLookupResourceByType((pointer
*) &pPixmap
, pixID
,
927 RT_PIXMAP
, client
, DixReadAccess
);
928 if (ret
== Success
) {
929 if ((pPixmap
->drawable
.depth
!= depth
) ||
930 (pPixmap
->drawable
.pScreen
!= pScreen
)) {
934 pAttr
->pBackgroundPixmap
= pPixmap
;
936 pAttr
->mask
&= ~CWBackPixmap
;
939 client
->errorValue
= pixID
;
945 *values
++ = (CARD32
) *pVlist
;
948 pixID
= (Pixmap
) * pVlist
;
949 if (pixID
== CopyFromParent
) {
950 if (depth
!= pParent
->drawable
.depth
) {
954 *values
++ = CopyFromParent
;
958 dixLookupResourceByType((pointer
*) &pPixmap
, pixID
,
959 RT_PIXMAP
, client
, DixReadAccess
);
960 if (ret
== Success
) {
961 if ((pPixmap
->drawable
.depth
!= depth
) ||
962 (pPixmap
->drawable
.pScreen
!= pScreen
)) {
966 pAttr
->pBorderPixmap
= pPixmap
;
968 pAttr
->mask
&= ~CWBorderPixmap
;
971 client
->errorValue
= pixID
;
977 *values
++ = (CARD32
) *pVlist
;
980 val
= (CARD8
) *pVlist
;
981 if (val
> StaticGravity
) {
983 client
->errorValue
= val
;
989 val
= (CARD8
) *pVlist
;
990 if (val
> StaticGravity
) {
992 client
->errorValue
= val
;
998 val
= (CARD8
) *pVlist
;
999 if ((val
!= NotUseful
) && (val
!= WhenMapped
) && (val
!= Always
)) {
1001 client
->errorValue
= val
;
1006 case CWBackingPlanes
:
1007 *values
++ = (CARD32
) *pVlist
;
1009 case CWBackingPixel
:
1010 *values
++ = (CARD32
) *pVlist
;
1013 val
= (BOOL
) * pVlist
;
1014 if ((val
!= xTrue
) && (val
!= xFalse
)) {
1016 client
->errorValue
= val
;
1022 *values
++ = (CARD32
) *pVlist
;
1024 case CWDontPropagate
:
1025 *values
++ = (CARD32
) *pVlist
;
1027 case CWOverrideRedirect
:
1028 if (!(stuff
->mask
& CWOverrideRedirect
))
1031 val
= (BOOL
) * pVlist
;
1032 if ((val
!= xTrue
) && (val
!= xFalse
)) {
1034 client
->errorValue
= val
;
1041 cmap
= (Colormap
) * pVlist
;
1042 ret
= dixLookupResourceByType((pointer
*) &pCmap
, cmap
, RT_COLORMAP
,
1043 client
, DixUseAccess
);
1044 if (ret
!= Success
) {
1045 client
->errorValue
= cmap
;
1048 if (pCmap
->pVisual
->vid
!= visual
|| pCmap
->pScreen
!= pScreen
) {
1052 pAttr
->colormap
= cmap
;
1053 pAttr
->mask
&= ~CWColormap
;
1056 cursorID
= (Cursor
) * pVlist
;
1057 if (cursorID
== None
) {
1061 ret
= dixLookupResourceByType((pointer
*) &pCursor
, cursorID
,
1062 RT_CURSOR
, client
, DixUseAccess
);
1063 if (ret
!= Success
) {
1064 client
->errorValue
= cursorID
;
1067 pAttr
->pCursor
= RefCursor(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
;