1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun Copyright (c) 1992 X Consortium
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a copy
6*4882a593Smuzhiyun of this software and associated documentation files (the "Software"), to deal
7*4882a593Smuzhiyun in the Software without restriction, including without limitation the rights
8*4882a593Smuzhiyun to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9*4882a593Smuzhiyun copies of the Software, and to permit persons to whom the Software is
10*4882a593Smuzhiyun furnished to do so, subject to the following conditions:
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
13*4882a593Smuzhiyun all copies or substantial portions of the Software.
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*4882a593Smuzhiyun X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun Except as contained in this notice, the name of the X Consortium shall not be
23*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
24*4882a593Smuzhiyun in this Software without prior written authorization from the X Consortium.
25*4882a593Smuzhiyun *
26*4882a593Smuzhiyun * Author: Keith Packard, MIT X Consortium
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
30*4882a593Smuzhiyun #include <dix-config.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include <X11/X.h>
34*4882a593Smuzhiyun #include <X11/Xproto.h>
35*4882a593Smuzhiyun #include "misc.h"
36*4882a593Smuzhiyun #include "os.h"
37*4882a593Smuzhiyun #include "windowstr.h"
38*4882a593Smuzhiyun #include "scrnintstr.h"
39*4882a593Smuzhiyun #include "pixmapstr.h"
40*4882a593Smuzhiyun #include "extnsionst.h"
41*4882a593Smuzhiyun #include "dixstruct.h"
42*4882a593Smuzhiyun #include "resource.h"
43*4882a593Smuzhiyun #include "opaque.h"
44*4882a593Smuzhiyun #include <X11/extensions/saverproto.h>
45*4882a593Smuzhiyun #include "gcstruct.h"
46*4882a593Smuzhiyun #include "cursorstr.h"
47*4882a593Smuzhiyun #include "colormapst.h"
48*4882a593Smuzhiyun #include "xace.h"
49*4882a593Smuzhiyun #include "inputstr.h"
50*4882a593Smuzhiyun #ifdef PANORAMIX
51*4882a593Smuzhiyun #include "panoramiX.h"
52*4882a593Smuzhiyun #include "panoramiXsrv.h"
53*4882a593Smuzhiyun #endif
54*4882a593Smuzhiyun #ifdef DPMSExtension
55*4882a593Smuzhiyun #include <X11/extensions/dpmsconst.h>
56*4882a593Smuzhiyun #include "dpmsproc.h"
57*4882a593Smuzhiyun #endif
58*4882a593Smuzhiyun #include "protocol-versions.h"
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #include <stdio.h>
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun #include "extinit.h"
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun static int ScreenSaverEventBase = 0;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun static Bool ScreenSaverHandle(ScreenPtr /* pScreen */ ,
67*4882a593Smuzhiyun int /* xstate */ ,
68*4882a593Smuzhiyun Bool /* force */
69*4882a593Smuzhiyun );
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun static Bool
72*4882a593Smuzhiyun CreateSaverWindow(ScreenPtr /* pScreen */
73*4882a593Smuzhiyun );
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun static Bool
76*4882a593Smuzhiyun DestroySaverWindow(ScreenPtr /* pScreen */
77*4882a593Smuzhiyun );
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun static void
80*4882a593Smuzhiyun UninstallSaverColormap(ScreenPtr /* pScreen */
81*4882a593Smuzhiyun );
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun static void
84*4882a593Smuzhiyun CheckScreenPrivate(ScreenPtr /* pScreen */
85*4882a593Smuzhiyun );
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun static void SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * /* from */ ,
88*4882a593Smuzhiyun xScreenSaverNotifyEvent * /* to */
89*4882a593Smuzhiyun );
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun static RESTYPE SuspendType; /* resource type for suspension records */
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* List of clients that are suspending the screensaver. */
96*4882a593Smuzhiyun static ScreenSaverSuspensionPtr suspendingClients = NULL;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /*
99*4882a593Smuzhiyun * clientResource is a resource ID that's added when the record is
100*4882a593Smuzhiyun * allocated, so the record is freed and the screensaver resumed when
101*4882a593Smuzhiyun * the client disconnects. count is the number of times the client has
102*4882a593Smuzhiyun * requested the screensaver be suspended.
103*4882a593Smuzhiyun */
104*4882a593Smuzhiyun typedef struct _ScreenSaverSuspension {
105*4882a593Smuzhiyun ScreenSaverSuspensionPtr next;
106*4882a593Smuzhiyun ClientPtr pClient;
107*4882a593Smuzhiyun XID clientResource;
108*4882a593Smuzhiyun int count;
109*4882a593Smuzhiyun } ScreenSaverSuspensionRec;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun static int ScreenSaverFreeSuspend(void *value, XID id);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun * each screen has a list of clients requesting
115*4882a593Smuzhiyun * ScreenSaverNotify events. Each client has a resource
116*4882a593Smuzhiyun * for each screen it selects ScreenSaverNotify input for,
117*4882a593Smuzhiyun * this resource is used to delete the ScreenSaverNotifyRec
118*4882a593Smuzhiyun * entry from the per-screen queue.
119*4882a593Smuzhiyun */
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun static RESTYPE SaverEventType; /* resource type for event masks */
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun typedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun typedef struct _ScreenSaverEvent {
126*4882a593Smuzhiyun ScreenSaverEventPtr next;
127*4882a593Smuzhiyun ClientPtr client;
128*4882a593Smuzhiyun ScreenPtr screen;
129*4882a593Smuzhiyun XID resource;
130*4882a593Smuzhiyun CARD32 mask;
131*4882a593Smuzhiyun } ScreenSaverEventRec;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun static int ScreenSaverFreeEvents(void * value, XID id);
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun static Bool setEventMask(ScreenPtr pScreen,
136*4882a593Smuzhiyun ClientPtr client,
137*4882a593Smuzhiyun unsigned long mask);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun static unsigned long getEventMask(ScreenPtr pScreen,
140*4882a593Smuzhiyun ClientPtr client);
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun /*
143*4882a593Smuzhiyun * when a client sets the screen saver attributes, a resource is
144*4882a593Smuzhiyun * kept to be freed when the client exits
145*4882a593Smuzhiyun */
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun static RESTYPE AttrType; /* resource type for attributes */
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun typedef struct _ScreenSaverAttr {
150*4882a593Smuzhiyun ScreenPtr screen;
151*4882a593Smuzhiyun ClientPtr client;
152*4882a593Smuzhiyun XID resource;
153*4882a593Smuzhiyun short x, y;
154*4882a593Smuzhiyun unsigned short width, height, borderWidth;
155*4882a593Smuzhiyun unsigned char class;
156*4882a593Smuzhiyun unsigned char depth;
157*4882a593Smuzhiyun VisualID visual;
158*4882a593Smuzhiyun CursorPtr pCursor;
159*4882a593Smuzhiyun PixmapPtr pBackgroundPixmap;
160*4882a593Smuzhiyun PixmapPtr pBorderPixmap;
161*4882a593Smuzhiyun Colormap colormap;
162*4882a593Smuzhiyun unsigned long mask; /* no pixmaps or cursors */
163*4882a593Smuzhiyun unsigned long *values;
164*4882a593Smuzhiyun } ScreenSaverAttrRec, *ScreenSaverAttrPtr;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun static int ScreenSaverFreeAttr(void *value, XID id);
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun static void FreeAttrs(ScreenSaverAttrPtr pAttr);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun static void FreeScreenAttr(ScreenSaverAttrPtr pAttr);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun static void
173*4882a593Smuzhiyun SendScreenSaverNotify(ScreenPtr pScreen,
174*4882a593Smuzhiyun int state,
175*4882a593Smuzhiyun Bool forced);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun typedef struct _ScreenSaverScreenPrivate {
178*4882a593Smuzhiyun ScreenSaverEventPtr events;
179*4882a593Smuzhiyun ScreenSaverAttrPtr attr;
180*4882a593Smuzhiyun Bool hasWindow;
181*4882a593Smuzhiyun Colormap installedMap;
182*4882a593Smuzhiyun } ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun static ScreenSaverScreenPrivatePtr MakeScreenPrivate(ScreenPtr pScreen);
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun static DevPrivateKeyRec ScreenPrivateKeyRec;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun #define ScreenPrivateKey (&ScreenPrivateKeyRec)
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun #define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
191*4882a593Smuzhiyun dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
192*4882a593Smuzhiyun #define SetScreenPrivate(s,v) \
193*4882a593Smuzhiyun dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v);
194*4882a593Smuzhiyun #define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun #define New(t) (malloc(sizeof (t)))
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun static void
CheckScreenPrivate(ScreenPtr pScreen)199*4882a593Smuzhiyun CheckScreenPrivate(ScreenPtr pScreen)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun SetupScreen(pScreen);
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun if (!pPriv)
204*4882a593Smuzhiyun return;
205*4882a593Smuzhiyun if (!pPriv->attr && !pPriv->events &&
206*4882a593Smuzhiyun !pPriv->hasWindow && pPriv->installedMap == None) {
207*4882a593Smuzhiyun free(pPriv);
208*4882a593Smuzhiyun SetScreenPrivate(pScreen, NULL);
209*4882a593Smuzhiyun pScreen->screensaver.ExternalScreenSaver = NULL;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun static ScreenSaverScreenPrivatePtr
MakeScreenPrivate(ScreenPtr pScreen)214*4882a593Smuzhiyun MakeScreenPrivate(ScreenPtr pScreen)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun SetupScreen(pScreen);
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun if (pPriv)
219*4882a593Smuzhiyun return pPriv;
220*4882a593Smuzhiyun pPriv = New(ScreenSaverScreenPrivateRec);
221*4882a593Smuzhiyun if (!pPriv)
222*4882a593Smuzhiyun return 0;
223*4882a593Smuzhiyun pPriv->events = 0;
224*4882a593Smuzhiyun pPriv->attr = 0;
225*4882a593Smuzhiyun pPriv->hasWindow = FALSE;
226*4882a593Smuzhiyun pPriv->installedMap = None;
227*4882a593Smuzhiyun SetScreenPrivate(pScreen, pPriv);
228*4882a593Smuzhiyun pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle;
229*4882a593Smuzhiyun return pPriv;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun static unsigned long
getEventMask(ScreenPtr pScreen,ClientPtr client)233*4882a593Smuzhiyun getEventMask(ScreenPtr pScreen, ClientPtr client)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun SetupScreen(pScreen);
236*4882a593Smuzhiyun ScreenSaverEventPtr pEv;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (!pPriv)
239*4882a593Smuzhiyun return 0;
240*4882a593Smuzhiyun for (pEv = pPriv->events; pEv; pEv = pEv->next)
241*4882a593Smuzhiyun if (pEv->client == client)
242*4882a593Smuzhiyun return pEv->mask;
243*4882a593Smuzhiyun return 0;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun static Bool
setEventMask(ScreenPtr pScreen,ClientPtr client,unsigned long mask)247*4882a593Smuzhiyun setEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun SetupScreen(pScreen);
250*4882a593Smuzhiyun ScreenSaverEventPtr pEv, *pPrev;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun if (getEventMask(pScreen, client) == mask)
253*4882a593Smuzhiyun return TRUE;
254*4882a593Smuzhiyun if (!pPriv) {
255*4882a593Smuzhiyun pPriv = MakeScreenPrivate(pScreen);
256*4882a593Smuzhiyun if (!pPriv)
257*4882a593Smuzhiyun return FALSE;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
260*4882a593Smuzhiyun if (pEv->client == client)
261*4882a593Smuzhiyun break;
262*4882a593Smuzhiyun if (mask == 0) {
263*4882a593Smuzhiyun FreeResource(pEv->resource, SaverEventType);
264*4882a593Smuzhiyun *pPrev = pEv->next;
265*4882a593Smuzhiyun free(pEv);
266*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun else {
269*4882a593Smuzhiyun if (!pEv) {
270*4882a593Smuzhiyun pEv = New(ScreenSaverEventRec);
271*4882a593Smuzhiyun if (!pEv) {
272*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
273*4882a593Smuzhiyun return FALSE;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun *pPrev = pEv;
276*4882a593Smuzhiyun pEv->next = NULL;
277*4882a593Smuzhiyun pEv->client = client;
278*4882a593Smuzhiyun pEv->screen = pScreen;
279*4882a593Smuzhiyun pEv->resource = FakeClientID(client->index);
280*4882a593Smuzhiyun if (!AddResource(pEv->resource, SaverEventType, (void *) pEv))
281*4882a593Smuzhiyun return FALSE;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun pEv->mask = mask;
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun return TRUE;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun static void
FreeAttrs(ScreenSaverAttrPtr pAttr)289*4882a593Smuzhiyun FreeAttrs(ScreenSaverAttrPtr pAttr)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun PixmapPtr pPixmap;
292*4882a593Smuzhiyun CursorPtr pCursor;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
295*4882a593Smuzhiyun (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
296*4882a593Smuzhiyun if ((pPixmap = pAttr->pBorderPixmap) != 0)
297*4882a593Smuzhiyun (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
298*4882a593Smuzhiyun if ((pCursor = pAttr->pCursor) != 0)
299*4882a593Smuzhiyun FreeCursor(pCursor, (Cursor) 0);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun static void
FreeScreenAttr(ScreenSaverAttrPtr pAttr)303*4882a593Smuzhiyun FreeScreenAttr(ScreenSaverAttrPtr pAttr)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun FreeAttrs(pAttr);
306*4882a593Smuzhiyun free(pAttr->values);
307*4882a593Smuzhiyun free(pAttr);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun static int
ScreenSaverFreeEvents(void * value,XID id)311*4882a593Smuzhiyun ScreenSaverFreeEvents(void *value, XID id)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun ScreenSaverEventPtr pOld = (ScreenSaverEventPtr) value;
314*4882a593Smuzhiyun ScreenPtr pScreen = pOld->screen;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun SetupScreen(pScreen);
317*4882a593Smuzhiyun ScreenSaverEventPtr pEv, *pPrev;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (!pPriv)
320*4882a593Smuzhiyun return TRUE;
321*4882a593Smuzhiyun for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
322*4882a593Smuzhiyun if (pEv == pOld)
323*4882a593Smuzhiyun break;
324*4882a593Smuzhiyun if (!pEv)
325*4882a593Smuzhiyun return TRUE;
326*4882a593Smuzhiyun *pPrev = pEv->next;
327*4882a593Smuzhiyun free(pEv);
328*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
329*4882a593Smuzhiyun return TRUE;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun static int
ScreenSaverFreeAttr(void * value,XID id)333*4882a593Smuzhiyun ScreenSaverFreeAttr(void *value, XID id)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr) value;
336*4882a593Smuzhiyun ScreenPtr pScreen = pOldAttr->screen;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun SetupScreen(pScreen);
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun if (!pPriv)
341*4882a593Smuzhiyun return TRUE;
342*4882a593Smuzhiyun if (pPriv->attr != pOldAttr)
343*4882a593Smuzhiyun return TRUE;
344*4882a593Smuzhiyun FreeScreenAttr(pOldAttr);
345*4882a593Smuzhiyun pPriv->attr = NULL;
346*4882a593Smuzhiyun if (pPriv->hasWindow) {
347*4882a593Smuzhiyun dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
348*4882a593Smuzhiyun dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
351*4882a593Smuzhiyun return TRUE;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun static int
ScreenSaverFreeSuspend(void * value,XID id)355*4882a593Smuzhiyun ScreenSaverFreeSuspend(void *value, XID id)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
358*4882a593Smuzhiyun ScreenSaverSuspensionPtr *prev, this;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun /* Unlink and free the suspension record for the client */
361*4882a593Smuzhiyun for (prev = &suspendingClients; (this = *prev); prev = &this->next) {
362*4882a593Smuzhiyun if (this == data) {
363*4882a593Smuzhiyun *prev = this->next;
364*4882a593Smuzhiyun free(this);
365*4882a593Smuzhiyun break;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun /* Reenable the screensaver if this was the last client suspending it. */
370*4882a593Smuzhiyun if (screenSaverSuspended && suspendingClients == NULL) {
371*4882a593Smuzhiyun screenSaverSuspended = FALSE;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun /* The screensaver could be active, since suspending it (by design)
374*4882a593Smuzhiyun doesn't prevent it from being forceably activated */
375*4882a593Smuzhiyun #ifdef DPMSExtension
376*4882a593Smuzhiyun if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn)
377*4882a593Smuzhiyun #else
378*4882a593Smuzhiyun if (screenIsSaved != SCREEN_SAVER_ON)
379*4882a593Smuzhiyun #endif
380*4882a593Smuzhiyun {
381*4882a593Smuzhiyun DeviceIntPtr dev;
382*4882a593Smuzhiyun UpdateCurrentTimeIf();
383*4882a593Smuzhiyun nt_list_for_each_entry(dev, inputInfo.devices, next)
384*4882a593Smuzhiyun NoticeTime(dev, currentTime);
385*4882a593Smuzhiyun SetScreenSaverTimer();
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun return Success;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun static void
SendScreenSaverNotify(ScreenPtr pScreen,int state,Bool forced)393*4882a593Smuzhiyun SendScreenSaverNotify(ScreenPtr pScreen, int state, Bool forced)
394*4882a593Smuzhiyun {
395*4882a593Smuzhiyun ScreenSaverScreenPrivatePtr pPriv;
396*4882a593Smuzhiyun ScreenSaverEventPtr pEv;
397*4882a593Smuzhiyun unsigned long mask;
398*4882a593Smuzhiyun int kind;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun UpdateCurrentTimeIf();
401*4882a593Smuzhiyun mask = ScreenSaverNotifyMask;
402*4882a593Smuzhiyun if (state == ScreenSaverCycle)
403*4882a593Smuzhiyun mask = ScreenSaverCycleMask;
404*4882a593Smuzhiyun pScreen = screenInfo.screens[pScreen->myNum];
405*4882a593Smuzhiyun pPriv = GetScreenPrivate(pScreen);
406*4882a593Smuzhiyun if (!pPriv)
407*4882a593Smuzhiyun return;
408*4882a593Smuzhiyun if (pPriv->attr)
409*4882a593Smuzhiyun kind = ScreenSaverExternal;
410*4882a593Smuzhiyun else if (ScreenSaverBlanking != DontPreferBlanking)
411*4882a593Smuzhiyun kind = ScreenSaverBlanked;
412*4882a593Smuzhiyun else
413*4882a593Smuzhiyun kind = ScreenSaverInternal;
414*4882a593Smuzhiyun for (pEv = pPriv->events; pEv; pEv = pEv->next) {
415*4882a593Smuzhiyun if (pEv->mask & mask) {
416*4882a593Smuzhiyun xScreenSaverNotifyEvent ev = {
417*4882a593Smuzhiyun .type = ScreenSaverNotify + ScreenSaverEventBase,
418*4882a593Smuzhiyun .state = state,
419*4882a593Smuzhiyun .timestamp = currentTime.milliseconds,
420*4882a593Smuzhiyun .root = pScreen->root->drawable.id,
421*4882a593Smuzhiyun .window = pScreen->screensaver.wid,
422*4882a593Smuzhiyun .kind = kind,
423*4882a593Smuzhiyun .forced = forced
424*4882a593Smuzhiyun };
425*4882a593Smuzhiyun WriteEventsToClient(pEv->client, 1, (xEvent *) &ev);
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun static void _X_COLD
SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * from,xScreenSaverNotifyEvent * to)431*4882a593Smuzhiyun SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * from,
432*4882a593Smuzhiyun xScreenSaverNotifyEvent * to)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun to->type = from->type;
435*4882a593Smuzhiyun to->state = from->state;
436*4882a593Smuzhiyun cpswaps(from->sequenceNumber, to->sequenceNumber);
437*4882a593Smuzhiyun cpswapl(from->timestamp, to->timestamp);
438*4882a593Smuzhiyun cpswapl(from->root, to->root);
439*4882a593Smuzhiyun cpswapl(from->window, to->window);
440*4882a593Smuzhiyun to->kind = from->kind;
441*4882a593Smuzhiyun to->forced = from->forced;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun static void
UninstallSaverColormap(ScreenPtr pScreen)445*4882a593Smuzhiyun UninstallSaverColormap(ScreenPtr pScreen)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun SetupScreen(pScreen);
448*4882a593Smuzhiyun ColormapPtr pCmap;
449*4882a593Smuzhiyun int rc;
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (pPriv && pPriv->installedMap != None) {
452*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pCmap, pPriv->installedMap,
453*4882a593Smuzhiyun RT_COLORMAP, serverClient,
454*4882a593Smuzhiyun DixUninstallAccess);
455*4882a593Smuzhiyun if (rc == Success)
456*4882a593Smuzhiyun (*pCmap->pScreen->UninstallColormap) (pCmap);
457*4882a593Smuzhiyun pPriv->installedMap = None;
458*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun static Bool
CreateSaverWindow(ScreenPtr pScreen)463*4882a593Smuzhiyun CreateSaverWindow(ScreenPtr pScreen)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun SetupScreen(pScreen);
466*4882a593Smuzhiyun ScreenSaverStuffPtr pSaver;
467*4882a593Smuzhiyun ScreenSaverAttrPtr pAttr;
468*4882a593Smuzhiyun WindowPtr pWin;
469*4882a593Smuzhiyun int result;
470*4882a593Smuzhiyun unsigned long mask;
471*4882a593Smuzhiyun Colormap wantMap;
472*4882a593Smuzhiyun ColormapPtr pCmap;
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun pSaver = &pScreen->screensaver;
475*4882a593Smuzhiyun if (pSaver->pWindow) {
476*4882a593Smuzhiyun pSaver->pWindow = NullWindow;
477*4882a593Smuzhiyun FreeResource(pSaver->wid, RT_NONE);
478*4882a593Smuzhiyun if (pPriv) {
479*4882a593Smuzhiyun UninstallSaverColormap(pScreen);
480*4882a593Smuzhiyun pPriv->hasWindow = FALSE;
481*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun if (!pPriv || !(pAttr = pPriv->attr))
486*4882a593Smuzhiyun return FALSE;
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun pPriv->installedMap = None;
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun if (GrabInProgress && GrabInProgress != pAttr->client->index)
491*4882a593Smuzhiyun return FALSE;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun pWin = CreateWindow(pSaver->wid, pScreen->root,
494*4882a593Smuzhiyun pAttr->x, pAttr->y, pAttr->width, pAttr->height,
495*4882a593Smuzhiyun pAttr->borderWidth, pAttr->class,
496*4882a593Smuzhiyun pAttr->mask, (XID *) pAttr->values,
497*4882a593Smuzhiyun pAttr->depth, serverClient, pAttr->visual, &result);
498*4882a593Smuzhiyun if (!pWin)
499*4882a593Smuzhiyun return FALSE;
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
502*4882a593Smuzhiyun return FALSE;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun mask = 0;
505*4882a593Smuzhiyun if (pAttr->pBackgroundPixmap) {
506*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixmap;
507*4882a593Smuzhiyun pWin->background.pixmap = pAttr->pBackgroundPixmap;
508*4882a593Smuzhiyun pAttr->pBackgroundPixmap->refcnt++;
509*4882a593Smuzhiyun mask |= CWBackPixmap;
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun if (pAttr->pBorderPixmap) {
512*4882a593Smuzhiyun pWin->borderIsPixel = FALSE;
513*4882a593Smuzhiyun pWin->border.pixmap = pAttr->pBorderPixmap;
514*4882a593Smuzhiyun pAttr->pBorderPixmap->refcnt++;
515*4882a593Smuzhiyun mask |= CWBorderPixmap;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun if (pAttr->pCursor) {
518*4882a593Smuzhiyun CursorPtr cursor;
519*4882a593Smuzhiyun if (!pWin->optional)
520*4882a593Smuzhiyun if (!MakeWindowOptional(pWin)) {
521*4882a593Smuzhiyun FreeResource(pWin->drawable.id, RT_NONE);
522*4882a593Smuzhiyun return FALSE;
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun cursor = RefCursor(pAttr->pCursor);
525*4882a593Smuzhiyun if (pWin->optional->cursor)
526*4882a593Smuzhiyun FreeCursor(pWin->optional->cursor, (Cursor) 0);
527*4882a593Smuzhiyun pWin->optional->cursor = cursor;
528*4882a593Smuzhiyun pWin->cursorIsNone = FALSE;
529*4882a593Smuzhiyun CheckWindowOptionalNeed(pWin);
530*4882a593Smuzhiyun mask |= CWCursor;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun if (mask)
533*4882a593Smuzhiyun (*pScreen->ChangeWindowAttributes) (pWin, mask);
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun if (pAttr->colormap != None)
536*4882a593Smuzhiyun (void) ChangeWindowAttributes(pWin, CWColormap, &pAttr->colormap,
537*4882a593Smuzhiyun serverClient);
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun MapWindow(pWin, serverClient);
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun pPriv->hasWindow = TRUE;
542*4882a593Smuzhiyun pSaver->pWindow = pWin;
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun /* check and install our own colormap if it isn't installed now */
545*4882a593Smuzhiyun wantMap = wColormap(pWin);
546*4882a593Smuzhiyun if (wantMap == None || IsMapInstalled(wantMap, pWin))
547*4882a593Smuzhiyun return TRUE;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun result = dixLookupResourceByType((void **) &pCmap, wantMap, RT_COLORMAP,
550*4882a593Smuzhiyun serverClient, DixInstallAccess);
551*4882a593Smuzhiyun if (result != Success)
552*4882a593Smuzhiyun return TRUE;
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun pPriv->installedMap = wantMap;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun (*pCmap->pScreen->InstallColormap) (pCmap);
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun return TRUE;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun static Bool
DestroySaverWindow(ScreenPtr pScreen)562*4882a593Smuzhiyun DestroySaverWindow(ScreenPtr pScreen)
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun SetupScreen(pScreen);
565*4882a593Smuzhiyun ScreenSaverStuffPtr pSaver;
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun if (!pPriv || !pPriv->hasWindow)
568*4882a593Smuzhiyun return FALSE;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun pSaver = &pScreen->screensaver;
571*4882a593Smuzhiyun if (pSaver->pWindow) {
572*4882a593Smuzhiyun pSaver->pWindow = NullWindow;
573*4882a593Smuzhiyun FreeResource(pSaver->wid, RT_NONE);
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun pPriv->hasWindow = FALSE;
576*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
577*4882a593Smuzhiyun UninstallSaverColormap(pScreen);
578*4882a593Smuzhiyun return TRUE;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun static Bool
ScreenSaverHandle(ScreenPtr pScreen,int xstate,Bool force)582*4882a593Smuzhiyun ScreenSaverHandle(ScreenPtr pScreen, int xstate, Bool force)
583*4882a593Smuzhiyun {
584*4882a593Smuzhiyun int state = 0;
585*4882a593Smuzhiyun Bool ret = FALSE;
586*4882a593Smuzhiyun ScreenSaverScreenPrivatePtr pPriv;
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun switch (xstate) {
589*4882a593Smuzhiyun case SCREEN_SAVER_ON:
590*4882a593Smuzhiyun state = ScreenSaverOn;
591*4882a593Smuzhiyun ret = CreateSaverWindow(pScreen);
592*4882a593Smuzhiyun break;
593*4882a593Smuzhiyun case SCREEN_SAVER_OFF:
594*4882a593Smuzhiyun state = ScreenSaverOff;
595*4882a593Smuzhiyun ret = DestroySaverWindow(pScreen);
596*4882a593Smuzhiyun break;
597*4882a593Smuzhiyun case SCREEN_SAVER_CYCLE:
598*4882a593Smuzhiyun state = ScreenSaverCycle;
599*4882a593Smuzhiyun pPriv = GetScreenPrivate(pScreen);
600*4882a593Smuzhiyun if (pPriv && pPriv->hasWindow)
601*4882a593Smuzhiyun ret = TRUE;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun #ifdef PANORAMIX
605*4882a593Smuzhiyun if (noPanoramiXExtension || !pScreen->myNum)
606*4882a593Smuzhiyun #endif
607*4882a593Smuzhiyun SendScreenSaverNotify(pScreen, state, force);
608*4882a593Smuzhiyun return ret;
609*4882a593Smuzhiyun }
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun static int
ProcScreenSaverQueryVersion(ClientPtr client)612*4882a593Smuzhiyun ProcScreenSaverQueryVersion(ClientPtr client)
613*4882a593Smuzhiyun {
614*4882a593Smuzhiyun xScreenSaverQueryVersionReply rep = {
615*4882a593Smuzhiyun .type = X_Reply,
616*4882a593Smuzhiyun .sequenceNumber = client->sequence,
617*4882a593Smuzhiyun .length = 0,
618*4882a593Smuzhiyun .majorVersion = SERVER_SAVER_MAJOR_VERSION,
619*4882a593Smuzhiyun .minorVersion = SERVER_SAVER_MINOR_VERSION
620*4882a593Smuzhiyun };
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun if (client->swapped) {
625*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
626*4882a593Smuzhiyun swapl(&rep.length);
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun WriteToClient(client, sizeof(xScreenSaverQueryVersionReply), &rep);
629*4882a593Smuzhiyun return Success;
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun static int
ProcScreenSaverQueryInfo(ClientPtr client)633*4882a593Smuzhiyun ProcScreenSaverQueryInfo(ClientPtr client)
634*4882a593Smuzhiyun {
635*4882a593Smuzhiyun REQUEST(xScreenSaverQueryInfoReq);
636*4882a593Smuzhiyun xScreenSaverQueryInfoReply rep;
637*4882a593Smuzhiyun int rc;
638*4882a593Smuzhiyun ScreenSaverStuffPtr pSaver;
639*4882a593Smuzhiyun DrawablePtr pDraw;
640*4882a593Smuzhiyun CARD32 lastInput;
641*4882a593Smuzhiyun ScreenSaverScreenPrivatePtr pPriv;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
644*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
645*4882a593Smuzhiyun DixGetAttrAccess);
646*4882a593Smuzhiyun if (rc != Success)
647*4882a593Smuzhiyun return rc;
648*4882a593Smuzhiyun rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
649*4882a593Smuzhiyun DixGetAttrAccess);
650*4882a593Smuzhiyun if (rc != Success)
651*4882a593Smuzhiyun return rc;
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun pSaver = &pDraw->pScreen->screensaver;
654*4882a593Smuzhiyun pPriv = GetScreenPrivate(pDraw->pScreen);
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun UpdateCurrentTime();
657*4882a593Smuzhiyun lastInput = GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun rep = (xScreenSaverQueryInfoReply) {
660*4882a593Smuzhiyun .type = X_Reply,
661*4882a593Smuzhiyun .sequenceNumber = client->sequence,
662*4882a593Smuzhiyun .length = 0,
663*4882a593Smuzhiyun .window = pSaver->wid
664*4882a593Smuzhiyun };
665*4882a593Smuzhiyun if (screenIsSaved != SCREEN_SAVER_OFF) {
666*4882a593Smuzhiyun rep.state = ScreenSaverOn;
667*4882a593Smuzhiyun if (ScreenSaverTime)
668*4882a593Smuzhiyun rep.tilOrSince = lastInput - ScreenSaverTime;
669*4882a593Smuzhiyun else
670*4882a593Smuzhiyun rep.tilOrSince = 0;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun else {
673*4882a593Smuzhiyun if (ScreenSaverTime) {
674*4882a593Smuzhiyun rep.state = ScreenSaverOff;
675*4882a593Smuzhiyun if (ScreenSaverTime < lastInput)
676*4882a593Smuzhiyun rep.tilOrSince = 0;
677*4882a593Smuzhiyun else
678*4882a593Smuzhiyun rep.tilOrSince = ScreenSaverTime - lastInput;
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun else {
681*4882a593Smuzhiyun rep.state = ScreenSaverDisabled;
682*4882a593Smuzhiyun rep.tilOrSince = 0;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun rep.idle = lastInput;
686*4882a593Smuzhiyun rep.eventMask = getEventMask(pDraw->pScreen, client);
687*4882a593Smuzhiyun if (pPriv && pPriv->attr)
688*4882a593Smuzhiyun rep.kind = ScreenSaverExternal;
689*4882a593Smuzhiyun else if (ScreenSaverBlanking != DontPreferBlanking)
690*4882a593Smuzhiyun rep.kind = ScreenSaverBlanked;
691*4882a593Smuzhiyun else
692*4882a593Smuzhiyun rep.kind = ScreenSaverInternal;
693*4882a593Smuzhiyun if (client->swapped) {
694*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
695*4882a593Smuzhiyun swapl(&rep.length);
696*4882a593Smuzhiyun swapl(&rep.window);
697*4882a593Smuzhiyun swapl(&rep.tilOrSince);
698*4882a593Smuzhiyun swapl(&rep.idle);
699*4882a593Smuzhiyun swapl(&rep.eventMask);
700*4882a593Smuzhiyun }
701*4882a593Smuzhiyun WriteToClient(client, sizeof(xScreenSaverQueryInfoReply), &rep);
702*4882a593Smuzhiyun return Success;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun static int
ProcScreenSaverSelectInput(ClientPtr client)706*4882a593Smuzhiyun ProcScreenSaverSelectInput(ClientPtr client)
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun REQUEST(xScreenSaverSelectInputReq);
709*4882a593Smuzhiyun DrawablePtr pDraw;
710*4882a593Smuzhiyun int rc;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
713*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
714*4882a593Smuzhiyun DixGetAttrAccess);
715*4882a593Smuzhiyun if (rc != Success)
716*4882a593Smuzhiyun return rc;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
719*4882a593Smuzhiyun DixSetAttrAccess);
720*4882a593Smuzhiyun if (rc != Success)
721*4882a593Smuzhiyun return rc;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun if (!setEventMask(pDraw->pScreen, client, stuff->eventMask))
724*4882a593Smuzhiyun return BadAlloc;
725*4882a593Smuzhiyun return Success;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun static int
ScreenSaverSetAttributes(ClientPtr client)729*4882a593Smuzhiyun ScreenSaverSetAttributes(ClientPtr client)
730*4882a593Smuzhiyun {
731*4882a593Smuzhiyun REQUEST(xScreenSaverSetAttributesReq);
732*4882a593Smuzhiyun DrawablePtr pDraw;
733*4882a593Smuzhiyun WindowPtr pParent;
734*4882a593Smuzhiyun ScreenPtr pScreen;
735*4882a593Smuzhiyun ScreenSaverScreenPrivatePtr pPriv = 0;
736*4882a593Smuzhiyun ScreenSaverAttrPtr pAttr = 0;
737*4882a593Smuzhiyun int ret, len, class, bw, depth;
738*4882a593Smuzhiyun unsigned long visual;
739*4882a593Smuzhiyun int idepth, ivisual;
740*4882a593Smuzhiyun Bool fOK;
741*4882a593Smuzhiyun DepthPtr pDepth;
742*4882a593Smuzhiyun WindowOptPtr ancwopt;
743*4882a593Smuzhiyun unsigned int *pVlist;
744*4882a593Smuzhiyun unsigned long *values = 0;
745*4882a593Smuzhiyun unsigned long tmask, imask;
746*4882a593Smuzhiyun unsigned long val;
747*4882a593Smuzhiyun Pixmap pixID;
748*4882a593Smuzhiyun PixmapPtr pPixmap;
749*4882a593Smuzhiyun Cursor cursorID;
750*4882a593Smuzhiyun CursorPtr pCursor;
751*4882a593Smuzhiyun Colormap cmap;
752*4882a593Smuzhiyun ColormapPtr pCmap;
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
755*4882a593Smuzhiyun ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
756*4882a593Smuzhiyun DixGetAttrAccess);
757*4882a593Smuzhiyun if (ret != Success)
758*4882a593Smuzhiyun return ret;
759*4882a593Smuzhiyun pScreen = pDraw->pScreen;
760*4882a593Smuzhiyun pParent = pScreen->root;
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess);
763*4882a593Smuzhiyun if (ret != Success)
764*4882a593Smuzhiyun return ret;
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
767*4882a593Smuzhiyun if (Ones(stuff->mask) != len)
768*4882a593Smuzhiyun return BadLength;
769*4882a593Smuzhiyun if (!stuff->width || !stuff->height) {
770*4882a593Smuzhiyun client->errorValue = 0;
771*4882a593Smuzhiyun return BadValue;
772*4882a593Smuzhiyun }
773*4882a593Smuzhiyun switch (class = stuff->c_class) {
774*4882a593Smuzhiyun case CopyFromParent:
775*4882a593Smuzhiyun case InputOnly:
776*4882a593Smuzhiyun case InputOutput:
777*4882a593Smuzhiyun break;
778*4882a593Smuzhiyun default:
779*4882a593Smuzhiyun client->errorValue = class;
780*4882a593Smuzhiyun return BadValue;
781*4882a593Smuzhiyun }
782*4882a593Smuzhiyun bw = stuff->borderWidth;
783*4882a593Smuzhiyun depth = stuff->depth;
784*4882a593Smuzhiyun visual = stuff->visualID;
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun /* copied directly from CreateWindow */
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun if (class == CopyFromParent)
789*4882a593Smuzhiyun class = pParent->drawable.class;
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun if ((class != InputOutput) && (class != InputOnly)) {
792*4882a593Smuzhiyun client->errorValue = class;
793*4882a593Smuzhiyun return BadValue;
794*4882a593Smuzhiyun }
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
797*4882a593Smuzhiyun return BadMatch;
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
800*4882a593Smuzhiyun return BadMatch;
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun if ((class == InputOutput) && (depth == 0))
803*4882a593Smuzhiyun depth = pParent->drawable.depth;
804*4882a593Smuzhiyun ancwopt = pParent->optional;
805*4882a593Smuzhiyun if (!ancwopt)
806*4882a593Smuzhiyun ancwopt = FindWindowWithOptional(pParent)->optional;
807*4882a593Smuzhiyun if (visual == CopyFromParent)
808*4882a593Smuzhiyun visual = ancwopt->visual;
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun /* Find out if the depth and visual are acceptable for this Screen */
811*4882a593Smuzhiyun if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
812*4882a593Smuzhiyun fOK = FALSE;
813*4882a593Smuzhiyun for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
814*4882a593Smuzhiyun pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
815*4882a593Smuzhiyun if ((depth == pDepth->depth) || (depth == 0)) {
816*4882a593Smuzhiyun for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
817*4882a593Smuzhiyun if (visual == pDepth->vids[ivisual]) {
818*4882a593Smuzhiyun fOK = TRUE;
819*4882a593Smuzhiyun break;
820*4882a593Smuzhiyun }
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun }
823*4882a593Smuzhiyun }
824*4882a593Smuzhiyun if (fOK == FALSE)
825*4882a593Smuzhiyun return BadMatch;
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
829*4882a593Smuzhiyun (class != InputOnly) && (depth != pParent->drawable.depth)) {
830*4882a593Smuzhiyun return BadMatch;
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun if (((stuff->mask & CWColormap) == 0) &&
834*4882a593Smuzhiyun (class != InputOnly) &&
835*4882a593Smuzhiyun ((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
836*4882a593Smuzhiyun return BadMatch;
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun /* end of errors from CreateWindow */
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun pPriv = GetScreenPrivate(pScreen);
842*4882a593Smuzhiyun if (pPriv && pPriv->attr) {
843*4882a593Smuzhiyun if (pPriv->attr->client != client)
844*4882a593Smuzhiyun return BadAccess;
845*4882a593Smuzhiyun }
846*4882a593Smuzhiyun if (!pPriv) {
847*4882a593Smuzhiyun pPriv = MakeScreenPrivate(pScreen);
848*4882a593Smuzhiyun if (!pPriv)
849*4882a593Smuzhiyun return FALSE;
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun pAttr = New(ScreenSaverAttrRec);
852*4882a593Smuzhiyun if (!pAttr) {
853*4882a593Smuzhiyun ret = BadAlloc;
854*4882a593Smuzhiyun goto bail;
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun /* over allocate for override redirect */
857*4882a593Smuzhiyun pAttr->values = values = xallocarray(len + 1, sizeof(unsigned long));
858*4882a593Smuzhiyun if (!values) {
859*4882a593Smuzhiyun ret = BadAlloc;
860*4882a593Smuzhiyun goto bail;
861*4882a593Smuzhiyun }
862*4882a593Smuzhiyun pAttr->screen = pScreen;
863*4882a593Smuzhiyun pAttr->client = client;
864*4882a593Smuzhiyun pAttr->x = stuff->x;
865*4882a593Smuzhiyun pAttr->y = stuff->y;
866*4882a593Smuzhiyun pAttr->width = stuff->width;
867*4882a593Smuzhiyun pAttr->height = stuff->height;
868*4882a593Smuzhiyun pAttr->borderWidth = stuff->borderWidth;
869*4882a593Smuzhiyun pAttr->class = stuff->c_class;
870*4882a593Smuzhiyun pAttr->depth = depth;
871*4882a593Smuzhiyun pAttr->visual = visual;
872*4882a593Smuzhiyun pAttr->colormap = None;
873*4882a593Smuzhiyun pAttr->pCursor = NullCursor;
874*4882a593Smuzhiyun pAttr->pBackgroundPixmap = NullPixmap;
875*4882a593Smuzhiyun pAttr->pBorderPixmap = NullPixmap;
876*4882a593Smuzhiyun /*
877*4882a593Smuzhiyun * go through the mask, checking the values,
878*4882a593Smuzhiyun * looking up pixmaps and cursors and hold a reference
879*4882a593Smuzhiyun * to them.
880*4882a593Smuzhiyun */
881*4882a593Smuzhiyun pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
882*4882a593Smuzhiyun pVlist = (unsigned int *) (stuff + 1);
883*4882a593Smuzhiyun while (tmask) {
884*4882a593Smuzhiyun imask = lowbit(tmask);
885*4882a593Smuzhiyun tmask &= ~imask;
886*4882a593Smuzhiyun switch (imask) {
887*4882a593Smuzhiyun case CWBackPixmap:
888*4882a593Smuzhiyun pixID = (Pixmap) * pVlist;
889*4882a593Smuzhiyun if (pixID == None) {
890*4882a593Smuzhiyun *values++ = None;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun else if (pixID == ParentRelative) {
893*4882a593Smuzhiyun if (depth != pParent->drawable.depth) {
894*4882a593Smuzhiyun ret = BadMatch;
895*4882a593Smuzhiyun goto PatchUp;
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun *values++ = ParentRelative;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun else {
900*4882a593Smuzhiyun ret =
901*4882a593Smuzhiyun dixLookupResourceByType((void **) &pPixmap, pixID,
902*4882a593Smuzhiyun RT_PIXMAP, client, DixReadAccess);
903*4882a593Smuzhiyun if (ret == Success) {
904*4882a593Smuzhiyun if ((pPixmap->drawable.depth != depth) ||
905*4882a593Smuzhiyun (pPixmap->drawable.pScreen != pScreen)) {
906*4882a593Smuzhiyun ret = BadMatch;
907*4882a593Smuzhiyun goto PatchUp;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun pAttr->pBackgroundPixmap = pPixmap;
910*4882a593Smuzhiyun pPixmap->refcnt++;
911*4882a593Smuzhiyun pAttr->mask &= ~CWBackPixmap;
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun else {
914*4882a593Smuzhiyun client->errorValue = pixID;
915*4882a593Smuzhiyun goto PatchUp;
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun }
918*4882a593Smuzhiyun break;
919*4882a593Smuzhiyun case CWBackPixel:
920*4882a593Smuzhiyun *values++ = (CARD32) *pVlist;
921*4882a593Smuzhiyun break;
922*4882a593Smuzhiyun case CWBorderPixmap:
923*4882a593Smuzhiyun pixID = (Pixmap) * pVlist;
924*4882a593Smuzhiyun if (pixID == CopyFromParent) {
925*4882a593Smuzhiyun if (depth != pParent->drawable.depth) {
926*4882a593Smuzhiyun ret = BadMatch;
927*4882a593Smuzhiyun goto PatchUp;
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun *values++ = CopyFromParent;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun else {
932*4882a593Smuzhiyun ret =
933*4882a593Smuzhiyun dixLookupResourceByType((void **) &pPixmap, pixID,
934*4882a593Smuzhiyun RT_PIXMAP, client, DixReadAccess);
935*4882a593Smuzhiyun if (ret == Success) {
936*4882a593Smuzhiyun if ((pPixmap->drawable.depth != depth) ||
937*4882a593Smuzhiyun (pPixmap->drawable.pScreen != pScreen)) {
938*4882a593Smuzhiyun ret = BadMatch;
939*4882a593Smuzhiyun goto PatchUp;
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun pAttr->pBorderPixmap = pPixmap;
942*4882a593Smuzhiyun pPixmap->refcnt++;
943*4882a593Smuzhiyun pAttr->mask &= ~CWBorderPixmap;
944*4882a593Smuzhiyun }
945*4882a593Smuzhiyun else {
946*4882a593Smuzhiyun client->errorValue = pixID;
947*4882a593Smuzhiyun goto PatchUp;
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun break;
951*4882a593Smuzhiyun case CWBorderPixel:
952*4882a593Smuzhiyun *values++ = (CARD32) *pVlist;
953*4882a593Smuzhiyun break;
954*4882a593Smuzhiyun case CWBitGravity:
955*4882a593Smuzhiyun val = (CARD8) *pVlist;
956*4882a593Smuzhiyun if (val > StaticGravity) {
957*4882a593Smuzhiyun ret = BadValue;
958*4882a593Smuzhiyun client->errorValue = val;
959*4882a593Smuzhiyun goto PatchUp;
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun *values++ = val;
962*4882a593Smuzhiyun break;
963*4882a593Smuzhiyun case CWWinGravity:
964*4882a593Smuzhiyun val = (CARD8) *pVlist;
965*4882a593Smuzhiyun if (val > StaticGravity) {
966*4882a593Smuzhiyun ret = BadValue;
967*4882a593Smuzhiyun client->errorValue = val;
968*4882a593Smuzhiyun goto PatchUp;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun *values++ = val;
971*4882a593Smuzhiyun break;
972*4882a593Smuzhiyun case CWBackingStore:
973*4882a593Smuzhiyun val = (CARD8) *pVlist;
974*4882a593Smuzhiyun if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
975*4882a593Smuzhiyun ret = BadValue;
976*4882a593Smuzhiyun client->errorValue = val;
977*4882a593Smuzhiyun goto PatchUp;
978*4882a593Smuzhiyun }
979*4882a593Smuzhiyun *values++ = val;
980*4882a593Smuzhiyun break;
981*4882a593Smuzhiyun case CWBackingPlanes:
982*4882a593Smuzhiyun *values++ = (CARD32) *pVlist;
983*4882a593Smuzhiyun break;
984*4882a593Smuzhiyun case CWBackingPixel:
985*4882a593Smuzhiyun *values++ = (CARD32) *pVlist;
986*4882a593Smuzhiyun break;
987*4882a593Smuzhiyun case CWSaveUnder:
988*4882a593Smuzhiyun val = (BOOL) * pVlist;
989*4882a593Smuzhiyun if ((val != xTrue) && (val != xFalse)) {
990*4882a593Smuzhiyun ret = BadValue;
991*4882a593Smuzhiyun client->errorValue = val;
992*4882a593Smuzhiyun goto PatchUp;
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun *values++ = val;
995*4882a593Smuzhiyun break;
996*4882a593Smuzhiyun case CWEventMask:
997*4882a593Smuzhiyun *values++ = (CARD32) *pVlist;
998*4882a593Smuzhiyun break;
999*4882a593Smuzhiyun case CWDontPropagate:
1000*4882a593Smuzhiyun *values++ = (CARD32) *pVlist;
1001*4882a593Smuzhiyun break;
1002*4882a593Smuzhiyun case CWOverrideRedirect:
1003*4882a593Smuzhiyun if (!(stuff->mask & CWOverrideRedirect))
1004*4882a593Smuzhiyun pVlist--;
1005*4882a593Smuzhiyun else {
1006*4882a593Smuzhiyun val = (BOOL) * pVlist;
1007*4882a593Smuzhiyun if ((val != xTrue) && (val != xFalse)) {
1008*4882a593Smuzhiyun ret = BadValue;
1009*4882a593Smuzhiyun client->errorValue = val;
1010*4882a593Smuzhiyun goto PatchUp;
1011*4882a593Smuzhiyun }
1012*4882a593Smuzhiyun }
1013*4882a593Smuzhiyun *values++ = xTrue;
1014*4882a593Smuzhiyun break;
1015*4882a593Smuzhiyun case CWColormap:
1016*4882a593Smuzhiyun cmap = (Colormap) * pVlist;
1017*4882a593Smuzhiyun ret = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP,
1018*4882a593Smuzhiyun client, DixUseAccess);
1019*4882a593Smuzhiyun if (ret != Success) {
1020*4882a593Smuzhiyun client->errorValue = cmap;
1021*4882a593Smuzhiyun goto PatchUp;
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) {
1024*4882a593Smuzhiyun ret = BadMatch;
1025*4882a593Smuzhiyun goto PatchUp;
1026*4882a593Smuzhiyun }
1027*4882a593Smuzhiyun pAttr->colormap = cmap;
1028*4882a593Smuzhiyun pAttr->mask &= ~CWColormap;
1029*4882a593Smuzhiyun break;
1030*4882a593Smuzhiyun case CWCursor:
1031*4882a593Smuzhiyun cursorID = (Cursor) * pVlist;
1032*4882a593Smuzhiyun if (cursorID == None) {
1033*4882a593Smuzhiyun *values++ = None;
1034*4882a593Smuzhiyun }
1035*4882a593Smuzhiyun else {
1036*4882a593Smuzhiyun ret = dixLookupResourceByType((void **) &pCursor, cursorID,
1037*4882a593Smuzhiyun RT_CURSOR, client, DixUseAccess);
1038*4882a593Smuzhiyun if (ret != Success) {
1039*4882a593Smuzhiyun client->errorValue = cursorID;
1040*4882a593Smuzhiyun goto PatchUp;
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun pAttr->pCursor = RefCursor(pCursor);
1043*4882a593Smuzhiyun pAttr->mask &= ~CWCursor;
1044*4882a593Smuzhiyun }
1045*4882a593Smuzhiyun break;
1046*4882a593Smuzhiyun default:
1047*4882a593Smuzhiyun ret = BadValue;
1048*4882a593Smuzhiyun client->errorValue = stuff->mask;
1049*4882a593Smuzhiyun goto PatchUp;
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun pVlist++;
1052*4882a593Smuzhiyun }
1053*4882a593Smuzhiyun if (pPriv->attr)
1054*4882a593Smuzhiyun FreeScreenAttr(pPriv->attr);
1055*4882a593Smuzhiyun pPriv->attr = pAttr;
1056*4882a593Smuzhiyun pAttr->resource = FakeClientID(client->index);
1057*4882a593Smuzhiyun if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
1058*4882a593Smuzhiyun return BadAlloc;
1059*4882a593Smuzhiyun return Success;
1060*4882a593Smuzhiyun PatchUp:
1061*4882a593Smuzhiyun FreeAttrs(pAttr);
1062*4882a593Smuzhiyun bail:
1063*4882a593Smuzhiyun CheckScreenPrivate(pScreen);
1064*4882a593Smuzhiyun if (pAttr)
1065*4882a593Smuzhiyun free(pAttr->values);
1066*4882a593Smuzhiyun free(pAttr);
1067*4882a593Smuzhiyun return ret;
1068*4882a593Smuzhiyun }
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun static int
ScreenSaverUnsetAttributes(ClientPtr client)1071*4882a593Smuzhiyun ScreenSaverUnsetAttributes(ClientPtr client)
1072*4882a593Smuzhiyun {
1073*4882a593Smuzhiyun REQUEST(xScreenSaverSetAttributesReq);
1074*4882a593Smuzhiyun DrawablePtr pDraw;
1075*4882a593Smuzhiyun ScreenSaverScreenPrivatePtr pPriv;
1076*4882a593Smuzhiyun int rc;
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
1079*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
1080*4882a593Smuzhiyun DixGetAttrAccess);
1081*4882a593Smuzhiyun if (rc != Success)
1082*4882a593Smuzhiyun return rc;
1083*4882a593Smuzhiyun pPriv = GetScreenPrivate(pDraw->pScreen);
1084*4882a593Smuzhiyun if (pPriv && pPriv->attr && pPriv->attr->client == client) {
1085*4882a593Smuzhiyun FreeResource(pPriv->attr->resource, AttrType);
1086*4882a593Smuzhiyun FreeScreenAttr(pPriv->attr);
1087*4882a593Smuzhiyun pPriv->attr = NULL;
1088*4882a593Smuzhiyun CheckScreenPrivate(pDraw->pScreen);
1089*4882a593Smuzhiyun }
1090*4882a593Smuzhiyun return Success;
1091*4882a593Smuzhiyun }
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun static int
ProcScreenSaverSetAttributes(ClientPtr client)1094*4882a593Smuzhiyun ProcScreenSaverSetAttributes(ClientPtr client)
1095*4882a593Smuzhiyun {
1096*4882a593Smuzhiyun #ifdef PANORAMIX
1097*4882a593Smuzhiyun if (!noPanoramiXExtension) {
1098*4882a593Smuzhiyun REQUEST(xScreenSaverSetAttributesReq);
1099*4882a593Smuzhiyun PanoramiXRes *draw;
1100*4882a593Smuzhiyun PanoramiXRes *backPix = NULL;
1101*4882a593Smuzhiyun PanoramiXRes *bordPix = NULL;
1102*4882a593Smuzhiyun PanoramiXRes *cmap = NULL;
1103*4882a593Smuzhiyun int i, status, len;
1104*4882a593Smuzhiyun int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
1105*4882a593Smuzhiyun XID orig_visual, tmp;
1106*4882a593Smuzhiyun
1107*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
1108*4882a593Smuzhiyun
1109*4882a593Smuzhiyun status = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1110*4882a593Smuzhiyun XRC_DRAWABLE, client, DixWriteAccess);
1111*4882a593Smuzhiyun if (status != Success)
1112*4882a593Smuzhiyun return (status == BadValue) ? BadDrawable : status;
1113*4882a593Smuzhiyun
1114*4882a593Smuzhiyun len =
1115*4882a593Smuzhiyun stuff->length -
1116*4882a593Smuzhiyun bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
1117*4882a593Smuzhiyun if (Ones(stuff->mask) != len)
1118*4882a593Smuzhiyun return BadLength;
1119*4882a593Smuzhiyun
1120*4882a593Smuzhiyun if ((Mask) stuff->mask & CWBackPixmap) {
1121*4882a593Smuzhiyun pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1));
1122*4882a593Smuzhiyun tmp = *((CARD32 *) &stuff[1] + pback_offset);
1123*4882a593Smuzhiyun if ((tmp != None) && (tmp != ParentRelative)) {
1124*4882a593Smuzhiyun status = dixLookupResourceByType((void **) &backPix, tmp,
1125*4882a593Smuzhiyun XRT_PIXMAP, client,
1126*4882a593Smuzhiyun DixReadAccess);
1127*4882a593Smuzhiyun if (status != Success)
1128*4882a593Smuzhiyun return status;
1129*4882a593Smuzhiyun }
1130*4882a593Smuzhiyun }
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun if ((Mask) stuff->mask & CWBorderPixmap) {
1133*4882a593Smuzhiyun pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1));
1134*4882a593Smuzhiyun tmp = *((CARD32 *) &stuff[1] + pbord_offset);
1135*4882a593Smuzhiyun if (tmp != CopyFromParent) {
1136*4882a593Smuzhiyun status = dixLookupResourceByType((void **) &bordPix, tmp,
1137*4882a593Smuzhiyun XRT_PIXMAP, client,
1138*4882a593Smuzhiyun DixReadAccess);
1139*4882a593Smuzhiyun if (status != Success)
1140*4882a593Smuzhiyun return status;
1141*4882a593Smuzhiyun }
1142*4882a593Smuzhiyun }
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun if ((Mask) stuff->mask & CWColormap) {
1145*4882a593Smuzhiyun cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
1146*4882a593Smuzhiyun tmp = *((CARD32 *) &stuff[1] + cmap_offset);
1147*4882a593Smuzhiyun if (tmp != CopyFromParent) {
1148*4882a593Smuzhiyun status = dixLookupResourceByType((void **) &cmap, tmp,
1149*4882a593Smuzhiyun XRT_COLORMAP, client,
1150*4882a593Smuzhiyun DixReadAccess);
1151*4882a593Smuzhiyun if (status != Success)
1152*4882a593Smuzhiyun return status;
1153*4882a593Smuzhiyun }
1154*4882a593Smuzhiyun }
1155*4882a593Smuzhiyun
1156*4882a593Smuzhiyun orig_visual = stuff->visualID;
1157*4882a593Smuzhiyun
1158*4882a593Smuzhiyun FOR_NSCREENS_BACKWARD(i) {
1159*4882a593Smuzhiyun stuff->drawable = draw->info[i].id;
1160*4882a593Smuzhiyun if (backPix)
1161*4882a593Smuzhiyun *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
1162*4882a593Smuzhiyun if (bordPix)
1163*4882a593Smuzhiyun *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
1164*4882a593Smuzhiyun if (cmap)
1165*4882a593Smuzhiyun *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
1166*4882a593Smuzhiyun
1167*4882a593Smuzhiyun if (orig_visual != CopyFromParent)
1168*4882a593Smuzhiyun stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual);
1169*4882a593Smuzhiyun
1170*4882a593Smuzhiyun status = ScreenSaverSetAttributes(client);
1171*4882a593Smuzhiyun }
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun return status;
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun #endif
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun return ScreenSaverSetAttributes(client);
1178*4882a593Smuzhiyun }
1179*4882a593Smuzhiyun
1180*4882a593Smuzhiyun static int
ProcScreenSaverUnsetAttributes(ClientPtr client)1181*4882a593Smuzhiyun ProcScreenSaverUnsetAttributes(ClientPtr client)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun #ifdef PANORAMIX
1184*4882a593Smuzhiyun if (!noPanoramiXExtension) {
1185*4882a593Smuzhiyun REQUEST(xScreenSaverUnsetAttributesReq);
1186*4882a593Smuzhiyun PanoramiXRes *draw;
1187*4882a593Smuzhiyun int rc, i;
1188*4882a593Smuzhiyun
1189*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1192*4882a593Smuzhiyun XRC_DRAWABLE, client, DixWriteAccess);
1193*4882a593Smuzhiyun if (rc != Success)
1194*4882a593Smuzhiyun return (rc == BadValue) ? BadDrawable : rc;
1195*4882a593Smuzhiyun
1196*4882a593Smuzhiyun for (i = PanoramiXNumScreens - 1; i > 0; i--) {
1197*4882a593Smuzhiyun stuff->drawable = draw->info[i].id;
1198*4882a593Smuzhiyun ScreenSaverUnsetAttributes(client);
1199*4882a593Smuzhiyun }
1200*4882a593Smuzhiyun
1201*4882a593Smuzhiyun stuff->drawable = draw->info[0].id;
1202*4882a593Smuzhiyun }
1203*4882a593Smuzhiyun #endif
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun return ScreenSaverUnsetAttributes(client);
1206*4882a593Smuzhiyun }
1207*4882a593Smuzhiyun
1208*4882a593Smuzhiyun static int
ProcScreenSaverSuspend(ClientPtr client)1209*4882a593Smuzhiyun ProcScreenSaverSuspend(ClientPtr client)
1210*4882a593Smuzhiyun {
1211*4882a593Smuzhiyun ScreenSaverSuspensionPtr *prev, this;
1212*4882a593Smuzhiyun BOOL suspend;
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun REQUEST(xScreenSaverSuspendReq);
1215*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun /*
1218*4882a593Smuzhiyun * Old versions of XCB encode suspend as 1 byte followed by three
1219*4882a593Smuzhiyun * pad bytes (which are always cleared), instead of a 4 byte
1220*4882a593Smuzhiyun * value. Be compatible by just checking for a non-zero value in
1221*4882a593Smuzhiyun * all 32-bits.
1222*4882a593Smuzhiyun */
1223*4882a593Smuzhiyun suspend = stuff->suspend != 0;
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun /* Check if this client is suspending the screensaver */
1226*4882a593Smuzhiyun for (prev = &suspendingClients; (this = *prev); prev = &this->next)
1227*4882a593Smuzhiyun if (this->pClient == client)
1228*4882a593Smuzhiyun break;
1229*4882a593Smuzhiyun
1230*4882a593Smuzhiyun if (this) {
1231*4882a593Smuzhiyun if (suspend == TRUE)
1232*4882a593Smuzhiyun this->count++;
1233*4882a593Smuzhiyun else if (--this->count == 0)
1234*4882a593Smuzhiyun FreeResource(this->clientResource, RT_NONE);
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun return Success;
1237*4882a593Smuzhiyun }
1238*4882a593Smuzhiyun
1239*4882a593Smuzhiyun /* If we get to this point, this client isn't suspending the screensaver */
1240*4882a593Smuzhiyun if (suspend == FALSE)
1241*4882a593Smuzhiyun return Success;
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun /*
1244*4882a593Smuzhiyun * Allocate a suspension record for the client, and stop the screensaver
1245*4882a593Smuzhiyun * if it isn't already suspended by another client. We attach a resource ID
1246*4882a593Smuzhiyun * to the record, so the screensaver will be reenabled and the record freed
1247*4882a593Smuzhiyun * if the client disconnects without reenabling it first.
1248*4882a593Smuzhiyun */
1249*4882a593Smuzhiyun this = malloc(sizeof(ScreenSaverSuspensionRec));
1250*4882a593Smuzhiyun
1251*4882a593Smuzhiyun if (!this)
1252*4882a593Smuzhiyun return BadAlloc;
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun this->next = NULL;
1255*4882a593Smuzhiyun this->pClient = client;
1256*4882a593Smuzhiyun this->count = 1;
1257*4882a593Smuzhiyun this->clientResource = FakeClientID(client->index);
1258*4882a593Smuzhiyun
1259*4882a593Smuzhiyun if (!AddResource(this->clientResource, SuspendType, (void *) this)) {
1260*4882a593Smuzhiyun free(this);
1261*4882a593Smuzhiyun return BadAlloc;
1262*4882a593Smuzhiyun }
1263*4882a593Smuzhiyun
1264*4882a593Smuzhiyun *prev = this;
1265*4882a593Smuzhiyun if (!screenSaverSuspended) {
1266*4882a593Smuzhiyun screenSaverSuspended = TRUE;
1267*4882a593Smuzhiyun FreeScreenSaverTimer();
1268*4882a593Smuzhiyun }
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun return Success;
1271*4882a593Smuzhiyun }
1272*4882a593Smuzhiyun
1273*4882a593Smuzhiyun static int (*NormalVector[]) (ClientPtr /* client */ ) = {
1274*4882a593Smuzhiyun ProcScreenSaverQueryVersion,
1275*4882a593Smuzhiyun ProcScreenSaverQueryInfo,
1276*4882a593Smuzhiyun ProcScreenSaverSelectInput,
1277*4882a593Smuzhiyun ProcScreenSaverSetAttributes,
1278*4882a593Smuzhiyun ProcScreenSaverUnsetAttributes, ProcScreenSaverSuspend,};
1279*4882a593Smuzhiyun
1280*4882a593Smuzhiyun static int
ProcScreenSaverDispatch(ClientPtr client)1281*4882a593Smuzhiyun ProcScreenSaverDispatch(ClientPtr client)
1282*4882a593Smuzhiyun {
1283*4882a593Smuzhiyun REQUEST(xReq);
1284*4882a593Smuzhiyun
1285*4882a593Smuzhiyun if (stuff->data < ARRAY_SIZE(NormalVector))
1286*4882a593Smuzhiyun return (*NormalVector[stuff->data]) (client);
1287*4882a593Smuzhiyun return BadRequest;
1288*4882a593Smuzhiyun }
1289*4882a593Smuzhiyun
1290*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverQueryVersion(ClientPtr client)1291*4882a593Smuzhiyun SProcScreenSaverQueryVersion(ClientPtr client)
1292*4882a593Smuzhiyun {
1293*4882a593Smuzhiyun REQUEST(xScreenSaverQueryVersionReq);
1294*4882a593Smuzhiyun swaps(&stuff->length);
1295*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
1296*4882a593Smuzhiyun return ProcScreenSaverQueryVersion(client);
1297*4882a593Smuzhiyun }
1298*4882a593Smuzhiyun
1299*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverQueryInfo(ClientPtr client)1300*4882a593Smuzhiyun SProcScreenSaverQueryInfo(ClientPtr client)
1301*4882a593Smuzhiyun {
1302*4882a593Smuzhiyun REQUEST(xScreenSaverQueryInfoReq);
1303*4882a593Smuzhiyun swaps(&stuff->length);
1304*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
1305*4882a593Smuzhiyun swapl(&stuff->drawable);
1306*4882a593Smuzhiyun return ProcScreenSaverQueryInfo(client);
1307*4882a593Smuzhiyun }
1308*4882a593Smuzhiyun
1309*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverSelectInput(ClientPtr client)1310*4882a593Smuzhiyun SProcScreenSaverSelectInput(ClientPtr client)
1311*4882a593Smuzhiyun {
1312*4882a593Smuzhiyun REQUEST(xScreenSaverSelectInputReq);
1313*4882a593Smuzhiyun swaps(&stuff->length);
1314*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
1315*4882a593Smuzhiyun swapl(&stuff->drawable);
1316*4882a593Smuzhiyun swapl(&stuff->eventMask);
1317*4882a593Smuzhiyun return ProcScreenSaverSelectInput(client);
1318*4882a593Smuzhiyun }
1319*4882a593Smuzhiyun
1320*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverSetAttributes(ClientPtr client)1321*4882a593Smuzhiyun SProcScreenSaverSetAttributes(ClientPtr client)
1322*4882a593Smuzhiyun {
1323*4882a593Smuzhiyun REQUEST(xScreenSaverSetAttributesReq);
1324*4882a593Smuzhiyun swaps(&stuff->length);
1325*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
1326*4882a593Smuzhiyun swapl(&stuff->drawable);
1327*4882a593Smuzhiyun swaps(&stuff->x);
1328*4882a593Smuzhiyun swaps(&stuff->y);
1329*4882a593Smuzhiyun swaps(&stuff->width);
1330*4882a593Smuzhiyun swaps(&stuff->height);
1331*4882a593Smuzhiyun swaps(&stuff->borderWidth);
1332*4882a593Smuzhiyun swapl(&stuff->visualID);
1333*4882a593Smuzhiyun swapl(&stuff->mask);
1334*4882a593Smuzhiyun SwapRestL(stuff);
1335*4882a593Smuzhiyun return ProcScreenSaverSetAttributes(client);
1336*4882a593Smuzhiyun }
1337*4882a593Smuzhiyun
1338*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverUnsetAttributes(ClientPtr client)1339*4882a593Smuzhiyun SProcScreenSaverUnsetAttributes(ClientPtr client)
1340*4882a593Smuzhiyun {
1341*4882a593Smuzhiyun REQUEST(xScreenSaverUnsetAttributesReq);
1342*4882a593Smuzhiyun swaps(&stuff->length);
1343*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
1344*4882a593Smuzhiyun swapl(&stuff->drawable);
1345*4882a593Smuzhiyun return ProcScreenSaverUnsetAttributes(client);
1346*4882a593Smuzhiyun }
1347*4882a593Smuzhiyun
1348*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverSuspend(ClientPtr client)1349*4882a593Smuzhiyun SProcScreenSaverSuspend(ClientPtr client)
1350*4882a593Smuzhiyun {
1351*4882a593Smuzhiyun REQUEST(xScreenSaverSuspendReq);
1352*4882a593Smuzhiyun
1353*4882a593Smuzhiyun swaps(&stuff->length);
1354*4882a593Smuzhiyun swapl(&stuff->suspend);
1355*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
1356*4882a593Smuzhiyun return ProcScreenSaverSuspend(client);
1357*4882a593Smuzhiyun }
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun static int (*SwappedVector[]) (ClientPtr /* client */ ) = {
1360*4882a593Smuzhiyun SProcScreenSaverQueryVersion,
1361*4882a593Smuzhiyun SProcScreenSaverQueryInfo,
1362*4882a593Smuzhiyun SProcScreenSaverSelectInput,
1363*4882a593Smuzhiyun SProcScreenSaverSetAttributes,
1364*4882a593Smuzhiyun SProcScreenSaverUnsetAttributes, SProcScreenSaverSuspend,};
1365*4882a593Smuzhiyun
1366*4882a593Smuzhiyun static int _X_COLD
SProcScreenSaverDispatch(ClientPtr client)1367*4882a593Smuzhiyun SProcScreenSaverDispatch(ClientPtr client)
1368*4882a593Smuzhiyun {
1369*4882a593Smuzhiyun REQUEST(xReq);
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun if (stuff->data < ARRAY_SIZE(NormalVector))
1372*4882a593Smuzhiyun return (*SwappedVector[stuff->data]) (client);
1373*4882a593Smuzhiyun return BadRequest;
1374*4882a593Smuzhiyun }
1375*4882a593Smuzhiyun
1376*4882a593Smuzhiyun void
ScreenSaverExtensionInit(void)1377*4882a593Smuzhiyun ScreenSaverExtensionInit(void)
1378*4882a593Smuzhiyun {
1379*4882a593Smuzhiyun ExtensionEntry *extEntry;
1380*4882a593Smuzhiyun int i;
1381*4882a593Smuzhiyun ScreenPtr pScreen;
1382*4882a593Smuzhiyun
1383*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
1384*4882a593Smuzhiyun return;
1385*4882a593Smuzhiyun
1386*4882a593Smuzhiyun AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr");
1387*4882a593Smuzhiyun SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, "SaverEvent");
1388*4882a593Smuzhiyun SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, "SaverSuspend");
1389*4882a593Smuzhiyun
1390*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
1391*4882a593Smuzhiyun pScreen = screenInfo.screens[i];
1392*4882a593Smuzhiyun SetScreenPrivate(pScreen, NULL);
1393*4882a593Smuzhiyun }
1394*4882a593Smuzhiyun if (AttrType && SaverEventType && SuspendType &&
1395*4882a593Smuzhiyun (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
1396*4882a593Smuzhiyun ProcScreenSaverDispatch,
1397*4882a593Smuzhiyun SProcScreenSaverDispatch, NULL,
1398*4882a593Smuzhiyun StandardMinorOpcode))) {
1399*4882a593Smuzhiyun ScreenSaverEventBase = extEntry->eventBase;
1400*4882a593Smuzhiyun EventSwapVector[ScreenSaverEventBase] =
1401*4882a593Smuzhiyun (EventSwapPtr) SScreenSaverNotifyEvent;
1402*4882a593Smuzhiyun }
1403*4882a593Smuzhiyun }
1404