saver.c revision 4642e01f
105b261ecSmrg/* 205b261ecSmrg * 305b261ecSmrgCopyright (c) 1992 X Consortium 405b261ecSmrg 505b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 605b261ecSmrgof this software and associated documentation files (the "Software"), to deal 705b261ecSmrgin the Software without restriction, including without limitation the rights 805b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 905b261ecSmrgcopies of the Software, and to permit persons to whom the Software is 1005b261ecSmrgfurnished to do so, subject to the following conditions: 1105b261ecSmrg 1205b261ecSmrgThe above copyright notice and this permission notice shall be included in 1305b261ecSmrgall copies or substantial portions of the Software. 1405b261ecSmrg 1505b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1605b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1705b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1805b261ecSmrgX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1905b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2005b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2105b261ecSmrg 2205b261ecSmrgExcept as contained in this notice, the name of the X Consortium shall not be 2305b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2405b261ecSmrgin this Software without prior written authorization from the X Consortium. 2505b261ecSmrg * 2605b261ecSmrg * Author: Keith Packard, MIT X Consortium 2705b261ecSmrg */ 2805b261ecSmrg 2905b261ecSmrg 3005b261ecSmrg#define NEED_REPLIES 3105b261ecSmrg#define NEED_EVENTS 3205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 3305b261ecSmrg#include <dix-config.h> 3405b261ecSmrg#endif 3505b261ecSmrg 3605b261ecSmrg#include <X11/X.h> 3705b261ecSmrg#include <X11/Xproto.h> 3805b261ecSmrg#include "misc.h" 3905b261ecSmrg#include "os.h" 4005b261ecSmrg#include "windowstr.h" 4105b261ecSmrg#include "scrnintstr.h" 4205b261ecSmrg#include "pixmapstr.h" 4305b261ecSmrg#include "extnsionst.h" 4405b261ecSmrg#include "dixstruct.h" 4505b261ecSmrg#include "resource.h" 4605b261ecSmrg#include "opaque.h" 4705b261ecSmrg#include <X11/extensions/saverproto.h> 4805b261ecSmrg#include "gcstruct.h" 4905b261ecSmrg#include "cursorstr.h" 5005b261ecSmrg#include "colormapst.h" 514642e01fSmrg#include "xace.h" 5205b261ecSmrg#ifdef PANORAMIX 5305b261ecSmrg#include "panoramiX.h" 5405b261ecSmrg#include "panoramiXsrv.h" 5505b261ecSmrg#endif 5605b261ecSmrg#ifdef DPMSExtension 5705b261ecSmrg#define DPMS_SERVER 5805b261ecSmrg#include <X11/extensions/dpms.h> 5905b261ecSmrg#endif 6005b261ecSmrg 6105b261ecSmrg#include <stdio.h> 6205b261ecSmrg 6305b261ecSmrg#include "modinit.h" 6405b261ecSmrg 6505b261ecSmrgstatic int ScreenSaverEventBase = 0; 6605b261ecSmrg 6705b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverQueryInfo); 6805b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverDispatch); 6905b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverQueryVersion); 7005b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSelectInput); 7105b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSetAttributes); 7205b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverUnsetAttributes); 7305b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSuspend); 7405b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverDispatch); 7505b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverQueryInfo); 7605b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverQueryVersion); 7705b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSelectInput); 7805b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSetAttributes); 7905b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverUnsetAttributes); 8005b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSuspend); 8105b261ecSmrg 8205b261ecSmrgstatic Bool ScreenSaverHandle ( 8305b261ecSmrg ScreenPtr /* pScreen */, 8405b261ecSmrg int /* xstate */, 8505b261ecSmrg Bool /* force */ 8605b261ecSmrg ); 8705b261ecSmrg 8805b261ecSmrgstatic Bool 8905b261ecSmrgCreateSaverWindow ( 9005b261ecSmrg ScreenPtr /* pScreen */ 9105b261ecSmrg ); 9205b261ecSmrg 9305b261ecSmrgstatic Bool 9405b261ecSmrgDestroySaverWindow ( 9505b261ecSmrg ScreenPtr /* pScreen */ 9605b261ecSmrg ); 9705b261ecSmrg 9805b261ecSmrgstatic void 9905b261ecSmrgUninstallSaverColormap ( 10005b261ecSmrg ScreenPtr /* pScreen */ 10105b261ecSmrg ); 10205b261ecSmrg 10305b261ecSmrgstatic void 10405b261ecSmrgCheckScreenPrivate ( 10505b261ecSmrg ScreenPtr /* pScreen */ 10605b261ecSmrg ); 10705b261ecSmrg 10805b261ecSmrgstatic void SScreenSaverNotifyEvent ( 10905b261ecSmrg xScreenSaverNotifyEvent * /* from */, 11005b261ecSmrg xScreenSaverNotifyEvent * /* to */ 11105b261ecSmrg ); 11205b261ecSmrg 11305b261ecSmrgstatic RESTYPE SuspendType; /* resource type for suspension records */ 11405b261ecSmrg 11505b261ecSmrgtypedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; 11605b261ecSmrg 11705b261ecSmrg/* List of clients that are suspending the screensaver. */ 11805b261ecSmrgstatic ScreenSaverSuspensionPtr suspendingClients = NULL; 11905b261ecSmrg 12005b261ecSmrg/* 12105b261ecSmrg * clientResource is a resource ID that's added when the record is 12205b261ecSmrg * allocated, so the record is freed and the screensaver resumed when 12305b261ecSmrg * the client disconnects. count is the number of times the client has 12405b261ecSmrg * requested the screensaver be suspended. 12505b261ecSmrg */ 12605b261ecSmrgtypedef struct _ScreenSaverSuspension 12705b261ecSmrg{ 12805b261ecSmrg ScreenSaverSuspensionPtr next; 12905b261ecSmrg ClientPtr pClient; 13005b261ecSmrg XID clientResource; 13105b261ecSmrg int count; 13205b261ecSmrg} ScreenSaverSuspensionRec; 13305b261ecSmrg 13405b261ecSmrgstatic int ScreenSaverFreeSuspend( 13505b261ecSmrg pointer /*value */, 13605b261ecSmrg XID /* id */ 13705b261ecSmrg); 13805b261ecSmrg 13905b261ecSmrg/* 14005b261ecSmrg * each screen has a list of clients requesting 14105b261ecSmrg * ScreenSaverNotify events. Each client has a resource 14205b261ecSmrg * for each screen it selects ScreenSaverNotify input for, 14305b261ecSmrg * this resource is used to delete the ScreenSaverNotifyRec 14405b261ecSmrg * entry from the per-screen queue. 14505b261ecSmrg */ 14605b261ecSmrg 14705b261ecSmrgstatic RESTYPE EventType; /* resource type for event masks */ 14805b261ecSmrg 14905b261ecSmrgtypedef struct _ScreenSaverEvent *ScreenSaverEventPtr; 15005b261ecSmrg 15105b261ecSmrgtypedef struct _ScreenSaverEvent { 15205b261ecSmrg ScreenSaverEventPtr next; 15305b261ecSmrg ClientPtr client; 15405b261ecSmrg ScreenPtr screen; 15505b261ecSmrg XID resource; 15605b261ecSmrg CARD32 mask; 15705b261ecSmrg} ScreenSaverEventRec; 15805b261ecSmrg 15905b261ecSmrgstatic int ScreenSaverFreeEvents( 16005b261ecSmrg pointer /* value */, 16105b261ecSmrg XID /* id */ 16205b261ecSmrg); 16305b261ecSmrg 16405b261ecSmrgstatic Bool setEventMask ( 16505b261ecSmrg ScreenPtr /* pScreen */, 16605b261ecSmrg ClientPtr /* client */, 16705b261ecSmrg unsigned long /* mask */ 16805b261ecSmrg); 16905b261ecSmrg 17005b261ecSmrgstatic unsigned long getEventMask ( 17105b261ecSmrg ScreenPtr /* pScreen */, 17205b261ecSmrg ClientPtr /* client */ 17305b261ecSmrg); 17405b261ecSmrg 17505b261ecSmrg/* 17605b261ecSmrg * when a client sets the screen saver attributes, a resource is 17705b261ecSmrg * kept to be freed when the client exits 17805b261ecSmrg */ 17905b261ecSmrg 18005b261ecSmrgstatic RESTYPE AttrType; /* resource type for attributes */ 18105b261ecSmrg 18205b261ecSmrgtypedef struct _ScreenSaverAttr { 18305b261ecSmrg ScreenPtr screen; 18405b261ecSmrg ClientPtr client; 18505b261ecSmrg XID resource; 18605b261ecSmrg short x, y; 18705b261ecSmrg unsigned short width, height, borderWidth; 18805b261ecSmrg unsigned char class; 18905b261ecSmrg unsigned char depth; 19005b261ecSmrg VisualID visual; 19105b261ecSmrg CursorPtr pCursor; 19205b261ecSmrg PixmapPtr pBackgroundPixmap; 19305b261ecSmrg PixmapPtr pBorderPixmap; 19405b261ecSmrg Colormap colormap; 19505b261ecSmrg unsigned long mask; /* no pixmaps or cursors */ 19605b261ecSmrg unsigned long *values; 19705b261ecSmrg} ScreenSaverAttrRec, *ScreenSaverAttrPtr; 19805b261ecSmrg 19905b261ecSmrgstatic int ScreenSaverFreeAttr ( 20005b261ecSmrg pointer /* value */, 20105b261ecSmrg XID /* id */ 20205b261ecSmrg); 20305b261ecSmrg 20405b261ecSmrgstatic void FreeAttrs ( 20505b261ecSmrg ScreenSaverAttrPtr /* pAttr */ 20605b261ecSmrg); 20705b261ecSmrg 20805b261ecSmrgstatic void FreeScreenAttr ( 20905b261ecSmrg ScreenSaverAttrPtr /* pAttr */ 21005b261ecSmrg); 21105b261ecSmrg 21205b261ecSmrgstatic void 21305b261ecSmrgSendScreenSaverNotify ( 21405b261ecSmrg ScreenPtr /* pScreen */, 21505b261ecSmrg int /* state */, 21605b261ecSmrg Bool /* forced */ 21705b261ecSmrg); 21805b261ecSmrg 21905b261ecSmrgtypedef struct _ScreenSaverScreenPrivate { 22005b261ecSmrg ScreenSaverEventPtr events; 22105b261ecSmrg ScreenSaverAttrPtr attr; 22205b261ecSmrg Bool hasWindow; 22305b261ecSmrg Colormap installedMap; 22405b261ecSmrg} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr; 22505b261ecSmrg 22605b261ecSmrgstatic ScreenSaverScreenPrivatePtr 22705b261ecSmrgMakeScreenPrivate ( 22805b261ecSmrg ScreenPtr /* pScreen */ 22905b261ecSmrg ); 23005b261ecSmrg 2314642e01fSmrgstatic int ScreenPrivateKeyIndex; 2324642e01fSmrgstatic DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex; 23305b261ecSmrg 2344642e01fSmrg#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \ 2354642e01fSmrg dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey)) 2364642e01fSmrg#define SetScreenPrivate(s,v) \ 2374642e01fSmrg dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v); 23805b261ecSmrg#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL) 23905b261ecSmrg 24005b261ecSmrg#define New(t) ((t *) xalloc (sizeof (t))) 24105b261ecSmrg 24205b261ecSmrg/**************** 24305b261ecSmrg * ScreenSaverExtensionInit 24405b261ecSmrg * 24505b261ecSmrg * Called from InitExtensions in main() or from QueryExtension() if the 24605b261ecSmrg * extension is dynamically loaded. 24705b261ecSmrg * 24805b261ecSmrg ****************/ 24905b261ecSmrg 25005b261ecSmrgvoid 25105b261ecSmrgScreenSaverExtensionInit(INITARGS) 25205b261ecSmrg{ 25305b261ecSmrg ExtensionEntry *extEntry; 25405b261ecSmrg int i; 25505b261ecSmrg ScreenPtr pScreen; 25605b261ecSmrg 25705b261ecSmrg AttrType = CreateNewResourceType(ScreenSaverFreeAttr); 25805b261ecSmrg EventType = CreateNewResourceType(ScreenSaverFreeEvents); 25905b261ecSmrg SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend); 26005b261ecSmrg 26105b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) 26205b261ecSmrg { 26305b261ecSmrg pScreen = screenInfo.screens[i]; 26405b261ecSmrg SetScreenPrivate (pScreen, NULL); 26505b261ecSmrg } 2664642e01fSmrg if (AttrType && EventType && SuspendType && 26705b261ecSmrg (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, 26805b261ecSmrg ProcScreenSaverDispatch, SProcScreenSaverDispatch, 2694642e01fSmrg NULL, StandardMinorOpcode))) 27005b261ecSmrg { 27105b261ecSmrg ScreenSaverEventBase = extEntry->eventBase; 27205b261ecSmrg EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent; 27305b261ecSmrg } 27405b261ecSmrg} 27505b261ecSmrg 27605b261ecSmrgstatic void 27705b261ecSmrgCheckScreenPrivate (pScreen) 27805b261ecSmrg ScreenPtr pScreen; 27905b261ecSmrg{ 28005b261ecSmrg SetupScreen (pScreen); 28105b261ecSmrg 28205b261ecSmrg if (!pPriv) 28305b261ecSmrg return; 28405b261ecSmrg if (!pPriv->attr && !pPriv->events && 28505b261ecSmrg !pPriv->hasWindow && pPriv->installedMap == None) 28605b261ecSmrg { 28705b261ecSmrg xfree (pPriv); 28805b261ecSmrg SetScreenPrivate (pScreen, NULL); 28905b261ecSmrg savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL; 29005b261ecSmrg } 29105b261ecSmrg} 29205b261ecSmrg 29305b261ecSmrgstatic ScreenSaverScreenPrivatePtr 29405b261ecSmrgMakeScreenPrivate (pScreen) 29505b261ecSmrg ScreenPtr pScreen; 29605b261ecSmrg{ 29705b261ecSmrg SetupScreen (pScreen); 29805b261ecSmrg 29905b261ecSmrg if (pPriv) 30005b261ecSmrg return pPriv; 30105b261ecSmrg pPriv = New (ScreenSaverScreenPrivateRec); 30205b261ecSmrg if (!pPriv) 30305b261ecSmrg return 0; 30405b261ecSmrg pPriv->events = 0; 30505b261ecSmrg pPriv->attr = 0; 30605b261ecSmrg pPriv->hasWindow = FALSE; 30705b261ecSmrg pPriv->installedMap = None; 30805b261ecSmrg SetScreenPrivate (pScreen, pPriv); 30905b261ecSmrg savedScreenInfo[pScreen->myNum].ExternalScreenSaver = ScreenSaverHandle; 31005b261ecSmrg return pPriv; 31105b261ecSmrg} 31205b261ecSmrg 31305b261ecSmrgstatic unsigned long 31405b261ecSmrggetEventMask (pScreen, client) 31505b261ecSmrg ScreenPtr pScreen; 31605b261ecSmrg ClientPtr client; 31705b261ecSmrg{ 31805b261ecSmrg SetupScreen(pScreen); 31905b261ecSmrg ScreenSaverEventPtr pEv; 32005b261ecSmrg 32105b261ecSmrg if (!pPriv) 32205b261ecSmrg return 0; 32305b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 32405b261ecSmrg if (pEv->client == client) 32505b261ecSmrg return pEv->mask; 32605b261ecSmrg return 0; 32705b261ecSmrg} 32805b261ecSmrg 32905b261ecSmrgstatic Bool 33005b261ecSmrgsetEventMask (pScreen, client, mask) 33105b261ecSmrg ScreenPtr pScreen; 33205b261ecSmrg ClientPtr client; 33305b261ecSmrg unsigned long mask; 33405b261ecSmrg{ 33505b261ecSmrg SetupScreen(pScreen); 33605b261ecSmrg ScreenSaverEventPtr pEv, *pPrev; 33705b261ecSmrg 33805b261ecSmrg if (getEventMask (pScreen, client) == mask) 33905b261ecSmrg return TRUE; 34005b261ecSmrg if (!pPriv) 34105b261ecSmrg { 34205b261ecSmrg pPriv = MakeScreenPrivate (pScreen); 34305b261ecSmrg if (!pPriv) 34405b261ecSmrg return FALSE; 34505b261ecSmrg } 34605b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 34705b261ecSmrg if (pEv->client == client) 34805b261ecSmrg break; 34905b261ecSmrg if (mask == 0) 35005b261ecSmrg { 35105b261ecSmrg FreeResource (pEv->resource, EventType); 35205b261ecSmrg *pPrev = pEv->next; 35305b261ecSmrg xfree (pEv); 35405b261ecSmrg CheckScreenPrivate (pScreen); 35505b261ecSmrg } 35605b261ecSmrg else 35705b261ecSmrg { 35805b261ecSmrg if (!pEv) 35905b261ecSmrg { 36005b261ecSmrg pEv = New (ScreenSaverEventRec); 36105b261ecSmrg if (!pEv) 36205b261ecSmrg { 36305b261ecSmrg CheckScreenPrivate (pScreen); 36405b261ecSmrg return FALSE; 36505b261ecSmrg } 36605b261ecSmrg *pPrev = pEv; 36705b261ecSmrg pEv->next = NULL; 36805b261ecSmrg pEv->client = client; 36905b261ecSmrg pEv->screen = pScreen; 37005b261ecSmrg pEv->resource = FakeClientID (client->index); 37105b261ecSmrg if (!AddResource (pEv->resource, EventType, (pointer) pEv)) 37205b261ecSmrg return FALSE; 37305b261ecSmrg } 37405b261ecSmrg pEv->mask = mask; 37505b261ecSmrg } 37605b261ecSmrg return TRUE; 37705b261ecSmrg} 37805b261ecSmrg 37905b261ecSmrgstatic void 38005b261ecSmrgFreeAttrs (pAttr) 38105b261ecSmrg ScreenSaverAttrPtr pAttr; 38205b261ecSmrg{ 38305b261ecSmrg PixmapPtr pPixmap; 38405b261ecSmrg CursorPtr pCursor; 38505b261ecSmrg 38605b261ecSmrg if ((pPixmap = pAttr->pBackgroundPixmap) != 0) 38705b261ecSmrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 38805b261ecSmrg if ((pPixmap = pAttr->pBorderPixmap) != 0) 38905b261ecSmrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 39005b261ecSmrg if ((pCursor = pAttr->pCursor) != 0) 39105b261ecSmrg FreeCursor (pCursor, (Cursor) 0); 39205b261ecSmrg} 39305b261ecSmrg 39405b261ecSmrgstatic void 39505b261ecSmrgFreeScreenAttr (pAttr) 39605b261ecSmrg ScreenSaverAttrPtr pAttr; 39705b261ecSmrg{ 39805b261ecSmrg FreeAttrs (pAttr); 39905b261ecSmrg xfree (pAttr->values); 40005b261ecSmrg xfree (pAttr); 40105b261ecSmrg} 40205b261ecSmrg 40305b261ecSmrgstatic int 40405b261ecSmrgScreenSaverFreeEvents (value, id) 40505b261ecSmrg pointer value; 40605b261ecSmrg XID id; 40705b261ecSmrg{ 40805b261ecSmrg ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value; 40905b261ecSmrg ScreenPtr pScreen = pOld->screen; 41005b261ecSmrg SetupScreen (pScreen); 41105b261ecSmrg ScreenSaverEventPtr pEv, *pPrev; 41205b261ecSmrg 41305b261ecSmrg if (!pPriv) 41405b261ecSmrg return TRUE; 41505b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 41605b261ecSmrg if (pEv == pOld) 41705b261ecSmrg break; 41805b261ecSmrg if (!pEv) 41905b261ecSmrg return TRUE; 42005b261ecSmrg *pPrev = pEv->next; 42105b261ecSmrg xfree (pEv); 42205b261ecSmrg CheckScreenPrivate (pScreen); 42305b261ecSmrg return TRUE; 42405b261ecSmrg} 42505b261ecSmrg 42605b261ecSmrgstatic int 42705b261ecSmrgScreenSaverFreeAttr (value, id) 42805b261ecSmrg pointer value; 42905b261ecSmrg XID id; 43005b261ecSmrg{ 43105b261ecSmrg ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value; 43205b261ecSmrg ScreenPtr pScreen = pOldAttr->screen; 43305b261ecSmrg SetupScreen (pScreen); 43405b261ecSmrg 43505b261ecSmrg if (!pPriv) 43605b261ecSmrg return TRUE; 43705b261ecSmrg if (pPriv->attr != pOldAttr) 43805b261ecSmrg return TRUE; 43905b261ecSmrg FreeScreenAttr (pOldAttr); 44005b261ecSmrg pPriv->attr = NULL; 44105b261ecSmrg if (pPriv->hasWindow) 44205b261ecSmrg { 4434642e01fSmrg dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); 4444642e01fSmrg dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive); 44505b261ecSmrg } 44605b261ecSmrg CheckScreenPrivate (pScreen); 44705b261ecSmrg return TRUE; 44805b261ecSmrg} 44905b261ecSmrg 45005b261ecSmrgstatic int 45105b261ecSmrgScreenSaverFreeSuspend (pointer value, XID id) 45205b261ecSmrg{ 45305b261ecSmrg ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; 45405b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 45505b261ecSmrg 45605b261ecSmrg /* Unlink and free the suspension record for the client */ 45705b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 45805b261ecSmrg { 45905b261ecSmrg if (this == data) 46005b261ecSmrg { 46105b261ecSmrg *prev = this->next; 46205b261ecSmrg xfree (this); 46305b261ecSmrg break; 46405b261ecSmrg } 46505b261ecSmrg } 46605b261ecSmrg 46705b261ecSmrg /* Reenable the screensaver if this was the last client suspending it. */ 46805b261ecSmrg if (screenSaverSuspended && suspendingClients == NULL) 46905b261ecSmrg { 47005b261ecSmrg screenSaverSuspended = FALSE; 47105b261ecSmrg 47205b261ecSmrg /* The screensaver could be active, since suspending it (by design) 47305b261ecSmrg doesn't prevent it from being forceably activated */ 47405b261ecSmrg#ifdef DPMSExtension 47505b261ecSmrg if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) 47605b261ecSmrg#else 47705b261ecSmrg if (screenIsSaved != SCREEN_SAVER_ON) 47805b261ecSmrg#endif 47905b261ecSmrg { 48005b261ecSmrg UpdateCurrentTimeIf(); 48105b261ecSmrg lastDeviceEventTime = currentTime; 48205b261ecSmrg SetScreenSaverTimer(); 48305b261ecSmrg } 48405b261ecSmrg } 48505b261ecSmrg 48605b261ecSmrg return Success; 48705b261ecSmrg} 48805b261ecSmrg 48905b261ecSmrgstatic void 49005b261ecSmrgSendScreenSaverNotify (pScreen, state, forced) 49105b261ecSmrg ScreenPtr pScreen; 49205b261ecSmrg int state; 49305b261ecSmrg Bool forced; 49405b261ecSmrg{ 49505b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 49605b261ecSmrg ScreenSaverEventPtr pEv; 49705b261ecSmrg unsigned long mask; 49805b261ecSmrg xScreenSaverNotifyEvent ev; 49905b261ecSmrg ClientPtr client; 50005b261ecSmrg int kind; 50105b261ecSmrg 50205b261ecSmrg UpdateCurrentTimeIf (); 50305b261ecSmrg mask = ScreenSaverNotifyMask; 50405b261ecSmrg if (state == ScreenSaverCycle) 50505b261ecSmrg mask = ScreenSaverCycleMask; 50605b261ecSmrg pScreen = screenInfo.screens[pScreen->myNum]; 50705b261ecSmrg pPriv = GetScreenPrivate(pScreen); 50805b261ecSmrg if (!pPriv) 50905b261ecSmrg return; 51005b261ecSmrg if (pPriv->attr) 51105b261ecSmrg kind = ScreenSaverExternal; 51205b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 51305b261ecSmrg kind = ScreenSaverBlanked; 51405b261ecSmrg else 51505b261ecSmrg kind = ScreenSaverInternal; 51605b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 51705b261ecSmrg { 51805b261ecSmrg client = pEv->client; 51905b261ecSmrg if (client->clientGone) 52005b261ecSmrg continue; 52105b261ecSmrg if (!(pEv->mask & mask)) 52205b261ecSmrg continue; 52305b261ecSmrg ev.type = ScreenSaverNotify + ScreenSaverEventBase; 52405b261ecSmrg ev.state = state; 52505b261ecSmrg ev.sequenceNumber = client->sequence; 52605b261ecSmrg ev.timestamp = currentTime.milliseconds; 52705b261ecSmrg ev.root = WindowTable[pScreen->myNum]->drawable.id; 52805b261ecSmrg ev.window = savedScreenInfo[pScreen->myNum].wid; 52905b261ecSmrg ev.kind = kind; 53005b261ecSmrg ev.forced = forced; 53105b261ecSmrg WriteEventsToClient (client, 1, (xEvent *) &ev); 53205b261ecSmrg } 53305b261ecSmrg} 53405b261ecSmrg 53505b261ecSmrgstatic void 53605b261ecSmrgSScreenSaverNotifyEvent (from, to) 53705b261ecSmrg xScreenSaverNotifyEvent *from, *to; 53805b261ecSmrg{ 53905b261ecSmrg to->type = from->type; 54005b261ecSmrg to->state = from->state; 54105b261ecSmrg cpswaps (from->sequenceNumber, to->sequenceNumber); 54205b261ecSmrg cpswapl (from->timestamp, to->timestamp); 54305b261ecSmrg cpswapl (from->root, to->root); 54405b261ecSmrg cpswapl (from->window, to->window); 54505b261ecSmrg to->kind = from->kind; 54605b261ecSmrg to->forced = from->forced; 54705b261ecSmrg} 54805b261ecSmrg 54905b261ecSmrgstatic void 55005b261ecSmrgUninstallSaverColormap (pScreen) 55105b261ecSmrg ScreenPtr pScreen; 55205b261ecSmrg{ 55305b261ecSmrg SetupScreen(pScreen); 55405b261ecSmrg ColormapPtr pCmap; 55505b261ecSmrg 55605b261ecSmrg if (pPriv && pPriv->installedMap != None) 55705b261ecSmrg { 55805b261ecSmrg pCmap = (ColormapPtr) LookupIDByType (pPriv->installedMap, RT_COLORMAP); 55905b261ecSmrg if (pCmap) 56005b261ecSmrg (*pCmap->pScreen->UninstallColormap) (pCmap); 56105b261ecSmrg pPriv->installedMap = None; 56205b261ecSmrg CheckScreenPrivate (pScreen); 56305b261ecSmrg } 56405b261ecSmrg} 56505b261ecSmrg 56605b261ecSmrgstatic Bool 56705b261ecSmrgCreateSaverWindow (pScreen) 56805b261ecSmrg ScreenPtr pScreen; 56905b261ecSmrg{ 57005b261ecSmrg SetupScreen (pScreen); 57105b261ecSmrg ScreenSaverStuffPtr pSaver; 57205b261ecSmrg ScreenSaverAttrPtr pAttr; 57305b261ecSmrg WindowPtr pWin; 57405b261ecSmrg int result; 57505b261ecSmrg unsigned long mask; 57605b261ecSmrg Colormap *installedMaps; 57705b261ecSmrg int numInstalled; 57805b261ecSmrg int i; 57905b261ecSmrg Colormap wantMap; 58005b261ecSmrg ColormapPtr pCmap; 58105b261ecSmrg 58205b261ecSmrg pSaver = &savedScreenInfo[pScreen->myNum]; 58305b261ecSmrg if (pSaver->pWindow) 58405b261ecSmrg { 58505b261ecSmrg pSaver->pWindow = NullWindow; 58605b261ecSmrg FreeResource (pSaver->wid, RT_NONE); 58705b261ecSmrg if (pPriv) 58805b261ecSmrg { 58905b261ecSmrg UninstallSaverColormap (pScreen); 59005b261ecSmrg pPriv->hasWindow = FALSE; 59105b261ecSmrg CheckScreenPrivate (pScreen); 59205b261ecSmrg } 59305b261ecSmrg } 59405b261ecSmrg 59505b261ecSmrg if (!pPriv || !(pAttr = pPriv->attr)) 59605b261ecSmrg return FALSE; 59705b261ecSmrg 59805b261ecSmrg pPriv->installedMap = None; 59905b261ecSmrg 60005b261ecSmrg if (GrabInProgress && GrabInProgress != pAttr->client->index) 60105b261ecSmrg return FALSE; 60205b261ecSmrg 60305b261ecSmrg pWin = CreateWindow (pSaver->wid, WindowTable[pScreen->myNum], 60405b261ecSmrg pAttr->x, pAttr->y, pAttr->width, pAttr->height, 60505b261ecSmrg pAttr->borderWidth, pAttr->class, 60605b261ecSmrg pAttr->mask, (XID *)pAttr->values, 60705b261ecSmrg pAttr->depth, serverClient, pAttr->visual, 60805b261ecSmrg &result); 60905b261ecSmrg if (!pWin) 61005b261ecSmrg return FALSE; 61105b261ecSmrg 61205b261ecSmrg if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin)) 61305b261ecSmrg return FALSE; 61405b261ecSmrg 61505b261ecSmrg mask = 0; 61605b261ecSmrg if (pAttr->pBackgroundPixmap) 61705b261ecSmrg { 61805b261ecSmrg pWin->backgroundState = BackgroundPixmap; 61905b261ecSmrg pWin->background.pixmap = pAttr->pBackgroundPixmap; 62005b261ecSmrg pAttr->pBackgroundPixmap->refcnt++; 62105b261ecSmrg mask |= CWBackPixmap; 62205b261ecSmrg } 62305b261ecSmrg if (pAttr->pBorderPixmap) 62405b261ecSmrg { 62505b261ecSmrg pWin->borderIsPixel = FALSE; 62605b261ecSmrg pWin->border.pixmap = pAttr->pBorderPixmap; 62705b261ecSmrg pAttr->pBorderPixmap->refcnt++; 62805b261ecSmrg mask |= CWBorderPixmap; 62905b261ecSmrg } 63005b261ecSmrg if (pAttr->pCursor) 63105b261ecSmrg { 63205b261ecSmrg if (!pWin->optional) 63305b261ecSmrg if (!MakeWindowOptional (pWin)) 63405b261ecSmrg { 63505b261ecSmrg FreeResource (pWin->drawable.id, RT_NONE); 63605b261ecSmrg return FALSE; 63705b261ecSmrg } 63805b261ecSmrg if (pWin->optional->cursor) 63905b261ecSmrg FreeCursor (pWin->optional->cursor, (Cursor)0); 64005b261ecSmrg pWin->optional->cursor = pAttr->pCursor; 64105b261ecSmrg pAttr->pCursor->refcnt++; 64205b261ecSmrg pWin->cursorIsNone = FALSE; 64305b261ecSmrg CheckWindowOptionalNeed (pWin); 64405b261ecSmrg mask |= CWCursor; 64505b261ecSmrg } 64605b261ecSmrg if (mask) 64705b261ecSmrg (*pScreen->ChangeWindowAttributes) (pWin, mask); 64805b261ecSmrg 64905b261ecSmrg if (pAttr->colormap != None) 65005b261ecSmrg (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap, 65105b261ecSmrg serverClient); 65205b261ecSmrg 65305b261ecSmrg MapWindow (pWin, serverClient); 65405b261ecSmrg 65505b261ecSmrg pPriv->hasWindow = TRUE; 65605b261ecSmrg pSaver->pWindow = pWin; 65705b261ecSmrg 65805b261ecSmrg /* check and install our own colormap if it isn't installed now */ 65905b261ecSmrg wantMap = wColormap (pWin); 66005b261ecSmrg if (wantMap == None) 66105b261ecSmrg return TRUE; 6624642e01fSmrg installedMaps = (Colormap *) xalloc (pScreen->maxInstalledCmaps * 66305b261ecSmrg sizeof (Colormap)); 66405b261ecSmrg numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps) 66505b261ecSmrg (pScreen, installedMaps); 66605b261ecSmrg for (i = 0; i < numInstalled; i++) 66705b261ecSmrg if (installedMaps[i] == wantMap) 66805b261ecSmrg break; 66905b261ecSmrg 6704642e01fSmrg xfree ((char *) installedMaps); 67105b261ecSmrg 67205b261ecSmrg if (i < numInstalled) 67305b261ecSmrg return TRUE; 67405b261ecSmrg 67505b261ecSmrg pCmap = (ColormapPtr) LookupIDByType (wantMap, RT_COLORMAP); 67605b261ecSmrg if (!pCmap) 67705b261ecSmrg return TRUE; 67805b261ecSmrg 67905b261ecSmrg pPriv->installedMap = wantMap; 68005b261ecSmrg 68105b261ecSmrg (*pCmap->pScreen->InstallColormap) (pCmap); 68205b261ecSmrg 68305b261ecSmrg return TRUE; 68405b261ecSmrg} 68505b261ecSmrg 68605b261ecSmrgstatic Bool 68705b261ecSmrgDestroySaverWindow (pScreen) 68805b261ecSmrg ScreenPtr pScreen; 68905b261ecSmrg{ 69005b261ecSmrg SetupScreen(pScreen); 69105b261ecSmrg ScreenSaverStuffPtr pSaver; 69205b261ecSmrg 69305b261ecSmrg if (!pPriv || !pPriv->hasWindow) 69405b261ecSmrg return FALSE; 69505b261ecSmrg 69605b261ecSmrg pSaver = &savedScreenInfo[pScreen->myNum]; 69705b261ecSmrg if (pSaver->pWindow) 69805b261ecSmrg { 69905b261ecSmrg pSaver->pWindow = NullWindow; 70005b261ecSmrg FreeResource (pSaver->wid, RT_NONE); 70105b261ecSmrg } 70205b261ecSmrg pPriv->hasWindow = FALSE; 70305b261ecSmrg CheckScreenPrivate (pScreen); 70405b261ecSmrg UninstallSaverColormap (pScreen); 70505b261ecSmrg return TRUE; 70605b261ecSmrg} 70705b261ecSmrg 70805b261ecSmrgstatic Bool 70905b261ecSmrgScreenSaverHandle (pScreen, xstate, force) 71005b261ecSmrg ScreenPtr pScreen; 71105b261ecSmrg int xstate; 71205b261ecSmrg Bool force; 71305b261ecSmrg{ 71405b261ecSmrg int state = 0; 71505b261ecSmrg Bool ret = FALSE; 71605b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 71705b261ecSmrg 71805b261ecSmrg switch (xstate) 71905b261ecSmrg { 72005b261ecSmrg case SCREEN_SAVER_ON: 72105b261ecSmrg state = ScreenSaverOn; 72205b261ecSmrg ret = CreateSaverWindow (pScreen); 72305b261ecSmrg break; 72405b261ecSmrg case SCREEN_SAVER_OFF: 72505b261ecSmrg state = ScreenSaverOff; 72605b261ecSmrg ret = DestroySaverWindow (pScreen); 72705b261ecSmrg break; 72805b261ecSmrg case SCREEN_SAVER_CYCLE: 72905b261ecSmrg state = ScreenSaverCycle; 73005b261ecSmrg pPriv = GetScreenPrivate (pScreen); 73105b261ecSmrg if (pPriv && pPriv->hasWindow) 73205b261ecSmrg ret = TRUE; 73305b261ecSmrg 73405b261ecSmrg } 73505b261ecSmrg#ifdef PANORAMIX 73605b261ecSmrg if(noPanoramiXExtension || !pScreen->myNum) 73705b261ecSmrg#endif 73805b261ecSmrg SendScreenSaverNotify (pScreen, state, force); 73905b261ecSmrg return ret; 74005b261ecSmrg} 74105b261ecSmrg 74205b261ecSmrgstatic int 74305b261ecSmrgProcScreenSaverQueryVersion (client) 7444642e01fSmrg ClientPtr client; 74505b261ecSmrg{ 74605b261ecSmrg xScreenSaverQueryVersionReply rep; 7474642e01fSmrg int n; 74805b261ecSmrg 74905b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq); 75005b261ecSmrg rep.type = X_Reply; 75105b261ecSmrg rep.length = 0; 75205b261ecSmrg rep.sequenceNumber = client->sequence; 75305b261ecSmrg rep.majorVersion = ScreenSaverMajorVersion; 75405b261ecSmrg rep.minorVersion = ScreenSaverMinorVersion; 75505b261ecSmrg if (client->swapped) { 75605b261ecSmrg swaps(&rep.sequenceNumber, n); 75705b261ecSmrg swapl(&rep.length, n); 75805b261ecSmrg } 75905b261ecSmrg WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep); 76005b261ecSmrg return (client->noClientException); 76105b261ecSmrg} 76205b261ecSmrg 76305b261ecSmrgstatic int 76405b261ecSmrgProcScreenSaverQueryInfo (client) 7654642e01fSmrg ClientPtr client; 76605b261ecSmrg{ 76705b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 76805b261ecSmrg xScreenSaverQueryInfoReply rep; 7694642e01fSmrg int n, rc; 77005b261ecSmrg ScreenSaverStuffPtr pSaver; 77105b261ecSmrg DrawablePtr pDraw; 77205b261ecSmrg CARD32 lastInput; 77305b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 77405b261ecSmrg 77505b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq); 77605b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 7774642e01fSmrg DixGetAttrAccess); 7784642e01fSmrg if (rc != Success) 7794642e01fSmrg return rc; 7804642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 7814642e01fSmrg DixGetAttrAccess); 78205b261ecSmrg if (rc != Success) 78305b261ecSmrg return rc; 78405b261ecSmrg 78505b261ecSmrg pSaver = &savedScreenInfo[pDraw->pScreen->myNum]; 78605b261ecSmrg pPriv = GetScreenPrivate (pDraw->pScreen); 78705b261ecSmrg 78805b261ecSmrg UpdateCurrentTime (); 78905b261ecSmrg lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; 79005b261ecSmrg 79105b261ecSmrg rep.type = X_Reply; 79205b261ecSmrg rep.length = 0; 79305b261ecSmrg rep.sequenceNumber = client->sequence; 79405b261ecSmrg rep.window = pSaver->wid; 79505b261ecSmrg if (screenIsSaved != SCREEN_SAVER_OFF) 79605b261ecSmrg { 79705b261ecSmrg rep.state = ScreenSaverOn; 79805b261ecSmrg if (ScreenSaverTime) 79905b261ecSmrg rep.tilOrSince = lastInput - ScreenSaverTime; 80005b261ecSmrg else 80105b261ecSmrg rep.tilOrSince = 0; 80205b261ecSmrg } 80305b261ecSmrg else 80405b261ecSmrg { 80505b261ecSmrg if (ScreenSaverTime) 80605b261ecSmrg { 80705b261ecSmrg rep.state = ScreenSaverOff; 80805b261ecSmrg if (ScreenSaverTime < lastInput) 80905b261ecSmrg rep.tilOrSince = 0; 81005b261ecSmrg else 81105b261ecSmrg rep.tilOrSince = ScreenSaverTime - lastInput; 81205b261ecSmrg } 81305b261ecSmrg else 81405b261ecSmrg { 81505b261ecSmrg rep.state = ScreenSaverDisabled; 81605b261ecSmrg rep.tilOrSince = 0; 81705b261ecSmrg } 81805b261ecSmrg } 81905b261ecSmrg rep.idle = lastInput; 82005b261ecSmrg rep.eventMask = getEventMask (pDraw->pScreen, client); 82105b261ecSmrg if (pPriv && pPriv->attr) 82205b261ecSmrg rep.kind = ScreenSaverExternal; 82305b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 82405b261ecSmrg rep.kind = ScreenSaverBlanked; 82505b261ecSmrg else 82605b261ecSmrg rep.kind = ScreenSaverInternal; 82705b261ecSmrg if (client->swapped) 82805b261ecSmrg { 82905b261ecSmrg swaps (&rep.sequenceNumber, n); 83005b261ecSmrg swapl (&rep.length, n); 83105b261ecSmrg swapl (&rep.window, n); 83205b261ecSmrg swapl (&rep.tilOrSince, n); 83305b261ecSmrg swapl (&rep.idle, n); 83405b261ecSmrg swapl (&rep.eventMask, n); 83505b261ecSmrg } 83605b261ecSmrg WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep); 83705b261ecSmrg return (client->noClientException); 83805b261ecSmrg} 83905b261ecSmrg 84005b261ecSmrgstatic int 84105b261ecSmrgProcScreenSaverSelectInput (client) 8424642e01fSmrg ClientPtr client; 84305b261ecSmrg{ 84405b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 84505b261ecSmrg DrawablePtr pDraw; 84605b261ecSmrg int rc; 84705b261ecSmrg 84805b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq); 84905b261ecSmrg rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0, 8504642e01fSmrg DixGetAttrAccess); 8514642e01fSmrg if (rc != Success) 8524642e01fSmrg return rc; 8534642e01fSmrg 8544642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 8554642e01fSmrg DixSetAttrAccess); 85605b261ecSmrg if (rc != Success) 85705b261ecSmrg return rc; 8584642e01fSmrg 85905b261ecSmrg if (!setEventMask (pDraw->pScreen, client, stuff->eventMask)) 86005b261ecSmrg return BadAlloc; 86105b261ecSmrg return Success; 86205b261ecSmrg} 86305b261ecSmrg 86405b261ecSmrgstatic int 86505b261ecSmrgScreenSaverSetAttributes (ClientPtr client) 86605b261ecSmrg{ 86705b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 86805b261ecSmrg DrawablePtr pDraw; 86905b261ecSmrg WindowPtr pParent; 87005b261ecSmrg ScreenPtr pScreen; 87105b261ecSmrg ScreenSaverScreenPrivatePtr pPriv = 0; 87205b261ecSmrg ScreenSaverAttrPtr pAttr = 0; 87305b261ecSmrg int ret, len, class, bw, depth; 87405b261ecSmrg unsigned long visual; 87505b261ecSmrg int idepth, ivisual; 87605b261ecSmrg Bool fOK; 87705b261ecSmrg DepthPtr pDepth; 87805b261ecSmrg WindowOptPtr ancwopt; 87905b261ecSmrg unsigned int *pVlist; 88005b261ecSmrg unsigned long *values = 0; 88105b261ecSmrg unsigned long tmask, imask; 88205b261ecSmrg unsigned long val; 88305b261ecSmrg Pixmap pixID; 88405b261ecSmrg PixmapPtr pPixmap; 88505b261ecSmrg Cursor cursorID; 88605b261ecSmrg CursorPtr pCursor; 88705b261ecSmrg Colormap cmap; 88805b261ecSmrg ColormapPtr pCmap; 88905b261ecSmrg 89005b261ecSmrg REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 89105b261ecSmrg ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 8924642e01fSmrg DixGetAttrAccess); 89305b261ecSmrg if (ret != Success) 89405b261ecSmrg return ret; 89505b261ecSmrg pScreen = pDraw->pScreen; 89605b261ecSmrg pParent = WindowTable[pScreen->myNum]; 89705b261ecSmrg 8984642e01fSmrg ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess); 8994642e01fSmrg if (ret != Success) 9004642e01fSmrg return ret; 9014642e01fSmrg 90205b261ecSmrg len = stuff->length - (sizeof(xScreenSaverSetAttributesReq) >> 2); 90305b261ecSmrg if (Ones(stuff->mask) != len) 90405b261ecSmrg return BadLength; 90505b261ecSmrg if (!stuff->width || !stuff->height) 90605b261ecSmrg { 90705b261ecSmrg client->errorValue = 0; 90805b261ecSmrg return BadValue; 90905b261ecSmrg } 91005b261ecSmrg switch (class = stuff->c_class) 91105b261ecSmrg { 91205b261ecSmrg case CopyFromParent: 91305b261ecSmrg case InputOnly: 91405b261ecSmrg case InputOutput: 91505b261ecSmrg break; 91605b261ecSmrg default: 91705b261ecSmrg client->errorValue = class; 91805b261ecSmrg return BadValue; 91905b261ecSmrg } 92005b261ecSmrg bw = stuff->borderWidth; 92105b261ecSmrg depth = stuff->depth; 92205b261ecSmrg visual = stuff->visualID; 92305b261ecSmrg 92405b261ecSmrg /* copied directly from CreateWindow */ 92505b261ecSmrg 92605b261ecSmrg if (class == CopyFromParent) 92705b261ecSmrg class = pParent->drawable.class; 92805b261ecSmrg 92905b261ecSmrg if ((class != InputOutput) && (class != InputOnly)) 93005b261ecSmrg { 93105b261ecSmrg client->errorValue = class; 93205b261ecSmrg return BadValue; 93305b261ecSmrg } 93405b261ecSmrg 93505b261ecSmrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) 93605b261ecSmrg return BadMatch; 93705b261ecSmrg 93805b261ecSmrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) 93905b261ecSmrg return BadMatch; 94005b261ecSmrg 94105b261ecSmrg if ((class == InputOutput) && (depth == 0)) 94205b261ecSmrg depth = pParent->drawable.depth; 94305b261ecSmrg ancwopt = pParent->optional; 94405b261ecSmrg if (!ancwopt) 94505b261ecSmrg ancwopt = FindWindowWithOptional(pParent)->optional; 94605b261ecSmrg if (visual == CopyFromParent) 94705b261ecSmrg visual = ancwopt->visual; 94805b261ecSmrg 94905b261ecSmrg /* Find out if the depth and visual are acceptable for this Screen */ 95005b261ecSmrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) 95105b261ecSmrg { 95205b261ecSmrg fOK = FALSE; 95305b261ecSmrg for(idepth = 0; idepth < pScreen->numDepths; idepth++) 95405b261ecSmrg { 95505b261ecSmrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 95605b261ecSmrg if ((depth == pDepth->depth) || (depth == 0)) 95705b261ecSmrg { 95805b261ecSmrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) 95905b261ecSmrg { 96005b261ecSmrg if (visual == pDepth->vids[ivisual]) 96105b261ecSmrg { 96205b261ecSmrg fOK = TRUE; 96305b261ecSmrg break; 96405b261ecSmrg } 96505b261ecSmrg } 96605b261ecSmrg } 96705b261ecSmrg } 96805b261ecSmrg if (fOK == FALSE) 96905b261ecSmrg return BadMatch; 97005b261ecSmrg } 97105b261ecSmrg 97205b261ecSmrg if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) && 97305b261ecSmrg (class != InputOnly) && 97405b261ecSmrg (depth != pParent->drawable.depth)) 97505b261ecSmrg { 97605b261ecSmrg return BadMatch; 97705b261ecSmrg } 97805b261ecSmrg 97905b261ecSmrg if (((stuff->mask & CWColormap) == 0) && 98005b261ecSmrg (class != InputOnly) && 98105b261ecSmrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) 98205b261ecSmrg { 98305b261ecSmrg return BadMatch; 98405b261ecSmrg } 98505b261ecSmrg 98605b261ecSmrg /* end of errors from CreateWindow */ 98705b261ecSmrg 98805b261ecSmrg pPriv = GetScreenPrivate (pScreen); 98905b261ecSmrg if (pPriv && pPriv->attr) 99005b261ecSmrg { 99105b261ecSmrg if (pPriv->attr->client != client) 99205b261ecSmrg return BadAccess; 99305b261ecSmrg } 99405b261ecSmrg if (!pPriv) 99505b261ecSmrg { 99605b261ecSmrg pPriv = MakeScreenPrivate (pScreen); 99705b261ecSmrg if (!pPriv) 99805b261ecSmrg return FALSE; 99905b261ecSmrg } 100005b261ecSmrg pAttr = New (ScreenSaverAttrRec); 100105b261ecSmrg if (!pAttr) 100205b261ecSmrg { 100305b261ecSmrg ret = BadAlloc; 100405b261ecSmrg goto bail; 100505b261ecSmrg } 100605b261ecSmrg /* over allocate for override redirect */ 100705b261ecSmrg values = (unsigned long *) xalloc ((len + 1) * sizeof (unsigned long)); 100805b261ecSmrg if (!values) 100905b261ecSmrg { 101005b261ecSmrg ret = BadAlloc; 101105b261ecSmrg goto bail; 101205b261ecSmrg } 101305b261ecSmrg pAttr->screen = pScreen; 101405b261ecSmrg pAttr->client = client; 101505b261ecSmrg pAttr->x = stuff->x; 101605b261ecSmrg pAttr->y = stuff->y; 101705b261ecSmrg pAttr->width = stuff->width; 101805b261ecSmrg pAttr->height = stuff->height; 101905b261ecSmrg pAttr->borderWidth = stuff->borderWidth; 102005b261ecSmrg pAttr->class = stuff->c_class; 102105b261ecSmrg pAttr->depth = depth; 102205b261ecSmrg pAttr->visual = visual; 102305b261ecSmrg pAttr->colormap = None; 102405b261ecSmrg pAttr->pCursor = NullCursor; 102505b261ecSmrg pAttr->pBackgroundPixmap = NullPixmap; 102605b261ecSmrg pAttr->pBorderPixmap = NullPixmap; 102705b261ecSmrg pAttr->values = values; 102805b261ecSmrg /* 102905b261ecSmrg * go through the mask, checking the values, 103005b261ecSmrg * looking up pixmaps and cursors and hold a reference 103105b261ecSmrg * to them. 103205b261ecSmrg */ 103305b261ecSmrg pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; 103405b261ecSmrg pVlist = (unsigned int *) (stuff + 1); 103505b261ecSmrg while (tmask) { 103605b261ecSmrg imask = lowbit (tmask); 103705b261ecSmrg tmask &= ~imask; 103805b261ecSmrg switch (imask) 103905b261ecSmrg { 104005b261ecSmrg case CWBackPixmap: 104105b261ecSmrg pixID = (Pixmap )*pVlist; 104205b261ecSmrg if (pixID == None) 104305b261ecSmrg { 104405b261ecSmrg *values++ = None; 104505b261ecSmrg } 104605b261ecSmrg else if (pixID == ParentRelative) 104705b261ecSmrg { 104805b261ecSmrg if (depth != pParent->drawable.depth) 104905b261ecSmrg { 105005b261ecSmrg ret = BadMatch; 105105b261ecSmrg goto PatchUp; 105205b261ecSmrg } 105305b261ecSmrg *values++ = ParentRelative; 105405b261ecSmrg } 105505b261ecSmrg else 105605b261ecSmrg { 10574642e01fSmrg ret = dixLookupResource((pointer *)&pPixmap, pixID, RT_PIXMAP, 10584642e01fSmrg client, DixReadAccess); 10594642e01fSmrg if (ret == Success) 106005b261ecSmrg { 106105b261ecSmrg if ((pPixmap->drawable.depth != depth) || 106205b261ecSmrg (pPixmap->drawable.pScreen != pScreen)) 106305b261ecSmrg { 106405b261ecSmrg ret = BadMatch; 106505b261ecSmrg goto PatchUp; 106605b261ecSmrg } 106705b261ecSmrg pAttr->pBackgroundPixmap = pPixmap; 106805b261ecSmrg pPixmap->refcnt++; 106905b261ecSmrg pAttr->mask &= ~CWBackPixmap; 107005b261ecSmrg } 107105b261ecSmrg else 107205b261ecSmrg { 10734642e01fSmrg ret = (ret == BadValue) ? BadPixmap : ret; 107405b261ecSmrg client->errorValue = pixID; 107505b261ecSmrg goto PatchUp; 107605b261ecSmrg } 107705b261ecSmrg } 107805b261ecSmrg break; 107905b261ecSmrg case CWBackPixel: 108005b261ecSmrg *values++ = (CARD32) *pVlist; 108105b261ecSmrg break; 108205b261ecSmrg case CWBorderPixmap: 108305b261ecSmrg pixID = (Pixmap ) *pVlist; 108405b261ecSmrg if (pixID == CopyFromParent) 108505b261ecSmrg { 108605b261ecSmrg if (depth != pParent->drawable.depth) 108705b261ecSmrg { 108805b261ecSmrg ret = BadMatch; 108905b261ecSmrg goto PatchUp; 109005b261ecSmrg } 109105b261ecSmrg *values++ = CopyFromParent; 109205b261ecSmrg } 109305b261ecSmrg else 109405b261ecSmrg { 10954642e01fSmrg ret = dixLookupResource((pointer *)&pPixmap, pixID, RT_PIXMAP, 10964642e01fSmrg client, DixReadAccess); 10974642e01fSmrg if (ret == Success) 109805b261ecSmrg { 109905b261ecSmrg if ((pPixmap->drawable.depth != depth) || 110005b261ecSmrg (pPixmap->drawable.pScreen != pScreen)) 110105b261ecSmrg { 110205b261ecSmrg ret = BadMatch; 110305b261ecSmrg goto PatchUp; 110405b261ecSmrg } 110505b261ecSmrg pAttr->pBorderPixmap = pPixmap; 110605b261ecSmrg pPixmap->refcnt++; 110705b261ecSmrg pAttr->mask &= ~CWBorderPixmap; 110805b261ecSmrg } 110905b261ecSmrg else 111005b261ecSmrg { 11114642e01fSmrg ret = (ret == BadValue) ? BadPixmap : ret; 111205b261ecSmrg client->errorValue = pixID; 111305b261ecSmrg goto PatchUp; 111405b261ecSmrg } 111505b261ecSmrg } 111605b261ecSmrg break; 111705b261ecSmrg case CWBorderPixel: 111805b261ecSmrg *values++ = (CARD32) *pVlist; 111905b261ecSmrg break; 112005b261ecSmrg case CWBitGravity: 112105b261ecSmrg val = (CARD8 )*pVlist; 112205b261ecSmrg if (val > StaticGravity) 112305b261ecSmrg { 112405b261ecSmrg ret = BadValue; 112505b261ecSmrg client->errorValue = val; 112605b261ecSmrg goto PatchUp; 112705b261ecSmrg } 112805b261ecSmrg *values++ = val; 112905b261ecSmrg break; 113005b261ecSmrg case CWWinGravity: 113105b261ecSmrg val = (CARD8 )*pVlist; 113205b261ecSmrg if (val > StaticGravity) 113305b261ecSmrg { 113405b261ecSmrg ret = BadValue; 113505b261ecSmrg client->errorValue = val; 113605b261ecSmrg goto PatchUp; 113705b261ecSmrg } 113805b261ecSmrg *values++ = val; 113905b261ecSmrg break; 114005b261ecSmrg case CWBackingStore: 114105b261ecSmrg val = (CARD8 )*pVlist; 114205b261ecSmrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) 114305b261ecSmrg { 114405b261ecSmrg ret = BadValue; 114505b261ecSmrg client->errorValue = val; 114605b261ecSmrg goto PatchUp; 114705b261ecSmrg } 114805b261ecSmrg *values++ = val; 114905b261ecSmrg break; 115005b261ecSmrg case CWBackingPlanes: 115105b261ecSmrg *values++ = (CARD32) *pVlist; 115205b261ecSmrg break; 115305b261ecSmrg case CWBackingPixel: 115405b261ecSmrg *values++ = (CARD32) *pVlist; 115505b261ecSmrg break; 115605b261ecSmrg case CWSaveUnder: 115705b261ecSmrg val = (BOOL) *pVlist; 115805b261ecSmrg if ((val != xTrue) && (val != xFalse)) 115905b261ecSmrg { 116005b261ecSmrg ret = BadValue; 116105b261ecSmrg client->errorValue = val; 116205b261ecSmrg goto PatchUp; 116305b261ecSmrg } 116405b261ecSmrg *values++ = val; 116505b261ecSmrg break; 116605b261ecSmrg case CWEventMask: 116705b261ecSmrg *values++ = (CARD32) *pVlist; 116805b261ecSmrg break; 116905b261ecSmrg case CWDontPropagate: 117005b261ecSmrg *values++ = (CARD32) *pVlist; 117105b261ecSmrg break; 117205b261ecSmrg case CWOverrideRedirect: 117305b261ecSmrg if (!(stuff->mask & CWOverrideRedirect)) 117405b261ecSmrg pVlist--; 117505b261ecSmrg else 117605b261ecSmrg { 117705b261ecSmrg val = (BOOL ) *pVlist; 117805b261ecSmrg if ((val != xTrue) && (val != xFalse)) 117905b261ecSmrg { 118005b261ecSmrg ret = BadValue; 118105b261ecSmrg client->errorValue = val; 118205b261ecSmrg goto PatchUp; 118305b261ecSmrg } 118405b261ecSmrg } 118505b261ecSmrg *values++ = xTrue; 118605b261ecSmrg break; 118705b261ecSmrg case CWColormap: 118805b261ecSmrg cmap = (Colormap) *pVlist; 11894642e01fSmrg ret = dixLookupResource((pointer *)&pCmap, cmap, RT_COLORMAP, 11904642e01fSmrg client, DixUseAccess); 11914642e01fSmrg if (ret != Success) 119205b261ecSmrg { 11934642e01fSmrg ret = (ret == BadValue) ? BadColor : ret; 119405b261ecSmrg client->errorValue = cmap; 119505b261ecSmrg goto PatchUp; 119605b261ecSmrg } 119705b261ecSmrg if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) 119805b261ecSmrg { 119905b261ecSmrg ret = BadMatch; 120005b261ecSmrg goto PatchUp; 120105b261ecSmrg } 120205b261ecSmrg pAttr->colormap = cmap; 120305b261ecSmrg pAttr->mask &= ~CWColormap; 120405b261ecSmrg break; 120505b261ecSmrg case CWCursor: 120605b261ecSmrg cursorID = (Cursor ) *pVlist; 120705b261ecSmrg if ( cursorID == None) 120805b261ecSmrg { 120905b261ecSmrg *values++ = None; 121005b261ecSmrg } 121105b261ecSmrg else 121205b261ecSmrg { 12134642e01fSmrg ret = dixLookupResource((pointer *)&pCursor, cursorID, 12144642e01fSmrg RT_CURSOR, client, DixUseAccess); 12154642e01fSmrg if (ret != Success) 121605b261ecSmrg { 12174642e01fSmrg ret = (ret == BadValue) ? BadCursor : ret; 121805b261ecSmrg client->errorValue = cursorID; 121905b261ecSmrg goto PatchUp; 122005b261ecSmrg } 122105b261ecSmrg pCursor->refcnt++; 122205b261ecSmrg pAttr->pCursor = pCursor; 122305b261ecSmrg pAttr->mask &= ~CWCursor; 122405b261ecSmrg } 122505b261ecSmrg break; 122605b261ecSmrg default: 122705b261ecSmrg ret = BadValue; 122805b261ecSmrg client->errorValue = stuff->mask; 122905b261ecSmrg goto PatchUp; 123005b261ecSmrg } 123105b261ecSmrg pVlist++; 123205b261ecSmrg } 123305b261ecSmrg if (pPriv->attr) 123405b261ecSmrg FreeScreenAttr (pPriv->attr); 123505b261ecSmrg pPriv->attr = pAttr; 123605b261ecSmrg pAttr->resource = FakeClientID (client->index); 123705b261ecSmrg if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr)) 123805b261ecSmrg return BadAlloc; 123905b261ecSmrg return Success; 124005b261ecSmrgPatchUp: 124105b261ecSmrg FreeAttrs (pAttr); 124205b261ecSmrgbail: 124305b261ecSmrg CheckScreenPrivate (pScreen); 124405b261ecSmrg if (pAttr) xfree (pAttr->values); 124505b261ecSmrg xfree (pAttr); 124605b261ecSmrg return ret; 124705b261ecSmrg} 124805b261ecSmrg 124905b261ecSmrgstatic int 125005b261ecSmrgScreenSaverUnsetAttributes (ClientPtr client) 125105b261ecSmrg{ 125205b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 125305b261ecSmrg DrawablePtr pDraw; 125405b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 125505b261ecSmrg int rc; 125605b261ecSmrg 125705b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq); 125805b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 12594642e01fSmrg DixGetAttrAccess); 126005b261ecSmrg if (rc != Success) 126105b261ecSmrg return rc; 126205b261ecSmrg pPriv = GetScreenPrivate (pDraw->pScreen); 126305b261ecSmrg if (pPriv && pPriv->attr && pPriv->attr->client == client) 126405b261ecSmrg { 126505b261ecSmrg FreeResource (pPriv->attr->resource, AttrType); 126605b261ecSmrg FreeScreenAttr (pPriv->attr); 126705b261ecSmrg pPriv->attr = NULL; 126805b261ecSmrg CheckScreenPrivate (pDraw->pScreen); 126905b261ecSmrg } 127005b261ecSmrg return Success; 127105b261ecSmrg} 127205b261ecSmrg 127305b261ecSmrgstatic int 127405b261ecSmrgProcScreenSaverSetAttributes (ClientPtr client) 127505b261ecSmrg{ 127605b261ecSmrg#ifdef PANORAMIX 127705b261ecSmrg if(!noPanoramiXExtension) { 127805b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 127905b261ecSmrg PanoramiXRes *draw; 128005b261ecSmrg PanoramiXRes *backPix = NULL; 128105b261ecSmrg PanoramiXRes *bordPix = NULL; 128205b261ecSmrg PanoramiXRes *cmap = NULL; 128305b261ecSmrg int i, status = 0, len; 128405b261ecSmrg int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; 128505b261ecSmrg XID orig_visual, tmp; 128605b261ecSmrg 128705b261ecSmrg REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 128805b261ecSmrg 128905b261ecSmrg if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 129005b261ecSmrg client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 129105b261ecSmrg return BadDrawable; 129205b261ecSmrg 129305b261ecSmrg len = stuff->length - (sizeof(xScreenSaverSetAttributesReq) >> 2); 129405b261ecSmrg if (Ones(stuff->mask) != len) 129505b261ecSmrg return BadLength; 129605b261ecSmrg 129705b261ecSmrg if((Mask)stuff->mask & CWBackPixmap) { 129805b261ecSmrg pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); 129905b261ecSmrg tmp = *((CARD32 *) &stuff[1] + pback_offset); 130005b261ecSmrg if ((tmp != None) && (tmp != ParentRelative)) { 130105b261ecSmrg if(!(backPix = (PanoramiXRes*) SecurityLookupIDByType( 130205b261ecSmrg client, tmp, XRT_PIXMAP, DixReadAccess))) 130305b261ecSmrg return BadPixmap; 130405b261ecSmrg } 130505b261ecSmrg } 130605b261ecSmrg 130705b261ecSmrg if ((Mask)stuff->mask & CWBorderPixmap) { 130805b261ecSmrg pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); 130905b261ecSmrg tmp = *((CARD32 *) &stuff[1] + pbord_offset); 131005b261ecSmrg if (tmp != CopyFromParent) { 131105b261ecSmrg if(!(bordPix = (PanoramiXRes*) SecurityLookupIDByType( 131205b261ecSmrg client, tmp, XRT_PIXMAP, DixReadAccess))) 131305b261ecSmrg return BadPixmap; 131405b261ecSmrg } 131505b261ecSmrg } 131605b261ecSmrg 131705b261ecSmrg if ((Mask)stuff->mask & CWColormap) { 131805b261ecSmrg cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); 131905b261ecSmrg tmp = *((CARD32 *) &stuff[1] + cmap_offset); 132005b261ecSmrg if ((tmp != CopyFromParent) && (tmp != None)) { 132105b261ecSmrg if(!(cmap = (PanoramiXRes*) SecurityLookupIDByType( 132205b261ecSmrg client, tmp, XRT_COLORMAP, DixReadAccess))) 132305b261ecSmrg return BadColor; 132405b261ecSmrg } 132505b261ecSmrg } 132605b261ecSmrg 132705b261ecSmrg orig_visual = stuff->visualID; 132805b261ecSmrg 132905b261ecSmrg FOR_NSCREENS_BACKWARD(i) { 133005b261ecSmrg stuff->drawable = draw->info[i].id; 133105b261ecSmrg if (backPix) 133205b261ecSmrg *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; 133305b261ecSmrg if (bordPix) 133405b261ecSmrg *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; 133505b261ecSmrg if (cmap) 133605b261ecSmrg *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; 133705b261ecSmrg 133805b261ecSmrg if (orig_visual != CopyFromParent) 13394642e01fSmrg stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); 134005b261ecSmrg 134105b261ecSmrg status = ScreenSaverSetAttributes(client); 134205b261ecSmrg } 134305b261ecSmrg 134405b261ecSmrg return status; 134505b261ecSmrg } 134605b261ecSmrg#endif 134705b261ecSmrg 134805b261ecSmrg return ScreenSaverSetAttributes(client); 134905b261ecSmrg} 135005b261ecSmrg 135105b261ecSmrgstatic int 135205b261ecSmrgProcScreenSaverUnsetAttributes (ClientPtr client) 135305b261ecSmrg{ 135405b261ecSmrg#ifdef PANORAMIX 135505b261ecSmrg if(!noPanoramiXExtension) { 135605b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 135705b261ecSmrg PanoramiXRes *draw; 135805b261ecSmrg int i; 135905b261ecSmrg 136005b261ecSmrg if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass( 136105b261ecSmrg client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) 136205b261ecSmrg return BadDrawable; 136305b261ecSmrg 136405b261ecSmrg for(i = PanoramiXNumScreens - 1; i > 0; i--) { 136505b261ecSmrg stuff->drawable = draw->info[i].id; 136605b261ecSmrg ScreenSaverUnsetAttributes(client); 136705b261ecSmrg } 136805b261ecSmrg 136905b261ecSmrg stuff->drawable = draw->info[0].id; 137005b261ecSmrg } 137105b261ecSmrg#endif 137205b261ecSmrg 137305b261ecSmrg return ScreenSaverUnsetAttributes(client); 137405b261ecSmrg} 137505b261ecSmrg 137605b261ecSmrgstatic int 137705b261ecSmrgProcScreenSaverSuspend (ClientPtr client) 137805b261ecSmrg{ 137905b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 138005b261ecSmrg 138105b261ecSmrg REQUEST(xScreenSaverSuspendReq); 138205b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 138305b261ecSmrg 138405b261ecSmrg /* Check if this client is suspending the screensaver */ 138505b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 138605b261ecSmrg if (this->pClient == client) 138705b261ecSmrg break; 138805b261ecSmrg 138905b261ecSmrg if (this) 139005b261ecSmrg { 139105b261ecSmrg if (stuff->suspend == TRUE) 139205b261ecSmrg this->count++; 139305b261ecSmrg else if (--this->count == 0) 139405b261ecSmrg FreeResource (this->clientResource, RT_NONE); 139505b261ecSmrg 139605b261ecSmrg return Success; 139705b261ecSmrg } 139805b261ecSmrg 139905b261ecSmrg /* If we get to this point, this client isn't suspending the screensaver */ 140005b261ecSmrg if (stuff->suspend == FALSE) 140105b261ecSmrg return Success; 140205b261ecSmrg 140305b261ecSmrg /* 140405b261ecSmrg * Allocate a suspension record for the client, and stop the screensaver 140505b261ecSmrg * if it isn't already suspended by another client. We attach a resource ID 140605b261ecSmrg * to the record, so the screensaver will be reenabled and the record freed 140705b261ecSmrg * if the client disconnects without reenabling it first. 140805b261ecSmrg */ 140905b261ecSmrg this = (ScreenSaverSuspensionPtr) xalloc (sizeof (ScreenSaverSuspensionRec)); 141005b261ecSmrg 141105b261ecSmrg if (!this) 141205b261ecSmrg return BadAlloc; 141305b261ecSmrg 141405b261ecSmrg this->next = NULL; 141505b261ecSmrg this->pClient = client; 141605b261ecSmrg this->count = 1; 141705b261ecSmrg this->clientResource = FakeClientID (client->index); 141805b261ecSmrg 141905b261ecSmrg if (!AddResource (this->clientResource, SuspendType, (pointer) this)) 142005b261ecSmrg { 142105b261ecSmrg xfree (this); 142205b261ecSmrg return BadAlloc; 142305b261ecSmrg } 142405b261ecSmrg 142505b261ecSmrg *prev = this; 142605b261ecSmrg if (!screenSaverSuspended) 142705b261ecSmrg { 142805b261ecSmrg screenSaverSuspended = TRUE; 142905b261ecSmrg FreeScreenSaverTimer(); 143005b261ecSmrg } 143105b261ecSmrg 143205b261ecSmrg return (client->noClientException); 143305b261ecSmrg} 143405b261ecSmrg 143505b261ecSmrgstatic DISPATCH_PROC((*NormalVector[])) = { 143605b261ecSmrg ProcScreenSaverQueryVersion, 143705b261ecSmrg ProcScreenSaverQueryInfo, 143805b261ecSmrg ProcScreenSaverSelectInput, 143905b261ecSmrg ProcScreenSaverSetAttributes, 144005b261ecSmrg ProcScreenSaverUnsetAttributes, 144105b261ecSmrg ProcScreenSaverSuspend, 144205b261ecSmrg}; 144305b261ecSmrg 144405b261ecSmrg#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) 144505b261ecSmrg 144605b261ecSmrgstatic int 144705b261ecSmrgProcScreenSaverDispatch (client) 144805b261ecSmrg ClientPtr client; 144905b261ecSmrg{ 145005b261ecSmrg REQUEST(xReq); 145105b261ecSmrg 145205b261ecSmrg if (stuff->data < NUM_REQUESTS) 145305b261ecSmrg return (*NormalVector[stuff->data])(client); 145405b261ecSmrg return BadRequest; 145505b261ecSmrg} 145605b261ecSmrg 145705b261ecSmrgstatic int 145805b261ecSmrgSProcScreenSaverQueryVersion (client) 145905b261ecSmrg ClientPtr client; 146005b261ecSmrg{ 146105b261ecSmrg REQUEST(xScreenSaverQueryVersionReq); 146205b261ecSmrg int n; 146305b261ecSmrg 146405b261ecSmrg swaps (&stuff->length, n); 146505b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 146605b261ecSmrg return ProcScreenSaverQueryVersion (client); 146705b261ecSmrg} 146805b261ecSmrg 146905b261ecSmrgstatic int 147005b261ecSmrgSProcScreenSaverQueryInfo (client) 147105b261ecSmrg ClientPtr client; 147205b261ecSmrg{ 147305b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 147405b261ecSmrg int n; 147505b261ecSmrg 147605b261ecSmrg swaps (&stuff->length, n); 147705b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 147805b261ecSmrg swapl (&stuff->drawable, n); 147905b261ecSmrg return ProcScreenSaverQueryInfo (client); 148005b261ecSmrg} 148105b261ecSmrg 148205b261ecSmrgstatic int 148305b261ecSmrgSProcScreenSaverSelectInput (client) 148405b261ecSmrg ClientPtr client; 148505b261ecSmrg{ 148605b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 148705b261ecSmrg int n; 148805b261ecSmrg 148905b261ecSmrg swaps (&stuff->length, n); 149005b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 149105b261ecSmrg swapl (&stuff->drawable, n); 149205b261ecSmrg swapl (&stuff->eventMask, n); 149305b261ecSmrg return ProcScreenSaverSelectInput (client); 149405b261ecSmrg} 149505b261ecSmrg 149605b261ecSmrgstatic int 149705b261ecSmrgSProcScreenSaverSetAttributes (client) 149805b261ecSmrg ClientPtr client; 149905b261ecSmrg{ 150005b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 150105b261ecSmrg int n; 150205b261ecSmrg 150305b261ecSmrg swaps (&stuff->length, n); 150405b261ecSmrg REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 150505b261ecSmrg swapl (&stuff->drawable, n); 150605b261ecSmrg swaps (&stuff->x, n); 150705b261ecSmrg swaps (&stuff->y, n); 150805b261ecSmrg swaps (&stuff->width, n); 150905b261ecSmrg swaps (&stuff->height, n); 151005b261ecSmrg swaps (&stuff->borderWidth, n); 151105b261ecSmrg swapl (&stuff->visualID, n); 151205b261ecSmrg swapl (&stuff->mask, n); 151305b261ecSmrg SwapRestL(stuff); 151405b261ecSmrg return ProcScreenSaverSetAttributes (client); 151505b261ecSmrg} 151605b261ecSmrg 151705b261ecSmrgstatic int 151805b261ecSmrgSProcScreenSaverUnsetAttributes (client) 151905b261ecSmrg ClientPtr client; 152005b261ecSmrg{ 152105b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 152205b261ecSmrg int n; 152305b261ecSmrg 152405b261ecSmrg swaps (&stuff->length, n); 152505b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 152605b261ecSmrg swapl (&stuff->drawable, n); 152705b261ecSmrg return ProcScreenSaverUnsetAttributes (client); 152805b261ecSmrg} 152905b261ecSmrg 153005b261ecSmrgstatic int 153105b261ecSmrgSProcScreenSaverSuspend (ClientPtr client) 153205b261ecSmrg{ 153305b261ecSmrg int n; 153405b261ecSmrg REQUEST(xScreenSaverSuspendReq); 153505b261ecSmrg 153605b261ecSmrg swaps(&stuff->length, n); 153705b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 153805b261ecSmrg swapl(&stuff->suspend, n); 153905b261ecSmrg return ProcScreenSaverSuspend (client); 154005b261ecSmrg} 154105b261ecSmrg 154205b261ecSmrgstatic DISPATCH_PROC((*SwappedVector[])) = { 154305b261ecSmrg SProcScreenSaverQueryVersion, 154405b261ecSmrg SProcScreenSaverQueryInfo, 154505b261ecSmrg SProcScreenSaverSelectInput, 154605b261ecSmrg SProcScreenSaverSetAttributes, 154705b261ecSmrg SProcScreenSaverUnsetAttributes, 154805b261ecSmrg SProcScreenSaverSuspend, 154905b261ecSmrg}; 155005b261ecSmrg 155105b261ecSmrgstatic int 155205b261ecSmrgSProcScreenSaverDispatch (client) 155305b261ecSmrg ClientPtr client; 155405b261ecSmrg{ 155505b261ecSmrg REQUEST(xReq); 155605b261ecSmrg 155705b261ecSmrg if (stuff->data < NUM_REQUESTS) 155805b261ecSmrg return (*SwappedVector[stuff->data])(client); 155905b261ecSmrg return BadRequest; 156005b261ecSmrg} 1561