saver.c revision 5a112b11
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#ifdef HAVE_DIX_CONFIG_H 3005b261ecSmrg#include <dix-config.h> 3105b261ecSmrg#endif 3205b261ecSmrg 3305b261ecSmrg#include <X11/X.h> 3405b261ecSmrg#include <X11/Xproto.h> 3505b261ecSmrg#include "misc.h" 3605b261ecSmrg#include "os.h" 3705b261ecSmrg#include "windowstr.h" 3805b261ecSmrg#include "scrnintstr.h" 3905b261ecSmrg#include "pixmapstr.h" 4005b261ecSmrg#include "extnsionst.h" 4105b261ecSmrg#include "dixstruct.h" 4205b261ecSmrg#include "resource.h" 4305b261ecSmrg#include "opaque.h" 4405b261ecSmrg#include <X11/extensions/saverproto.h> 4505b261ecSmrg#include "gcstruct.h" 4605b261ecSmrg#include "cursorstr.h" 4705b261ecSmrg#include "colormapst.h" 484642e01fSmrg#include "xace.h" 4935c4bbdfSmrg#include "inputstr.h" 5005b261ecSmrg#ifdef PANORAMIX 5105b261ecSmrg#include "panoramiX.h" 5205b261ecSmrg#include "panoramiXsrv.h" 5305b261ecSmrg#endif 5405b261ecSmrg#ifdef DPMSExtension 556747b715Smrg#include <X11/extensions/dpmsconst.h> 567e31ba66Smrg#include "dpmsproc.h" 5705b261ecSmrg#endif 586747b715Smrg#include "protocol-versions.h" 5905b261ecSmrg 6005b261ecSmrg#include <stdio.h> 6105b261ecSmrg 6235c4bbdfSmrg#include "extinit.h" 6305b261ecSmrg 6405b261ecSmrgstatic int ScreenSaverEventBase = 0; 6505b261ecSmrg 6635c4bbdfSmrgstatic Bool ScreenSaverHandle(ScreenPtr /* pScreen */ , 6735c4bbdfSmrg int /* xstate */ , 6835c4bbdfSmrg Bool /* force */ 6935c4bbdfSmrg ); 7005b261ecSmrg 7105b261ecSmrgstatic Bool 7235c4bbdfSmrg CreateSaverWindow(ScreenPtr /* pScreen */ 7335c4bbdfSmrg ); 7405b261ecSmrg 7505b261ecSmrgstatic Bool 7635c4bbdfSmrg DestroySaverWindow(ScreenPtr /* pScreen */ 7735c4bbdfSmrg ); 7805b261ecSmrg 7905b261ecSmrgstatic void 8035c4bbdfSmrg UninstallSaverColormap(ScreenPtr /* pScreen */ 8135c4bbdfSmrg ); 8205b261ecSmrg 8305b261ecSmrgstatic void 8435c4bbdfSmrg CheckScreenPrivate(ScreenPtr /* pScreen */ 8535c4bbdfSmrg ); 8605b261ecSmrg 8735c4bbdfSmrgstatic void SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * /* from */ , 8835c4bbdfSmrg xScreenSaverNotifyEvent * /* to */ 8935c4bbdfSmrg ); 9005b261ecSmrg 9135c4bbdfSmrgstatic RESTYPE SuspendType; /* resource type for suspension records */ 9205b261ecSmrg 9305b261ecSmrgtypedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; 9405b261ecSmrg 9505b261ecSmrg/* List of clients that are suspending the screensaver. */ 9605b261ecSmrgstatic ScreenSaverSuspensionPtr suspendingClients = NULL; 9705b261ecSmrg 9805b261ecSmrg/* 9905b261ecSmrg * clientResource is a resource ID that's added when the record is 10005b261ecSmrg * allocated, so the record is freed and the screensaver resumed when 10105b261ecSmrg * the client disconnects. count is the number of times the client has 10205b261ecSmrg * requested the screensaver be suspended. 10305b261ecSmrg */ 10435c4bbdfSmrgtypedef struct _ScreenSaverSuspension { 10535c4bbdfSmrg ScreenSaverSuspensionPtr next; 10635c4bbdfSmrg ClientPtr pClient; 10735c4bbdfSmrg XID clientResource; 10835c4bbdfSmrg int count; 10905b261ecSmrg} ScreenSaverSuspensionRec; 11005b261ecSmrg 11135c4bbdfSmrgstatic int ScreenSaverFreeSuspend(void *value, XID id); 11205b261ecSmrg 11305b261ecSmrg/* 11405b261ecSmrg * each screen has a list of clients requesting 11505b261ecSmrg * ScreenSaverNotify events. Each client has a resource 11605b261ecSmrg * for each screen it selects ScreenSaverNotify input for, 11705b261ecSmrg * this resource is used to delete the ScreenSaverNotifyRec 11805b261ecSmrg * entry from the per-screen queue. 11905b261ecSmrg */ 12005b261ecSmrg 12135c4bbdfSmrgstatic RESTYPE SaverEventType; /* resource type for event masks */ 12205b261ecSmrg 12305b261ecSmrgtypedef struct _ScreenSaverEvent *ScreenSaverEventPtr; 12405b261ecSmrg 12505b261ecSmrgtypedef struct _ScreenSaverEvent { 12635c4bbdfSmrg ScreenSaverEventPtr next; 12735c4bbdfSmrg ClientPtr client; 12835c4bbdfSmrg ScreenPtr screen; 12935c4bbdfSmrg XID resource; 13035c4bbdfSmrg CARD32 mask; 13105b261ecSmrg} ScreenSaverEventRec; 13205b261ecSmrg 13335c4bbdfSmrgstatic int ScreenSaverFreeEvents(void * value, XID id); 13405b261ecSmrg 13535c4bbdfSmrgstatic Bool setEventMask(ScreenPtr pScreen, 13635c4bbdfSmrg ClientPtr client, 13735c4bbdfSmrg unsigned long mask); 13805b261ecSmrg 13935c4bbdfSmrgstatic unsigned long getEventMask(ScreenPtr pScreen, 14035c4bbdfSmrg ClientPtr client); 14105b261ecSmrg 14205b261ecSmrg/* 14305b261ecSmrg * when a client sets the screen saver attributes, a resource is 14405b261ecSmrg * kept to be freed when the client exits 14505b261ecSmrg */ 14605b261ecSmrg 14735c4bbdfSmrgstatic RESTYPE AttrType; /* resource type for attributes */ 14805b261ecSmrg 14905b261ecSmrgtypedef struct _ScreenSaverAttr { 15035c4bbdfSmrg ScreenPtr screen; 15135c4bbdfSmrg ClientPtr client; 15235c4bbdfSmrg XID resource; 15335c4bbdfSmrg short x, y; 15435c4bbdfSmrg unsigned short width, height, borderWidth; 15535c4bbdfSmrg unsigned char class; 15635c4bbdfSmrg unsigned char depth; 15735c4bbdfSmrg VisualID visual; 15835c4bbdfSmrg CursorPtr pCursor; 15935c4bbdfSmrg PixmapPtr pBackgroundPixmap; 16035c4bbdfSmrg PixmapPtr pBorderPixmap; 16135c4bbdfSmrg Colormap colormap; 16235c4bbdfSmrg unsigned long mask; /* no pixmaps or cursors */ 16335c4bbdfSmrg unsigned long *values; 16405b261ecSmrg} ScreenSaverAttrRec, *ScreenSaverAttrPtr; 16505b261ecSmrg 16635c4bbdfSmrgstatic int ScreenSaverFreeAttr(void *value, XID id); 16705b261ecSmrg 16835c4bbdfSmrgstatic void FreeAttrs(ScreenSaverAttrPtr pAttr); 16905b261ecSmrg 17035c4bbdfSmrgstatic void FreeScreenAttr(ScreenSaverAttrPtr pAttr); 17105b261ecSmrg 17205b261ecSmrgstatic void 17335c4bbdfSmrgSendScreenSaverNotify(ScreenPtr pScreen, 17435c4bbdfSmrg int state, 17535c4bbdfSmrg Bool forced); 17605b261ecSmrg 17705b261ecSmrgtypedef struct _ScreenSaverScreenPrivate { 17835c4bbdfSmrg ScreenSaverEventPtr events; 17935c4bbdfSmrg ScreenSaverAttrPtr attr; 18035c4bbdfSmrg Bool hasWindow; 18135c4bbdfSmrg Colormap installedMap; 18205b261ecSmrg} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr; 18305b261ecSmrg 18435c4bbdfSmrgstatic ScreenSaverScreenPrivatePtr MakeScreenPrivate(ScreenPtr pScreen); 18505b261ecSmrg 1866747b715Smrgstatic DevPrivateKeyRec ScreenPrivateKeyRec; 18735c4bbdfSmrg 1886747b715Smrg#define ScreenPrivateKey (&ScreenPrivateKeyRec) 18905b261ecSmrg 1904642e01fSmrg#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \ 1914642e01fSmrg dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey)) 1924642e01fSmrg#define SetScreenPrivate(s,v) \ 1934642e01fSmrg dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v); 19405b261ecSmrg#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL) 19505b261ecSmrg 1966747b715Smrg#define New(t) (malloc(sizeof (t))) 19705b261ecSmrg 19805b261ecSmrgstatic void 19935c4bbdfSmrgCheckScreenPrivate(ScreenPtr pScreen) 20005b261ecSmrg{ 20135c4bbdfSmrg SetupScreen(pScreen); 20205b261ecSmrg 20305b261ecSmrg if (!pPriv) 20435c4bbdfSmrg return; 20505b261ecSmrg if (!pPriv->attr && !pPriv->events && 20635c4bbdfSmrg !pPriv->hasWindow && pPriv->installedMap == None) { 20735c4bbdfSmrg free(pPriv); 20835c4bbdfSmrg SetScreenPrivate(pScreen, NULL); 20935c4bbdfSmrg pScreen->screensaver.ExternalScreenSaver = NULL; 21005b261ecSmrg } 21105b261ecSmrg} 21205b261ecSmrg 21305b261ecSmrgstatic ScreenSaverScreenPrivatePtr 21435c4bbdfSmrgMakeScreenPrivate(ScreenPtr pScreen) 21505b261ecSmrg{ 21635c4bbdfSmrg SetupScreen(pScreen); 21705b261ecSmrg 21805b261ecSmrg if (pPriv) 21935c4bbdfSmrg return pPriv; 22035c4bbdfSmrg pPriv = New(ScreenSaverScreenPrivateRec); 22105b261ecSmrg if (!pPriv) 22235c4bbdfSmrg return 0; 22305b261ecSmrg pPriv->events = 0; 22405b261ecSmrg pPriv->attr = 0; 22505b261ecSmrg pPriv->hasWindow = FALSE; 22605b261ecSmrg pPriv->installedMap = None; 22735c4bbdfSmrg SetScreenPrivate(pScreen, pPriv); 2286747b715Smrg pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle; 22905b261ecSmrg return pPriv; 23005b261ecSmrg} 23105b261ecSmrg 23205b261ecSmrgstatic unsigned long 23335c4bbdfSmrggetEventMask(ScreenPtr pScreen, ClientPtr client) 23405b261ecSmrg{ 23505b261ecSmrg SetupScreen(pScreen); 23635c4bbdfSmrg ScreenSaverEventPtr pEv; 23705b261ecSmrg 23805b261ecSmrg if (!pPriv) 23935c4bbdfSmrg return 0; 24005b261ecSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) 24135c4bbdfSmrg if (pEv->client == client) 24235c4bbdfSmrg return pEv->mask; 24305b261ecSmrg return 0; 24405b261ecSmrg} 24505b261ecSmrg 24605b261ecSmrgstatic Bool 24735c4bbdfSmrgsetEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask) 24805b261ecSmrg{ 24905b261ecSmrg SetupScreen(pScreen); 25035c4bbdfSmrg ScreenSaverEventPtr pEv, *pPrev; 25135c4bbdfSmrg 25235c4bbdfSmrg if (getEventMask(pScreen, client) == mask) 25335c4bbdfSmrg return TRUE; 25435c4bbdfSmrg if (!pPriv) { 25535c4bbdfSmrg pPriv = MakeScreenPrivate(pScreen); 25635c4bbdfSmrg if (!pPriv) 25735c4bbdfSmrg return FALSE; 25805b261ecSmrg } 25905b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 26035c4bbdfSmrg if (pEv->client == client) 26135c4bbdfSmrg break; 26235c4bbdfSmrg if (mask == 0) { 26335c4bbdfSmrg FreeResource(pEv->resource, SaverEventType); 26435c4bbdfSmrg *pPrev = pEv->next; 26535c4bbdfSmrg free(pEv); 26635c4bbdfSmrg CheckScreenPrivate(pScreen); 26705b261ecSmrg } 26835c4bbdfSmrg else { 26935c4bbdfSmrg if (!pEv) { 27035c4bbdfSmrg pEv = New(ScreenSaverEventRec); 27135c4bbdfSmrg if (!pEv) { 27235c4bbdfSmrg CheckScreenPrivate(pScreen); 27335c4bbdfSmrg return FALSE; 27435c4bbdfSmrg } 27535c4bbdfSmrg *pPrev = pEv; 27635c4bbdfSmrg pEv->next = NULL; 27735c4bbdfSmrg pEv->client = client; 27835c4bbdfSmrg pEv->screen = pScreen; 27935c4bbdfSmrg pEv->resource = FakeClientID(client->index); 28035c4bbdfSmrg if (!AddResource(pEv->resource, SaverEventType, (void *) pEv)) 28135c4bbdfSmrg return FALSE; 28235c4bbdfSmrg } 28335c4bbdfSmrg pEv->mask = mask; 28405b261ecSmrg } 28505b261ecSmrg return TRUE; 28605b261ecSmrg} 28705b261ecSmrg 28805b261ecSmrgstatic void 28935c4bbdfSmrgFreeAttrs(ScreenSaverAttrPtr pAttr) 29005b261ecSmrg{ 29135c4bbdfSmrg PixmapPtr pPixmap; 29235c4bbdfSmrg CursorPtr pCursor; 29305b261ecSmrg 29405b261ecSmrg if ((pPixmap = pAttr->pBackgroundPixmap) != 0) 29535c4bbdfSmrg (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); 29605b261ecSmrg if ((pPixmap = pAttr->pBorderPixmap) != 0) 29735c4bbdfSmrg (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); 29805b261ecSmrg if ((pCursor = pAttr->pCursor) != 0) 29935c4bbdfSmrg FreeCursor(pCursor, (Cursor) 0); 30005b261ecSmrg} 30105b261ecSmrg 30205b261ecSmrgstatic void 30335c4bbdfSmrgFreeScreenAttr(ScreenSaverAttrPtr pAttr) 30405b261ecSmrg{ 30535c4bbdfSmrg FreeAttrs(pAttr); 3066747b715Smrg free(pAttr->values); 3076747b715Smrg free(pAttr); 30805b261ecSmrg} 30905b261ecSmrg 31005b261ecSmrgstatic int 31135c4bbdfSmrgScreenSaverFreeEvents(void *value, XID id) 31205b261ecSmrg{ 31335c4bbdfSmrg ScreenSaverEventPtr pOld = (ScreenSaverEventPtr) value; 31405b261ecSmrg ScreenPtr pScreen = pOld->screen; 31535c4bbdfSmrg 31635c4bbdfSmrg SetupScreen(pScreen); 31735c4bbdfSmrg ScreenSaverEventPtr pEv, *pPrev; 31805b261ecSmrg 31905b261ecSmrg if (!pPriv) 32035c4bbdfSmrg return TRUE; 32105b261ecSmrg for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 32235c4bbdfSmrg if (pEv == pOld) 32335c4bbdfSmrg break; 32405b261ecSmrg if (!pEv) 32535c4bbdfSmrg return TRUE; 32605b261ecSmrg *pPrev = pEv->next; 3276747b715Smrg free(pEv); 32835c4bbdfSmrg CheckScreenPrivate(pScreen); 32905b261ecSmrg return TRUE; 33005b261ecSmrg} 33105b261ecSmrg 33205b261ecSmrgstatic int 33335c4bbdfSmrgScreenSaverFreeAttr(void *value, XID id) 33405b261ecSmrg{ 33535c4bbdfSmrg ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr) value; 33635c4bbdfSmrg ScreenPtr pScreen = pOldAttr->screen; 33735c4bbdfSmrg 33835c4bbdfSmrg SetupScreen(pScreen); 33905b261ecSmrg 34005b261ecSmrg if (!pPriv) 34135c4bbdfSmrg return TRUE; 34205b261ecSmrg if (pPriv->attr != pOldAttr) 34335c4bbdfSmrg return TRUE; 34435c4bbdfSmrg FreeScreenAttr(pOldAttr); 34505b261ecSmrg pPriv->attr = NULL; 34635c4bbdfSmrg if (pPriv->hasWindow) { 34735c4bbdfSmrg dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); 34835c4bbdfSmrg dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive); 34905b261ecSmrg } 35035c4bbdfSmrg CheckScreenPrivate(pScreen); 35105b261ecSmrg return TRUE; 35205b261ecSmrg} 35305b261ecSmrg 35405b261ecSmrgstatic int 35535c4bbdfSmrgScreenSaverFreeSuspend(void *value, XID id) 35605b261ecSmrg{ 35705b261ecSmrg ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; 35805b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 35905b261ecSmrg 36005b261ecSmrg /* Unlink and free the suspension record for the client */ 36135c4bbdfSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) { 36235c4bbdfSmrg if (this == data) { 36335c4bbdfSmrg *prev = this->next; 36435c4bbdfSmrg free(this); 36535c4bbdfSmrg break; 36635c4bbdfSmrg } 36705b261ecSmrg } 36805b261ecSmrg 3695a112b11Smrg /* Re-enable the screensaver if this was the last client suspending it. */ 37035c4bbdfSmrg if (screenSaverSuspended && suspendingClients == NULL) { 37135c4bbdfSmrg screenSaverSuspended = FALSE; 37205b261ecSmrg 37335c4bbdfSmrg /* The screensaver could be active, since suspending it (by design) 37435c4bbdfSmrg doesn't prevent it from being forceably activated */ 37505b261ecSmrg#ifdef DPMSExtension 37635c4bbdfSmrg if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) 37705b261ecSmrg#else 37835c4bbdfSmrg if (screenIsSaved != SCREEN_SAVER_ON) 37905b261ecSmrg#endif 38035c4bbdfSmrg { 38135c4bbdfSmrg DeviceIntPtr dev; 38235c4bbdfSmrg UpdateCurrentTimeIf(); 38335c4bbdfSmrg nt_list_for_each_entry(dev, inputInfo.devices, next) 38435c4bbdfSmrg NoticeTime(dev, currentTime); 38535c4bbdfSmrg SetScreenSaverTimer(); 38635c4bbdfSmrg } 38705b261ecSmrg } 38805b261ecSmrg 38905b261ecSmrg return Success; 39005b261ecSmrg} 39105b261ecSmrg 39205b261ecSmrgstatic void 39335c4bbdfSmrgSendScreenSaverNotify(ScreenPtr pScreen, int state, Bool forced) 39405b261ecSmrg{ 39535c4bbdfSmrg ScreenSaverScreenPrivatePtr pPriv; 39635c4bbdfSmrg ScreenSaverEventPtr pEv; 39735c4bbdfSmrg unsigned long mask; 39835c4bbdfSmrg int kind; 39905b261ecSmrg 40035c4bbdfSmrg UpdateCurrentTimeIf(); 40105b261ecSmrg mask = ScreenSaverNotifyMask; 40205b261ecSmrg if (state == ScreenSaverCycle) 40335c4bbdfSmrg mask = ScreenSaverCycleMask; 40405b261ecSmrg pScreen = screenInfo.screens[pScreen->myNum]; 40505b261ecSmrg pPriv = GetScreenPrivate(pScreen); 40605b261ecSmrg if (!pPriv) 40735c4bbdfSmrg return; 40805b261ecSmrg if (pPriv->attr) 40935c4bbdfSmrg kind = ScreenSaverExternal; 41005b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 41135c4bbdfSmrg kind = ScreenSaverBlanked; 41205b261ecSmrg else 41335c4bbdfSmrg kind = ScreenSaverInternal; 41435c4bbdfSmrg for (pEv = pPriv->events; pEv; pEv = pEv->next) { 41535c4bbdfSmrg if (pEv->mask & mask) { 41635c4bbdfSmrg xScreenSaverNotifyEvent ev = { 41735c4bbdfSmrg .type = ScreenSaverNotify + ScreenSaverEventBase, 41835c4bbdfSmrg .state = state, 41935c4bbdfSmrg .timestamp = currentTime.milliseconds, 42035c4bbdfSmrg .root = pScreen->root->drawable.id, 42135c4bbdfSmrg .window = pScreen->screensaver.wid, 42235c4bbdfSmrg .kind = kind, 42335c4bbdfSmrg .forced = forced 42435c4bbdfSmrg }; 42535c4bbdfSmrg WriteEventsToClient(pEv->client, 1, (xEvent *) &ev); 42635c4bbdfSmrg } 42705b261ecSmrg } 42805b261ecSmrg} 42905b261ecSmrg 4307e31ba66Smrgstatic void _X_COLD 43135c4bbdfSmrgSScreenSaverNotifyEvent(xScreenSaverNotifyEvent * from, 43235c4bbdfSmrg xScreenSaverNotifyEvent * to) 43305b261ecSmrg{ 43405b261ecSmrg to->type = from->type; 43505b261ecSmrg to->state = from->state; 43635c4bbdfSmrg cpswaps(from->sequenceNumber, to->sequenceNumber); 43735c4bbdfSmrg cpswapl(from->timestamp, to->timestamp); 43835c4bbdfSmrg cpswapl(from->root, to->root); 43935c4bbdfSmrg cpswapl(from->window, to->window); 44005b261ecSmrg to->kind = from->kind; 44105b261ecSmrg to->forced = from->forced; 44205b261ecSmrg} 44305b261ecSmrg 44405b261ecSmrgstatic void 44535c4bbdfSmrgUninstallSaverColormap(ScreenPtr pScreen) 44605b261ecSmrg{ 44705b261ecSmrg SetupScreen(pScreen); 44835c4bbdfSmrg ColormapPtr pCmap; 4496747b715Smrg int rc; 45005b261ecSmrg 45135c4bbdfSmrg if (pPriv && pPriv->installedMap != None) { 45235c4bbdfSmrg rc = dixLookupResourceByType((void **) &pCmap, pPriv->installedMap, 45335c4bbdfSmrg RT_COLORMAP, serverClient, 45435c4bbdfSmrg DixUninstallAccess); 45535c4bbdfSmrg if (rc == Success) 45635c4bbdfSmrg (*pCmap->pScreen->UninstallColormap) (pCmap); 45735c4bbdfSmrg pPriv->installedMap = None; 45835c4bbdfSmrg CheckScreenPrivate(pScreen); 45905b261ecSmrg } 46005b261ecSmrg} 46105b261ecSmrg 46205b261ecSmrgstatic Bool 46335c4bbdfSmrgCreateSaverWindow(ScreenPtr pScreen) 46405b261ecSmrg{ 46535c4bbdfSmrg SetupScreen(pScreen); 46635c4bbdfSmrg ScreenSaverStuffPtr pSaver; 46735c4bbdfSmrg ScreenSaverAttrPtr pAttr; 46835c4bbdfSmrg WindowPtr pWin; 46935c4bbdfSmrg int result; 47035c4bbdfSmrg unsigned long mask; 47135c4bbdfSmrg Colormap wantMap; 47235c4bbdfSmrg ColormapPtr pCmap; 47305b261ecSmrg 4746747b715Smrg pSaver = &pScreen->screensaver; 47535c4bbdfSmrg if (pSaver->pWindow) { 47635c4bbdfSmrg pSaver->pWindow = NullWindow; 47735c4bbdfSmrg FreeResource(pSaver->wid, RT_NONE); 47835c4bbdfSmrg if (pPriv) { 47935c4bbdfSmrg UninstallSaverColormap(pScreen); 48035c4bbdfSmrg pPriv->hasWindow = FALSE; 48135c4bbdfSmrg CheckScreenPrivate(pScreen); 48235c4bbdfSmrg } 48305b261ecSmrg } 48405b261ecSmrg 48505b261ecSmrg if (!pPriv || !(pAttr = pPriv->attr)) 48635c4bbdfSmrg return FALSE; 48705b261ecSmrg 48805b261ecSmrg pPriv->installedMap = None; 48905b261ecSmrg 49005b261ecSmrg if (GrabInProgress && GrabInProgress != pAttr->client->index) 49135c4bbdfSmrg return FALSE; 49235c4bbdfSmrg 49335c4bbdfSmrg pWin = CreateWindow(pSaver->wid, pScreen->root, 49435c4bbdfSmrg pAttr->x, pAttr->y, pAttr->width, pAttr->height, 49535c4bbdfSmrg pAttr->borderWidth, pAttr->class, 49635c4bbdfSmrg pAttr->mask, (XID *) pAttr->values, 49735c4bbdfSmrg pAttr->depth, serverClient, pAttr->visual, &result); 49805b261ecSmrg if (!pWin) 49935c4bbdfSmrg return FALSE; 50005b261ecSmrg 50105b261ecSmrg if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin)) 50235c4bbdfSmrg return FALSE; 50305b261ecSmrg 50405b261ecSmrg mask = 0; 50535c4bbdfSmrg if (pAttr->pBackgroundPixmap) { 50635c4bbdfSmrg pWin->backgroundState = BackgroundPixmap; 50735c4bbdfSmrg pWin->background.pixmap = pAttr->pBackgroundPixmap; 50835c4bbdfSmrg pAttr->pBackgroundPixmap->refcnt++; 50935c4bbdfSmrg mask |= CWBackPixmap; 51005b261ecSmrg } 51135c4bbdfSmrg if (pAttr->pBorderPixmap) { 51235c4bbdfSmrg pWin->borderIsPixel = FALSE; 51335c4bbdfSmrg pWin->border.pixmap = pAttr->pBorderPixmap; 51435c4bbdfSmrg pAttr->pBorderPixmap->refcnt++; 51535c4bbdfSmrg mask |= CWBorderPixmap; 51605b261ecSmrg } 51735c4bbdfSmrg if (pAttr->pCursor) { 51835c4bbdfSmrg CursorPtr cursor; 51935c4bbdfSmrg if (!pWin->optional) 52035c4bbdfSmrg if (!MakeWindowOptional(pWin)) { 52135c4bbdfSmrg FreeResource(pWin->drawable.id, RT_NONE); 52235c4bbdfSmrg return FALSE; 52335c4bbdfSmrg } 52435c4bbdfSmrg cursor = RefCursor(pAttr->pCursor); 52535c4bbdfSmrg if (pWin->optional->cursor) 52635c4bbdfSmrg FreeCursor(pWin->optional->cursor, (Cursor) 0); 52735c4bbdfSmrg pWin->optional->cursor = cursor; 52835c4bbdfSmrg pWin->cursorIsNone = FALSE; 52935c4bbdfSmrg CheckWindowOptionalNeed(pWin); 53035c4bbdfSmrg mask |= CWCursor; 53105b261ecSmrg } 53205b261ecSmrg if (mask) 53335c4bbdfSmrg (*pScreen->ChangeWindowAttributes) (pWin, mask); 53405b261ecSmrg 53505b261ecSmrg if (pAttr->colormap != None) 53635c4bbdfSmrg (void) ChangeWindowAttributes(pWin, CWColormap, &pAttr->colormap, 53735c4bbdfSmrg serverClient); 53805b261ecSmrg 53935c4bbdfSmrg MapWindow(pWin, serverClient); 54005b261ecSmrg 54105b261ecSmrg pPriv->hasWindow = TRUE; 54205b261ecSmrg pSaver->pWindow = pWin; 54305b261ecSmrg 54405b261ecSmrg /* check and install our own colormap if it isn't installed now */ 54535c4bbdfSmrg wantMap = wColormap(pWin); 54635c4bbdfSmrg if (wantMap == None || IsMapInstalled(wantMap, pWin)) 54735c4bbdfSmrg return TRUE; 54835c4bbdfSmrg 54935c4bbdfSmrg result = dixLookupResourceByType((void **) &pCmap, wantMap, RT_COLORMAP, 55035c4bbdfSmrg serverClient, DixInstallAccess); 5516747b715Smrg if (result != Success) 55235c4bbdfSmrg return TRUE; 55305b261ecSmrg 55405b261ecSmrg pPriv->installedMap = wantMap; 55505b261ecSmrg 55605b261ecSmrg (*pCmap->pScreen->InstallColormap) (pCmap); 55705b261ecSmrg 55805b261ecSmrg return TRUE; 55905b261ecSmrg} 56005b261ecSmrg 56105b261ecSmrgstatic Bool 56235c4bbdfSmrgDestroySaverWindow(ScreenPtr pScreen) 56305b261ecSmrg{ 56405b261ecSmrg SetupScreen(pScreen); 56535c4bbdfSmrg ScreenSaverStuffPtr pSaver; 56605b261ecSmrg 56705b261ecSmrg if (!pPriv || !pPriv->hasWindow) 56835c4bbdfSmrg return FALSE; 56905b261ecSmrg 5706747b715Smrg pSaver = &pScreen->screensaver; 57135c4bbdfSmrg if (pSaver->pWindow) { 57235c4bbdfSmrg pSaver->pWindow = NullWindow; 57335c4bbdfSmrg FreeResource(pSaver->wid, RT_NONE); 57405b261ecSmrg } 57505b261ecSmrg pPriv->hasWindow = FALSE; 57635c4bbdfSmrg CheckScreenPrivate(pScreen); 57735c4bbdfSmrg UninstallSaverColormap(pScreen); 57805b261ecSmrg return TRUE; 57905b261ecSmrg} 58005b261ecSmrg 58105b261ecSmrgstatic Bool 58235c4bbdfSmrgScreenSaverHandle(ScreenPtr pScreen, int xstate, Bool force) 58305b261ecSmrg{ 58435c4bbdfSmrg int state = 0; 58535c4bbdfSmrg Bool ret = FALSE; 58635c4bbdfSmrg ScreenSaverScreenPrivatePtr pPriv; 58735c4bbdfSmrg 58835c4bbdfSmrg switch (xstate) { 58935c4bbdfSmrg case SCREEN_SAVER_ON: 59035c4bbdfSmrg state = ScreenSaverOn; 59135c4bbdfSmrg ret = CreateSaverWindow(pScreen); 59235c4bbdfSmrg break; 59335c4bbdfSmrg case SCREEN_SAVER_OFF: 59435c4bbdfSmrg state = ScreenSaverOff; 59535c4bbdfSmrg ret = DestroySaverWindow(pScreen); 59635c4bbdfSmrg break; 59735c4bbdfSmrg case SCREEN_SAVER_CYCLE: 59835c4bbdfSmrg state = ScreenSaverCycle; 59935c4bbdfSmrg pPriv = GetScreenPrivate(pScreen); 60035c4bbdfSmrg if (pPriv && pPriv->hasWindow) 60135c4bbdfSmrg ret = TRUE; 60235c4bbdfSmrg 60305b261ecSmrg } 60405b261ecSmrg#ifdef PANORAMIX 60535c4bbdfSmrg if (noPanoramiXExtension || !pScreen->myNum) 60605b261ecSmrg#endif 60735c4bbdfSmrg SendScreenSaverNotify(pScreen, state, force); 60805b261ecSmrg return ret; 60905b261ecSmrg} 61005b261ecSmrg 61105b261ecSmrgstatic int 61235c4bbdfSmrgProcScreenSaverQueryVersion(ClientPtr client) 61305b261ecSmrg{ 61435c4bbdfSmrg xScreenSaverQueryVersionReply rep = { 61535c4bbdfSmrg .type = X_Reply, 61635c4bbdfSmrg .sequenceNumber = client->sequence, 61735c4bbdfSmrg .length = 0, 61835c4bbdfSmrg .majorVersion = SERVER_SAVER_MAJOR_VERSION, 61935c4bbdfSmrg .minorVersion = SERVER_SAVER_MINOR_VERSION 62035c4bbdfSmrg }; 62135c4bbdfSmrg 62235c4bbdfSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 62335c4bbdfSmrg 62405b261ecSmrg if (client->swapped) { 62535c4bbdfSmrg swaps(&rep.sequenceNumber); 62635c4bbdfSmrg swapl(&rep.length); 62705b261ecSmrg } 62835c4bbdfSmrg WriteToClient(client, sizeof(xScreenSaverQueryVersionReply), &rep); 6296747b715Smrg return Success; 63005b261ecSmrg} 63105b261ecSmrg 63205b261ecSmrgstatic int 63335c4bbdfSmrgProcScreenSaverQueryInfo(ClientPtr client) 63405b261ecSmrg{ 63505b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 63635c4bbdfSmrg xScreenSaverQueryInfoReply rep; 63735c4bbdfSmrg int rc; 63835c4bbdfSmrg ScreenSaverStuffPtr pSaver; 63935c4bbdfSmrg DrawablePtr pDraw; 64035c4bbdfSmrg CARD32 lastInput; 64135c4bbdfSmrg ScreenSaverScreenPrivatePtr pPriv; 64235c4bbdfSmrg 64335c4bbdfSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 64405b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 64535c4bbdfSmrg DixGetAttrAccess); 6464642e01fSmrg if (rc != Success) 64735c4bbdfSmrg return rc; 6484642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 64935c4bbdfSmrg DixGetAttrAccess); 65005b261ecSmrg if (rc != Success) 65135c4bbdfSmrg return rc; 65205b261ecSmrg 6536747b715Smrg pSaver = &pDraw->pScreen->screensaver; 65435c4bbdfSmrg pPriv = GetScreenPrivate(pDraw->pScreen); 65535c4bbdfSmrg 65635c4bbdfSmrg UpdateCurrentTime(); 65735c4bbdfSmrg lastInput = GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds; 65835c4bbdfSmrg 65935c4bbdfSmrg rep = (xScreenSaverQueryInfoReply) { 66035c4bbdfSmrg .type = X_Reply, 66135c4bbdfSmrg .sequenceNumber = client->sequence, 66235c4bbdfSmrg .length = 0, 66335c4bbdfSmrg .window = pSaver->wid 66435c4bbdfSmrg }; 66535c4bbdfSmrg if (screenIsSaved != SCREEN_SAVER_OFF) { 66635c4bbdfSmrg rep.state = ScreenSaverOn; 66735c4bbdfSmrg if (ScreenSaverTime) 66835c4bbdfSmrg rep.tilOrSince = lastInput - ScreenSaverTime; 66935c4bbdfSmrg else 67035c4bbdfSmrg rep.tilOrSince = 0; 67105b261ecSmrg } 67235c4bbdfSmrg else { 67335c4bbdfSmrg if (ScreenSaverTime) { 67435c4bbdfSmrg rep.state = ScreenSaverOff; 67535c4bbdfSmrg if (ScreenSaverTime < lastInput) 67635c4bbdfSmrg rep.tilOrSince = 0; 67735c4bbdfSmrg else 67835c4bbdfSmrg rep.tilOrSince = ScreenSaverTime - lastInput; 67935c4bbdfSmrg } 68035c4bbdfSmrg else { 68135c4bbdfSmrg rep.state = ScreenSaverDisabled; 68235c4bbdfSmrg rep.tilOrSince = 0; 68335c4bbdfSmrg } 68405b261ecSmrg } 68505b261ecSmrg rep.idle = lastInput; 68635c4bbdfSmrg rep.eventMask = getEventMask(pDraw->pScreen, client); 68705b261ecSmrg if (pPriv && pPriv->attr) 68835c4bbdfSmrg rep.kind = ScreenSaverExternal; 68905b261ecSmrg else if (ScreenSaverBlanking != DontPreferBlanking) 69035c4bbdfSmrg rep.kind = ScreenSaverBlanked; 69105b261ecSmrg else 69235c4bbdfSmrg rep.kind = ScreenSaverInternal; 69335c4bbdfSmrg if (client->swapped) { 69435c4bbdfSmrg swaps(&rep.sequenceNumber); 69535c4bbdfSmrg swapl(&rep.length); 69635c4bbdfSmrg swapl(&rep.window); 69735c4bbdfSmrg swapl(&rep.tilOrSince); 69835c4bbdfSmrg swapl(&rep.idle); 69935c4bbdfSmrg swapl(&rep.eventMask); 70005b261ecSmrg } 70135c4bbdfSmrg WriteToClient(client, sizeof(xScreenSaverQueryInfoReply), &rep); 7026747b715Smrg return Success; 70305b261ecSmrg} 70405b261ecSmrg 70505b261ecSmrgstatic int 70635c4bbdfSmrgProcScreenSaverSelectInput(ClientPtr client) 70705b261ecSmrg{ 70805b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 70935c4bbdfSmrg DrawablePtr pDraw; 71035c4bbdfSmrg int rc; 71105b261ecSmrg 71235c4bbdfSmrg REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 71335c4bbdfSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 71435c4bbdfSmrg DixGetAttrAccess); 7154642e01fSmrg if (rc != Success) 71635c4bbdfSmrg return rc; 7174642e01fSmrg 7184642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 71935c4bbdfSmrg DixSetAttrAccess); 72005b261ecSmrg if (rc != Success) 72135c4bbdfSmrg return rc; 7224642e01fSmrg 72335c4bbdfSmrg if (!setEventMask(pDraw->pScreen, client, stuff->eventMask)) 72435c4bbdfSmrg return BadAlloc; 72505b261ecSmrg return Success; 72605b261ecSmrg} 72705b261ecSmrg 72805b261ecSmrgstatic int 72935c4bbdfSmrgScreenSaverSetAttributes(ClientPtr client) 73005b261ecSmrg{ 73105b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 73235c4bbdfSmrg DrawablePtr pDraw; 73335c4bbdfSmrg WindowPtr pParent; 73435c4bbdfSmrg ScreenPtr pScreen; 73505b261ecSmrg ScreenSaverScreenPrivatePtr pPriv = 0; 73635c4bbdfSmrg ScreenSaverAttrPtr pAttr = 0; 73735c4bbdfSmrg int ret, len, class, bw, depth; 73835c4bbdfSmrg unsigned long visual; 73935c4bbdfSmrg int idepth, ivisual; 74035c4bbdfSmrg Bool fOK; 74135c4bbdfSmrg DepthPtr pDepth; 74235c4bbdfSmrg WindowOptPtr ancwopt; 74335c4bbdfSmrg unsigned int *pVlist; 74435c4bbdfSmrg unsigned long *values = 0; 74535c4bbdfSmrg unsigned long tmask, imask; 74635c4bbdfSmrg unsigned long val; 74735c4bbdfSmrg Pixmap pixID; 74835c4bbdfSmrg PixmapPtr pPixmap; 74935c4bbdfSmrg Cursor cursorID; 75035c4bbdfSmrg CursorPtr pCursor; 75135c4bbdfSmrg Colormap cmap; 75235c4bbdfSmrg ColormapPtr pCmap; 75335c4bbdfSmrg 75435c4bbdfSmrg REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 75505b261ecSmrg ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 75635c4bbdfSmrg DixGetAttrAccess); 75705b261ecSmrg if (ret != Success) 75835c4bbdfSmrg return ret; 75905b261ecSmrg pScreen = pDraw->pScreen; 7606747b715Smrg pParent = pScreen->root; 76105b261ecSmrg 7624642e01fSmrg ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess); 7634642e01fSmrg if (ret != Success) 76435c4bbdfSmrg return ret; 7654642e01fSmrg 76635c4bbdfSmrg len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 76705b261ecSmrg if (Ones(stuff->mask) != len) 76805b261ecSmrg return BadLength; 76935c4bbdfSmrg if (!stuff->width || !stuff->height) { 77035c4bbdfSmrg client->errorValue = 0; 77105b261ecSmrg return BadValue; 77205b261ecSmrg } 77335c4bbdfSmrg switch (class = stuff->c_class) { 77405b261ecSmrg case CopyFromParent: 77505b261ecSmrg case InputOnly: 77605b261ecSmrg case InputOutput: 77735c4bbdfSmrg break; 77805b261ecSmrg default: 77935c4bbdfSmrg client->errorValue = class; 78035c4bbdfSmrg return BadValue; 78105b261ecSmrg } 78205b261ecSmrg bw = stuff->borderWidth; 78305b261ecSmrg depth = stuff->depth; 78405b261ecSmrg visual = stuff->visualID; 78505b261ecSmrg 78605b261ecSmrg /* copied directly from CreateWindow */ 78705b261ecSmrg 78805b261ecSmrg if (class == CopyFromParent) 78935c4bbdfSmrg class = pParent->drawable.class; 79005b261ecSmrg 79135c4bbdfSmrg if ((class != InputOutput) && (class != InputOnly)) { 79235c4bbdfSmrg client->errorValue = class; 79335c4bbdfSmrg return BadValue; 79405b261ecSmrg } 79505b261ecSmrg 79605b261ecSmrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) 79705b261ecSmrg return BadMatch; 79805b261ecSmrg 79905b261ecSmrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) 80005b261ecSmrg return BadMatch; 80105b261ecSmrg 80205b261ecSmrg if ((class == InputOutput) && (depth == 0)) 80305b261ecSmrg depth = pParent->drawable.depth; 80405b261ecSmrg ancwopt = pParent->optional; 80505b261ecSmrg if (!ancwopt) 80635c4bbdfSmrg ancwopt = FindWindowWithOptional(pParent)->optional; 80705b261ecSmrg if (visual == CopyFromParent) 80835c4bbdfSmrg visual = ancwopt->visual; 80905b261ecSmrg 81005b261ecSmrg /* Find out if the depth and visual are acceptable for this Screen */ 81135c4bbdfSmrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) { 81235c4bbdfSmrg fOK = FALSE; 81335c4bbdfSmrg for (idepth = 0; idepth < pScreen->numDepths; idepth++) { 81435c4bbdfSmrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 81535c4bbdfSmrg if ((depth == pDepth->depth) || (depth == 0)) { 81635c4bbdfSmrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) { 81735c4bbdfSmrg if (visual == pDepth->vids[ivisual]) { 81835c4bbdfSmrg fOK = TRUE; 81935c4bbdfSmrg break; 82035c4bbdfSmrg } 82135c4bbdfSmrg } 82235c4bbdfSmrg } 82335c4bbdfSmrg } 82435c4bbdfSmrg if (fOK == FALSE) 82535c4bbdfSmrg return BadMatch; 82605b261ecSmrg } 82705b261ecSmrg 82805b261ecSmrg if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) && 82935c4bbdfSmrg (class != InputOnly) && (depth != pParent->drawable.depth)) { 83005b261ecSmrg return BadMatch; 83105b261ecSmrg } 83205b261ecSmrg 83305b261ecSmrg if (((stuff->mask & CWColormap) == 0) && 83435c4bbdfSmrg (class != InputOnly) && 83535c4bbdfSmrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) { 83635c4bbdfSmrg return BadMatch; 83705b261ecSmrg } 83805b261ecSmrg 83905b261ecSmrg /* end of errors from CreateWindow */ 84005b261ecSmrg 84135c4bbdfSmrg pPriv = GetScreenPrivate(pScreen); 84235c4bbdfSmrg if (pPriv && pPriv->attr) { 84335c4bbdfSmrg if (pPriv->attr->client != client) 84435c4bbdfSmrg return BadAccess; 84505b261ecSmrg } 84635c4bbdfSmrg if (!pPriv) { 84735c4bbdfSmrg pPriv = MakeScreenPrivate(pScreen); 84835c4bbdfSmrg if (!pPriv) 84935c4bbdfSmrg return FALSE; 85005b261ecSmrg } 85135c4bbdfSmrg pAttr = New(ScreenSaverAttrRec); 85235c4bbdfSmrg if (!pAttr) { 85335c4bbdfSmrg ret = BadAlloc; 85435c4bbdfSmrg goto bail; 85505b261ecSmrg } 85605b261ecSmrg /* over allocate for override redirect */ 85735c4bbdfSmrg pAttr->values = values = xallocarray(len + 1, sizeof(unsigned long)); 85835c4bbdfSmrg if (!values) { 85935c4bbdfSmrg ret = BadAlloc; 86035c4bbdfSmrg goto bail; 86105b261ecSmrg } 86205b261ecSmrg pAttr->screen = pScreen; 86305b261ecSmrg pAttr->client = client; 86405b261ecSmrg pAttr->x = stuff->x; 86505b261ecSmrg pAttr->y = stuff->y; 86605b261ecSmrg pAttr->width = stuff->width; 86705b261ecSmrg pAttr->height = stuff->height; 86805b261ecSmrg pAttr->borderWidth = stuff->borderWidth; 86905b261ecSmrg pAttr->class = stuff->c_class; 87005b261ecSmrg pAttr->depth = depth; 87105b261ecSmrg pAttr->visual = visual; 87205b261ecSmrg pAttr->colormap = None; 87305b261ecSmrg pAttr->pCursor = NullCursor; 87405b261ecSmrg pAttr->pBackgroundPixmap = NullPixmap; 87505b261ecSmrg pAttr->pBorderPixmap = NullPixmap; 87605b261ecSmrg /* 87705b261ecSmrg * go through the mask, checking the values, 87805b261ecSmrg * looking up pixmaps and cursors and hold a reference 87905b261ecSmrg * to them. 88005b261ecSmrg */ 88105b261ecSmrg pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; 88205b261ecSmrg pVlist = (unsigned int *) (stuff + 1); 88305b261ecSmrg while (tmask) { 88435c4bbdfSmrg imask = lowbit(tmask); 88535c4bbdfSmrg tmask &= ~imask; 88635c4bbdfSmrg switch (imask) { 88735c4bbdfSmrg case CWBackPixmap: 88835c4bbdfSmrg pixID = (Pixmap) * pVlist; 88935c4bbdfSmrg if (pixID == None) { 89035c4bbdfSmrg *values++ = None; 89135c4bbdfSmrg } 89235c4bbdfSmrg else if (pixID == ParentRelative) { 89335c4bbdfSmrg if (depth != pParent->drawable.depth) { 89435c4bbdfSmrg ret = BadMatch; 89535c4bbdfSmrg goto PatchUp; 89635c4bbdfSmrg } 89735c4bbdfSmrg *values++ = ParentRelative; 89835c4bbdfSmrg } 89935c4bbdfSmrg else { 90035c4bbdfSmrg ret = 90135c4bbdfSmrg dixLookupResourceByType((void **) &pPixmap, pixID, 90235c4bbdfSmrg RT_PIXMAP, client, DixReadAccess); 90335c4bbdfSmrg if (ret == Success) { 90435c4bbdfSmrg if ((pPixmap->drawable.depth != depth) || 90535c4bbdfSmrg (pPixmap->drawable.pScreen != pScreen)) { 90635c4bbdfSmrg ret = BadMatch; 90735c4bbdfSmrg goto PatchUp; 90835c4bbdfSmrg } 90935c4bbdfSmrg pAttr->pBackgroundPixmap = pPixmap; 91035c4bbdfSmrg pPixmap->refcnt++; 91135c4bbdfSmrg pAttr->mask &= ~CWBackPixmap; 91235c4bbdfSmrg } 91335c4bbdfSmrg else { 91435c4bbdfSmrg client->errorValue = pixID; 91535c4bbdfSmrg goto PatchUp; 91635c4bbdfSmrg } 91735c4bbdfSmrg } 91835c4bbdfSmrg break; 91935c4bbdfSmrg case CWBackPixel: 92035c4bbdfSmrg *values++ = (CARD32) *pVlist; 92135c4bbdfSmrg break; 92235c4bbdfSmrg case CWBorderPixmap: 92335c4bbdfSmrg pixID = (Pixmap) * pVlist; 92435c4bbdfSmrg if (pixID == CopyFromParent) { 92535c4bbdfSmrg if (depth != pParent->drawable.depth) { 92635c4bbdfSmrg ret = BadMatch; 92735c4bbdfSmrg goto PatchUp; 92835c4bbdfSmrg } 92935c4bbdfSmrg *values++ = CopyFromParent; 93035c4bbdfSmrg } 93135c4bbdfSmrg else { 93235c4bbdfSmrg ret = 93335c4bbdfSmrg dixLookupResourceByType((void **) &pPixmap, pixID, 93435c4bbdfSmrg RT_PIXMAP, client, DixReadAccess); 93535c4bbdfSmrg if (ret == Success) { 93635c4bbdfSmrg if ((pPixmap->drawable.depth != depth) || 93735c4bbdfSmrg (pPixmap->drawable.pScreen != pScreen)) { 93805b261ecSmrg ret = BadMatch; 93935c4bbdfSmrg goto PatchUp; 94035c4bbdfSmrg } 94135c4bbdfSmrg pAttr->pBorderPixmap = pPixmap; 94235c4bbdfSmrg pPixmap->refcnt++; 94335c4bbdfSmrg pAttr->mask &= ~CWBorderPixmap; 94435c4bbdfSmrg } 94535c4bbdfSmrg else { 94635c4bbdfSmrg client->errorValue = pixID; 94735c4bbdfSmrg goto PatchUp; 94835c4bbdfSmrg } 94935c4bbdfSmrg } 95035c4bbdfSmrg break; 95135c4bbdfSmrg case CWBorderPixel: 95235c4bbdfSmrg *values++ = (CARD32) *pVlist; 95335c4bbdfSmrg break; 95435c4bbdfSmrg case CWBitGravity: 95535c4bbdfSmrg val = (CARD8) *pVlist; 95635c4bbdfSmrg if (val > StaticGravity) { 95735c4bbdfSmrg ret = BadValue; 95835c4bbdfSmrg client->errorValue = val; 95935c4bbdfSmrg goto PatchUp; 96035c4bbdfSmrg } 96135c4bbdfSmrg *values++ = val; 96235c4bbdfSmrg break; 96335c4bbdfSmrg case CWWinGravity: 96435c4bbdfSmrg val = (CARD8) *pVlist; 96535c4bbdfSmrg if (val > StaticGravity) { 96635c4bbdfSmrg ret = BadValue; 96735c4bbdfSmrg client->errorValue = val; 96835c4bbdfSmrg goto PatchUp; 96935c4bbdfSmrg } 97035c4bbdfSmrg *values++ = val; 97135c4bbdfSmrg break; 97235c4bbdfSmrg case CWBackingStore: 97335c4bbdfSmrg val = (CARD8) *pVlist; 97435c4bbdfSmrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) { 97535c4bbdfSmrg ret = BadValue; 97635c4bbdfSmrg client->errorValue = val; 97735c4bbdfSmrg goto PatchUp; 97835c4bbdfSmrg } 97935c4bbdfSmrg *values++ = val; 98035c4bbdfSmrg break; 98135c4bbdfSmrg case CWBackingPlanes: 98235c4bbdfSmrg *values++ = (CARD32) *pVlist; 98335c4bbdfSmrg break; 98435c4bbdfSmrg case CWBackingPixel: 98505b261ecSmrg *values++ = (CARD32) *pVlist; 98605b261ecSmrg break; 98735c4bbdfSmrg case CWSaveUnder: 98835c4bbdfSmrg val = (BOOL) * pVlist; 98935c4bbdfSmrg if ((val != xTrue) && (val != xFalse)) { 99035c4bbdfSmrg ret = BadValue; 99135c4bbdfSmrg client->errorValue = val; 99235c4bbdfSmrg goto PatchUp; 99335c4bbdfSmrg } 99435c4bbdfSmrg *values++ = val; 99535c4bbdfSmrg break; 99635c4bbdfSmrg case CWEventMask: 99735c4bbdfSmrg *values++ = (CARD32) *pVlist; 99835c4bbdfSmrg break; 99935c4bbdfSmrg case CWDontPropagate: 100035c4bbdfSmrg *values++ = (CARD32) *pVlist; 100135c4bbdfSmrg break; 100235c4bbdfSmrg case CWOverrideRedirect: 100335c4bbdfSmrg if (!(stuff->mask & CWOverrideRedirect)) 100435c4bbdfSmrg pVlist--; 100535c4bbdfSmrg else { 100635c4bbdfSmrg val = (BOOL) * pVlist; 100735c4bbdfSmrg if ((val != xTrue) && (val != xFalse)) { 100835c4bbdfSmrg ret = BadValue; 100935c4bbdfSmrg client->errorValue = val; 101035c4bbdfSmrg goto PatchUp; 101135c4bbdfSmrg } 101235c4bbdfSmrg } 101335c4bbdfSmrg *values++ = xTrue; 101435c4bbdfSmrg break; 101535c4bbdfSmrg case CWColormap: 101635c4bbdfSmrg cmap = (Colormap) * pVlist; 101735c4bbdfSmrg ret = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP, 101835c4bbdfSmrg client, DixUseAccess); 101935c4bbdfSmrg if (ret != Success) { 102035c4bbdfSmrg client->errorValue = cmap; 102135c4bbdfSmrg goto PatchUp; 102235c4bbdfSmrg } 102335c4bbdfSmrg if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) { 102435c4bbdfSmrg ret = BadMatch; 102535c4bbdfSmrg goto PatchUp; 102635c4bbdfSmrg } 102735c4bbdfSmrg pAttr->colormap = cmap; 102835c4bbdfSmrg pAttr->mask &= ~CWColormap; 102935c4bbdfSmrg break; 103035c4bbdfSmrg case CWCursor: 103135c4bbdfSmrg cursorID = (Cursor) * pVlist; 103235c4bbdfSmrg if (cursorID == None) { 103335c4bbdfSmrg *values++ = None; 103435c4bbdfSmrg } 103535c4bbdfSmrg else { 103635c4bbdfSmrg ret = dixLookupResourceByType((void **) &pCursor, cursorID, 103735c4bbdfSmrg RT_CURSOR, client, DixUseAccess); 103835c4bbdfSmrg if (ret != Success) { 103935c4bbdfSmrg client->errorValue = cursorID; 104035c4bbdfSmrg goto PatchUp; 104135c4bbdfSmrg } 104235c4bbdfSmrg pAttr->pCursor = RefCursor(pCursor); 104335c4bbdfSmrg pAttr->mask &= ~CWCursor; 104435c4bbdfSmrg } 104535c4bbdfSmrg break; 104635c4bbdfSmrg default: 104735c4bbdfSmrg ret = BadValue; 104835c4bbdfSmrg client->errorValue = stuff->mask; 104935c4bbdfSmrg goto PatchUp; 105035c4bbdfSmrg } 105135c4bbdfSmrg pVlist++; 105205b261ecSmrg } 105305b261ecSmrg if (pPriv->attr) 105435c4bbdfSmrg FreeScreenAttr(pPriv->attr); 105505b261ecSmrg pPriv->attr = pAttr; 105635c4bbdfSmrg pAttr->resource = FakeClientID(client->index); 105735c4bbdfSmrg if (!AddResource(pAttr->resource, AttrType, (void *) pAttr)) 105835c4bbdfSmrg return BadAlloc; 105905b261ecSmrg return Success; 106035c4bbdfSmrg PatchUp: 106135c4bbdfSmrg FreeAttrs(pAttr); 106235c4bbdfSmrg bail: 106335c4bbdfSmrg CheckScreenPrivate(pScreen); 106435c4bbdfSmrg if (pAttr) 106535c4bbdfSmrg free(pAttr->values); 10666747b715Smrg free(pAttr); 106705b261ecSmrg return ret; 106805b261ecSmrg} 106905b261ecSmrg 107005b261ecSmrgstatic int 107135c4bbdfSmrgScreenSaverUnsetAttributes(ClientPtr client) 107205b261ecSmrg{ 107305b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 107435c4bbdfSmrg DrawablePtr pDraw; 107535c4bbdfSmrg ScreenSaverScreenPrivatePtr pPriv; 107635c4bbdfSmrg int rc; 107705b261ecSmrg 107835c4bbdfSmrg REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 107905b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 108035c4bbdfSmrg DixGetAttrAccess); 108105b261ecSmrg if (rc != Success) 108235c4bbdfSmrg return rc; 108335c4bbdfSmrg pPriv = GetScreenPrivate(pDraw->pScreen); 108435c4bbdfSmrg if (pPriv && pPriv->attr && pPriv->attr->client == client) { 108535c4bbdfSmrg FreeResource(pPriv->attr->resource, AttrType); 108635c4bbdfSmrg FreeScreenAttr(pPriv->attr); 108735c4bbdfSmrg pPriv->attr = NULL; 108835c4bbdfSmrg CheckScreenPrivate(pDraw->pScreen); 108905b261ecSmrg } 109005b261ecSmrg return Success; 109105b261ecSmrg} 109205b261ecSmrg 109305b261ecSmrgstatic int 109435c4bbdfSmrgProcScreenSaverSetAttributes(ClientPtr client) 109505b261ecSmrg{ 109605b261ecSmrg#ifdef PANORAMIX 109735c4bbdfSmrg if (!noPanoramiXExtension) { 109835c4bbdfSmrg REQUEST(xScreenSaverSetAttributesReq); 109935c4bbdfSmrg PanoramiXRes *draw; 110035c4bbdfSmrg PanoramiXRes *backPix = NULL; 110135c4bbdfSmrg PanoramiXRes *bordPix = NULL; 110235c4bbdfSmrg PanoramiXRes *cmap = NULL; 110335c4bbdfSmrg int i, status, len; 110435c4bbdfSmrg int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; 110535c4bbdfSmrg XID orig_visual, tmp; 110635c4bbdfSmrg 110735c4bbdfSmrg REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 110835c4bbdfSmrg 110935c4bbdfSmrg status = dixLookupResourceByClass((void **) &draw, stuff->drawable, 111035c4bbdfSmrg XRC_DRAWABLE, client, DixWriteAccess); 111135c4bbdfSmrg if (status != Success) 111235c4bbdfSmrg return (status == BadValue) ? BadDrawable : status; 111335c4bbdfSmrg 111435c4bbdfSmrg len = 111535c4bbdfSmrg stuff->length - 111635c4bbdfSmrg bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 111735c4bbdfSmrg if (Ones(stuff->mask) != len) 111835c4bbdfSmrg return BadLength; 111935c4bbdfSmrg 112035c4bbdfSmrg if ((Mask) stuff->mask & CWBackPixmap) { 112135c4bbdfSmrg pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1)); 112235c4bbdfSmrg tmp = *((CARD32 *) &stuff[1] + pback_offset); 112335c4bbdfSmrg if ((tmp != None) && (tmp != ParentRelative)) { 112435c4bbdfSmrg status = dixLookupResourceByType((void **) &backPix, tmp, 112535c4bbdfSmrg XRT_PIXMAP, client, 112635c4bbdfSmrg DixReadAccess); 112735c4bbdfSmrg if (status != Success) 112835c4bbdfSmrg return status; 112935c4bbdfSmrg } 113035c4bbdfSmrg } 113135c4bbdfSmrg 113235c4bbdfSmrg if ((Mask) stuff->mask & CWBorderPixmap) { 113335c4bbdfSmrg pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1)); 113435c4bbdfSmrg tmp = *((CARD32 *) &stuff[1] + pbord_offset); 113535c4bbdfSmrg if (tmp != CopyFromParent) { 113635c4bbdfSmrg status = dixLookupResourceByType((void **) &bordPix, tmp, 113735c4bbdfSmrg XRT_PIXMAP, client, 113835c4bbdfSmrg DixReadAccess); 113935c4bbdfSmrg if (status != Success) 114035c4bbdfSmrg return status; 114135c4bbdfSmrg } 114235c4bbdfSmrg } 114335c4bbdfSmrg 114435c4bbdfSmrg if ((Mask) stuff->mask & CWColormap) { 114535c4bbdfSmrg cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1)); 114635c4bbdfSmrg tmp = *((CARD32 *) &stuff[1] + cmap_offset); 114735c4bbdfSmrg if (tmp != CopyFromParent) { 114835c4bbdfSmrg status = dixLookupResourceByType((void **) &cmap, tmp, 114935c4bbdfSmrg XRT_COLORMAP, client, 115035c4bbdfSmrg DixReadAccess); 115135c4bbdfSmrg if (status != Success) 115235c4bbdfSmrg return status; 115335c4bbdfSmrg } 115435c4bbdfSmrg } 115535c4bbdfSmrg 115635c4bbdfSmrg orig_visual = stuff->visualID; 115735c4bbdfSmrg 115835c4bbdfSmrg FOR_NSCREENS_BACKWARD(i) { 115935c4bbdfSmrg stuff->drawable = draw->info[i].id; 116035c4bbdfSmrg if (backPix) 116135c4bbdfSmrg *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; 116235c4bbdfSmrg if (bordPix) 116335c4bbdfSmrg *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; 116435c4bbdfSmrg if (cmap) 116535c4bbdfSmrg *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; 116635c4bbdfSmrg 116735c4bbdfSmrg if (orig_visual != CopyFromParent) 116835c4bbdfSmrg stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); 116935c4bbdfSmrg 117035c4bbdfSmrg status = ScreenSaverSetAttributes(client); 117135c4bbdfSmrg } 117235c4bbdfSmrg 117335c4bbdfSmrg return status; 117405b261ecSmrg } 117505b261ecSmrg#endif 117605b261ecSmrg 117705b261ecSmrg return ScreenSaverSetAttributes(client); 117805b261ecSmrg} 117905b261ecSmrg 118005b261ecSmrgstatic int 118135c4bbdfSmrgProcScreenSaverUnsetAttributes(ClientPtr client) 118205b261ecSmrg{ 118305b261ecSmrg#ifdef PANORAMIX 118435c4bbdfSmrg if (!noPanoramiXExtension) { 118535c4bbdfSmrg REQUEST(xScreenSaverUnsetAttributesReq); 118635c4bbdfSmrg PanoramiXRes *draw; 118735c4bbdfSmrg int rc, i; 118805b261ecSmrg 11896e78d31fSmrg REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 11906e78d31fSmrg 119135c4bbdfSmrg rc = dixLookupResourceByClass((void **) &draw, stuff->drawable, 119235c4bbdfSmrg XRC_DRAWABLE, client, DixWriteAccess); 119335c4bbdfSmrg if (rc != Success) 119435c4bbdfSmrg return (rc == BadValue) ? BadDrawable : rc; 119505b261ecSmrg 119635c4bbdfSmrg for (i = PanoramiXNumScreens - 1; i > 0; i--) { 119705b261ecSmrg stuff->drawable = draw->info[i].id; 119805b261ecSmrg ScreenSaverUnsetAttributes(client); 119935c4bbdfSmrg } 120005b261ecSmrg 120135c4bbdfSmrg stuff->drawable = draw->info[0].id; 120205b261ecSmrg } 120305b261ecSmrg#endif 120405b261ecSmrg 120505b261ecSmrg return ScreenSaverUnsetAttributes(client); 120605b261ecSmrg} 120705b261ecSmrg 120805b261ecSmrgstatic int 120935c4bbdfSmrgProcScreenSaverSuspend(ClientPtr client) 121005b261ecSmrg{ 121105b261ecSmrg ScreenSaverSuspensionPtr *prev, this; 12127e31ba66Smrg BOOL suspend; 121305b261ecSmrg 121405b261ecSmrg REQUEST(xScreenSaverSuspendReq); 121505b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 121605b261ecSmrg 12177e31ba66Smrg /* 12187e31ba66Smrg * Old versions of XCB encode suspend as 1 byte followed by three 12197e31ba66Smrg * pad bytes (which are always cleared), instead of a 4 byte 12207e31ba66Smrg * value. Be compatible by just checking for a non-zero value in 12217e31ba66Smrg * all 32-bits. 12227e31ba66Smrg */ 12237e31ba66Smrg suspend = stuff->suspend != 0; 12247e31ba66Smrg 122505b261ecSmrg /* Check if this client is suspending the screensaver */ 122605b261ecSmrg for (prev = &suspendingClients; (this = *prev); prev = &this->next) 122735c4bbdfSmrg if (this->pClient == client) 122835c4bbdfSmrg break; 122905b261ecSmrg 123035c4bbdfSmrg if (this) { 12317e31ba66Smrg if (suspend == TRUE) 123235c4bbdfSmrg this->count++; 123335c4bbdfSmrg else if (--this->count == 0) 123435c4bbdfSmrg FreeResource(this->clientResource, RT_NONE); 123505b261ecSmrg 123635c4bbdfSmrg return Success; 123705b261ecSmrg } 123805b261ecSmrg 123905b261ecSmrg /* If we get to this point, this client isn't suspending the screensaver */ 12407e31ba66Smrg if (suspend == FALSE) 124135c4bbdfSmrg return Success; 124205b261ecSmrg 124305b261ecSmrg /* 124405b261ecSmrg * Allocate a suspension record for the client, and stop the screensaver 124505b261ecSmrg * if it isn't already suspended by another client. We attach a resource ID 12465a112b11Smrg * to the record, so the screensaver will be re-enabled and the record freed 124705b261ecSmrg * if the client disconnects without reenabling it first. 124805b261ecSmrg */ 124935c4bbdfSmrg this = malloc(sizeof(ScreenSaverSuspensionRec)); 125005b261ecSmrg 125105b261ecSmrg if (!this) 125235c4bbdfSmrg return BadAlloc; 125305b261ecSmrg 125435c4bbdfSmrg this->next = NULL; 125535c4bbdfSmrg this->pClient = client; 125635c4bbdfSmrg this->count = 1; 125735c4bbdfSmrg this->clientResource = FakeClientID(client->index); 125805b261ecSmrg 125935c4bbdfSmrg if (!AddResource(this->clientResource, SuspendType, (void *) this)) { 126035c4bbdfSmrg free(this); 126135c4bbdfSmrg return BadAlloc; 126205b261ecSmrg } 126305b261ecSmrg 126405b261ecSmrg *prev = this; 126535c4bbdfSmrg if (!screenSaverSuspended) { 126635c4bbdfSmrg screenSaverSuspended = TRUE; 126735c4bbdfSmrg FreeScreenSaverTimer(); 126805b261ecSmrg } 126905b261ecSmrg 12706747b715Smrg return Success; 127105b261ecSmrg} 127205b261ecSmrg 127335c4bbdfSmrgstatic int (*NormalVector[]) (ClientPtr /* client */ ) = { 127435c4bbdfSmrgProcScreenSaverQueryVersion, 127535c4bbdfSmrg ProcScreenSaverQueryInfo, 127635c4bbdfSmrg ProcScreenSaverSelectInput, 127735c4bbdfSmrg ProcScreenSaverSetAttributes, 127835c4bbdfSmrg ProcScreenSaverUnsetAttributes, ProcScreenSaverSuspend,}; 127905b261ecSmrg 128005b261ecSmrgstatic int 128135c4bbdfSmrgProcScreenSaverDispatch(ClientPtr client) 128205b261ecSmrg{ 128305b261ecSmrg REQUEST(xReq); 128405b261ecSmrg 12857e31ba66Smrg if (stuff->data < ARRAY_SIZE(NormalVector)) 128635c4bbdfSmrg return (*NormalVector[stuff->data]) (client); 128705b261ecSmrg return BadRequest; 128805b261ecSmrg} 128905b261ecSmrg 12907e31ba66Smrgstatic int _X_COLD 129135c4bbdfSmrgSProcScreenSaverQueryVersion(ClientPtr client) 129205b261ecSmrg{ 129305b261ecSmrg REQUEST(xScreenSaverQueryVersionReq); 129435c4bbdfSmrg swaps(&stuff->length); 129505b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 129635c4bbdfSmrg return ProcScreenSaverQueryVersion(client); 129705b261ecSmrg} 129805b261ecSmrg 12997e31ba66Smrgstatic int _X_COLD 130035c4bbdfSmrgSProcScreenSaverQueryInfo(ClientPtr client) 130105b261ecSmrg{ 130205b261ecSmrg REQUEST(xScreenSaverQueryInfoReq); 130335c4bbdfSmrg swaps(&stuff->length); 130405b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 130535c4bbdfSmrg swapl(&stuff->drawable); 130635c4bbdfSmrg return ProcScreenSaverQueryInfo(client); 130705b261ecSmrg} 130805b261ecSmrg 13097e31ba66Smrgstatic int _X_COLD 131035c4bbdfSmrgSProcScreenSaverSelectInput(ClientPtr client) 131105b261ecSmrg{ 131205b261ecSmrg REQUEST(xScreenSaverSelectInputReq); 131335c4bbdfSmrg swaps(&stuff->length); 131405b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 131535c4bbdfSmrg swapl(&stuff->drawable); 131635c4bbdfSmrg swapl(&stuff->eventMask); 131735c4bbdfSmrg return ProcScreenSaverSelectInput(client); 131805b261ecSmrg} 131905b261ecSmrg 13207e31ba66Smrgstatic int _X_COLD 132135c4bbdfSmrgSProcScreenSaverSetAttributes(ClientPtr client) 132205b261ecSmrg{ 132305b261ecSmrg REQUEST(xScreenSaverSetAttributesReq); 132435c4bbdfSmrg swaps(&stuff->length); 132505b261ecSmrg REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 132635c4bbdfSmrg swapl(&stuff->drawable); 132735c4bbdfSmrg swaps(&stuff->x); 132835c4bbdfSmrg swaps(&stuff->y); 132935c4bbdfSmrg swaps(&stuff->width); 133035c4bbdfSmrg swaps(&stuff->height); 133135c4bbdfSmrg swaps(&stuff->borderWidth); 133235c4bbdfSmrg swapl(&stuff->visualID); 133335c4bbdfSmrg swapl(&stuff->mask); 133405b261ecSmrg SwapRestL(stuff); 133535c4bbdfSmrg return ProcScreenSaverSetAttributes(client); 133605b261ecSmrg} 133705b261ecSmrg 13387e31ba66Smrgstatic int _X_COLD 133935c4bbdfSmrgSProcScreenSaverUnsetAttributes(ClientPtr client) 134005b261ecSmrg{ 134105b261ecSmrg REQUEST(xScreenSaverUnsetAttributesReq); 134235c4bbdfSmrg swaps(&stuff->length); 134305b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 134435c4bbdfSmrg swapl(&stuff->drawable); 134535c4bbdfSmrg return ProcScreenSaverUnsetAttributes(client); 134605b261ecSmrg} 134705b261ecSmrg 13487e31ba66Smrgstatic int _X_COLD 134935c4bbdfSmrgSProcScreenSaverSuspend(ClientPtr client) 135005b261ecSmrg{ 135105b261ecSmrg REQUEST(xScreenSaverSuspendReq); 135205b261ecSmrg 135335c4bbdfSmrg swaps(&stuff->length); 135405b261ecSmrg REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 13555a112b11Smrg swapl(&stuff->suspend); 135635c4bbdfSmrg return ProcScreenSaverSuspend(client); 135705b261ecSmrg} 135805b261ecSmrg 135935c4bbdfSmrgstatic int (*SwappedVector[]) (ClientPtr /* client */ ) = { 136035c4bbdfSmrgSProcScreenSaverQueryVersion, 136135c4bbdfSmrg SProcScreenSaverQueryInfo, 136235c4bbdfSmrg SProcScreenSaverSelectInput, 136335c4bbdfSmrg SProcScreenSaverSetAttributes, 136435c4bbdfSmrg SProcScreenSaverUnsetAttributes, SProcScreenSaverSuspend,}; 136505b261ecSmrg 13667e31ba66Smrgstatic int _X_COLD 136735c4bbdfSmrgSProcScreenSaverDispatch(ClientPtr client) 136805b261ecSmrg{ 136905b261ecSmrg REQUEST(xReq); 137005b261ecSmrg 13717e31ba66Smrg if (stuff->data < ARRAY_SIZE(NormalVector)) 137235c4bbdfSmrg return (*SwappedVector[stuff->data]) (client); 137305b261ecSmrg return BadRequest; 137405b261ecSmrg} 13759ace9065Smrg 13769ace9065Smrgvoid 137735c4bbdfSmrgScreenSaverExtensionInit(void) 13789ace9065Smrg{ 13799ace9065Smrg ExtensionEntry *extEntry; 138035c4bbdfSmrg int i; 138135c4bbdfSmrg ScreenPtr pScreen; 13829ace9065Smrg 13839ace9065Smrg if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 138435c4bbdfSmrg return; 13859ace9065Smrg 13869ace9065Smrg AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr"); 138735c4bbdfSmrg SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, "SaverEvent"); 138835c4bbdfSmrg SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, "SaverSuspend"); 138935c4bbdfSmrg 139035c4bbdfSmrg for (i = 0; i < screenInfo.numScreens; i++) { 139135c4bbdfSmrg pScreen = screenInfo.screens[i]; 139235c4bbdfSmrg SetScreenPrivate(pScreen, NULL); 13939ace9065Smrg } 13949ace9065Smrg if (AttrType && SaverEventType && SuspendType && 139535c4bbdfSmrg (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, 139635c4bbdfSmrg ProcScreenSaverDispatch, 139735c4bbdfSmrg SProcScreenSaverDispatch, NULL, 139835c4bbdfSmrg StandardMinorOpcode))) { 139935c4bbdfSmrg ScreenSaverEventBase = extEntry->eventBase; 140035c4bbdfSmrg EventSwapVector[ScreenSaverEventBase] = 140135c4bbdfSmrg (EventSwapPtr) SScreenSaverNotifyEvent; 14029ace9065Smrg } 14039ace9065Smrg} 1404