saver.c revision 6747b715
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#ifdef HAVE_DIX_CONFIG_H 3105b261ecSmrg#include <dix-config.h> 3205b261ecSmrg#endif 3305b261ecSmrg 3405b261ecSmrg#include <X11/X.h> 3505b261ecSmrg#include <X11/Xproto.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "os.h" 3805b261ecSmrg#include "windowstr.h" 3905b261ecSmrg#include "scrnintstr.h" 4005b261ecSmrg#include "pixmapstr.h" 4105b261ecSmrg#include "extnsionst.h" 4205b261ecSmrg#include "dixstruct.h" 4305b261ecSmrg#include "resource.h" 4405b261ecSmrg#include "opaque.h" 4505b261ecSmrg#include <X11/extensions/saverproto.h> 4605b261ecSmrg#include "gcstruct.h" 4705b261ecSmrg#include "cursorstr.h" 4805b261ecSmrg#include "colormapst.h" 494642e01fSmrg#include "xace.h" 5005b261ecSmrg#ifdef PANORAMIX 5105b261ecSmrg#include "panoramiX.h" 5205b261ecSmrg#include "panoramiXsrv.h" 5305b261ecSmrg#endif 5405b261ecSmrg#ifdef DPMSExtension 556747b715Smrg#include <X11/extensions/dpmsconst.h> 5605b261ecSmrg#endif 576747b715Smrg#include "protocol-versions.h" 5805b261ecSmrg 5905b261ecSmrg#include <stdio.h> 6005b261ecSmrg 6105b261ecSmrg#include "modinit.h" 6205b261ecSmrg 6305b261ecSmrgstatic int ScreenSaverEventBase = 0; 6405b261ecSmrg 6505b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverQueryInfo); 6605b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverDispatch); 6705b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverQueryVersion); 6805b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSelectInput); 6905b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSetAttributes); 7005b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverUnsetAttributes); 7105b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSuspend); 7205b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverDispatch); 7305b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverQueryInfo); 7405b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverQueryVersion); 7505b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSelectInput); 7605b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSetAttributes); 7705b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverUnsetAttributes); 7805b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSuspend); 7905b261ecSmrg 8005b261ecSmrgstatic Bool ScreenSaverHandle ( 8105b261ecSmrg ScreenPtr /* pScreen */, 8205b261ecSmrg int /* xstate */, 8305b261ecSmrg Bool /* force */ 8405b261ecSmrg ); 8505b261ecSmrg 8605b261ecSmrgstatic Bool 8705b261ecSmrgCreateSaverWindow ( 8805b261ecSmrg ScreenPtr /* pScreen */ 8905b261ecSmrg ); 9005b261ecSmrg 9105b261ecSmrgstatic Bool 9205b261ecSmrgDestroySaverWindow ( 9305b261ecSmrg ScreenPtr /* pScreen */ 9405b261ecSmrg ); 9505b261ecSmrg 9605b261ecSmrgstatic void 9705b261ecSmrgUninstallSaverColormap ( 9805b261ecSmrg ScreenPtr /* pScreen */ 9905b261ecSmrg ); 10005b261ecSmrg 10105b261ecSmrgstatic void 10205b261ecSmrgCheckScreenPrivate ( 10305b261ecSmrg ScreenPtr /* pScreen */ 10405b261ecSmrg ); 10505b261ecSmrg 10605b261ecSmrgstatic void SScreenSaverNotifyEvent ( 10705b261ecSmrg xScreenSaverNotifyEvent * /* from */, 10805b261ecSmrg xScreenSaverNotifyEvent * /* to */ 10905b261ecSmrg ); 11005b261ecSmrg 11105b261ecSmrgstatic RESTYPE SuspendType; /* resource type for suspension records */ 11205b261ecSmrg 11305b261ecSmrgtypedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; 11405b261ecSmrg 11505b261ecSmrg/* List of clients that are suspending the screensaver. */ 11605b261ecSmrgstatic ScreenSaverSuspensionPtr suspendingClients = NULL; 11705b261ecSmrg 11805b261ecSmrg/* 11905b261ecSmrg * clientResource is a resource ID that's added when the record is 12005b261ecSmrg * allocated, so the record is freed and the screensaver resumed when 12105b261ecSmrg * the client disconnects. count is the number of times the client has 12205b261ecSmrg * requested the screensaver be suspended. 12305b261ecSmrg */ 12405b261ecSmrgtypedef struct _ScreenSaverSuspension 12505b261ecSmrg{ 12605b261ecSmrg ScreenSaverSuspensionPtr next; 12705b261ecSmrg ClientPtr pClient; 12805b261ecSmrg XID clientResource; 12905b261ecSmrg int count; 13005b261ecSmrg} ScreenSaverSuspensionRec; 13105b261ecSmrg 13205b261ecSmrgstatic int ScreenSaverFreeSuspend( 13305b261ecSmrg pointer /*value */, 13405b261ecSmrg XID /* id */ 13505b261ecSmrg); 13605b261ecSmrg 13705b261ecSmrg/* 13805b261ecSmrg * each screen has a list of clients requesting 13905b261ecSmrg * ScreenSaverNotify events. Each client has a resource 14005b261ecSmrg * for each screen it selects ScreenSaverNotify input for, 14105b261ecSmrg * this resource is used to delete the ScreenSaverNotifyRec 14205b261ecSmrg * entry from the per-screen queue. 14305b261ecSmrg */ 14405b261ecSmrg 1456747b715Smrgstatic RESTYPE SaverEventType; /* resource type for event masks */ 14605b261ecSmrg 14705b261ecSmrgtypedef struct _ScreenSaverEvent *ScreenSaverEventPtr; 14805b261ecSmrg 14905b261ecSmrgtypedef struct _ScreenSaverEvent { 15005b261ecSmrg ScreenSaverEventPtr next; 15105b261ecSmrg ClientPtr client; 15205b261ecSmrg ScreenPtr screen; 15305b261ecSmrg XID resource; 15405b261ecSmrg CARD32 mask; 15505b261ecSmrg} ScreenSaverEventRec; 15605b261ecSmrg 15705b261ecSmrgstatic int ScreenSaverFreeEvents( 15805b261ecSmrg pointer /* value */, 15905b261ecSmrg XID /* id */ 16005b261ecSmrg); 16105b261ecSmrg 16205b261ecSmrgstatic Bool setEventMask ( 16305b261ecSmrg ScreenPtr /* pScreen */, 16405b261ecSmrg ClientPtr /* client */, 16505b261ecSmrg unsigned long /* mask */ 16605b261ecSmrg); 16705b261ecSmrg 16805b261ecSmrgstatic unsigned long getEventMask ( 16905b261ecSmrg ScreenPtr /* pScreen */, 17005b261ecSmrg ClientPtr /* client */ 17105b261ecSmrg); 17205b261ecSmrg 17305b261ecSmrg/* 17405b261ecSmrg * when a client sets the screen saver attributes, a resource is 17505b261ecSmrg * kept to be freed when the client exits 17605b261ecSmrg */ 17705b261ecSmrg 17805b261ecSmrgstatic RESTYPE AttrType; /* resource type for attributes */ 17905b261ecSmrg 18005b261ecSmrgtypedef struct _ScreenSaverAttr { 18105b261ecSmrg ScreenPtr screen; 18205b261ecSmrg ClientPtr client; 18305b261ecSmrg XID resource; 18405b261ecSmrg short x, y; 18505b261ecSmrg unsigned short width, height, borderWidth; 18605b261ecSmrg unsigned char class; 18705b261ecSmrg unsigned char depth; 18805b261ecSmrg VisualID visual; 18905b261ecSmrg CursorPtr pCursor; 19005b261ecSmrg PixmapPtr pBackgroundPixmap; 19105b261ecSmrg PixmapPtr pBorderPixmap; 19205b261ecSmrg Colormap colormap; 19305b261ecSmrg unsigned long mask; /* no pixmaps or cursors */ 19405b261ecSmrg unsigned long *values; 19505b261ecSmrg} ScreenSaverAttrRec, *ScreenSaverAttrPtr; 19605b261ecSmrg 19705b261ecSmrgstatic int ScreenSaverFreeAttr ( 19805b261ecSmrg pointer /* value */, 19905b261ecSmrg XID /* id */ 20005b261ecSmrg); 20105b261ecSmrg 20205b261ecSmrgstatic void FreeAttrs ( 20305b261ecSmrg ScreenSaverAttrPtr /* pAttr */ 20405b261ecSmrg); 20505b261ecSmrg 20605b261ecSmrgstatic void FreeScreenAttr ( 20705b261ecSmrg ScreenSaverAttrPtr /* pAttr */ 20805b261ecSmrg); 20905b261ecSmrg 21005b261ecSmrgstatic void 21105b261ecSmrgSendScreenSaverNotify ( 21205b261ecSmrg ScreenPtr /* pScreen */, 21305b261ecSmrg int /* state */, 21405b261ecSmrg Bool /* forced */ 21505b261ecSmrg); 21605b261ecSmrg 21705b261ecSmrgtypedef struct _ScreenSaverScreenPrivate { 21805b261ecSmrg ScreenSaverEventPtr events; 21905b261ecSmrg ScreenSaverAttrPtr attr; 22005b261ecSmrg Bool hasWindow; 22105b261ecSmrg Colormap installedMap; 22205b261ecSmrg} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr; 22305b261ecSmrg 22405b261ecSmrgstatic ScreenSaverScreenPrivatePtr 22505b261ecSmrgMakeScreenPrivate ( 22605b261ecSmrg ScreenPtr /* pScreen */ 22705b261ecSmrg ); 22805b261ecSmrg 2296747b715Smrgstatic DevPrivateKeyRec ScreenPrivateKeyRec; 2306747b715Smrg#define ScreenPrivateKey (&ScreenPrivateKeyRec) 23105b261ecSmrg 2324642e01fSmrg#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \ 2334642e01fSmrg dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey)) 2344642e01fSmrg#define SetScreenPrivate(s,v) \ 2354642e01fSmrg dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v); 23605b261ecSmrg#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL) 23705b261ecSmrg 2386747b715Smrg#define New(t) (malloc(sizeof (t))) 23905b261ecSmrg 24005b261ecSmrg/**************** 24105b261ecSmrg * ScreenSaverExtensionInit 24205b261ecSmrg * 24305b261ecSmrg * Called from InitExtensions in main() or from QueryExtension() if the 24405b261ecSmrg * extension is dynamically loaded. 24505b261ecSmrg * 24605b261ecSmrg ****************/ 24705b261ecSmrg 24805b261ecSmrgvoid 24905b261ecSmrgScreenSaverExtensionInit(INITARGS) 25005b261ecSmrg{ 25105b261ecSmrg ExtensionEntry *extEntry; 25205b261ecSmrg int i; 25305b261ecSmrg ScreenPtr pScreen; 25405b261ecSmrg 2556747b715Smrg if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 2566747b715Smrg return; 2576747b715Smrg 2586747b715Smrg AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr"); 2596747b715Smrg SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, 2606747b715Smrg "SaverEvent"); 2616747b715Smrg SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, 2626747b715Smrg "SaverSuspend"); 26305b261ecSmrg 26405b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) 26505b261ecSmrg { 26605b261ecSmrg pScreen = screenInfo.screens[i]; 26705b261ecSmrg SetScreenPrivate (pScreen, NULL); 26805b261ecSmrg } 2696747b715Smrg if (AttrType && SaverEventType && SuspendType && 27005b261ecSmrg (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, 27105b261ecSmrg ProcScreenSaverDispatch, SProcScreenSaverDispatch, 2724642e01fSmrg NULL, StandardMinorOpcode))) 27305b261ecSmrg { 27405b261ecSmrg ScreenSaverEventBase = extEntry->eventBase; 27505b261ecSmrg EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent; 27605b261ecSmrg } 27705b261ecSmrg} 27805b261ecSmrg 27905b261ecSmrgstatic void 2806747b715SmrgCheckScreenPrivate (ScreenPtr pScreen) 28105b261ecSmrg{ 28205b261ecSmrg SetupScreen (pScreen); 28305b261ecSmrg 28405b261ecSmrg if (!pPriv) 28505b261ecSmrg return; 28605b261ecSmrg if (!pPriv->attr && !pPriv->events && 28705b261ecSmrg !pPriv->hasWindow && pPriv->installedMap == None) 28805b261ecSmrg { 2896747b715Smrg free(pPriv); 29005b261ecSmrg SetScreenPrivate (pScreen, NULL); 2916747b715Smrg pScreen->screensaver.ExternalScreenSaver = NULL; 29205b261ecSmrg } 29305b261ecSmrg} 29405b261ecSmrg 29505b261ecSmrgstatic ScreenSaverScreenPrivatePtr 2966747b715SmrgMakeScreenPrivate (ScreenPtr pScreen) 29705b261ecSmrg{ 29805b261ecSmrg SetupScreen (pScreen); 29905b261ecSmrg 30005b261ecSmrg if (pPriv) 30105b261ecSmrg return pPriv; 30205b261ecSmrg pPriv = New (ScreenSaverScreenPrivateRec); 30305b261ecSmrg if (!pPriv) 30405b261ecSmrg return 0; 30505b261ecSmrg pPriv->events = 0; 30605b261ecSmrg pPriv->attr = 0; 30705b261ecSmrg pPriv->hasWindow = FALSE; 30805b261ecSmrg pPriv->installedMap = None; 30905b261ecSmrg SetScreenPrivate (pScreen, pPriv); 3106747b715Smrg pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle; 31105b261ecSmrg return pPriv; 31205b261ecSmrg} 31305b261ecSmrg 31405b261ecSmrgstatic unsigned long 3156747b715SmrggetEventMask (ScreenPtr pScreen, ClientPtr client) 31605b261ecSmrg{ 31705b261ecSmrg SetupScreen(pScreen); 31805b261ecSmrg ScreenSaverEventPtr pEv; 31905b261ecSmrg 32005b261ecSmrg if (!pPriv) 32105b261ecSmrg return 0; 32205b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 32305b261ecSmrg if (pEv->client == client) 32405b261ecSmrg return pEv->mask; 32505b261ecSmrg return 0; 32605b261ecSmrg} 32705b261ecSmrg 32805b261ecSmrgstatic Bool 3296747b715SmrgsetEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask) 33005b261ecSmrg{ 33105b261ecSmrg SetupScreen(pScreen); 33205b261ecSmrg ScreenSaverEventPtr pEv, *pPrev; 33305b261ecSmrg 33405b261ecSmrg if (getEventMask (pScreen, client) == mask) 33505b261ecSmrg return TRUE; 33605b261ecSmrg if (!pPriv) 33705b261ecSmrg { 33805b261ecSmrg pPriv = MakeScreenPrivate (pScreen); 33905b261ecSmrg if (!pPriv) 34005b261ecSmrg return FALSE; 34105b261ecSmrg } 34205b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 34305b261ecSmrg if (pEv->client == client) 34405b261ecSmrg break; 34505b261ecSmrg if (mask == 0) 34605b261ecSmrg { 3476747b715Smrg FreeResource (pEv->resource, SaverEventType); 34805b261ecSmrg *pPrev = pEv->next; 3496747b715Smrg free(pEv); 35005b261ecSmrg CheckScreenPrivate (pScreen); 35105b261ecSmrg } 35205b261ecSmrg else 35305b261ecSmrg { 35405b261ecSmrg if (!pEv) 35505b261ecSmrg { 35605b261ecSmrg pEv = New (ScreenSaverEventRec); 35705b261ecSmrg if (!pEv) 35805b261ecSmrg { 35905b261ecSmrg CheckScreenPrivate (pScreen); 36005b261ecSmrg return FALSE; 36105b261ecSmrg } 36205b261ecSmrg *pPrev = pEv; 36305b261ecSmrg pEv->next = NULL; 36405b261ecSmrg pEv->client = client; 36505b261ecSmrg pEv->screen = pScreen; 36605b261ecSmrg pEv->resource = FakeClientID (client->index); 3676747b715Smrg if (!AddResource (pEv->resource, SaverEventType, (pointer) pEv)) 36805b261ecSmrg return FALSE; 36905b261ecSmrg } 37005b261ecSmrg pEv->mask = mask; 37105b261ecSmrg } 37205b261ecSmrg return TRUE; 37305b261ecSmrg} 37405b261ecSmrg 37505b261ecSmrgstatic void 3766747b715SmrgFreeAttrs (ScreenSaverAttrPtr pAttr) 37705b261ecSmrg{ 37805b261ecSmrg PixmapPtr pPixmap; 37905b261ecSmrg CursorPtr pCursor; 38005b261ecSmrg 38105b261ecSmrg if ((pPixmap = pAttr->pBackgroundPixmap) != 0) 38205b261ecSmrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 38305b261ecSmrg if ((pPixmap = pAttr->pBorderPixmap) != 0) 38405b261ecSmrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 38505b261ecSmrg if ((pCursor = pAttr->pCursor) != 0) 38605b261ecSmrg FreeCursor (pCursor, (Cursor) 0); 38705b261ecSmrg} 38805b261ecSmrg 38905b261ecSmrgstatic void 3906747b715SmrgFreeScreenAttr (ScreenSaverAttrPtr pAttr) 39105b261ecSmrg{ 39205b261ecSmrg FreeAttrs (pAttr); 3936747b715Smrg free(pAttr->values); 3946747b715Smrg free(pAttr); 39505b261ecSmrg} 39605b261ecSmrg 39705b261ecSmrgstatic int 3986747b715SmrgScreenSaverFreeEvents (pointer value, XID id) 39905b261ecSmrg{ 40005b261ecSmrg ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value; 40105b261ecSmrg ScreenPtr pScreen = pOld->screen; 40205b261ecSmrg SetupScreen (pScreen); 40305b261ecSmrg ScreenSaverEventPtr pEv, *pPrev; 40405b261ecSmrg 40505b261ecSmrg if (!pPriv) 40605b261ecSmrg return TRUE; 40705b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 40805b261ecSmrg if (pEv == pOld) 40905b261ecSmrg break; 41005b261ecSmrg if (!pEv) 41105b261ecSmrg return TRUE; 41205b261ecSmrg *pPrev = pEv->next; 4136747b715Smrg free(pEv); 41405b261ecSmrg CheckScreenPrivate (pScreen); 41505b261ecSmrg return TRUE; 41605b261ecSmrg} 41705b261ecSmrg 41805b261ecSmrgstatic int 4196747b715SmrgScreenSaverFreeAttr (pointer value, XID id) 42005b261ecSmrg{ 42105b261ecSmrg ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value; 42205b261ecSmrg ScreenPtr pScreen = pOldAttr->screen; 42305b261ecSmrg SetupScreen (pScreen); 42405b261ecSmrg 42505b261ecSmrg if (!pPriv) 42605b261ecSmrg return TRUE; 42705b261ecSmrg if (pPriv->attr != pOldAttr) 42805b261ecSmrg return TRUE; 42905b261ecSmrg FreeScreenAttr (pOldAttr); 43005b261ecSmrg pPriv->attr = NULL; 43105b261ecSmrg if (pPriv->hasWindow) 43205b261ecSmrg { 4334642e01fSmrg dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); 4344642e01fSmrg dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive); 43505b261ecSmrg } 43605b261ecSmrg CheckScreenPrivate (pScreen); 43705b261ecSmrg return TRUE; 43805b261ecSmrg} 43905b261ecSmrg 44005b261ecSmrgstatic int 44105b261ecSmrgScreenSaverFreeSuspend (pointer value, XID id) 44205b261ecSmrg{ 44305b261ecSmrg ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; 44405b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 44505b261ecSmrg 44605b261ecSmrg /* Unlink and free the suspension record for the client */ 44705b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 44805b261ecSmrg { 44905b261ecSmrg if (this == data) 45005b261ecSmrg { 45105b261ecSmrg *prev = this->next; 4526747b715Smrg free(this); 45305b261ecSmrg break; 45405b261ecSmrg } 45505b261ecSmrg } 45605b261ecSmrg 45705b261ecSmrg /* Reenable the screensaver if this was the last client suspending it. */ 45805b261ecSmrg if (screenSaverSuspended && suspendingClients == NULL) 45905b261ecSmrg { 46005b261ecSmrg screenSaverSuspended = FALSE; 46105b261ecSmrg 46205b261ecSmrg /* The screensaver could be active, since suspending it (by design) 46305b261ecSmrg doesn't prevent it from being forceably activated */ 46405b261ecSmrg#ifdef DPMSExtension 46505b261ecSmrg if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) 46605b261ecSmrg#else 46705b261ecSmrg if (screenIsSaved != SCREEN_SAVER_ON) 46805b261ecSmrg#endif 46905b261ecSmrg { 47005b261ecSmrg UpdateCurrentTimeIf(); 47105b261ecSmrg lastDeviceEventTime = currentTime; 47205b261ecSmrg SetScreenSaverTimer(); 47305b261ecSmrg } 47405b261ecSmrg } 47505b261ecSmrg 47605b261ecSmrg return Success; 47705b261ecSmrg} 47805b261ecSmrg 47905b261ecSmrgstatic void 4806747b715SmrgSendScreenSaverNotify (ScreenPtr pScreen, int state, Bool forced) 48105b261ecSmrg{ 48205b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 48305b261ecSmrg ScreenSaverEventPtr pEv; 48405b261ecSmrg unsigned long mask; 48505b261ecSmrg xScreenSaverNotifyEvent ev; 48605b261ecSmrg int kind; 48705b261ecSmrg 48805b261ecSmrg UpdateCurrentTimeIf (); 48905b261ecSmrg mask = ScreenSaverNotifyMask; 49005b261ecSmrg if (state == ScreenSaverCycle) 49105b261ecSmrg mask = ScreenSaverCycleMask; 49205b261ecSmrg pScreen = screenInfo.screens[pScreen->myNum]; 49305b261ecSmrg pPriv = GetScreenPrivate(pScreen); 49405b261ecSmrg if (!pPriv) 49505b261ecSmrg return; 49605b261ecSmrg if (pPriv->attr) 49705b261ecSmrg kind = ScreenSaverExternal; 49805b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 49905b261ecSmrg kind = ScreenSaverBlanked; 50005b261ecSmrg else 50105b261ecSmrg kind = ScreenSaverInternal; 50205b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 50305b261ecSmrg { 50405b261ecSmrg if (!(pEv->mask & mask)) 50505b261ecSmrg continue; 50605b261ecSmrg ev.type = ScreenSaverNotify + ScreenSaverEventBase; 50705b261ecSmrg ev.state = state; 50805b261ecSmrg ev.timestamp = currentTime.milliseconds; 5096747b715Smrg ev.root = pScreen->root->drawable.id; 5106747b715Smrg ev.window = pScreen->screensaver.wid; 51105b261ecSmrg ev.kind = kind; 51205b261ecSmrg ev.forced = forced; 5136747b715Smrg WriteEventsToClient (pEv->client, 1, (xEvent *) &ev); 51405b261ecSmrg } 51505b261ecSmrg} 51605b261ecSmrg 51705b261ecSmrgstatic void 5186747b715SmrgSScreenSaverNotifyEvent (xScreenSaverNotifyEvent *from, 5196747b715Smrg xScreenSaverNotifyEvent *to) 52005b261ecSmrg{ 52105b261ecSmrg to->type = from->type; 52205b261ecSmrg to->state = from->state; 52305b261ecSmrg cpswaps (from->sequenceNumber, to->sequenceNumber); 52405b261ecSmrg cpswapl (from->timestamp, to->timestamp); 52505b261ecSmrg cpswapl (from->root, to->root); 52605b261ecSmrg cpswapl (from->window, to->window); 52705b261ecSmrg to->kind = from->kind; 52805b261ecSmrg to->forced = from->forced; 52905b261ecSmrg} 53005b261ecSmrg 53105b261ecSmrgstatic void 5326747b715SmrgUninstallSaverColormap (ScreenPtr pScreen) 53305b261ecSmrg{ 53405b261ecSmrg SetupScreen(pScreen); 53505b261ecSmrg ColormapPtr pCmap; 5366747b715Smrg int rc; 53705b261ecSmrg 53805b261ecSmrg if (pPriv && pPriv->installedMap != None) 53905b261ecSmrg { 5406747b715Smrg rc = dixLookupResourceByType((pointer *)&pCmap, pPriv->installedMap, 5416747b715Smrg RT_COLORMAP, serverClient, 5426747b715Smrg DixUninstallAccess); 5436747b715Smrg if (rc == Success) 54405b261ecSmrg (*pCmap->pScreen->UninstallColormap) (pCmap); 54505b261ecSmrg pPriv->installedMap = None; 54605b261ecSmrg CheckScreenPrivate (pScreen); 54705b261ecSmrg } 54805b261ecSmrg} 54905b261ecSmrg 55005b261ecSmrgstatic Bool 5516747b715SmrgCreateSaverWindow (ScreenPtr pScreen) 55205b261ecSmrg{ 55305b261ecSmrg SetupScreen (pScreen); 55405b261ecSmrg ScreenSaverStuffPtr pSaver; 55505b261ecSmrg ScreenSaverAttrPtr pAttr; 55605b261ecSmrg WindowPtr pWin; 55705b261ecSmrg int result; 55805b261ecSmrg unsigned long mask; 55905b261ecSmrg Colormap *installedMaps; 56005b261ecSmrg int numInstalled; 56105b261ecSmrg int i; 56205b261ecSmrg Colormap wantMap; 56305b261ecSmrg ColormapPtr pCmap; 56405b261ecSmrg 5656747b715Smrg pSaver = &pScreen->screensaver; 56605b261ecSmrg if (pSaver->pWindow) 56705b261ecSmrg { 56805b261ecSmrg pSaver->pWindow = NullWindow; 56905b261ecSmrg FreeResource (pSaver->wid, RT_NONE); 57005b261ecSmrg if (pPriv) 57105b261ecSmrg { 57205b261ecSmrg UninstallSaverColormap (pScreen); 57305b261ecSmrg pPriv->hasWindow = FALSE; 57405b261ecSmrg CheckScreenPrivate (pScreen); 57505b261ecSmrg } 57605b261ecSmrg } 57705b261ecSmrg 57805b261ecSmrg if (!pPriv || !(pAttr = pPriv->attr)) 57905b261ecSmrg return FALSE; 58005b261ecSmrg 58105b261ecSmrg pPriv->installedMap = None; 58205b261ecSmrg 58305b261ecSmrg if (GrabInProgress && GrabInProgress != pAttr->client->index) 58405b261ecSmrg return FALSE; 58505b261ecSmrg 5866747b715Smrg pWin = CreateWindow (pSaver->wid, pScreen->root, 58705b261ecSmrg pAttr->x, pAttr->y, pAttr->width, pAttr->height, 58805b261ecSmrg pAttr->borderWidth, pAttr->class, 58905b261ecSmrg pAttr->mask, (XID *)pAttr->values, 59005b261ecSmrg pAttr->depth, serverClient, pAttr->visual, 59105b261ecSmrg &result); 59205b261ecSmrg if (!pWin) 59305b261ecSmrg return FALSE; 59405b261ecSmrg 59505b261ecSmrg if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin)) 59605b261ecSmrg return FALSE; 59705b261ecSmrg 59805b261ecSmrg mask = 0; 59905b261ecSmrg if (pAttr->pBackgroundPixmap) 60005b261ecSmrg { 60105b261ecSmrg pWin->backgroundState = BackgroundPixmap; 60205b261ecSmrg pWin->background.pixmap = pAttr->pBackgroundPixmap; 60305b261ecSmrg pAttr->pBackgroundPixmap->refcnt++; 60405b261ecSmrg mask |= CWBackPixmap; 60505b261ecSmrg } 60605b261ecSmrg if (pAttr->pBorderPixmap) 60705b261ecSmrg { 60805b261ecSmrg pWin->borderIsPixel = FALSE; 60905b261ecSmrg pWin->border.pixmap = pAttr->pBorderPixmap; 61005b261ecSmrg pAttr->pBorderPixmap->refcnt++; 61105b261ecSmrg mask |= CWBorderPixmap; 61205b261ecSmrg } 61305b261ecSmrg if (pAttr->pCursor) 61405b261ecSmrg { 61505b261ecSmrg if (!pWin->optional) 61605b261ecSmrg if (!MakeWindowOptional (pWin)) 61705b261ecSmrg { 61805b261ecSmrg FreeResource (pWin->drawable.id, RT_NONE); 61905b261ecSmrg return FALSE; 62005b261ecSmrg } 6216747b715Smrg pAttr->pCursor->refcnt++; 62205b261ecSmrg if (pWin->optional->cursor) 62305b261ecSmrg FreeCursor (pWin->optional->cursor, (Cursor)0); 62405b261ecSmrg pWin->optional->cursor = pAttr->pCursor; 62505b261ecSmrg pWin->cursorIsNone = FALSE; 62605b261ecSmrg CheckWindowOptionalNeed (pWin); 62705b261ecSmrg mask |= CWCursor; 62805b261ecSmrg } 62905b261ecSmrg if (mask) 63005b261ecSmrg (*pScreen->ChangeWindowAttributes) (pWin, mask); 63105b261ecSmrg 63205b261ecSmrg if (pAttr->colormap != None) 63305b261ecSmrg (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap, 63405b261ecSmrg serverClient); 63505b261ecSmrg 63605b261ecSmrg MapWindow (pWin, serverClient); 63705b261ecSmrg 63805b261ecSmrg pPriv->hasWindow = TRUE; 63905b261ecSmrg pSaver->pWindow = pWin; 64005b261ecSmrg 64105b261ecSmrg /* check and install our own colormap if it isn't installed now */ 64205b261ecSmrg wantMap = wColormap (pWin); 64305b261ecSmrg if (wantMap == None) 64405b261ecSmrg return TRUE; 6456747b715Smrg installedMaps = malloc(pScreen->maxInstalledCmaps * sizeof (Colormap)); 64605b261ecSmrg numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps) 64705b261ecSmrg (pScreen, installedMaps); 64805b261ecSmrg for (i = 0; i < numInstalled; i++) 64905b261ecSmrg if (installedMaps[i] == wantMap) 65005b261ecSmrg break; 65105b261ecSmrg 6526747b715Smrg free((char *) installedMaps); 65305b261ecSmrg 65405b261ecSmrg if (i < numInstalled) 65505b261ecSmrg return TRUE; 65605b261ecSmrg 6576747b715Smrg result = dixLookupResourceByType((pointer *)&pCmap, wantMap, RT_COLORMAP, 6586747b715Smrg serverClient, DixInstallAccess); 6596747b715Smrg if (result != Success) 66005b261ecSmrg return TRUE; 66105b261ecSmrg 66205b261ecSmrg pPriv->installedMap = wantMap; 66305b261ecSmrg 66405b261ecSmrg (*pCmap->pScreen->InstallColormap) (pCmap); 66505b261ecSmrg 66605b261ecSmrg return TRUE; 66705b261ecSmrg} 66805b261ecSmrg 66905b261ecSmrgstatic Bool 6706747b715SmrgDestroySaverWindow (ScreenPtr pScreen) 67105b261ecSmrg{ 67205b261ecSmrg SetupScreen(pScreen); 67305b261ecSmrg ScreenSaverStuffPtr pSaver; 67405b261ecSmrg 67505b261ecSmrg if (!pPriv || !pPriv->hasWindow) 67605b261ecSmrg return FALSE; 67705b261ecSmrg 6786747b715Smrg pSaver = &pScreen->screensaver; 67905b261ecSmrg if (pSaver->pWindow) 68005b261ecSmrg { 68105b261ecSmrg pSaver->pWindow = NullWindow; 68205b261ecSmrg FreeResource (pSaver->wid, RT_NONE); 68305b261ecSmrg } 68405b261ecSmrg pPriv->hasWindow = FALSE; 68505b261ecSmrg CheckScreenPrivate (pScreen); 68605b261ecSmrg UninstallSaverColormap (pScreen); 68705b261ecSmrg return TRUE; 68805b261ecSmrg} 68905b261ecSmrg 69005b261ecSmrgstatic Bool 6916747b715SmrgScreenSaverHandle (ScreenPtr pScreen, int xstate, Bool force) 69205b261ecSmrg{ 69305b261ecSmrg int state = 0; 69405b261ecSmrg Bool ret = FALSE; 69505b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 69605b261ecSmrg 69705b261ecSmrg switch (xstate) 69805b261ecSmrg { 69905b261ecSmrg case SCREEN_SAVER_ON: 70005b261ecSmrg state = ScreenSaverOn; 70105b261ecSmrg ret = CreateSaverWindow (pScreen); 70205b261ecSmrg break; 70305b261ecSmrg case SCREEN_SAVER_OFF: 70405b261ecSmrg state = ScreenSaverOff; 70505b261ecSmrg ret = DestroySaverWindow (pScreen); 70605b261ecSmrg break; 70705b261ecSmrg case SCREEN_SAVER_CYCLE: 70805b261ecSmrg state = ScreenSaverCycle; 70905b261ecSmrg pPriv = GetScreenPrivate (pScreen); 71005b261ecSmrg if (pPriv && pPriv->hasWindow) 71105b261ecSmrg ret = TRUE; 71205b261ecSmrg 71305b261ecSmrg } 71405b261ecSmrg#ifdef PANORAMIX 71505b261ecSmrg if(noPanoramiXExtension || !pScreen->myNum) 71605b261ecSmrg#endif 71705b261ecSmrg SendScreenSaverNotify (pScreen, state, force); 71805b261ecSmrg return ret; 71905b261ecSmrg} 72005b261ecSmrg 72105b261ecSmrgstatic int 7226747b715SmrgProcScreenSaverQueryVersion (ClientPtr client) 72305b261ecSmrg{ 72405b261ecSmrg xScreenSaverQueryVersionReply rep; 7254642e01fSmrg int n; 72605b261ecSmrg 72705b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq); 72805b261ecSmrg rep.type = X_Reply; 72905b261ecSmrg rep.length = 0; 73005b261ecSmrg rep.sequenceNumber = client->sequence; 7316747b715Smrg rep.majorVersion = SERVER_SAVER_MAJOR_VERSION; 7326747b715Smrg rep.minorVersion = SERVER_SAVER_MINOR_VERSION; 73305b261ecSmrg if (client->swapped) { 73405b261ecSmrg swaps(&rep.sequenceNumber, n); 73505b261ecSmrg swapl(&rep.length, n); 73605b261ecSmrg } 73705b261ecSmrg WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep); 7386747b715Smrg return Success; 73905b261ecSmrg} 74005b261ecSmrg 74105b261ecSmrgstatic int 7426747b715SmrgProcScreenSaverQueryInfo (ClientPtr client) 74305b261ecSmrg{ 74405b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 74505b261ecSmrg xScreenSaverQueryInfoReply rep; 7464642e01fSmrg int n, rc; 74705b261ecSmrg ScreenSaverStuffPtr pSaver; 74805b261ecSmrg DrawablePtr pDraw; 74905b261ecSmrg CARD32 lastInput; 75005b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 75105b261ecSmrg 75205b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq); 75305b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 7544642e01fSmrg DixGetAttrAccess); 7554642e01fSmrg if (rc != Success) 7564642e01fSmrg return rc; 7574642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 7584642e01fSmrg DixGetAttrAccess); 75905b261ecSmrg if (rc != Success) 76005b261ecSmrg return rc; 76105b261ecSmrg 7626747b715Smrg pSaver = &pDraw->pScreen->screensaver; 76305b261ecSmrg pPriv = GetScreenPrivate (pDraw->pScreen); 76405b261ecSmrg 76505b261ecSmrg UpdateCurrentTime (); 76605b261ecSmrg lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; 76705b261ecSmrg 76805b261ecSmrg rep.type = X_Reply; 76905b261ecSmrg rep.length = 0; 77005b261ecSmrg rep.sequenceNumber = client->sequence; 77105b261ecSmrg rep.window = pSaver->wid; 77205b261ecSmrg if (screenIsSaved != SCREEN_SAVER_OFF) 77305b261ecSmrg { 77405b261ecSmrg rep.state = ScreenSaverOn; 77505b261ecSmrg if (ScreenSaverTime) 77605b261ecSmrg rep.tilOrSince = lastInput - ScreenSaverTime; 77705b261ecSmrg else 77805b261ecSmrg rep.tilOrSince = 0; 77905b261ecSmrg } 78005b261ecSmrg else 78105b261ecSmrg { 78205b261ecSmrg if (ScreenSaverTime) 78305b261ecSmrg { 78405b261ecSmrg rep.state = ScreenSaverOff; 78505b261ecSmrg if (ScreenSaverTime < lastInput) 78605b261ecSmrg rep.tilOrSince = 0; 78705b261ecSmrg else 78805b261ecSmrg rep.tilOrSince = ScreenSaverTime - lastInput; 78905b261ecSmrg } 79005b261ecSmrg else 79105b261ecSmrg { 79205b261ecSmrg rep.state = ScreenSaverDisabled; 79305b261ecSmrg rep.tilOrSince = 0; 79405b261ecSmrg } 79505b261ecSmrg } 79605b261ecSmrg rep.idle = lastInput; 79705b261ecSmrg rep.eventMask = getEventMask (pDraw->pScreen, client); 79805b261ecSmrg if (pPriv && pPriv->attr) 79905b261ecSmrg rep.kind = ScreenSaverExternal; 80005b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 80105b261ecSmrg rep.kind = ScreenSaverBlanked; 80205b261ecSmrg else 80305b261ecSmrg rep.kind = ScreenSaverInternal; 80405b261ecSmrg if (client->swapped) 80505b261ecSmrg { 80605b261ecSmrg swaps (&rep.sequenceNumber, n); 80705b261ecSmrg swapl (&rep.length, n); 80805b261ecSmrg swapl (&rep.window, n); 80905b261ecSmrg swapl (&rep.tilOrSince, n); 81005b261ecSmrg swapl (&rep.idle, n); 81105b261ecSmrg swapl (&rep.eventMask, n); 81205b261ecSmrg } 81305b261ecSmrg WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep); 8146747b715Smrg return Success; 81505b261ecSmrg} 81605b261ecSmrg 81705b261ecSmrgstatic int 8186747b715SmrgProcScreenSaverSelectInput (ClientPtr client) 81905b261ecSmrg{ 82005b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 82105b261ecSmrg DrawablePtr pDraw; 82205b261ecSmrg int rc; 82305b261ecSmrg 82405b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq); 82505b261ecSmrg rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0, 8264642e01fSmrg DixGetAttrAccess); 8274642e01fSmrg if (rc != Success) 8284642e01fSmrg return rc; 8294642e01fSmrg 8304642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 8314642e01fSmrg DixSetAttrAccess); 83205b261ecSmrg if (rc != Success) 83305b261ecSmrg return rc; 8344642e01fSmrg 83505b261ecSmrg if (!setEventMask (pDraw->pScreen, client, stuff->eventMask)) 83605b261ecSmrg return BadAlloc; 83705b261ecSmrg return Success; 83805b261ecSmrg} 83905b261ecSmrg 84005b261ecSmrgstatic int 84105b261ecSmrgScreenSaverSetAttributes (ClientPtr client) 84205b261ecSmrg{ 84305b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 84405b261ecSmrg DrawablePtr pDraw; 84505b261ecSmrg WindowPtr pParent; 84605b261ecSmrg ScreenPtr pScreen; 84705b261ecSmrg ScreenSaverScreenPrivatePtr pPriv = 0; 84805b261ecSmrg ScreenSaverAttrPtr pAttr = 0; 84905b261ecSmrg int ret, len, class, bw, depth; 85005b261ecSmrg unsigned long visual; 85105b261ecSmrg int idepth, ivisual; 85205b261ecSmrg Bool fOK; 85305b261ecSmrg DepthPtr pDepth; 85405b261ecSmrg WindowOptPtr ancwopt; 85505b261ecSmrg unsigned int *pVlist; 85605b261ecSmrg unsigned long *values = 0; 85705b261ecSmrg unsigned long tmask, imask; 85805b261ecSmrg unsigned long val; 85905b261ecSmrg Pixmap pixID; 86005b261ecSmrg PixmapPtr pPixmap; 86105b261ecSmrg Cursor cursorID; 86205b261ecSmrg CursorPtr pCursor; 86305b261ecSmrg Colormap cmap; 86405b261ecSmrg ColormapPtr pCmap; 86505b261ecSmrg 86605b261ecSmrg REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 86705b261ecSmrg ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 8684642e01fSmrg DixGetAttrAccess); 86905b261ecSmrg if (ret != Success) 87005b261ecSmrg return ret; 87105b261ecSmrg pScreen = pDraw->pScreen; 8726747b715Smrg pParent = pScreen->root; 87305b261ecSmrg 8744642e01fSmrg ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess); 8754642e01fSmrg if (ret != Success) 8764642e01fSmrg return ret; 8774642e01fSmrg 8786747b715Smrg len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 87905b261ecSmrg if (Ones(stuff->mask) != len) 88005b261ecSmrg return BadLength; 88105b261ecSmrg if (!stuff->width || !stuff->height) 88205b261ecSmrg { 88305b261ecSmrg client->errorValue = 0; 88405b261ecSmrg return BadValue; 88505b261ecSmrg } 88605b261ecSmrg switch (class = stuff->c_class) 88705b261ecSmrg { 88805b261ecSmrg case CopyFromParent: 88905b261ecSmrg case InputOnly: 89005b261ecSmrg case InputOutput: 89105b261ecSmrg break; 89205b261ecSmrg default: 89305b261ecSmrg client->errorValue = class; 89405b261ecSmrg return BadValue; 89505b261ecSmrg } 89605b261ecSmrg bw = stuff->borderWidth; 89705b261ecSmrg depth = stuff->depth; 89805b261ecSmrg visual = stuff->visualID; 89905b261ecSmrg 90005b261ecSmrg /* copied directly from CreateWindow */ 90105b261ecSmrg 90205b261ecSmrg if (class == CopyFromParent) 90305b261ecSmrg class = pParent->drawable.class; 90405b261ecSmrg 90505b261ecSmrg if ((class != InputOutput) && (class != InputOnly)) 90605b261ecSmrg { 90705b261ecSmrg client->errorValue = class; 90805b261ecSmrg return BadValue; 90905b261ecSmrg } 91005b261ecSmrg 91105b261ecSmrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) 91205b261ecSmrg return BadMatch; 91305b261ecSmrg 91405b261ecSmrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) 91505b261ecSmrg return BadMatch; 91605b261ecSmrg 91705b261ecSmrg if ((class == InputOutput) && (depth == 0)) 91805b261ecSmrg depth = pParent->drawable.depth; 91905b261ecSmrg ancwopt = pParent->optional; 92005b261ecSmrg if (!ancwopt) 92105b261ecSmrg ancwopt = FindWindowWithOptional(pParent)->optional; 92205b261ecSmrg if (visual == CopyFromParent) 92305b261ecSmrg visual = ancwopt->visual; 92405b261ecSmrg 92505b261ecSmrg /* Find out if the depth and visual are acceptable for this Screen */ 92605b261ecSmrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) 92705b261ecSmrg { 92805b261ecSmrg fOK = FALSE; 92905b261ecSmrg for(idepth = 0; idepth < pScreen->numDepths; idepth++) 93005b261ecSmrg { 93105b261ecSmrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 93205b261ecSmrg if ((depth == pDepth->depth) || (depth == 0)) 93305b261ecSmrg { 93405b261ecSmrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) 93505b261ecSmrg { 93605b261ecSmrg if (visual == pDepth->vids[ivisual]) 93705b261ecSmrg { 93805b261ecSmrg fOK = TRUE; 93905b261ecSmrg break; 94005b261ecSmrg } 94105b261ecSmrg } 94205b261ecSmrg } 94305b261ecSmrg } 94405b261ecSmrg if (fOK == FALSE) 94505b261ecSmrg return BadMatch; 94605b261ecSmrg } 94705b261ecSmrg 94805b261ecSmrg if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) && 94905b261ecSmrg (class != InputOnly) && 95005b261ecSmrg (depth != pParent->drawable.depth)) 95105b261ecSmrg { 95205b261ecSmrg return BadMatch; 95305b261ecSmrg } 95405b261ecSmrg 95505b261ecSmrg if (((stuff->mask & CWColormap) == 0) && 95605b261ecSmrg (class != InputOnly) && 95705b261ecSmrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) 95805b261ecSmrg { 95905b261ecSmrg return BadMatch; 96005b261ecSmrg } 96105b261ecSmrg 96205b261ecSmrg /* end of errors from CreateWindow */ 96305b261ecSmrg 96405b261ecSmrg pPriv = GetScreenPrivate (pScreen); 96505b261ecSmrg if (pPriv && pPriv->attr) 96605b261ecSmrg { 96705b261ecSmrg if (pPriv->attr->client != client) 96805b261ecSmrg return BadAccess; 96905b261ecSmrg } 97005b261ecSmrg if (!pPriv) 97105b261ecSmrg { 97205b261ecSmrg pPriv = MakeScreenPrivate (pScreen); 97305b261ecSmrg if (!pPriv) 97405b261ecSmrg return FALSE; 97505b261ecSmrg } 97605b261ecSmrg pAttr = New (ScreenSaverAttrRec); 97705b261ecSmrg if (!pAttr) 97805b261ecSmrg { 97905b261ecSmrg ret = BadAlloc; 98005b261ecSmrg goto bail; 98105b261ecSmrg } 98205b261ecSmrg /* over allocate for override redirect */ 9836747b715Smrg values = malloc((len + 1) * sizeof (unsigned long)); 98405b261ecSmrg if (!values) 98505b261ecSmrg { 98605b261ecSmrg ret = BadAlloc; 98705b261ecSmrg goto bail; 98805b261ecSmrg } 98905b261ecSmrg pAttr->screen = pScreen; 99005b261ecSmrg pAttr->client = client; 99105b261ecSmrg pAttr->x = stuff->x; 99205b261ecSmrg pAttr->y = stuff->y; 99305b261ecSmrg pAttr->width = stuff->width; 99405b261ecSmrg pAttr->height = stuff->height; 99505b261ecSmrg pAttr->borderWidth = stuff->borderWidth; 99605b261ecSmrg pAttr->class = stuff->c_class; 99705b261ecSmrg pAttr->depth = depth; 99805b261ecSmrg pAttr->visual = visual; 99905b261ecSmrg pAttr->colormap = None; 100005b261ecSmrg pAttr->pCursor = NullCursor; 100105b261ecSmrg pAttr->pBackgroundPixmap = NullPixmap; 100205b261ecSmrg pAttr->pBorderPixmap = NullPixmap; 100305b261ecSmrg pAttr->values = values; 100405b261ecSmrg /* 100505b261ecSmrg * go through the mask, checking the values, 100605b261ecSmrg * looking up pixmaps and cursors and hold a reference 100705b261ecSmrg * to them. 100805b261ecSmrg */ 100905b261ecSmrg pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; 101005b261ecSmrg pVlist = (unsigned int *) (stuff + 1); 101105b261ecSmrg while (tmask) { 101205b261ecSmrg imask = lowbit (tmask); 101305b261ecSmrg tmask &= ~imask; 101405b261ecSmrg switch (imask) 101505b261ecSmrg { 101605b261ecSmrg case CWBackPixmap: 101705b261ecSmrg pixID = (Pixmap )*pVlist; 101805b261ecSmrg if (pixID == None) 101905b261ecSmrg { 102005b261ecSmrg *values++ = None; 102105b261ecSmrg } 102205b261ecSmrg else if (pixID == ParentRelative) 102305b261ecSmrg { 102405b261ecSmrg if (depth != pParent->drawable.depth) 102505b261ecSmrg { 102605b261ecSmrg ret = BadMatch; 102705b261ecSmrg goto PatchUp; 102805b261ecSmrg } 102905b261ecSmrg *values++ = ParentRelative; 103005b261ecSmrg } 103105b261ecSmrg else 103205b261ecSmrg { 1033b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 10344642e01fSmrg client, DixReadAccess); 10354642e01fSmrg if (ret == Success) 103605b261ecSmrg { 103705b261ecSmrg if ((pPixmap->drawable.depth != depth) || 103805b261ecSmrg (pPixmap->drawable.pScreen != pScreen)) 103905b261ecSmrg { 104005b261ecSmrg ret = BadMatch; 104105b261ecSmrg goto PatchUp; 104205b261ecSmrg } 104305b261ecSmrg pAttr->pBackgroundPixmap = pPixmap; 104405b261ecSmrg pPixmap->refcnt++; 104505b261ecSmrg pAttr->mask &= ~CWBackPixmap; 104605b261ecSmrg } 104705b261ecSmrg else 104805b261ecSmrg { 104905b261ecSmrg client->errorValue = pixID; 105005b261ecSmrg goto PatchUp; 105105b261ecSmrg } 105205b261ecSmrg } 105305b261ecSmrg break; 105405b261ecSmrg case CWBackPixel: 105505b261ecSmrg *values++ = (CARD32) *pVlist; 105605b261ecSmrg break; 105705b261ecSmrg case CWBorderPixmap: 105805b261ecSmrg pixID = (Pixmap ) *pVlist; 105905b261ecSmrg if (pixID == CopyFromParent) 106005b261ecSmrg { 106105b261ecSmrg if (depth != pParent->drawable.depth) 106205b261ecSmrg { 106305b261ecSmrg ret = BadMatch; 106405b261ecSmrg goto PatchUp; 106505b261ecSmrg } 106605b261ecSmrg *values++ = CopyFromParent; 106705b261ecSmrg } 106805b261ecSmrg else 106905b261ecSmrg { 1070b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 10714642e01fSmrg client, DixReadAccess); 10724642e01fSmrg if (ret == Success) 107305b261ecSmrg { 107405b261ecSmrg if ((pPixmap->drawable.depth != depth) || 107505b261ecSmrg (pPixmap->drawable.pScreen != pScreen)) 107605b261ecSmrg { 107705b261ecSmrg ret = BadMatch; 107805b261ecSmrg goto PatchUp; 107905b261ecSmrg } 108005b261ecSmrg pAttr->pBorderPixmap = pPixmap; 108105b261ecSmrg pPixmap->refcnt++; 108205b261ecSmrg pAttr->mask &= ~CWBorderPixmap; 108305b261ecSmrg } 108405b261ecSmrg else 108505b261ecSmrg { 108605b261ecSmrg client->errorValue = pixID; 108705b261ecSmrg goto PatchUp; 108805b261ecSmrg } 108905b261ecSmrg } 109005b261ecSmrg break; 109105b261ecSmrg case CWBorderPixel: 109205b261ecSmrg *values++ = (CARD32) *pVlist; 109305b261ecSmrg break; 109405b261ecSmrg case CWBitGravity: 109505b261ecSmrg val = (CARD8 )*pVlist; 109605b261ecSmrg if (val > StaticGravity) 109705b261ecSmrg { 109805b261ecSmrg ret = BadValue; 109905b261ecSmrg client->errorValue = val; 110005b261ecSmrg goto PatchUp; 110105b261ecSmrg } 110205b261ecSmrg *values++ = val; 110305b261ecSmrg break; 110405b261ecSmrg case CWWinGravity: 110505b261ecSmrg val = (CARD8 )*pVlist; 110605b261ecSmrg if (val > StaticGravity) 110705b261ecSmrg { 110805b261ecSmrg ret = BadValue; 110905b261ecSmrg client->errorValue = val; 111005b261ecSmrg goto PatchUp; 111105b261ecSmrg } 111205b261ecSmrg *values++ = val; 111305b261ecSmrg break; 111405b261ecSmrg case CWBackingStore: 111505b261ecSmrg val = (CARD8 )*pVlist; 111605b261ecSmrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) 111705b261ecSmrg { 111805b261ecSmrg ret = BadValue; 111905b261ecSmrg client->errorValue = val; 112005b261ecSmrg goto PatchUp; 112105b261ecSmrg } 112205b261ecSmrg *values++ = val; 112305b261ecSmrg break; 112405b261ecSmrg case CWBackingPlanes: 112505b261ecSmrg *values++ = (CARD32) *pVlist; 112605b261ecSmrg break; 112705b261ecSmrg case CWBackingPixel: 112805b261ecSmrg *values++ = (CARD32) *pVlist; 112905b261ecSmrg break; 113005b261ecSmrg case CWSaveUnder: 113105b261ecSmrg val = (BOOL) *pVlist; 113205b261ecSmrg if ((val != xTrue) && (val != xFalse)) 113305b261ecSmrg { 113405b261ecSmrg ret = BadValue; 113505b261ecSmrg client->errorValue = val; 113605b261ecSmrg goto PatchUp; 113705b261ecSmrg } 113805b261ecSmrg *values++ = val; 113905b261ecSmrg break; 114005b261ecSmrg case CWEventMask: 114105b261ecSmrg *values++ = (CARD32) *pVlist; 114205b261ecSmrg break; 114305b261ecSmrg case CWDontPropagate: 114405b261ecSmrg *values++ = (CARD32) *pVlist; 114505b261ecSmrg break; 114605b261ecSmrg case CWOverrideRedirect: 114705b261ecSmrg if (!(stuff->mask & CWOverrideRedirect)) 114805b261ecSmrg pVlist--; 114905b261ecSmrg else 115005b261ecSmrg { 115105b261ecSmrg val = (BOOL ) *pVlist; 115205b261ecSmrg if ((val != xTrue) && (val != xFalse)) 115305b261ecSmrg { 115405b261ecSmrg ret = BadValue; 115505b261ecSmrg client->errorValue = val; 115605b261ecSmrg goto PatchUp; 115705b261ecSmrg } 115805b261ecSmrg } 115905b261ecSmrg *values++ = xTrue; 116005b261ecSmrg break; 116105b261ecSmrg case CWColormap: 116205b261ecSmrg cmap = (Colormap) *pVlist; 1163b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, 11644642e01fSmrg client, DixUseAccess); 11654642e01fSmrg if (ret != Success) 116605b261ecSmrg { 116705b261ecSmrg client->errorValue = cmap; 116805b261ecSmrg goto PatchUp; 116905b261ecSmrg } 117005b261ecSmrg if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) 117105b261ecSmrg { 117205b261ecSmrg ret = BadMatch; 117305b261ecSmrg goto PatchUp; 117405b261ecSmrg } 117505b261ecSmrg pAttr->colormap = cmap; 117605b261ecSmrg pAttr->mask &= ~CWColormap; 117705b261ecSmrg break; 117805b261ecSmrg case CWCursor: 117905b261ecSmrg cursorID = (Cursor ) *pVlist; 118005b261ecSmrg if ( cursorID == None) 118105b261ecSmrg { 118205b261ecSmrg *values++ = None; 118305b261ecSmrg } 118405b261ecSmrg else 118505b261ecSmrg { 1186b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pCursor, cursorID, 11874642e01fSmrg RT_CURSOR, client, DixUseAccess); 11884642e01fSmrg if (ret != Success) 118905b261ecSmrg { 119005b261ecSmrg client->errorValue = cursorID; 119105b261ecSmrg goto PatchUp; 119205b261ecSmrg } 119305b261ecSmrg pCursor->refcnt++; 119405b261ecSmrg pAttr->pCursor = pCursor; 119505b261ecSmrg pAttr->mask &= ~CWCursor; 119605b261ecSmrg } 119705b261ecSmrg break; 119805b261ecSmrg default: 119905b261ecSmrg ret = BadValue; 120005b261ecSmrg client->errorValue = stuff->mask; 120105b261ecSmrg goto PatchUp; 120205b261ecSmrg } 120305b261ecSmrg pVlist++; 120405b261ecSmrg } 120505b261ecSmrg if (pPriv->attr) 120605b261ecSmrg FreeScreenAttr (pPriv->attr); 120705b261ecSmrg pPriv->attr = pAttr; 120805b261ecSmrg pAttr->resource = FakeClientID (client->index); 120905b261ecSmrg if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr)) 121005b261ecSmrg return BadAlloc; 121105b261ecSmrg return Success; 121205b261ecSmrgPatchUp: 121305b261ecSmrg FreeAttrs (pAttr); 121405b261ecSmrgbail: 121505b261ecSmrg CheckScreenPrivate (pScreen); 12166747b715Smrg if (pAttr) free(pAttr->values); 12176747b715Smrg free(pAttr); 121805b261ecSmrg return ret; 121905b261ecSmrg} 122005b261ecSmrg 122105b261ecSmrgstatic int 122205b261ecSmrgScreenSaverUnsetAttributes (ClientPtr client) 122305b261ecSmrg{ 122405b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 122505b261ecSmrg DrawablePtr pDraw; 122605b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 122705b261ecSmrg int rc; 122805b261ecSmrg 122905b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq); 123005b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 12314642e01fSmrg DixGetAttrAccess); 123205b261ecSmrg if (rc != Success) 123305b261ecSmrg return rc; 123405b261ecSmrg pPriv = GetScreenPrivate (pDraw->pScreen); 123505b261ecSmrg if (pPriv && pPriv->attr && pPriv->attr->client == client) 123605b261ecSmrg { 123705b261ecSmrg FreeResource (pPriv->attr->resource, AttrType); 123805b261ecSmrg FreeScreenAttr (pPriv->attr); 123905b261ecSmrg pPriv->attr = NULL; 124005b261ecSmrg CheckScreenPrivate (pDraw->pScreen); 124105b261ecSmrg } 124205b261ecSmrg return Success; 124305b261ecSmrg} 124405b261ecSmrg 124505b261ecSmrgstatic int 124605b261ecSmrgProcScreenSaverSetAttributes (ClientPtr client) 124705b261ecSmrg{ 124805b261ecSmrg#ifdef PANORAMIX 124905b261ecSmrg if(!noPanoramiXExtension) { 125005b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 125105b261ecSmrg PanoramiXRes *draw; 125205b261ecSmrg PanoramiXRes *backPix = NULL; 125305b261ecSmrg PanoramiXRes *bordPix = NULL; 125405b261ecSmrg PanoramiXRes *cmap = NULL; 12556747b715Smrg int i, status, len; 125605b261ecSmrg int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; 125705b261ecSmrg XID orig_visual, tmp; 125805b261ecSmrg 125905b261ecSmrg REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 126005b261ecSmrg 12616747b715Smrg status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 12626747b715Smrg XRC_DRAWABLE, client, DixWriteAccess); 12636747b715Smrg if (status != Success) 12646747b715Smrg return (status == BadValue) ? BadDrawable : status; 126505b261ecSmrg 12666747b715Smrg len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 126705b261ecSmrg if (Ones(stuff->mask) != len) 126805b261ecSmrg return BadLength; 126905b261ecSmrg 127005b261ecSmrg if((Mask)stuff->mask & CWBackPixmap) { 127105b261ecSmrg pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); 127205b261ecSmrg tmp = *((CARD32 *) &stuff[1] + pback_offset); 127305b261ecSmrg if ((tmp != None) && (tmp != ParentRelative)) { 12746747b715Smrg status = dixLookupResourceByType((pointer *)&backPix, tmp, 12756747b715Smrg XRT_PIXMAP, client, 12766747b715Smrg DixReadAccess); 12776747b715Smrg if (status != Success) 12786747b715Smrg return status; 127905b261ecSmrg } 128005b261ecSmrg } 128105b261ecSmrg 128205b261ecSmrg if ((Mask)stuff->mask & CWBorderPixmap) { 128305b261ecSmrg pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); 128405b261ecSmrg tmp = *((CARD32 *) &stuff[1] + pbord_offset); 128505b261ecSmrg if (tmp != CopyFromParent) { 12866747b715Smrg status = dixLookupResourceByType((pointer *)&bordPix, tmp, 12876747b715Smrg XRT_PIXMAP, client, 12886747b715Smrg DixReadAccess); 12896747b715Smrg if (status != Success) 12906747b715Smrg return status; 129105b261ecSmrg } 129205b261ecSmrg } 129305b261ecSmrg 129405b261ecSmrg if ((Mask)stuff->mask & CWColormap) { 129505b261ecSmrg cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); 129605b261ecSmrg tmp = *((CARD32 *) &stuff[1] + cmap_offset); 129705b261ecSmrg if ((tmp != CopyFromParent) && (tmp != None)) { 12986747b715Smrg status = dixLookupResourceByType((pointer *)&cmap, tmp, 12996747b715Smrg XRT_COLORMAP, client, 13006747b715Smrg DixReadAccess); 13016747b715Smrg if (status != Success) 13026747b715Smrg return status; 130305b261ecSmrg } 130405b261ecSmrg } 130505b261ecSmrg 130605b261ecSmrg orig_visual = stuff->visualID; 130705b261ecSmrg 130805b261ecSmrg FOR_NSCREENS_BACKWARD(i) { 130905b261ecSmrg stuff->drawable = draw->info[i].id; 131005b261ecSmrg if (backPix) 131105b261ecSmrg *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; 131205b261ecSmrg if (bordPix) 131305b261ecSmrg *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; 131405b261ecSmrg if (cmap) 131505b261ecSmrg *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; 131605b261ecSmrg 131705b261ecSmrg if (orig_visual != CopyFromParent) 13184642e01fSmrg stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); 131905b261ecSmrg 132005b261ecSmrg status = ScreenSaverSetAttributes(client); 132105b261ecSmrg } 132205b261ecSmrg 132305b261ecSmrg return status; 132405b261ecSmrg } 132505b261ecSmrg#endif 132605b261ecSmrg 132705b261ecSmrg return ScreenSaverSetAttributes(client); 132805b261ecSmrg} 132905b261ecSmrg 133005b261ecSmrgstatic int 133105b261ecSmrgProcScreenSaverUnsetAttributes (ClientPtr client) 133205b261ecSmrg{ 133305b261ecSmrg#ifdef PANORAMIX 133405b261ecSmrg if(!noPanoramiXExtension) { 133505b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 133605b261ecSmrg PanoramiXRes *draw; 13376747b715Smrg int rc, i; 133805b261ecSmrg 13396747b715Smrg rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 13406747b715Smrg XRC_DRAWABLE, client, DixWriteAccess); 13416747b715Smrg if (rc != Success) 13426747b715Smrg return (rc == BadValue) ? BadDrawable : rc; 134305b261ecSmrg 134405b261ecSmrg for(i = PanoramiXNumScreens - 1; i > 0; i--) { 134505b261ecSmrg stuff->drawable = draw->info[i].id; 134605b261ecSmrg ScreenSaverUnsetAttributes(client); 134705b261ecSmrg } 134805b261ecSmrg 134905b261ecSmrg stuff->drawable = draw->info[0].id; 135005b261ecSmrg } 135105b261ecSmrg#endif 135205b261ecSmrg 135305b261ecSmrg return ScreenSaverUnsetAttributes(client); 135405b261ecSmrg} 135505b261ecSmrg 135605b261ecSmrgstatic int 135705b261ecSmrgProcScreenSaverSuspend (ClientPtr client) 135805b261ecSmrg{ 135905b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 136005b261ecSmrg 136105b261ecSmrg REQUEST(xScreenSaverSuspendReq); 136205b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 136305b261ecSmrg 136405b261ecSmrg /* Check if this client is suspending the screensaver */ 136505b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 136605b261ecSmrg if (this->pClient == client) 136705b261ecSmrg break; 136805b261ecSmrg 136905b261ecSmrg if (this) 137005b261ecSmrg { 137105b261ecSmrg if (stuff->suspend == TRUE) 137205b261ecSmrg this->count++; 137305b261ecSmrg else if (--this->count == 0) 137405b261ecSmrg FreeResource (this->clientResource, RT_NONE); 137505b261ecSmrg 137605b261ecSmrg return Success; 137705b261ecSmrg } 137805b261ecSmrg 137905b261ecSmrg /* If we get to this point, this client isn't suspending the screensaver */ 138005b261ecSmrg if (stuff->suspend == FALSE) 138105b261ecSmrg return Success; 138205b261ecSmrg 138305b261ecSmrg /* 138405b261ecSmrg * Allocate a suspension record for the client, and stop the screensaver 138505b261ecSmrg * if it isn't already suspended by another client. We attach a resource ID 138605b261ecSmrg * to the record, so the screensaver will be reenabled and the record freed 138705b261ecSmrg * if the client disconnects without reenabling it first. 138805b261ecSmrg */ 13896747b715Smrg this = malloc(sizeof (ScreenSaverSuspensionRec)); 139005b261ecSmrg 139105b261ecSmrg if (!this) 139205b261ecSmrg return BadAlloc; 139305b261ecSmrg 139405b261ecSmrg this->next = NULL; 139505b261ecSmrg this->pClient = client; 139605b261ecSmrg this->count = 1; 139705b261ecSmrg this->clientResource = FakeClientID (client->index); 139805b261ecSmrg 139905b261ecSmrg if (!AddResource (this->clientResource, SuspendType, (pointer) this)) 140005b261ecSmrg { 14016747b715Smrg free(this); 140205b261ecSmrg return BadAlloc; 140305b261ecSmrg } 140405b261ecSmrg 140505b261ecSmrg *prev = this; 140605b261ecSmrg if (!screenSaverSuspended) 140705b261ecSmrg { 140805b261ecSmrg screenSaverSuspended = TRUE; 140905b261ecSmrg FreeScreenSaverTimer(); 141005b261ecSmrg } 141105b261ecSmrg 14126747b715Smrg return Success; 141305b261ecSmrg} 141405b261ecSmrg 141505b261ecSmrgstatic DISPATCH_PROC((*NormalVector[])) = { 141605b261ecSmrg ProcScreenSaverQueryVersion, 141705b261ecSmrg ProcScreenSaverQueryInfo, 141805b261ecSmrg ProcScreenSaverSelectInput, 141905b261ecSmrg ProcScreenSaverSetAttributes, 142005b261ecSmrg ProcScreenSaverUnsetAttributes, 142105b261ecSmrg ProcScreenSaverSuspend, 142205b261ecSmrg}; 142305b261ecSmrg 142405b261ecSmrg#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) 142505b261ecSmrg 142605b261ecSmrgstatic int 14276747b715SmrgProcScreenSaverDispatch (ClientPtr client) 142805b261ecSmrg{ 142905b261ecSmrg REQUEST(xReq); 143005b261ecSmrg 143105b261ecSmrg if (stuff->data < NUM_REQUESTS) 143205b261ecSmrg return (*NormalVector[stuff->data])(client); 143305b261ecSmrg return BadRequest; 143405b261ecSmrg} 143505b261ecSmrg 143605b261ecSmrgstatic int 14376747b715SmrgSProcScreenSaverQueryVersion (ClientPtr client) 143805b261ecSmrg{ 143905b261ecSmrg REQUEST(xScreenSaverQueryVersionReq); 144005b261ecSmrg int n; 144105b261ecSmrg 144205b261ecSmrg swaps (&stuff->length, n); 144305b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 144405b261ecSmrg return ProcScreenSaverQueryVersion (client); 144505b261ecSmrg} 144605b261ecSmrg 144705b261ecSmrgstatic int 14486747b715SmrgSProcScreenSaverQueryInfo (ClientPtr client) 144905b261ecSmrg{ 145005b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 145105b261ecSmrg int n; 145205b261ecSmrg 145305b261ecSmrg swaps (&stuff->length, n); 145405b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 145505b261ecSmrg swapl (&stuff->drawable, n); 145605b261ecSmrg return ProcScreenSaverQueryInfo (client); 145705b261ecSmrg} 145805b261ecSmrg 145905b261ecSmrgstatic int 14606747b715SmrgSProcScreenSaverSelectInput (ClientPtr client) 146105b261ecSmrg{ 146205b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 146305b261ecSmrg int n; 146405b261ecSmrg 146505b261ecSmrg swaps (&stuff->length, n); 146605b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 146705b261ecSmrg swapl (&stuff->drawable, n); 146805b261ecSmrg swapl (&stuff->eventMask, n); 146905b261ecSmrg return ProcScreenSaverSelectInput (client); 147005b261ecSmrg} 147105b261ecSmrg 147205b261ecSmrgstatic int 14736747b715SmrgSProcScreenSaverSetAttributes (ClientPtr client) 147405b261ecSmrg{ 147505b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 147605b261ecSmrg int n; 147705b261ecSmrg 147805b261ecSmrg swaps (&stuff->length, n); 147905b261ecSmrg REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 148005b261ecSmrg swapl (&stuff->drawable, n); 148105b261ecSmrg swaps (&stuff->x, n); 148205b261ecSmrg swaps (&stuff->y, n); 148305b261ecSmrg swaps (&stuff->width, n); 148405b261ecSmrg swaps (&stuff->height, n); 148505b261ecSmrg swaps (&stuff->borderWidth, n); 148605b261ecSmrg swapl (&stuff->visualID, n); 148705b261ecSmrg swapl (&stuff->mask, n); 148805b261ecSmrg SwapRestL(stuff); 148905b261ecSmrg return ProcScreenSaverSetAttributes (client); 149005b261ecSmrg} 149105b261ecSmrg 149205b261ecSmrgstatic int 14936747b715SmrgSProcScreenSaverUnsetAttributes (ClientPtr client) 149405b261ecSmrg{ 149505b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 149605b261ecSmrg int n; 149705b261ecSmrg 149805b261ecSmrg swaps (&stuff->length, n); 149905b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 150005b261ecSmrg swapl (&stuff->drawable, n); 150105b261ecSmrg return ProcScreenSaverUnsetAttributes (client); 150205b261ecSmrg} 150305b261ecSmrg 150405b261ecSmrgstatic int 150505b261ecSmrgSProcScreenSaverSuspend (ClientPtr client) 150605b261ecSmrg{ 150705b261ecSmrg int n; 150805b261ecSmrg REQUEST(xScreenSaverSuspendReq); 150905b261ecSmrg 151005b261ecSmrg swaps(&stuff->length, n); 151105b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 151205b261ecSmrg swapl(&stuff->suspend, n); 151305b261ecSmrg return ProcScreenSaverSuspend (client); 151405b261ecSmrg} 151505b261ecSmrg 151605b261ecSmrgstatic DISPATCH_PROC((*SwappedVector[])) = { 151705b261ecSmrg SProcScreenSaverQueryVersion, 151805b261ecSmrg SProcScreenSaverQueryInfo, 151905b261ecSmrg SProcScreenSaverSelectInput, 152005b261ecSmrg SProcScreenSaverSetAttributes, 152105b261ecSmrg SProcScreenSaverUnsetAttributes, 152205b261ecSmrg SProcScreenSaverSuspend, 152305b261ecSmrg}; 152405b261ecSmrg 152505b261ecSmrgstatic int 15266747b715SmrgSProcScreenSaverDispatch (ClientPtr client) 152705b261ecSmrg{ 152805b261ecSmrg REQUEST(xReq); 152905b261ecSmrg 153005b261ecSmrg if (stuff->data < NUM_REQUESTS) 153105b261ecSmrg return (*SwappedVector[stuff->data])(client); 153205b261ecSmrg return BadRequest; 153305b261ecSmrg} 1534