saver.c revision 9ace9065
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 6505b261ecSmrg 6605b261ecSmrgstatic Bool ScreenSaverHandle ( 6705b261ecSmrg ScreenPtr /* pScreen */, 6805b261ecSmrg int /* xstate */, 6905b261ecSmrg Bool /* force */ 7005b261ecSmrg ); 7105b261ecSmrg 7205b261ecSmrgstatic Bool 7305b261ecSmrgCreateSaverWindow ( 7405b261ecSmrg ScreenPtr /* pScreen */ 7505b261ecSmrg ); 7605b261ecSmrg 7705b261ecSmrgstatic Bool 7805b261ecSmrgDestroySaverWindow ( 7905b261ecSmrg ScreenPtr /* pScreen */ 8005b261ecSmrg ); 8105b261ecSmrg 8205b261ecSmrgstatic void 8305b261ecSmrgUninstallSaverColormap ( 8405b261ecSmrg ScreenPtr /* pScreen */ 8505b261ecSmrg ); 8605b261ecSmrg 8705b261ecSmrgstatic void 8805b261ecSmrgCheckScreenPrivate ( 8905b261ecSmrg ScreenPtr /* pScreen */ 9005b261ecSmrg ); 9105b261ecSmrg 9205b261ecSmrgstatic void SScreenSaverNotifyEvent ( 9305b261ecSmrg xScreenSaverNotifyEvent * /* from */, 9405b261ecSmrg xScreenSaverNotifyEvent * /* to */ 9505b261ecSmrg ); 9605b261ecSmrg 9705b261ecSmrgstatic RESTYPE SuspendType; /* resource type for suspension records */ 9805b261ecSmrg 9905b261ecSmrgtypedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; 10005b261ecSmrg 10105b261ecSmrg/* List of clients that are suspending the screensaver. */ 10205b261ecSmrgstatic ScreenSaverSuspensionPtr suspendingClients = NULL; 10305b261ecSmrg 10405b261ecSmrg/* 10505b261ecSmrg * clientResource is a resource ID that's added when the record is 10605b261ecSmrg * allocated, so the record is freed and the screensaver resumed when 10705b261ecSmrg * the client disconnects. count is the number of times the client has 10805b261ecSmrg * requested the screensaver be suspended. 10905b261ecSmrg */ 11005b261ecSmrgtypedef struct _ScreenSaverSuspension 11105b261ecSmrg{ 11205b261ecSmrg ScreenSaverSuspensionPtr next; 11305b261ecSmrg ClientPtr pClient; 11405b261ecSmrg XID clientResource; 11505b261ecSmrg int count; 11605b261ecSmrg} ScreenSaverSuspensionRec; 11705b261ecSmrg 11805b261ecSmrgstatic int ScreenSaverFreeSuspend( 11905b261ecSmrg pointer /*value */, 12005b261ecSmrg XID /* id */ 12105b261ecSmrg); 12205b261ecSmrg 12305b261ecSmrg/* 12405b261ecSmrg * each screen has a list of clients requesting 12505b261ecSmrg * ScreenSaverNotify events. Each client has a resource 12605b261ecSmrg * for each screen it selects ScreenSaverNotify input for, 12705b261ecSmrg * this resource is used to delete the ScreenSaverNotifyRec 12805b261ecSmrg * entry from the per-screen queue. 12905b261ecSmrg */ 13005b261ecSmrg 1316747b715Smrgstatic RESTYPE SaverEventType; /* resource type for event masks */ 13205b261ecSmrg 13305b261ecSmrgtypedef struct _ScreenSaverEvent *ScreenSaverEventPtr; 13405b261ecSmrg 13505b261ecSmrgtypedef struct _ScreenSaverEvent { 13605b261ecSmrg ScreenSaverEventPtr next; 13705b261ecSmrg ClientPtr client; 13805b261ecSmrg ScreenPtr screen; 13905b261ecSmrg XID resource; 14005b261ecSmrg CARD32 mask; 14105b261ecSmrg} ScreenSaverEventRec; 14205b261ecSmrg 14305b261ecSmrgstatic int ScreenSaverFreeEvents( 14405b261ecSmrg pointer /* value */, 14505b261ecSmrg XID /* id */ 14605b261ecSmrg); 14705b261ecSmrg 14805b261ecSmrgstatic Bool setEventMask ( 14905b261ecSmrg ScreenPtr /* pScreen */, 15005b261ecSmrg ClientPtr /* client */, 15105b261ecSmrg unsigned long /* mask */ 15205b261ecSmrg); 15305b261ecSmrg 15405b261ecSmrgstatic unsigned long getEventMask ( 15505b261ecSmrg ScreenPtr /* pScreen */, 15605b261ecSmrg ClientPtr /* client */ 15705b261ecSmrg); 15805b261ecSmrg 15905b261ecSmrg/* 16005b261ecSmrg * when a client sets the screen saver attributes, a resource is 16105b261ecSmrg * kept to be freed when the client exits 16205b261ecSmrg */ 16305b261ecSmrg 16405b261ecSmrgstatic RESTYPE AttrType; /* resource type for attributes */ 16505b261ecSmrg 16605b261ecSmrgtypedef struct _ScreenSaverAttr { 16705b261ecSmrg ScreenPtr screen; 16805b261ecSmrg ClientPtr client; 16905b261ecSmrg XID resource; 17005b261ecSmrg short x, y; 17105b261ecSmrg unsigned short width, height, borderWidth; 17205b261ecSmrg unsigned char class; 17305b261ecSmrg unsigned char depth; 17405b261ecSmrg VisualID visual; 17505b261ecSmrg CursorPtr pCursor; 17605b261ecSmrg PixmapPtr pBackgroundPixmap; 17705b261ecSmrg PixmapPtr pBorderPixmap; 17805b261ecSmrg Colormap colormap; 17905b261ecSmrg unsigned long mask; /* no pixmaps or cursors */ 18005b261ecSmrg unsigned long *values; 18105b261ecSmrg} ScreenSaverAttrRec, *ScreenSaverAttrPtr; 18205b261ecSmrg 18305b261ecSmrgstatic int ScreenSaverFreeAttr ( 18405b261ecSmrg pointer /* value */, 18505b261ecSmrg XID /* id */ 18605b261ecSmrg); 18705b261ecSmrg 18805b261ecSmrgstatic void FreeAttrs ( 18905b261ecSmrg ScreenSaverAttrPtr /* pAttr */ 19005b261ecSmrg); 19105b261ecSmrg 19205b261ecSmrgstatic void FreeScreenAttr ( 19305b261ecSmrg ScreenSaverAttrPtr /* pAttr */ 19405b261ecSmrg); 19505b261ecSmrg 19605b261ecSmrgstatic void 19705b261ecSmrgSendScreenSaverNotify ( 19805b261ecSmrg ScreenPtr /* pScreen */, 19905b261ecSmrg int /* state */, 20005b261ecSmrg Bool /* forced */ 20105b261ecSmrg); 20205b261ecSmrg 20305b261ecSmrgtypedef struct _ScreenSaverScreenPrivate { 20405b261ecSmrg ScreenSaverEventPtr events; 20505b261ecSmrg ScreenSaverAttrPtr attr; 20605b261ecSmrg Bool hasWindow; 20705b261ecSmrg Colormap installedMap; 20805b261ecSmrg} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr; 20905b261ecSmrg 21005b261ecSmrgstatic ScreenSaverScreenPrivatePtr 21105b261ecSmrgMakeScreenPrivate ( 21205b261ecSmrg ScreenPtr /* pScreen */ 21305b261ecSmrg ); 21405b261ecSmrg 2156747b715Smrgstatic DevPrivateKeyRec ScreenPrivateKeyRec; 2166747b715Smrg#define ScreenPrivateKey (&ScreenPrivateKeyRec) 21705b261ecSmrg 2184642e01fSmrg#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \ 2194642e01fSmrg dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey)) 2204642e01fSmrg#define SetScreenPrivate(s,v) \ 2214642e01fSmrg dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v); 22205b261ecSmrg#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL) 22305b261ecSmrg 2246747b715Smrg#define New(t) (malloc(sizeof (t))) 22505b261ecSmrg 22605b261ecSmrgstatic void 2276747b715SmrgCheckScreenPrivate (ScreenPtr pScreen) 22805b261ecSmrg{ 22905b261ecSmrg SetupScreen (pScreen); 23005b261ecSmrg 23105b261ecSmrg if (!pPriv) 23205b261ecSmrg return; 23305b261ecSmrg if (!pPriv->attr && !pPriv->events && 23405b261ecSmrg !pPriv->hasWindow && pPriv->installedMap == None) 23505b261ecSmrg { 2366747b715Smrg free(pPriv); 23705b261ecSmrg SetScreenPrivate (pScreen, NULL); 2386747b715Smrg pScreen->screensaver.ExternalScreenSaver = NULL; 23905b261ecSmrg } 24005b261ecSmrg} 24105b261ecSmrg 24205b261ecSmrgstatic ScreenSaverScreenPrivatePtr 2436747b715SmrgMakeScreenPrivate (ScreenPtr pScreen) 24405b261ecSmrg{ 24505b261ecSmrg SetupScreen (pScreen); 24605b261ecSmrg 24705b261ecSmrg if (pPriv) 24805b261ecSmrg return pPriv; 24905b261ecSmrg pPriv = New (ScreenSaverScreenPrivateRec); 25005b261ecSmrg if (!pPriv) 25105b261ecSmrg return 0; 25205b261ecSmrg pPriv->events = 0; 25305b261ecSmrg pPriv->attr = 0; 25405b261ecSmrg pPriv->hasWindow = FALSE; 25505b261ecSmrg pPriv->installedMap = None; 25605b261ecSmrg SetScreenPrivate (pScreen, pPriv); 2576747b715Smrg pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle; 25805b261ecSmrg return pPriv; 25905b261ecSmrg} 26005b261ecSmrg 26105b261ecSmrgstatic unsigned long 2626747b715SmrggetEventMask (ScreenPtr pScreen, ClientPtr client) 26305b261ecSmrg{ 26405b261ecSmrg SetupScreen(pScreen); 26505b261ecSmrg ScreenSaverEventPtr pEv; 26605b261ecSmrg 26705b261ecSmrg if (!pPriv) 26805b261ecSmrg return 0; 26905b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 27005b261ecSmrg if (pEv->client == client) 27105b261ecSmrg return pEv->mask; 27205b261ecSmrg return 0; 27305b261ecSmrg} 27405b261ecSmrg 27505b261ecSmrgstatic Bool 2766747b715SmrgsetEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask) 27705b261ecSmrg{ 27805b261ecSmrg SetupScreen(pScreen); 27905b261ecSmrg ScreenSaverEventPtr pEv, *pPrev; 28005b261ecSmrg 28105b261ecSmrg if (getEventMask (pScreen, client) == mask) 28205b261ecSmrg return TRUE; 28305b261ecSmrg if (!pPriv) 28405b261ecSmrg { 28505b261ecSmrg pPriv = MakeScreenPrivate (pScreen); 28605b261ecSmrg if (!pPriv) 28705b261ecSmrg return FALSE; 28805b261ecSmrg } 28905b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 29005b261ecSmrg if (pEv->client == client) 29105b261ecSmrg break; 29205b261ecSmrg if (mask == 0) 29305b261ecSmrg { 2946747b715Smrg FreeResource (pEv->resource, SaverEventType); 29505b261ecSmrg *pPrev = pEv->next; 2966747b715Smrg free(pEv); 29705b261ecSmrg CheckScreenPrivate (pScreen); 29805b261ecSmrg } 29905b261ecSmrg else 30005b261ecSmrg { 30105b261ecSmrg if (!pEv) 30205b261ecSmrg { 30305b261ecSmrg pEv = New (ScreenSaverEventRec); 30405b261ecSmrg if (!pEv) 30505b261ecSmrg { 30605b261ecSmrg CheckScreenPrivate (pScreen); 30705b261ecSmrg return FALSE; 30805b261ecSmrg } 30905b261ecSmrg *pPrev = pEv; 31005b261ecSmrg pEv->next = NULL; 31105b261ecSmrg pEv->client = client; 31205b261ecSmrg pEv->screen = pScreen; 31305b261ecSmrg pEv->resource = FakeClientID (client->index); 3146747b715Smrg if (!AddResource (pEv->resource, SaverEventType, (pointer) pEv)) 31505b261ecSmrg return FALSE; 31605b261ecSmrg } 31705b261ecSmrg pEv->mask = mask; 31805b261ecSmrg } 31905b261ecSmrg return TRUE; 32005b261ecSmrg} 32105b261ecSmrg 32205b261ecSmrgstatic void 3236747b715SmrgFreeAttrs (ScreenSaverAttrPtr pAttr) 32405b261ecSmrg{ 32505b261ecSmrg PixmapPtr pPixmap; 32605b261ecSmrg CursorPtr pCursor; 32705b261ecSmrg 32805b261ecSmrg if ((pPixmap = pAttr->pBackgroundPixmap) != 0) 32905b261ecSmrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 33005b261ecSmrg if ((pPixmap = pAttr->pBorderPixmap) != 0) 33105b261ecSmrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 33205b261ecSmrg if ((pCursor = pAttr->pCursor) != 0) 33305b261ecSmrg FreeCursor (pCursor, (Cursor) 0); 33405b261ecSmrg} 33505b261ecSmrg 33605b261ecSmrgstatic void 3376747b715SmrgFreeScreenAttr (ScreenSaverAttrPtr pAttr) 33805b261ecSmrg{ 33905b261ecSmrg FreeAttrs (pAttr); 3406747b715Smrg free(pAttr->values); 3416747b715Smrg free(pAttr); 34205b261ecSmrg} 34305b261ecSmrg 34405b261ecSmrgstatic int 3456747b715SmrgScreenSaverFreeEvents (pointer value, XID id) 34605b261ecSmrg{ 34705b261ecSmrg ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value; 34805b261ecSmrg ScreenPtr pScreen = pOld->screen; 34905b261ecSmrg SetupScreen (pScreen); 35005b261ecSmrg ScreenSaverEventPtr pEv, *pPrev; 35105b261ecSmrg 35205b261ecSmrg if (!pPriv) 35305b261ecSmrg return TRUE; 35405b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 35505b261ecSmrg if (pEv == pOld) 35605b261ecSmrg break; 35705b261ecSmrg if (!pEv) 35805b261ecSmrg return TRUE; 35905b261ecSmrg *pPrev = pEv->next; 3606747b715Smrg free(pEv); 36105b261ecSmrg CheckScreenPrivate (pScreen); 36205b261ecSmrg return TRUE; 36305b261ecSmrg} 36405b261ecSmrg 36505b261ecSmrgstatic int 3666747b715SmrgScreenSaverFreeAttr (pointer value, XID id) 36705b261ecSmrg{ 36805b261ecSmrg ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value; 36905b261ecSmrg ScreenPtr pScreen = pOldAttr->screen; 37005b261ecSmrg SetupScreen (pScreen); 37105b261ecSmrg 37205b261ecSmrg if (!pPriv) 37305b261ecSmrg return TRUE; 37405b261ecSmrg if (pPriv->attr != pOldAttr) 37505b261ecSmrg return TRUE; 37605b261ecSmrg FreeScreenAttr (pOldAttr); 37705b261ecSmrg pPriv->attr = NULL; 37805b261ecSmrg if (pPriv->hasWindow) 37905b261ecSmrg { 3804642e01fSmrg dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); 3814642e01fSmrg dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive); 38205b261ecSmrg } 38305b261ecSmrg CheckScreenPrivate (pScreen); 38405b261ecSmrg return TRUE; 38505b261ecSmrg} 38605b261ecSmrg 38705b261ecSmrgstatic int 38805b261ecSmrgScreenSaverFreeSuspend (pointer value, XID id) 38905b261ecSmrg{ 39005b261ecSmrg ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; 39105b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 39205b261ecSmrg 39305b261ecSmrg /* Unlink and free the suspension record for the client */ 39405b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 39505b261ecSmrg { 39605b261ecSmrg if (this == data) 39705b261ecSmrg { 39805b261ecSmrg *prev = this->next; 3996747b715Smrg free(this); 40005b261ecSmrg break; 40105b261ecSmrg } 40205b261ecSmrg } 40305b261ecSmrg 40405b261ecSmrg /* Reenable the screensaver if this was the last client suspending it. */ 40505b261ecSmrg if (screenSaverSuspended && suspendingClients == NULL) 40605b261ecSmrg { 40705b261ecSmrg screenSaverSuspended = FALSE; 40805b261ecSmrg 40905b261ecSmrg /* The screensaver could be active, since suspending it (by design) 41005b261ecSmrg doesn't prevent it from being forceably activated */ 41105b261ecSmrg#ifdef DPMSExtension 41205b261ecSmrg if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) 41305b261ecSmrg#else 41405b261ecSmrg if (screenIsSaved != SCREEN_SAVER_ON) 41505b261ecSmrg#endif 41605b261ecSmrg { 41705b261ecSmrg UpdateCurrentTimeIf(); 41805b261ecSmrg lastDeviceEventTime = currentTime; 41905b261ecSmrg SetScreenSaverTimer(); 42005b261ecSmrg } 42105b261ecSmrg } 42205b261ecSmrg 42305b261ecSmrg return Success; 42405b261ecSmrg} 42505b261ecSmrg 42605b261ecSmrgstatic void 4276747b715SmrgSendScreenSaverNotify (ScreenPtr pScreen, int state, Bool forced) 42805b261ecSmrg{ 42905b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 43005b261ecSmrg ScreenSaverEventPtr pEv; 43105b261ecSmrg unsigned long mask; 43205b261ecSmrg xScreenSaverNotifyEvent ev; 43305b261ecSmrg int kind; 43405b261ecSmrg 43505b261ecSmrg UpdateCurrentTimeIf (); 43605b261ecSmrg mask = ScreenSaverNotifyMask; 43705b261ecSmrg if (state == ScreenSaverCycle) 43805b261ecSmrg mask = ScreenSaverCycleMask; 43905b261ecSmrg pScreen = screenInfo.screens[pScreen->myNum]; 44005b261ecSmrg pPriv = GetScreenPrivate(pScreen); 44105b261ecSmrg if (!pPriv) 44205b261ecSmrg return; 44305b261ecSmrg if (pPriv->attr) 44405b261ecSmrg kind = ScreenSaverExternal; 44505b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 44605b261ecSmrg kind = ScreenSaverBlanked; 44705b261ecSmrg else 44805b261ecSmrg kind = ScreenSaverInternal; 44905b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 45005b261ecSmrg { 45105b261ecSmrg if (!(pEv->mask & mask)) 45205b261ecSmrg continue; 45305b261ecSmrg ev.type = ScreenSaverNotify + ScreenSaverEventBase; 45405b261ecSmrg ev.state = state; 45505b261ecSmrg ev.timestamp = currentTime.milliseconds; 4566747b715Smrg ev.root = pScreen->root->drawable.id; 4576747b715Smrg ev.window = pScreen->screensaver.wid; 45805b261ecSmrg ev.kind = kind; 45905b261ecSmrg ev.forced = forced; 4606747b715Smrg WriteEventsToClient (pEv->client, 1, (xEvent *) &ev); 46105b261ecSmrg } 46205b261ecSmrg} 46305b261ecSmrg 46405b261ecSmrgstatic void 4656747b715SmrgSScreenSaverNotifyEvent (xScreenSaverNotifyEvent *from, 4666747b715Smrg xScreenSaverNotifyEvent *to) 46705b261ecSmrg{ 46805b261ecSmrg to->type = from->type; 46905b261ecSmrg to->state = from->state; 47005b261ecSmrg cpswaps (from->sequenceNumber, to->sequenceNumber); 47105b261ecSmrg cpswapl (from->timestamp, to->timestamp); 47205b261ecSmrg cpswapl (from->root, to->root); 47305b261ecSmrg cpswapl (from->window, to->window); 47405b261ecSmrg to->kind = from->kind; 47505b261ecSmrg to->forced = from->forced; 47605b261ecSmrg} 47705b261ecSmrg 47805b261ecSmrgstatic void 4796747b715SmrgUninstallSaverColormap (ScreenPtr pScreen) 48005b261ecSmrg{ 48105b261ecSmrg SetupScreen(pScreen); 48205b261ecSmrg ColormapPtr pCmap; 4836747b715Smrg int rc; 48405b261ecSmrg 48505b261ecSmrg if (pPriv && pPriv->installedMap != None) 48605b261ecSmrg { 4876747b715Smrg rc = dixLookupResourceByType((pointer *)&pCmap, pPriv->installedMap, 4886747b715Smrg RT_COLORMAP, serverClient, 4896747b715Smrg DixUninstallAccess); 4906747b715Smrg if (rc == Success) 49105b261ecSmrg (*pCmap->pScreen->UninstallColormap) (pCmap); 49205b261ecSmrg pPriv->installedMap = None; 49305b261ecSmrg CheckScreenPrivate (pScreen); 49405b261ecSmrg } 49505b261ecSmrg} 49605b261ecSmrg 49705b261ecSmrgstatic Bool 4986747b715SmrgCreateSaverWindow (ScreenPtr pScreen) 49905b261ecSmrg{ 50005b261ecSmrg SetupScreen (pScreen); 50105b261ecSmrg ScreenSaverStuffPtr pSaver; 50205b261ecSmrg ScreenSaverAttrPtr pAttr; 50305b261ecSmrg WindowPtr pWin; 50405b261ecSmrg int result; 50505b261ecSmrg unsigned long mask; 50605b261ecSmrg Colormap *installedMaps; 50705b261ecSmrg int numInstalled; 50805b261ecSmrg int i; 50905b261ecSmrg Colormap wantMap; 51005b261ecSmrg ColormapPtr pCmap; 51105b261ecSmrg 5126747b715Smrg pSaver = &pScreen->screensaver; 51305b261ecSmrg if (pSaver->pWindow) 51405b261ecSmrg { 51505b261ecSmrg pSaver->pWindow = NullWindow; 51605b261ecSmrg FreeResource (pSaver->wid, RT_NONE); 51705b261ecSmrg if (pPriv) 51805b261ecSmrg { 51905b261ecSmrg UninstallSaverColormap (pScreen); 52005b261ecSmrg pPriv->hasWindow = FALSE; 52105b261ecSmrg CheckScreenPrivate (pScreen); 52205b261ecSmrg } 52305b261ecSmrg } 52405b261ecSmrg 52505b261ecSmrg if (!pPriv || !(pAttr = pPriv->attr)) 52605b261ecSmrg return FALSE; 52705b261ecSmrg 52805b261ecSmrg pPriv->installedMap = None; 52905b261ecSmrg 53005b261ecSmrg if (GrabInProgress && GrabInProgress != pAttr->client->index) 53105b261ecSmrg return FALSE; 53205b261ecSmrg 5336747b715Smrg pWin = CreateWindow (pSaver->wid, pScreen->root, 53405b261ecSmrg pAttr->x, pAttr->y, pAttr->width, pAttr->height, 53505b261ecSmrg pAttr->borderWidth, pAttr->class, 53605b261ecSmrg pAttr->mask, (XID *)pAttr->values, 53705b261ecSmrg pAttr->depth, serverClient, pAttr->visual, 53805b261ecSmrg &result); 53905b261ecSmrg if (!pWin) 54005b261ecSmrg return FALSE; 54105b261ecSmrg 54205b261ecSmrg if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin)) 54305b261ecSmrg return FALSE; 54405b261ecSmrg 54505b261ecSmrg mask = 0; 54605b261ecSmrg if (pAttr->pBackgroundPixmap) 54705b261ecSmrg { 54805b261ecSmrg pWin->backgroundState = BackgroundPixmap; 54905b261ecSmrg pWin->background.pixmap = pAttr->pBackgroundPixmap; 55005b261ecSmrg pAttr->pBackgroundPixmap->refcnt++; 55105b261ecSmrg mask |= CWBackPixmap; 55205b261ecSmrg } 55305b261ecSmrg if (pAttr->pBorderPixmap) 55405b261ecSmrg { 55505b261ecSmrg pWin->borderIsPixel = FALSE; 55605b261ecSmrg pWin->border.pixmap = pAttr->pBorderPixmap; 55705b261ecSmrg pAttr->pBorderPixmap->refcnt++; 55805b261ecSmrg mask |= CWBorderPixmap; 55905b261ecSmrg } 56005b261ecSmrg if (pAttr->pCursor) 56105b261ecSmrg { 56205b261ecSmrg if (!pWin->optional) 56305b261ecSmrg if (!MakeWindowOptional (pWin)) 56405b261ecSmrg { 56505b261ecSmrg FreeResource (pWin->drawable.id, RT_NONE); 56605b261ecSmrg return FALSE; 56705b261ecSmrg } 5686747b715Smrg pAttr->pCursor->refcnt++; 56905b261ecSmrg if (pWin->optional->cursor) 57005b261ecSmrg FreeCursor (pWin->optional->cursor, (Cursor)0); 57105b261ecSmrg pWin->optional->cursor = pAttr->pCursor; 57205b261ecSmrg pWin->cursorIsNone = FALSE; 57305b261ecSmrg CheckWindowOptionalNeed (pWin); 57405b261ecSmrg mask |= CWCursor; 57505b261ecSmrg } 57605b261ecSmrg if (mask) 57705b261ecSmrg (*pScreen->ChangeWindowAttributes) (pWin, mask); 57805b261ecSmrg 57905b261ecSmrg if (pAttr->colormap != None) 58005b261ecSmrg (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap, 58105b261ecSmrg serverClient); 58205b261ecSmrg 58305b261ecSmrg MapWindow (pWin, serverClient); 58405b261ecSmrg 58505b261ecSmrg pPriv->hasWindow = TRUE; 58605b261ecSmrg pSaver->pWindow = pWin; 58705b261ecSmrg 58805b261ecSmrg /* check and install our own colormap if it isn't installed now */ 58905b261ecSmrg wantMap = wColormap (pWin); 59005b261ecSmrg if (wantMap == None) 59105b261ecSmrg return TRUE; 5926747b715Smrg installedMaps = malloc(pScreen->maxInstalledCmaps * sizeof (Colormap)); 59305b261ecSmrg numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps) 59405b261ecSmrg (pScreen, installedMaps); 59505b261ecSmrg for (i = 0; i < numInstalled; i++) 59605b261ecSmrg if (installedMaps[i] == wantMap) 59705b261ecSmrg break; 59805b261ecSmrg 5996747b715Smrg free((char *) installedMaps); 60005b261ecSmrg 60105b261ecSmrg if (i < numInstalled) 60205b261ecSmrg return TRUE; 60305b261ecSmrg 6046747b715Smrg result = dixLookupResourceByType((pointer *)&pCmap, wantMap, RT_COLORMAP, 6056747b715Smrg serverClient, DixInstallAccess); 6066747b715Smrg if (result != Success) 60705b261ecSmrg return TRUE; 60805b261ecSmrg 60905b261ecSmrg pPriv->installedMap = wantMap; 61005b261ecSmrg 61105b261ecSmrg (*pCmap->pScreen->InstallColormap) (pCmap); 61205b261ecSmrg 61305b261ecSmrg return TRUE; 61405b261ecSmrg} 61505b261ecSmrg 61605b261ecSmrgstatic Bool 6176747b715SmrgDestroySaverWindow (ScreenPtr pScreen) 61805b261ecSmrg{ 61905b261ecSmrg SetupScreen(pScreen); 62005b261ecSmrg ScreenSaverStuffPtr pSaver; 62105b261ecSmrg 62205b261ecSmrg if (!pPriv || !pPriv->hasWindow) 62305b261ecSmrg return FALSE; 62405b261ecSmrg 6256747b715Smrg pSaver = &pScreen->screensaver; 62605b261ecSmrg if (pSaver->pWindow) 62705b261ecSmrg { 62805b261ecSmrg pSaver->pWindow = NullWindow; 62905b261ecSmrg FreeResource (pSaver->wid, RT_NONE); 63005b261ecSmrg } 63105b261ecSmrg pPriv->hasWindow = FALSE; 63205b261ecSmrg CheckScreenPrivate (pScreen); 63305b261ecSmrg UninstallSaverColormap (pScreen); 63405b261ecSmrg return TRUE; 63505b261ecSmrg} 63605b261ecSmrg 63705b261ecSmrgstatic Bool 6386747b715SmrgScreenSaverHandle (ScreenPtr pScreen, int xstate, Bool force) 63905b261ecSmrg{ 64005b261ecSmrg int state = 0; 64105b261ecSmrg Bool ret = FALSE; 64205b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 64305b261ecSmrg 64405b261ecSmrg switch (xstate) 64505b261ecSmrg { 64605b261ecSmrg case SCREEN_SAVER_ON: 64705b261ecSmrg state = ScreenSaverOn; 64805b261ecSmrg ret = CreateSaverWindow (pScreen); 64905b261ecSmrg break; 65005b261ecSmrg case SCREEN_SAVER_OFF: 65105b261ecSmrg state = ScreenSaverOff; 65205b261ecSmrg ret = DestroySaverWindow (pScreen); 65305b261ecSmrg break; 65405b261ecSmrg case SCREEN_SAVER_CYCLE: 65505b261ecSmrg state = ScreenSaverCycle; 65605b261ecSmrg pPriv = GetScreenPrivate (pScreen); 65705b261ecSmrg if (pPriv && pPriv->hasWindow) 65805b261ecSmrg ret = TRUE; 65905b261ecSmrg 66005b261ecSmrg } 66105b261ecSmrg#ifdef PANORAMIX 66205b261ecSmrg if(noPanoramiXExtension || !pScreen->myNum) 66305b261ecSmrg#endif 66405b261ecSmrg SendScreenSaverNotify (pScreen, state, force); 66505b261ecSmrg return ret; 66605b261ecSmrg} 66705b261ecSmrg 66805b261ecSmrgstatic int 6696747b715SmrgProcScreenSaverQueryVersion (ClientPtr client) 67005b261ecSmrg{ 67105b261ecSmrg xScreenSaverQueryVersionReply rep; 6724642e01fSmrg int n; 67305b261ecSmrg 67405b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq); 67505b261ecSmrg rep.type = X_Reply; 67605b261ecSmrg rep.length = 0; 67705b261ecSmrg rep.sequenceNumber = client->sequence; 6786747b715Smrg rep.majorVersion = SERVER_SAVER_MAJOR_VERSION; 6796747b715Smrg rep.minorVersion = SERVER_SAVER_MINOR_VERSION; 68005b261ecSmrg if (client->swapped) { 68105b261ecSmrg swaps(&rep.sequenceNumber, n); 68205b261ecSmrg swapl(&rep.length, n); 68305b261ecSmrg } 68405b261ecSmrg WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep); 6856747b715Smrg return Success; 68605b261ecSmrg} 68705b261ecSmrg 68805b261ecSmrgstatic int 6896747b715SmrgProcScreenSaverQueryInfo (ClientPtr client) 69005b261ecSmrg{ 69105b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 69205b261ecSmrg xScreenSaverQueryInfoReply rep; 6934642e01fSmrg int n, rc; 69405b261ecSmrg ScreenSaverStuffPtr pSaver; 69505b261ecSmrg DrawablePtr pDraw; 69605b261ecSmrg CARD32 lastInput; 69705b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 69805b261ecSmrg 69905b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq); 70005b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 7014642e01fSmrg DixGetAttrAccess); 7024642e01fSmrg if (rc != Success) 7034642e01fSmrg return rc; 7044642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 7054642e01fSmrg DixGetAttrAccess); 70605b261ecSmrg if (rc != Success) 70705b261ecSmrg return rc; 70805b261ecSmrg 7096747b715Smrg pSaver = &pDraw->pScreen->screensaver; 71005b261ecSmrg pPriv = GetScreenPrivate (pDraw->pScreen); 71105b261ecSmrg 71205b261ecSmrg UpdateCurrentTime (); 71305b261ecSmrg lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; 71405b261ecSmrg 71505b261ecSmrg rep.type = X_Reply; 71605b261ecSmrg rep.length = 0; 71705b261ecSmrg rep.sequenceNumber = client->sequence; 71805b261ecSmrg rep.window = pSaver->wid; 71905b261ecSmrg if (screenIsSaved != SCREEN_SAVER_OFF) 72005b261ecSmrg { 72105b261ecSmrg rep.state = ScreenSaverOn; 72205b261ecSmrg if (ScreenSaverTime) 72305b261ecSmrg rep.tilOrSince = lastInput - ScreenSaverTime; 72405b261ecSmrg else 72505b261ecSmrg rep.tilOrSince = 0; 72605b261ecSmrg } 72705b261ecSmrg else 72805b261ecSmrg { 72905b261ecSmrg if (ScreenSaverTime) 73005b261ecSmrg { 73105b261ecSmrg rep.state = ScreenSaverOff; 73205b261ecSmrg if (ScreenSaverTime < lastInput) 73305b261ecSmrg rep.tilOrSince = 0; 73405b261ecSmrg else 73505b261ecSmrg rep.tilOrSince = ScreenSaverTime - lastInput; 73605b261ecSmrg } 73705b261ecSmrg else 73805b261ecSmrg { 73905b261ecSmrg rep.state = ScreenSaverDisabled; 74005b261ecSmrg rep.tilOrSince = 0; 74105b261ecSmrg } 74205b261ecSmrg } 74305b261ecSmrg rep.idle = lastInput; 74405b261ecSmrg rep.eventMask = getEventMask (pDraw->pScreen, client); 74505b261ecSmrg if (pPriv && pPriv->attr) 74605b261ecSmrg rep.kind = ScreenSaverExternal; 74705b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 74805b261ecSmrg rep.kind = ScreenSaverBlanked; 74905b261ecSmrg else 75005b261ecSmrg rep.kind = ScreenSaverInternal; 75105b261ecSmrg if (client->swapped) 75205b261ecSmrg { 75305b261ecSmrg swaps (&rep.sequenceNumber, n); 75405b261ecSmrg swapl (&rep.length, n); 75505b261ecSmrg swapl (&rep.window, n); 75605b261ecSmrg swapl (&rep.tilOrSince, n); 75705b261ecSmrg swapl (&rep.idle, n); 75805b261ecSmrg swapl (&rep.eventMask, n); 75905b261ecSmrg } 76005b261ecSmrg WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep); 7616747b715Smrg return Success; 76205b261ecSmrg} 76305b261ecSmrg 76405b261ecSmrgstatic int 7656747b715SmrgProcScreenSaverSelectInput (ClientPtr client) 76605b261ecSmrg{ 76705b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 76805b261ecSmrg DrawablePtr pDraw; 76905b261ecSmrg int rc; 77005b261ecSmrg 77105b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq); 77205b261ecSmrg rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0, 7734642e01fSmrg DixGetAttrAccess); 7744642e01fSmrg if (rc != Success) 7754642e01fSmrg return rc; 7764642e01fSmrg 7774642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 7784642e01fSmrg DixSetAttrAccess); 77905b261ecSmrg if (rc != Success) 78005b261ecSmrg return rc; 7814642e01fSmrg 78205b261ecSmrg if (!setEventMask (pDraw->pScreen, client, stuff->eventMask)) 78305b261ecSmrg return BadAlloc; 78405b261ecSmrg return Success; 78505b261ecSmrg} 78605b261ecSmrg 78705b261ecSmrgstatic int 78805b261ecSmrgScreenSaverSetAttributes (ClientPtr client) 78905b261ecSmrg{ 79005b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 79105b261ecSmrg DrawablePtr pDraw; 79205b261ecSmrg WindowPtr pParent; 79305b261ecSmrg ScreenPtr pScreen; 79405b261ecSmrg ScreenSaverScreenPrivatePtr pPriv = 0; 79505b261ecSmrg ScreenSaverAttrPtr pAttr = 0; 79605b261ecSmrg int ret, len, class, bw, depth; 79705b261ecSmrg unsigned long visual; 79805b261ecSmrg int idepth, ivisual; 79905b261ecSmrg Bool fOK; 80005b261ecSmrg DepthPtr pDepth; 80105b261ecSmrg WindowOptPtr ancwopt; 80205b261ecSmrg unsigned int *pVlist; 80305b261ecSmrg unsigned long *values = 0; 80405b261ecSmrg unsigned long tmask, imask; 80505b261ecSmrg unsigned long val; 80605b261ecSmrg Pixmap pixID; 80705b261ecSmrg PixmapPtr pPixmap; 80805b261ecSmrg Cursor cursorID; 80905b261ecSmrg CursorPtr pCursor; 81005b261ecSmrg Colormap cmap; 81105b261ecSmrg ColormapPtr pCmap; 81205b261ecSmrg 81305b261ecSmrg REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 81405b261ecSmrg ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 8154642e01fSmrg DixGetAttrAccess); 81605b261ecSmrg if (ret != Success) 81705b261ecSmrg return ret; 81805b261ecSmrg pScreen = pDraw->pScreen; 8196747b715Smrg pParent = pScreen->root; 82005b261ecSmrg 8214642e01fSmrg ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess); 8224642e01fSmrg if (ret != Success) 8234642e01fSmrg return ret; 8244642e01fSmrg 8256747b715Smrg len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 82605b261ecSmrg if (Ones(stuff->mask) != len) 82705b261ecSmrg return BadLength; 82805b261ecSmrg if (!stuff->width || !stuff->height) 82905b261ecSmrg { 83005b261ecSmrg client->errorValue = 0; 83105b261ecSmrg return BadValue; 83205b261ecSmrg } 83305b261ecSmrg switch (class = stuff->c_class) 83405b261ecSmrg { 83505b261ecSmrg case CopyFromParent: 83605b261ecSmrg case InputOnly: 83705b261ecSmrg case InputOutput: 83805b261ecSmrg break; 83905b261ecSmrg default: 84005b261ecSmrg client->errorValue = class; 84105b261ecSmrg return BadValue; 84205b261ecSmrg } 84305b261ecSmrg bw = stuff->borderWidth; 84405b261ecSmrg depth = stuff->depth; 84505b261ecSmrg visual = stuff->visualID; 84605b261ecSmrg 84705b261ecSmrg /* copied directly from CreateWindow */ 84805b261ecSmrg 84905b261ecSmrg if (class == CopyFromParent) 85005b261ecSmrg class = pParent->drawable.class; 85105b261ecSmrg 85205b261ecSmrg if ((class != InputOutput) && (class != InputOnly)) 85305b261ecSmrg { 85405b261ecSmrg client->errorValue = class; 85505b261ecSmrg return BadValue; 85605b261ecSmrg } 85705b261ecSmrg 85805b261ecSmrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) 85905b261ecSmrg return BadMatch; 86005b261ecSmrg 86105b261ecSmrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) 86205b261ecSmrg return BadMatch; 86305b261ecSmrg 86405b261ecSmrg if ((class == InputOutput) && (depth == 0)) 86505b261ecSmrg depth = pParent->drawable.depth; 86605b261ecSmrg ancwopt = pParent->optional; 86705b261ecSmrg if (!ancwopt) 86805b261ecSmrg ancwopt = FindWindowWithOptional(pParent)->optional; 86905b261ecSmrg if (visual == CopyFromParent) 87005b261ecSmrg visual = ancwopt->visual; 87105b261ecSmrg 87205b261ecSmrg /* Find out if the depth and visual are acceptable for this Screen */ 87305b261ecSmrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) 87405b261ecSmrg { 87505b261ecSmrg fOK = FALSE; 87605b261ecSmrg for(idepth = 0; idepth < pScreen->numDepths; idepth++) 87705b261ecSmrg { 87805b261ecSmrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 87905b261ecSmrg if ((depth == pDepth->depth) || (depth == 0)) 88005b261ecSmrg { 88105b261ecSmrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) 88205b261ecSmrg { 88305b261ecSmrg if (visual == pDepth->vids[ivisual]) 88405b261ecSmrg { 88505b261ecSmrg fOK = TRUE; 88605b261ecSmrg break; 88705b261ecSmrg } 88805b261ecSmrg } 88905b261ecSmrg } 89005b261ecSmrg } 89105b261ecSmrg if (fOK == FALSE) 89205b261ecSmrg return BadMatch; 89305b261ecSmrg } 89405b261ecSmrg 89505b261ecSmrg if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) && 89605b261ecSmrg (class != InputOnly) && 89705b261ecSmrg (depth != pParent->drawable.depth)) 89805b261ecSmrg { 89905b261ecSmrg return BadMatch; 90005b261ecSmrg } 90105b261ecSmrg 90205b261ecSmrg if (((stuff->mask & CWColormap) == 0) && 90305b261ecSmrg (class != InputOnly) && 90405b261ecSmrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) 90505b261ecSmrg { 90605b261ecSmrg return BadMatch; 90705b261ecSmrg } 90805b261ecSmrg 90905b261ecSmrg /* end of errors from CreateWindow */ 91005b261ecSmrg 91105b261ecSmrg pPriv = GetScreenPrivate (pScreen); 91205b261ecSmrg if (pPriv && pPriv->attr) 91305b261ecSmrg { 91405b261ecSmrg if (pPriv->attr->client != client) 91505b261ecSmrg return BadAccess; 91605b261ecSmrg } 91705b261ecSmrg if (!pPriv) 91805b261ecSmrg { 91905b261ecSmrg pPriv = MakeScreenPrivate (pScreen); 92005b261ecSmrg if (!pPriv) 92105b261ecSmrg return FALSE; 92205b261ecSmrg } 92305b261ecSmrg pAttr = New (ScreenSaverAttrRec); 92405b261ecSmrg if (!pAttr) 92505b261ecSmrg { 92605b261ecSmrg ret = BadAlloc; 92705b261ecSmrg goto bail; 92805b261ecSmrg } 92905b261ecSmrg /* over allocate for override redirect */ 9306747b715Smrg values = malloc((len + 1) * sizeof (unsigned long)); 93105b261ecSmrg if (!values) 93205b261ecSmrg { 93305b261ecSmrg ret = BadAlloc; 93405b261ecSmrg goto bail; 93505b261ecSmrg } 93605b261ecSmrg pAttr->screen = pScreen; 93705b261ecSmrg pAttr->client = client; 93805b261ecSmrg pAttr->x = stuff->x; 93905b261ecSmrg pAttr->y = stuff->y; 94005b261ecSmrg pAttr->width = stuff->width; 94105b261ecSmrg pAttr->height = stuff->height; 94205b261ecSmrg pAttr->borderWidth = stuff->borderWidth; 94305b261ecSmrg pAttr->class = stuff->c_class; 94405b261ecSmrg pAttr->depth = depth; 94505b261ecSmrg pAttr->visual = visual; 94605b261ecSmrg pAttr->colormap = None; 94705b261ecSmrg pAttr->pCursor = NullCursor; 94805b261ecSmrg pAttr->pBackgroundPixmap = NullPixmap; 94905b261ecSmrg pAttr->pBorderPixmap = NullPixmap; 95005b261ecSmrg pAttr->values = values; 95105b261ecSmrg /* 95205b261ecSmrg * go through the mask, checking the values, 95305b261ecSmrg * looking up pixmaps and cursors and hold a reference 95405b261ecSmrg * to them. 95505b261ecSmrg */ 95605b261ecSmrg pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; 95705b261ecSmrg pVlist = (unsigned int *) (stuff + 1); 95805b261ecSmrg while (tmask) { 95905b261ecSmrg imask = lowbit (tmask); 96005b261ecSmrg tmask &= ~imask; 96105b261ecSmrg switch (imask) 96205b261ecSmrg { 96305b261ecSmrg case CWBackPixmap: 96405b261ecSmrg pixID = (Pixmap )*pVlist; 96505b261ecSmrg if (pixID == None) 96605b261ecSmrg { 96705b261ecSmrg *values++ = None; 96805b261ecSmrg } 96905b261ecSmrg else if (pixID == ParentRelative) 97005b261ecSmrg { 97105b261ecSmrg if (depth != pParent->drawable.depth) 97205b261ecSmrg { 97305b261ecSmrg ret = BadMatch; 97405b261ecSmrg goto PatchUp; 97505b261ecSmrg } 97605b261ecSmrg *values++ = ParentRelative; 97705b261ecSmrg } 97805b261ecSmrg else 97905b261ecSmrg { 980b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 9814642e01fSmrg client, DixReadAccess); 9824642e01fSmrg if (ret == Success) 98305b261ecSmrg { 98405b261ecSmrg if ((pPixmap->drawable.depth != depth) || 98505b261ecSmrg (pPixmap->drawable.pScreen != pScreen)) 98605b261ecSmrg { 98705b261ecSmrg ret = BadMatch; 98805b261ecSmrg goto PatchUp; 98905b261ecSmrg } 99005b261ecSmrg pAttr->pBackgroundPixmap = pPixmap; 99105b261ecSmrg pPixmap->refcnt++; 99205b261ecSmrg pAttr->mask &= ~CWBackPixmap; 99305b261ecSmrg } 99405b261ecSmrg else 99505b261ecSmrg { 99605b261ecSmrg client->errorValue = pixID; 99705b261ecSmrg goto PatchUp; 99805b261ecSmrg } 99905b261ecSmrg } 100005b261ecSmrg break; 100105b261ecSmrg case CWBackPixel: 100205b261ecSmrg *values++ = (CARD32) *pVlist; 100305b261ecSmrg break; 100405b261ecSmrg case CWBorderPixmap: 100505b261ecSmrg pixID = (Pixmap ) *pVlist; 100605b261ecSmrg if (pixID == CopyFromParent) 100705b261ecSmrg { 100805b261ecSmrg if (depth != pParent->drawable.depth) 100905b261ecSmrg { 101005b261ecSmrg ret = BadMatch; 101105b261ecSmrg goto PatchUp; 101205b261ecSmrg } 101305b261ecSmrg *values++ = CopyFromParent; 101405b261ecSmrg } 101505b261ecSmrg else 101605b261ecSmrg { 1017b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 10184642e01fSmrg client, DixReadAccess); 10194642e01fSmrg if (ret == Success) 102005b261ecSmrg { 102105b261ecSmrg if ((pPixmap->drawable.depth != depth) || 102205b261ecSmrg (pPixmap->drawable.pScreen != pScreen)) 102305b261ecSmrg { 102405b261ecSmrg ret = BadMatch; 102505b261ecSmrg goto PatchUp; 102605b261ecSmrg } 102705b261ecSmrg pAttr->pBorderPixmap = pPixmap; 102805b261ecSmrg pPixmap->refcnt++; 102905b261ecSmrg pAttr->mask &= ~CWBorderPixmap; 103005b261ecSmrg } 103105b261ecSmrg else 103205b261ecSmrg { 103305b261ecSmrg client->errorValue = pixID; 103405b261ecSmrg goto PatchUp; 103505b261ecSmrg } 103605b261ecSmrg } 103705b261ecSmrg break; 103805b261ecSmrg case CWBorderPixel: 103905b261ecSmrg *values++ = (CARD32) *pVlist; 104005b261ecSmrg break; 104105b261ecSmrg case CWBitGravity: 104205b261ecSmrg val = (CARD8 )*pVlist; 104305b261ecSmrg if (val > StaticGravity) 104405b261ecSmrg { 104505b261ecSmrg ret = BadValue; 104605b261ecSmrg client->errorValue = val; 104705b261ecSmrg goto PatchUp; 104805b261ecSmrg } 104905b261ecSmrg *values++ = val; 105005b261ecSmrg break; 105105b261ecSmrg case CWWinGravity: 105205b261ecSmrg val = (CARD8 )*pVlist; 105305b261ecSmrg if (val > StaticGravity) 105405b261ecSmrg { 105505b261ecSmrg ret = BadValue; 105605b261ecSmrg client->errorValue = val; 105705b261ecSmrg goto PatchUp; 105805b261ecSmrg } 105905b261ecSmrg *values++ = val; 106005b261ecSmrg break; 106105b261ecSmrg case CWBackingStore: 106205b261ecSmrg val = (CARD8 )*pVlist; 106305b261ecSmrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) 106405b261ecSmrg { 106505b261ecSmrg ret = BadValue; 106605b261ecSmrg client->errorValue = val; 106705b261ecSmrg goto PatchUp; 106805b261ecSmrg } 106905b261ecSmrg *values++ = val; 107005b261ecSmrg break; 107105b261ecSmrg case CWBackingPlanes: 107205b261ecSmrg *values++ = (CARD32) *pVlist; 107305b261ecSmrg break; 107405b261ecSmrg case CWBackingPixel: 107505b261ecSmrg *values++ = (CARD32) *pVlist; 107605b261ecSmrg break; 107705b261ecSmrg case CWSaveUnder: 107805b261ecSmrg val = (BOOL) *pVlist; 107905b261ecSmrg if ((val != xTrue) && (val != xFalse)) 108005b261ecSmrg { 108105b261ecSmrg ret = BadValue; 108205b261ecSmrg client->errorValue = val; 108305b261ecSmrg goto PatchUp; 108405b261ecSmrg } 108505b261ecSmrg *values++ = val; 108605b261ecSmrg break; 108705b261ecSmrg case CWEventMask: 108805b261ecSmrg *values++ = (CARD32) *pVlist; 108905b261ecSmrg break; 109005b261ecSmrg case CWDontPropagate: 109105b261ecSmrg *values++ = (CARD32) *pVlist; 109205b261ecSmrg break; 109305b261ecSmrg case CWOverrideRedirect: 109405b261ecSmrg if (!(stuff->mask & CWOverrideRedirect)) 109505b261ecSmrg pVlist--; 109605b261ecSmrg else 109705b261ecSmrg { 109805b261ecSmrg val = (BOOL ) *pVlist; 109905b261ecSmrg if ((val != xTrue) && (val != xFalse)) 110005b261ecSmrg { 110105b261ecSmrg ret = BadValue; 110205b261ecSmrg client->errorValue = val; 110305b261ecSmrg goto PatchUp; 110405b261ecSmrg } 110505b261ecSmrg } 110605b261ecSmrg *values++ = xTrue; 110705b261ecSmrg break; 110805b261ecSmrg case CWColormap: 110905b261ecSmrg cmap = (Colormap) *pVlist; 1110b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, 11114642e01fSmrg client, DixUseAccess); 11124642e01fSmrg if (ret != Success) 111305b261ecSmrg { 111405b261ecSmrg client->errorValue = cmap; 111505b261ecSmrg goto PatchUp; 111605b261ecSmrg } 111705b261ecSmrg if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) 111805b261ecSmrg { 111905b261ecSmrg ret = BadMatch; 112005b261ecSmrg goto PatchUp; 112105b261ecSmrg } 112205b261ecSmrg pAttr->colormap = cmap; 112305b261ecSmrg pAttr->mask &= ~CWColormap; 112405b261ecSmrg break; 112505b261ecSmrg case CWCursor: 112605b261ecSmrg cursorID = (Cursor ) *pVlist; 112705b261ecSmrg if ( cursorID == None) 112805b261ecSmrg { 112905b261ecSmrg *values++ = None; 113005b261ecSmrg } 113105b261ecSmrg else 113205b261ecSmrg { 1133b86d567bSmrg ret = dixLookupResourceByType((pointer *)&pCursor, cursorID, 11344642e01fSmrg RT_CURSOR, client, DixUseAccess); 11354642e01fSmrg if (ret != Success) 113605b261ecSmrg { 113705b261ecSmrg client->errorValue = cursorID; 113805b261ecSmrg goto PatchUp; 113905b261ecSmrg } 114005b261ecSmrg pCursor->refcnt++; 114105b261ecSmrg pAttr->pCursor = pCursor; 114205b261ecSmrg pAttr->mask &= ~CWCursor; 114305b261ecSmrg } 114405b261ecSmrg break; 114505b261ecSmrg default: 114605b261ecSmrg ret = BadValue; 114705b261ecSmrg client->errorValue = stuff->mask; 114805b261ecSmrg goto PatchUp; 114905b261ecSmrg } 115005b261ecSmrg pVlist++; 115105b261ecSmrg } 115205b261ecSmrg if (pPriv->attr) 115305b261ecSmrg FreeScreenAttr (pPriv->attr); 115405b261ecSmrg pPriv->attr = pAttr; 115505b261ecSmrg pAttr->resource = FakeClientID (client->index); 115605b261ecSmrg if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr)) 115705b261ecSmrg return BadAlloc; 115805b261ecSmrg return Success; 115905b261ecSmrgPatchUp: 116005b261ecSmrg FreeAttrs (pAttr); 116105b261ecSmrgbail: 116205b261ecSmrg CheckScreenPrivate (pScreen); 11636747b715Smrg if (pAttr) free(pAttr->values); 11646747b715Smrg free(pAttr); 116505b261ecSmrg return ret; 116605b261ecSmrg} 116705b261ecSmrg 116805b261ecSmrgstatic int 116905b261ecSmrgScreenSaverUnsetAttributes (ClientPtr client) 117005b261ecSmrg{ 117105b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 117205b261ecSmrg DrawablePtr pDraw; 117305b261ecSmrg ScreenSaverScreenPrivatePtr pPriv; 117405b261ecSmrg int rc; 117505b261ecSmrg 117605b261ecSmrg REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq); 117705b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 11784642e01fSmrg DixGetAttrAccess); 117905b261ecSmrg if (rc != Success) 118005b261ecSmrg return rc; 118105b261ecSmrg pPriv = GetScreenPrivate (pDraw->pScreen); 118205b261ecSmrg if (pPriv && pPriv->attr && pPriv->attr->client == client) 118305b261ecSmrg { 118405b261ecSmrg FreeResource (pPriv->attr->resource, AttrType); 118505b261ecSmrg FreeScreenAttr (pPriv->attr); 118605b261ecSmrg pPriv->attr = NULL; 118705b261ecSmrg CheckScreenPrivate (pDraw->pScreen); 118805b261ecSmrg } 118905b261ecSmrg return Success; 119005b261ecSmrg} 119105b261ecSmrg 119205b261ecSmrgstatic int 119305b261ecSmrgProcScreenSaverSetAttributes (ClientPtr client) 119405b261ecSmrg{ 119505b261ecSmrg#ifdef PANORAMIX 119605b261ecSmrg if(!noPanoramiXExtension) { 119705b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 119805b261ecSmrg PanoramiXRes *draw; 119905b261ecSmrg PanoramiXRes *backPix = NULL; 120005b261ecSmrg PanoramiXRes *bordPix = NULL; 120105b261ecSmrg PanoramiXRes *cmap = NULL; 12026747b715Smrg int i, status, len; 120305b261ecSmrg int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; 120405b261ecSmrg XID orig_visual, tmp; 120505b261ecSmrg 120605b261ecSmrg REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 120705b261ecSmrg 12086747b715Smrg status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 12096747b715Smrg XRC_DRAWABLE, client, DixWriteAccess); 12106747b715Smrg if (status != Success) 12116747b715Smrg return (status == BadValue) ? BadDrawable : status; 121205b261ecSmrg 12136747b715Smrg len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 121405b261ecSmrg if (Ones(stuff->mask) != len) 121505b261ecSmrg return BadLength; 121605b261ecSmrg 121705b261ecSmrg if((Mask)stuff->mask & CWBackPixmap) { 121805b261ecSmrg pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); 121905b261ecSmrg tmp = *((CARD32 *) &stuff[1] + pback_offset); 122005b261ecSmrg if ((tmp != None) && (tmp != ParentRelative)) { 12216747b715Smrg status = dixLookupResourceByType((pointer *)&backPix, tmp, 12226747b715Smrg XRT_PIXMAP, client, 12236747b715Smrg DixReadAccess); 12246747b715Smrg if (status != Success) 12256747b715Smrg return status; 122605b261ecSmrg } 122705b261ecSmrg } 122805b261ecSmrg 122905b261ecSmrg if ((Mask)stuff->mask & CWBorderPixmap) { 123005b261ecSmrg pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); 123105b261ecSmrg tmp = *((CARD32 *) &stuff[1] + pbord_offset); 123205b261ecSmrg if (tmp != CopyFromParent) { 12336747b715Smrg status = dixLookupResourceByType((pointer *)&bordPix, tmp, 12346747b715Smrg XRT_PIXMAP, client, 12356747b715Smrg DixReadAccess); 12366747b715Smrg if (status != Success) 12376747b715Smrg return status; 123805b261ecSmrg } 123905b261ecSmrg } 124005b261ecSmrg 124105b261ecSmrg if ((Mask)stuff->mask & CWColormap) { 124205b261ecSmrg cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); 124305b261ecSmrg tmp = *((CARD32 *) &stuff[1] + cmap_offset); 124405b261ecSmrg if ((tmp != CopyFromParent) && (tmp != None)) { 12456747b715Smrg status = dixLookupResourceByType((pointer *)&cmap, tmp, 12466747b715Smrg XRT_COLORMAP, client, 12476747b715Smrg DixReadAccess); 12486747b715Smrg if (status != Success) 12496747b715Smrg return status; 125005b261ecSmrg } 125105b261ecSmrg } 125205b261ecSmrg 125305b261ecSmrg orig_visual = stuff->visualID; 125405b261ecSmrg 125505b261ecSmrg FOR_NSCREENS_BACKWARD(i) { 125605b261ecSmrg stuff->drawable = draw->info[i].id; 125705b261ecSmrg if (backPix) 125805b261ecSmrg *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; 125905b261ecSmrg if (bordPix) 126005b261ecSmrg *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; 126105b261ecSmrg if (cmap) 126205b261ecSmrg *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; 126305b261ecSmrg 126405b261ecSmrg if (orig_visual != CopyFromParent) 12654642e01fSmrg stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); 126605b261ecSmrg 126705b261ecSmrg status = ScreenSaverSetAttributes(client); 126805b261ecSmrg } 126905b261ecSmrg 127005b261ecSmrg return status; 127105b261ecSmrg } 127205b261ecSmrg#endif 127305b261ecSmrg 127405b261ecSmrg return ScreenSaverSetAttributes(client); 127505b261ecSmrg} 127605b261ecSmrg 127705b261ecSmrgstatic int 127805b261ecSmrgProcScreenSaverUnsetAttributes (ClientPtr client) 127905b261ecSmrg{ 128005b261ecSmrg#ifdef PANORAMIX 128105b261ecSmrg if(!noPanoramiXExtension) { 128205b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 128305b261ecSmrg PanoramiXRes *draw; 12846747b715Smrg int rc, i; 128505b261ecSmrg 12866747b715Smrg rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 12876747b715Smrg XRC_DRAWABLE, client, DixWriteAccess); 12886747b715Smrg if (rc != Success) 12896747b715Smrg return (rc == BadValue) ? BadDrawable : rc; 129005b261ecSmrg 129105b261ecSmrg for(i = PanoramiXNumScreens - 1; i > 0; i--) { 129205b261ecSmrg stuff->drawable = draw->info[i].id; 129305b261ecSmrg ScreenSaverUnsetAttributes(client); 129405b261ecSmrg } 129505b261ecSmrg 129605b261ecSmrg stuff->drawable = draw->info[0].id; 129705b261ecSmrg } 129805b261ecSmrg#endif 129905b261ecSmrg 130005b261ecSmrg return ScreenSaverUnsetAttributes(client); 130105b261ecSmrg} 130205b261ecSmrg 130305b261ecSmrgstatic int 130405b261ecSmrgProcScreenSaverSuspend (ClientPtr client) 130505b261ecSmrg{ 130605b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 130705b261ecSmrg 130805b261ecSmrg REQUEST(xScreenSaverSuspendReq); 130905b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 131005b261ecSmrg 131105b261ecSmrg /* Check if this client is suspending the screensaver */ 131205b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 131305b261ecSmrg if (this->pClient == client) 131405b261ecSmrg break; 131505b261ecSmrg 131605b261ecSmrg if (this) 131705b261ecSmrg { 131805b261ecSmrg if (stuff->suspend == TRUE) 131905b261ecSmrg this->count++; 132005b261ecSmrg else if (--this->count == 0) 132105b261ecSmrg FreeResource (this->clientResource, RT_NONE); 132205b261ecSmrg 132305b261ecSmrg return Success; 132405b261ecSmrg } 132505b261ecSmrg 132605b261ecSmrg /* If we get to this point, this client isn't suspending the screensaver */ 132705b261ecSmrg if (stuff->suspend == FALSE) 132805b261ecSmrg return Success; 132905b261ecSmrg 133005b261ecSmrg /* 133105b261ecSmrg * Allocate a suspension record for the client, and stop the screensaver 133205b261ecSmrg * if it isn't already suspended by another client. We attach a resource ID 133305b261ecSmrg * to the record, so the screensaver will be reenabled and the record freed 133405b261ecSmrg * if the client disconnects without reenabling it first. 133505b261ecSmrg */ 13366747b715Smrg this = malloc(sizeof (ScreenSaverSuspensionRec)); 133705b261ecSmrg 133805b261ecSmrg if (!this) 133905b261ecSmrg return BadAlloc; 134005b261ecSmrg 134105b261ecSmrg this->next = NULL; 134205b261ecSmrg this->pClient = client; 134305b261ecSmrg this->count = 1; 134405b261ecSmrg this->clientResource = FakeClientID (client->index); 134505b261ecSmrg 134605b261ecSmrg if (!AddResource (this->clientResource, SuspendType, (pointer) this)) 134705b261ecSmrg { 13486747b715Smrg free(this); 134905b261ecSmrg return BadAlloc; 135005b261ecSmrg } 135105b261ecSmrg 135205b261ecSmrg *prev = this; 135305b261ecSmrg if (!screenSaverSuspended) 135405b261ecSmrg { 135505b261ecSmrg screenSaverSuspended = TRUE; 135605b261ecSmrg FreeScreenSaverTimer(); 135705b261ecSmrg } 135805b261ecSmrg 13596747b715Smrg return Success; 136005b261ecSmrg} 136105b261ecSmrg 13629ace9065Smrgstatic int (*NormalVector[]) (ClientPtr /* client */) = { 136305b261ecSmrg ProcScreenSaverQueryVersion, 136405b261ecSmrg ProcScreenSaverQueryInfo, 136505b261ecSmrg ProcScreenSaverSelectInput, 136605b261ecSmrg ProcScreenSaverSetAttributes, 136705b261ecSmrg ProcScreenSaverUnsetAttributes, 136805b261ecSmrg ProcScreenSaverSuspend, 136905b261ecSmrg}; 137005b261ecSmrg 137105b261ecSmrg#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) 137205b261ecSmrg 137305b261ecSmrgstatic int 13746747b715SmrgProcScreenSaverDispatch (ClientPtr client) 137505b261ecSmrg{ 137605b261ecSmrg REQUEST(xReq); 137705b261ecSmrg 137805b261ecSmrg if (stuff->data < NUM_REQUESTS) 137905b261ecSmrg return (*NormalVector[stuff->data])(client); 138005b261ecSmrg return BadRequest; 138105b261ecSmrg} 138205b261ecSmrg 138305b261ecSmrgstatic int 13846747b715SmrgSProcScreenSaverQueryVersion (ClientPtr client) 138505b261ecSmrg{ 138605b261ecSmrg REQUEST(xScreenSaverQueryVersionReq); 138705b261ecSmrg int n; 138805b261ecSmrg 138905b261ecSmrg swaps (&stuff->length, n); 139005b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 139105b261ecSmrg return ProcScreenSaverQueryVersion (client); 139205b261ecSmrg} 139305b261ecSmrg 139405b261ecSmrgstatic int 13956747b715SmrgSProcScreenSaverQueryInfo (ClientPtr client) 139605b261ecSmrg{ 139705b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 139805b261ecSmrg int n; 139905b261ecSmrg 140005b261ecSmrg swaps (&stuff->length, n); 140105b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 140205b261ecSmrg swapl (&stuff->drawable, n); 140305b261ecSmrg return ProcScreenSaverQueryInfo (client); 140405b261ecSmrg} 140505b261ecSmrg 140605b261ecSmrgstatic int 14076747b715SmrgSProcScreenSaverSelectInput (ClientPtr client) 140805b261ecSmrg{ 140905b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 141005b261ecSmrg int n; 141105b261ecSmrg 141205b261ecSmrg swaps (&stuff->length, n); 141305b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 141405b261ecSmrg swapl (&stuff->drawable, n); 141505b261ecSmrg swapl (&stuff->eventMask, n); 141605b261ecSmrg return ProcScreenSaverSelectInput (client); 141705b261ecSmrg} 141805b261ecSmrg 141905b261ecSmrgstatic int 14206747b715SmrgSProcScreenSaverSetAttributes (ClientPtr client) 142105b261ecSmrg{ 142205b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 142305b261ecSmrg int n; 142405b261ecSmrg 142505b261ecSmrg swaps (&stuff->length, n); 142605b261ecSmrg REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 142705b261ecSmrg swapl (&stuff->drawable, n); 142805b261ecSmrg swaps (&stuff->x, n); 142905b261ecSmrg swaps (&stuff->y, n); 143005b261ecSmrg swaps (&stuff->width, n); 143105b261ecSmrg swaps (&stuff->height, n); 143205b261ecSmrg swaps (&stuff->borderWidth, n); 143305b261ecSmrg swapl (&stuff->visualID, n); 143405b261ecSmrg swapl (&stuff->mask, n); 143505b261ecSmrg SwapRestL(stuff); 143605b261ecSmrg return ProcScreenSaverSetAttributes (client); 143705b261ecSmrg} 143805b261ecSmrg 143905b261ecSmrgstatic int 14406747b715SmrgSProcScreenSaverUnsetAttributes (ClientPtr client) 144105b261ecSmrg{ 144205b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 144305b261ecSmrg int n; 144405b261ecSmrg 144505b261ecSmrg swaps (&stuff->length, n); 144605b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 144705b261ecSmrg swapl (&stuff->drawable, n); 144805b261ecSmrg return ProcScreenSaverUnsetAttributes (client); 144905b261ecSmrg} 145005b261ecSmrg 145105b261ecSmrgstatic int 145205b261ecSmrgSProcScreenSaverSuspend (ClientPtr client) 145305b261ecSmrg{ 145405b261ecSmrg int n; 145505b261ecSmrg REQUEST(xScreenSaverSuspendReq); 145605b261ecSmrg 145705b261ecSmrg swaps(&stuff->length, n); 145805b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 145905b261ecSmrg swapl(&stuff->suspend, n); 146005b261ecSmrg return ProcScreenSaverSuspend (client); 146105b261ecSmrg} 146205b261ecSmrg 14639ace9065Smrgstatic int (*SwappedVector[]) (ClientPtr /* client */) = { 146405b261ecSmrg SProcScreenSaverQueryVersion, 146505b261ecSmrg SProcScreenSaverQueryInfo, 146605b261ecSmrg SProcScreenSaverSelectInput, 146705b261ecSmrg SProcScreenSaverSetAttributes, 146805b261ecSmrg SProcScreenSaverUnsetAttributes, 146905b261ecSmrg SProcScreenSaverSuspend, 147005b261ecSmrg}; 147105b261ecSmrg 147205b261ecSmrgstatic int 14736747b715SmrgSProcScreenSaverDispatch (ClientPtr client) 147405b261ecSmrg{ 147505b261ecSmrg REQUEST(xReq); 147605b261ecSmrg 147705b261ecSmrg if (stuff->data < NUM_REQUESTS) 147805b261ecSmrg return (*SwappedVector[stuff->data])(client); 147905b261ecSmrg return BadRequest; 148005b261ecSmrg} 14819ace9065Smrg 14829ace9065Smrgvoid 14839ace9065SmrgScreenSaverExtensionInit(INITARGS) 14849ace9065Smrg{ 14859ace9065Smrg ExtensionEntry *extEntry; 14869ace9065Smrg int i; 14879ace9065Smrg ScreenPtr pScreen; 14889ace9065Smrg 14899ace9065Smrg if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 14909ace9065Smrg return; 14919ace9065Smrg 14929ace9065Smrg AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr"); 14939ace9065Smrg SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, 14949ace9065Smrg "SaverEvent"); 14959ace9065Smrg SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, 14969ace9065Smrg "SaverSuspend"); 14979ace9065Smrg 14989ace9065Smrg for (i = 0; i < screenInfo.numScreens; i++) 14999ace9065Smrg { 15009ace9065Smrg pScreen = screenInfo.screens[i]; 15019ace9065Smrg SetScreenPrivate (pScreen, NULL); 15029ace9065Smrg } 15039ace9065Smrg if (AttrType && SaverEventType && SuspendType && 15049ace9065Smrg (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, 15059ace9065Smrg ProcScreenSaverDispatch, SProcScreenSaverDispatch, 15069ace9065Smrg NULL, StandardMinorOpcode))) 15079ace9065Smrg { 15089ace9065Smrg ScreenSaverEventBase = extEntry->eventBase; 15099ace9065Smrg EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent; 15109ace9065Smrg } 15119ace9065Smrg} 1512