saver.c revision 6e78d31f
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>
5605b261ecSmrg#endif
576747b715Smrg#include "protocol-versions.h"
5805b261ecSmrg
5905b261ecSmrg#include <stdio.h>
6005b261ecSmrg
6135c4bbdfSmrg#include "extinit.h"
6205b261ecSmrg
6305b261ecSmrgstatic int ScreenSaverEventBase = 0;
6405b261ecSmrg
6535c4bbdfSmrgstatic Bool ScreenSaverHandle(ScreenPtr /* pScreen */ ,
6635c4bbdfSmrg                              int /* xstate */ ,
6735c4bbdfSmrg                              Bool      /* force */
6835c4bbdfSmrg    );
6905b261ecSmrg
7005b261ecSmrgstatic Bool
7135c4bbdfSmrg CreateSaverWindow(ScreenPtr    /* pScreen */
7235c4bbdfSmrg    );
7305b261ecSmrg
7405b261ecSmrgstatic Bool
7535c4bbdfSmrg DestroySaverWindow(ScreenPtr   /* pScreen */
7635c4bbdfSmrg    );
7705b261ecSmrg
7805b261ecSmrgstatic void
7935c4bbdfSmrg UninstallSaverColormap(ScreenPtr       /* pScreen */
8035c4bbdfSmrg    );
8105b261ecSmrg
8205b261ecSmrgstatic void
8335c4bbdfSmrg CheckScreenPrivate(ScreenPtr   /* pScreen */
8435c4bbdfSmrg    );
8505b261ecSmrg
8635c4bbdfSmrgstatic void SScreenSaverNotifyEvent(xScreenSaverNotifyEvent * /* from */ ,
8735c4bbdfSmrg                                    xScreenSaverNotifyEvent *   /* to */
8835c4bbdfSmrg    );
8905b261ecSmrg
9035c4bbdfSmrgstatic RESTYPE SuspendType;     /* resource type for suspension records */
9105b261ecSmrg
9205b261ecSmrgtypedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr;
9305b261ecSmrg
9405b261ecSmrg/* List of clients that are suspending the screensaver. */
9505b261ecSmrgstatic ScreenSaverSuspensionPtr suspendingClients = NULL;
9605b261ecSmrg
9705b261ecSmrg/*
9805b261ecSmrg * clientResource is a resource ID that's added when the record is
9905b261ecSmrg * allocated, so the record is freed and the screensaver resumed when
10005b261ecSmrg * the client disconnects. count is the number of times the client has
10105b261ecSmrg * requested the screensaver be suspended.
10205b261ecSmrg */
10335c4bbdfSmrgtypedef struct _ScreenSaverSuspension {
10435c4bbdfSmrg    ScreenSaverSuspensionPtr next;
10535c4bbdfSmrg    ClientPtr pClient;
10635c4bbdfSmrg    XID clientResource;
10735c4bbdfSmrg    int count;
10805b261ecSmrg} ScreenSaverSuspensionRec;
10905b261ecSmrg
11035c4bbdfSmrgstatic int ScreenSaverFreeSuspend(void *value, XID id);
11105b261ecSmrg
11205b261ecSmrg/*
11305b261ecSmrg * each screen has a list of clients requesting
11405b261ecSmrg * ScreenSaverNotify events.  Each client has a resource
11505b261ecSmrg * for each screen it selects ScreenSaverNotify input for,
11605b261ecSmrg * this resource is used to delete the ScreenSaverNotifyRec
11705b261ecSmrg * entry from the per-screen queue.
11805b261ecSmrg */
11905b261ecSmrg
12035c4bbdfSmrgstatic RESTYPE SaverEventType;  /* resource type for event masks */
12105b261ecSmrg
12205b261ecSmrgtypedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
12305b261ecSmrg
12405b261ecSmrgtypedef struct _ScreenSaverEvent {
12535c4bbdfSmrg    ScreenSaverEventPtr next;
12635c4bbdfSmrg    ClientPtr client;
12735c4bbdfSmrg    ScreenPtr screen;
12835c4bbdfSmrg    XID resource;
12935c4bbdfSmrg    CARD32 mask;
13005b261ecSmrg} ScreenSaverEventRec;
13105b261ecSmrg
13235c4bbdfSmrgstatic int ScreenSaverFreeEvents(void * value, XID id);
13305b261ecSmrg
13435c4bbdfSmrgstatic Bool setEventMask(ScreenPtr      pScreen,
13535c4bbdfSmrg                         ClientPtr      client,
13635c4bbdfSmrg                         unsigned long  mask);
13705b261ecSmrg
13835c4bbdfSmrgstatic unsigned long getEventMask(ScreenPtr     pScreen,
13935c4bbdfSmrg                                  ClientPtr     client);
14005b261ecSmrg
14105b261ecSmrg/*
14205b261ecSmrg * when a client sets the screen saver attributes, a resource is
14305b261ecSmrg * kept to be freed when the client exits
14405b261ecSmrg */
14505b261ecSmrg
14635c4bbdfSmrgstatic RESTYPE AttrType;        /* resource type for attributes */
14705b261ecSmrg
14805b261ecSmrgtypedef struct _ScreenSaverAttr {
14935c4bbdfSmrg    ScreenPtr screen;
15035c4bbdfSmrg    ClientPtr client;
15135c4bbdfSmrg    XID resource;
15235c4bbdfSmrg    short x, y;
15335c4bbdfSmrg    unsigned short width, height, borderWidth;
15435c4bbdfSmrg    unsigned char class;
15535c4bbdfSmrg    unsigned char depth;
15635c4bbdfSmrg    VisualID visual;
15735c4bbdfSmrg    CursorPtr pCursor;
15835c4bbdfSmrg    PixmapPtr pBackgroundPixmap;
15935c4bbdfSmrg    PixmapPtr pBorderPixmap;
16035c4bbdfSmrg    Colormap colormap;
16135c4bbdfSmrg    unsigned long mask;         /* no pixmaps or cursors */
16235c4bbdfSmrg    unsigned long *values;
16305b261ecSmrg} ScreenSaverAttrRec, *ScreenSaverAttrPtr;
16405b261ecSmrg
16535c4bbdfSmrgstatic int ScreenSaverFreeAttr(void *value, XID id);
16605b261ecSmrg
16735c4bbdfSmrgstatic void FreeAttrs(ScreenSaverAttrPtr pAttr);
16805b261ecSmrg
16935c4bbdfSmrgstatic void FreeScreenAttr(ScreenSaverAttrPtr pAttr);
17005b261ecSmrg
17105b261ecSmrgstatic void
17235c4bbdfSmrgSendScreenSaverNotify(ScreenPtr pScreen,
17335c4bbdfSmrg                      int       state,
17435c4bbdfSmrg                      Bool      forced);
17505b261ecSmrg
17605b261ecSmrgtypedef struct _ScreenSaverScreenPrivate {
17735c4bbdfSmrg    ScreenSaverEventPtr events;
17835c4bbdfSmrg    ScreenSaverAttrPtr attr;
17935c4bbdfSmrg    Bool hasWindow;
18035c4bbdfSmrg    Colormap installedMap;
18105b261ecSmrg} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
18205b261ecSmrg
18335c4bbdfSmrgstatic ScreenSaverScreenPrivatePtr MakeScreenPrivate(ScreenPtr pScreen);
18405b261ecSmrg
1856747b715Smrgstatic DevPrivateKeyRec ScreenPrivateKeyRec;
18635c4bbdfSmrg
1876747b715Smrg#define ScreenPrivateKey (&ScreenPrivateKeyRec)
18805b261ecSmrg
1894642e01fSmrg#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
1904642e01fSmrg    dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
1914642e01fSmrg#define SetScreenPrivate(s,v) \
1924642e01fSmrg    dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v);
19305b261ecSmrg#define SetupScreen(s)	ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
19405b261ecSmrg
1956747b715Smrg#define New(t)	(malloc(sizeof (t)))
19605b261ecSmrg
19705b261ecSmrgstatic void
19835c4bbdfSmrgCheckScreenPrivate(ScreenPtr pScreen)
19905b261ecSmrg{
20035c4bbdfSmrg    SetupScreen(pScreen);
20105b261ecSmrg
20205b261ecSmrg    if (!pPriv)
20335c4bbdfSmrg        return;
20405b261ecSmrg    if (!pPriv->attr && !pPriv->events &&
20535c4bbdfSmrg        !pPriv->hasWindow && pPriv->installedMap == None) {
20635c4bbdfSmrg        free(pPriv);
20735c4bbdfSmrg        SetScreenPrivate(pScreen, NULL);
20835c4bbdfSmrg        pScreen->screensaver.ExternalScreenSaver = NULL;
20905b261ecSmrg    }
21005b261ecSmrg}
21105b261ecSmrg
21205b261ecSmrgstatic ScreenSaverScreenPrivatePtr
21335c4bbdfSmrgMakeScreenPrivate(ScreenPtr pScreen)
21405b261ecSmrg{
21535c4bbdfSmrg    SetupScreen(pScreen);
21605b261ecSmrg
21705b261ecSmrg    if (pPriv)
21835c4bbdfSmrg        return pPriv;
21935c4bbdfSmrg    pPriv = New(ScreenSaverScreenPrivateRec);
22005b261ecSmrg    if (!pPriv)
22135c4bbdfSmrg        return 0;
22205b261ecSmrg    pPriv->events = 0;
22305b261ecSmrg    pPriv->attr = 0;
22405b261ecSmrg    pPriv->hasWindow = FALSE;
22505b261ecSmrg    pPriv->installedMap = None;
22635c4bbdfSmrg    SetScreenPrivate(pScreen, pPriv);
2276747b715Smrg    pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle;
22805b261ecSmrg    return pPriv;
22905b261ecSmrg}
23005b261ecSmrg
23105b261ecSmrgstatic unsigned long
23235c4bbdfSmrggetEventMask(ScreenPtr pScreen, ClientPtr client)
23305b261ecSmrg{
23405b261ecSmrg    SetupScreen(pScreen);
23535c4bbdfSmrg    ScreenSaverEventPtr pEv;
23605b261ecSmrg
23705b261ecSmrg    if (!pPriv)
23835c4bbdfSmrg        return 0;
23905b261ecSmrg    for (pEv = pPriv->events; pEv; pEv = pEv->next)
24035c4bbdfSmrg        if (pEv->client == client)
24135c4bbdfSmrg            return pEv->mask;
24205b261ecSmrg    return 0;
24305b261ecSmrg}
24405b261ecSmrg
24505b261ecSmrgstatic Bool
24635c4bbdfSmrgsetEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask)
24705b261ecSmrg{
24805b261ecSmrg    SetupScreen(pScreen);
24935c4bbdfSmrg    ScreenSaverEventPtr pEv, *pPrev;
25035c4bbdfSmrg
25135c4bbdfSmrg    if (getEventMask(pScreen, client) == mask)
25235c4bbdfSmrg        return TRUE;
25335c4bbdfSmrg    if (!pPriv) {
25435c4bbdfSmrg        pPriv = MakeScreenPrivate(pScreen);
25535c4bbdfSmrg        if (!pPriv)
25635c4bbdfSmrg            return FALSE;
25705b261ecSmrg    }
25805b261ecSmrg    for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
25935c4bbdfSmrg        if (pEv->client == client)
26035c4bbdfSmrg            break;
26135c4bbdfSmrg    if (mask == 0) {
26235c4bbdfSmrg        FreeResource(pEv->resource, SaverEventType);
26335c4bbdfSmrg        *pPrev = pEv->next;
26435c4bbdfSmrg        free(pEv);
26535c4bbdfSmrg        CheckScreenPrivate(pScreen);
26605b261ecSmrg    }
26735c4bbdfSmrg    else {
26835c4bbdfSmrg        if (!pEv) {
26935c4bbdfSmrg            pEv = New(ScreenSaverEventRec);
27035c4bbdfSmrg            if (!pEv) {
27135c4bbdfSmrg                CheckScreenPrivate(pScreen);
27235c4bbdfSmrg                return FALSE;
27335c4bbdfSmrg            }
27435c4bbdfSmrg            *pPrev = pEv;
27535c4bbdfSmrg            pEv->next = NULL;
27635c4bbdfSmrg            pEv->client = client;
27735c4bbdfSmrg            pEv->screen = pScreen;
27835c4bbdfSmrg            pEv->resource = FakeClientID(client->index);
27935c4bbdfSmrg            if (!AddResource(pEv->resource, SaverEventType, (void *) pEv))
28035c4bbdfSmrg                return FALSE;
28135c4bbdfSmrg        }
28235c4bbdfSmrg        pEv->mask = mask;
28305b261ecSmrg    }
28405b261ecSmrg    return TRUE;
28505b261ecSmrg}
28605b261ecSmrg
28705b261ecSmrgstatic void
28835c4bbdfSmrgFreeAttrs(ScreenSaverAttrPtr pAttr)
28905b261ecSmrg{
29035c4bbdfSmrg    PixmapPtr pPixmap;
29135c4bbdfSmrg    CursorPtr pCursor;
29205b261ecSmrg
29305b261ecSmrg    if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
29435c4bbdfSmrg        (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
29505b261ecSmrg    if ((pPixmap = pAttr->pBorderPixmap) != 0)
29635c4bbdfSmrg        (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
29705b261ecSmrg    if ((pCursor = pAttr->pCursor) != 0)
29835c4bbdfSmrg        FreeCursor(pCursor, (Cursor) 0);
29905b261ecSmrg}
30005b261ecSmrg
30105b261ecSmrgstatic void
30235c4bbdfSmrgFreeScreenAttr(ScreenSaverAttrPtr pAttr)
30305b261ecSmrg{
30435c4bbdfSmrg    FreeAttrs(pAttr);
3056747b715Smrg    free(pAttr->values);
3066747b715Smrg    free(pAttr);
30705b261ecSmrg}
30805b261ecSmrg
30905b261ecSmrgstatic int
31035c4bbdfSmrgScreenSaverFreeEvents(void *value, XID id)
31105b261ecSmrg{
31235c4bbdfSmrg    ScreenSaverEventPtr pOld = (ScreenSaverEventPtr) value;
31305b261ecSmrg    ScreenPtr pScreen = pOld->screen;
31435c4bbdfSmrg
31535c4bbdfSmrg    SetupScreen(pScreen);
31635c4bbdfSmrg    ScreenSaverEventPtr pEv, *pPrev;
31705b261ecSmrg
31805b261ecSmrg    if (!pPriv)
31935c4bbdfSmrg        return TRUE;
32005b261ecSmrg    for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
32135c4bbdfSmrg        if (pEv == pOld)
32235c4bbdfSmrg            break;
32305b261ecSmrg    if (!pEv)
32435c4bbdfSmrg        return TRUE;
32505b261ecSmrg    *pPrev = pEv->next;
3266747b715Smrg    free(pEv);
32735c4bbdfSmrg    CheckScreenPrivate(pScreen);
32805b261ecSmrg    return TRUE;
32905b261ecSmrg}
33005b261ecSmrg
33105b261ecSmrgstatic int
33235c4bbdfSmrgScreenSaverFreeAttr(void *value, XID id)
33305b261ecSmrg{
33435c4bbdfSmrg    ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr) value;
33535c4bbdfSmrg    ScreenPtr pScreen = pOldAttr->screen;
33635c4bbdfSmrg
33735c4bbdfSmrg    SetupScreen(pScreen);
33805b261ecSmrg
33905b261ecSmrg    if (!pPriv)
34035c4bbdfSmrg        return TRUE;
34105b261ecSmrg    if (pPriv->attr != pOldAttr)
34235c4bbdfSmrg        return TRUE;
34335c4bbdfSmrg    FreeScreenAttr(pOldAttr);
34405b261ecSmrg    pPriv->attr = NULL;
34535c4bbdfSmrg    if (pPriv->hasWindow) {
34635c4bbdfSmrg        dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
34735c4bbdfSmrg        dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
34805b261ecSmrg    }
34935c4bbdfSmrg    CheckScreenPrivate(pScreen);
35005b261ecSmrg    return TRUE;
35105b261ecSmrg}
35205b261ecSmrg
35305b261ecSmrgstatic int
35435c4bbdfSmrgScreenSaverFreeSuspend(void *value, XID id)
35505b261ecSmrg{
35605b261ecSmrg    ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
35705b261ecSmrg    ScreenSaverSuspensionPtr *prev, this;
35805b261ecSmrg
35905b261ecSmrg    /* Unlink and free the suspension record for the client */
36035c4bbdfSmrg    for (prev = &suspendingClients; (this = *prev); prev = &this->next) {
36135c4bbdfSmrg        if (this == data) {
36235c4bbdfSmrg            *prev = this->next;
36335c4bbdfSmrg            free(this);
36435c4bbdfSmrg            break;
36535c4bbdfSmrg        }
36605b261ecSmrg    }
36705b261ecSmrg
36805b261ecSmrg    /* Reenable the screensaver if this was the last client suspending it. */
36935c4bbdfSmrg    if (screenSaverSuspended && suspendingClients == NULL) {
37035c4bbdfSmrg        screenSaverSuspended = FALSE;
37105b261ecSmrg
37235c4bbdfSmrg        /* The screensaver could be active, since suspending it (by design)
37335c4bbdfSmrg           doesn't prevent it from being forceably activated */
37405b261ecSmrg#ifdef DPMSExtension
37535c4bbdfSmrg        if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn)
37605b261ecSmrg#else
37735c4bbdfSmrg        if (screenIsSaved != SCREEN_SAVER_ON)
37805b261ecSmrg#endif
37935c4bbdfSmrg        {
38035c4bbdfSmrg            DeviceIntPtr dev;
38135c4bbdfSmrg            UpdateCurrentTimeIf();
38235c4bbdfSmrg            nt_list_for_each_entry(dev, inputInfo.devices, next)
38335c4bbdfSmrg                NoticeTime(dev, currentTime);
38435c4bbdfSmrg            SetScreenSaverTimer();
38535c4bbdfSmrg        }
38605b261ecSmrg    }
38705b261ecSmrg
38805b261ecSmrg    return Success;
38905b261ecSmrg}
39005b261ecSmrg
39105b261ecSmrgstatic void
39235c4bbdfSmrgSendScreenSaverNotify(ScreenPtr pScreen, int state, Bool forced)
39305b261ecSmrg{
39435c4bbdfSmrg    ScreenSaverScreenPrivatePtr pPriv;
39535c4bbdfSmrg    ScreenSaverEventPtr pEv;
39635c4bbdfSmrg    unsigned long mask;
39735c4bbdfSmrg    int kind;
39805b261ecSmrg
39935c4bbdfSmrg    UpdateCurrentTimeIf();
40005b261ecSmrg    mask = ScreenSaverNotifyMask;
40105b261ecSmrg    if (state == ScreenSaverCycle)
40235c4bbdfSmrg        mask = ScreenSaverCycleMask;
40305b261ecSmrg    pScreen = screenInfo.screens[pScreen->myNum];
40405b261ecSmrg    pPriv = GetScreenPrivate(pScreen);
40505b261ecSmrg    if (!pPriv)
40635c4bbdfSmrg        return;
40705b261ecSmrg    if (pPriv->attr)
40835c4bbdfSmrg        kind = ScreenSaverExternal;
40905b261ecSmrg    else if (ScreenSaverBlanking != DontPreferBlanking)
41035c4bbdfSmrg        kind = ScreenSaverBlanked;
41105b261ecSmrg    else
41235c4bbdfSmrg        kind = ScreenSaverInternal;
41335c4bbdfSmrg    for (pEv = pPriv->events; pEv; pEv = pEv->next) {
41435c4bbdfSmrg        if (pEv->mask & mask) {
41535c4bbdfSmrg            xScreenSaverNotifyEvent ev = {
41635c4bbdfSmrg                .type = ScreenSaverNotify + ScreenSaverEventBase,
41735c4bbdfSmrg                .state = state,
41835c4bbdfSmrg                .timestamp = currentTime.milliseconds,
41935c4bbdfSmrg                .root = pScreen->root->drawable.id,
42035c4bbdfSmrg                .window = pScreen->screensaver.wid,
42135c4bbdfSmrg                .kind = kind,
42235c4bbdfSmrg                .forced = forced
42335c4bbdfSmrg            };
42435c4bbdfSmrg            WriteEventsToClient(pEv->client, 1, (xEvent *) &ev);
42535c4bbdfSmrg        }
42605b261ecSmrg    }
42705b261ecSmrg}
42805b261ecSmrg
42905b261ecSmrgstatic void
43035c4bbdfSmrgSScreenSaverNotifyEvent(xScreenSaverNotifyEvent * from,
43135c4bbdfSmrg                        xScreenSaverNotifyEvent * to)
43205b261ecSmrg{
43305b261ecSmrg    to->type = from->type;
43405b261ecSmrg    to->state = from->state;
43535c4bbdfSmrg    cpswaps(from->sequenceNumber, to->sequenceNumber);
43635c4bbdfSmrg    cpswapl(from->timestamp, to->timestamp);
43735c4bbdfSmrg    cpswapl(from->root, to->root);
43835c4bbdfSmrg    cpswapl(from->window, to->window);
43905b261ecSmrg    to->kind = from->kind;
44005b261ecSmrg    to->forced = from->forced;
44105b261ecSmrg}
44205b261ecSmrg
44305b261ecSmrgstatic void
44435c4bbdfSmrgUninstallSaverColormap(ScreenPtr pScreen)
44505b261ecSmrg{
44605b261ecSmrg    SetupScreen(pScreen);
44735c4bbdfSmrg    ColormapPtr pCmap;
4486747b715Smrg    int rc;
44905b261ecSmrg
45035c4bbdfSmrg    if (pPriv && pPriv->installedMap != None) {
45135c4bbdfSmrg        rc = dixLookupResourceByType((void **) &pCmap, pPriv->installedMap,
45235c4bbdfSmrg                                     RT_COLORMAP, serverClient,
45335c4bbdfSmrg                                     DixUninstallAccess);
45435c4bbdfSmrg        if (rc == Success)
45535c4bbdfSmrg            (*pCmap->pScreen->UninstallColormap) (pCmap);
45635c4bbdfSmrg        pPriv->installedMap = None;
45735c4bbdfSmrg        CheckScreenPrivate(pScreen);
45805b261ecSmrg    }
45905b261ecSmrg}
46005b261ecSmrg
46105b261ecSmrgstatic Bool
46235c4bbdfSmrgCreateSaverWindow(ScreenPtr pScreen)
46305b261ecSmrg{
46435c4bbdfSmrg    SetupScreen(pScreen);
46535c4bbdfSmrg    ScreenSaverStuffPtr pSaver;
46635c4bbdfSmrg    ScreenSaverAttrPtr pAttr;
46735c4bbdfSmrg    WindowPtr pWin;
46835c4bbdfSmrg    int result;
46935c4bbdfSmrg    unsigned long mask;
47035c4bbdfSmrg    Colormap wantMap;
47135c4bbdfSmrg    ColormapPtr pCmap;
47205b261ecSmrg
4736747b715Smrg    pSaver = &pScreen->screensaver;
47435c4bbdfSmrg    if (pSaver->pWindow) {
47535c4bbdfSmrg        pSaver->pWindow = NullWindow;
47635c4bbdfSmrg        FreeResource(pSaver->wid, RT_NONE);
47735c4bbdfSmrg        if (pPriv) {
47835c4bbdfSmrg            UninstallSaverColormap(pScreen);
47935c4bbdfSmrg            pPriv->hasWindow = FALSE;
48035c4bbdfSmrg            CheckScreenPrivate(pScreen);
48135c4bbdfSmrg        }
48205b261ecSmrg    }
48305b261ecSmrg
48405b261ecSmrg    if (!pPriv || !(pAttr = pPriv->attr))
48535c4bbdfSmrg        return FALSE;
48605b261ecSmrg
48705b261ecSmrg    pPriv->installedMap = None;
48805b261ecSmrg
48905b261ecSmrg    if (GrabInProgress && GrabInProgress != pAttr->client->index)
49035c4bbdfSmrg        return FALSE;
49135c4bbdfSmrg
49235c4bbdfSmrg    pWin = CreateWindow(pSaver->wid, pScreen->root,
49335c4bbdfSmrg                        pAttr->x, pAttr->y, pAttr->width, pAttr->height,
49435c4bbdfSmrg                        pAttr->borderWidth, pAttr->class,
49535c4bbdfSmrg                        pAttr->mask, (XID *) pAttr->values,
49635c4bbdfSmrg                        pAttr->depth, serverClient, pAttr->visual, &result);
49705b261ecSmrg    if (!pWin)
49835c4bbdfSmrg        return FALSE;
49905b261ecSmrg
50005b261ecSmrg    if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
50135c4bbdfSmrg        return FALSE;
50205b261ecSmrg
50305b261ecSmrg    mask = 0;
50435c4bbdfSmrg    if (pAttr->pBackgroundPixmap) {
50535c4bbdfSmrg        pWin->backgroundState = BackgroundPixmap;
50635c4bbdfSmrg        pWin->background.pixmap = pAttr->pBackgroundPixmap;
50735c4bbdfSmrg        pAttr->pBackgroundPixmap->refcnt++;
50835c4bbdfSmrg        mask |= CWBackPixmap;
50905b261ecSmrg    }
51035c4bbdfSmrg    if (pAttr->pBorderPixmap) {
51135c4bbdfSmrg        pWin->borderIsPixel = FALSE;
51235c4bbdfSmrg        pWin->border.pixmap = pAttr->pBorderPixmap;
51335c4bbdfSmrg        pAttr->pBorderPixmap->refcnt++;
51435c4bbdfSmrg        mask |= CWBorderPixmap;
51505b261ecSmrg    }
51635c4bbdfSmrg    if (pAttr->pCursor) {
51735c4bbdfSmrg        CursorPtr cursor;
51835c4bbdfSmrg        if (!pWin->optional)
51935c4bbdfSmrg            if (!MakeWindowOptional(pWin)) {
52035c4bbdfSmrg                FreeResource(pWin->drawable.id, RT_NONE);
52135c4bbdfSmrg                return FALSE;
52235c4bbdfSmrg            }
52335c4bbdfSmrg        cursor = RefCursor(pAttr->pCursor);
52435c4bbdfSmrg        if (pWin->optional->cursor)
52535c4bbdfSmrg            FreeCursor(pWin->optional->cursor, (Cursor) 0);
52635c4bbdfSmrg        pWin->optional->cursor = cursor;
52735c4bbdfSmrg        pWin->cursorIsNone = FALSE;
52835c4bbdfSmrg        CheckWindowOptionalNeed(pWin);
52935c4bbdfSmrg        mask |= CWCursor;
53005b261ecSmrg    }
53105b261ecSmrg    if (mask)
53235c4bbdfSmrg        (*pScreen->ChangeWindowAttributes) (pWin, mask);
53305b261ecSmrg
53405b261ecSmrg    if (pAttr->colormap != None)
53535c4bbdfSmrg        (void) ChangeWindowAttributes(pWin, CWColormap, &pAttr->colormap,
53635c4bbdfSmrg                                      serverClient);
53705b261ecSmrg
53835c4bbdfSmrg    MapWindow(pWin, serverClient);
53905b261ecSmrg
54005b261ecSmrg    pPriv->hasWindow = TRUE;
54105b261ecSmrg    pSaver->pWindow = pWin;
54205b261ecSmrg
54305b261ecSmrg    /* check and install our own colormap if it isn't installed now */
54435c4bbdfSmrg    wantMap = wColormap(pWin);
54535c4bbdfSmrg    if (wantMap == None || IsMapInstalled(wantMap, pWin))
54635c4bbdfSmrg        return TRUE;
54735c4bbdfSmrg
54835c4bbdfSmrg    result = dixLookupResourceByType((void **) &pCmap, wantMap, RT_COLORMAP,
54935c4bbdfSmrg                                     serverClient, DixInstallAccess);
5506747b715Smrg    if (result != Success)
55135c4bbdfSmrg        return TRUE;
55205b261ecSmrg
55305b261ecSmrg    pPriv->installedMap = wantMap;
55405b261ecSmrg
55505b261ecSmrg    (*pCmap->pScreen->InstallColormap) (pCmap);
55605b261ecSmrg
55705b261ecSmrg    return TRUE;
55805b261ecSmrg}
55905b261ecSmrg
56005b261ecSmrgstatic Bool
56135c4bbdfSmrgDestroySaverWindow(ScreenPtr pScreen)
56205b261ecSmrg{
56305b261ecSmrg    SetupScreen(pScreen);
56435c4bbdfSmrg    ScreenSaverStuffPtr pSaver;
56505b261ecSmrg
56605b261ecSmrg    if (!pPriv || !pPriv->hasWindow)
56735c4bbdfSmrg        return FALSE;
56805b261ecSmrg
5696747b715Smrg    pSaver = &pScreen->screensaver;
57035c4bbdfSmrg    if (pSaver->pWindow) {
57135c4bbdfSmrg        pSaver->pWindow = NullWindow;
57235c4bbdfSmrg        FreeResource(pSaver->wid, RT_NONE);
57305b261ecSmrg    }
57405b261ecSmrg    pPriv->hasWindow = FALSE;
57535c4bbdfSmrg    CheckScreenPrivate(pScreen);
57635c4bbdfSmrg    UninstallSaverColormap(pScreen);
57705b261ecSmrg    return TRUE;
57805b261ecSmrg}
57905b261ecSmrg
58005b261ecSmrgstatic Bool
58135c4bbdfSmrgScreenSaverHandle(ScreenPtr pScreen, int xstate, Bool force)
58205b261ecSmrg{
58335c4bbdfSmrg    int state = 0;
58435c4bbdfSmrg    Bool ret = FALSE;
58535c4bbdfSmrg    ScreenSaverScreenPrivatePtr pPriv;
58635c4bbdfSmrg
58735c4bbdfSmrg    switch (xstate) {
58835c4bbdfSmrg    case SCREEN_SAVER_ON:
58935c4bbdfSmrg        state = ScreenSaverOn;
59035c4bbdfSmrg        ret = CreateSaverWindow(pScreen);
59135c4bbdfSmrg        break;
59235c4bbdfSmrg    case SCREEN_SAVER_OFF:
59335c4bbdfSmrg        state = ScreenSaverOff;
59435c4bbdfSmrg        ret = DestroySaverWindow(pScreen);
59535c4bbdfSmrg        break;
59635c4bbdfSmrg    case SCREEN_SAVER_CYCLE:
59735c4bbdfSmrg        state = ScreenSaverCycle;
59835c4bbdfSmrg        pPriv = GetScreenPrivate(pScreen);
59935c4bbdfSmrg        if (pPriv && pPriv->hasWindow)
60035c4bbdfSmrg            ret = TRUE;
60135c4bbdfSmrg
60205b261ecSmrg    }
60305b261ecSmrg#ifdef PANORAMIX
60435c4bbdfSmrg    if (noPanoramiXExtension || !pScreen->myNum)
60505b261ecSmrg#endif
60635c4bbdfSmrg        SendScreenSaverNotify(pScreen, state, force);
60705b261ecSmrg    return ret;
60805b261ecSmrg}
60905b261ecSmrg
61005b261ecSmrgstatic int
61135c4bbdfSmrgProcScreenSaverQueryVersion(ClientPtr client)
61205b261ecSmrg{
61335c4bbdfSmrg    xScreenSaverQueryVersionReply rep = {
61435c4bbdfSmrg        .type = X_Reply,
61535c4bbdfSmrg        .sequenceNumber = client->sequence,
61635c4bbdfSmrg        .length = 0,
61735c4bbdfSmrg        .majorVersion = SERVER_SAVER_MAJOR_VERSION,
61835c4bbdfSmrg        .minorVersion = SERVER_SAVER_MINOR_VERSION
61935c4bbdfSmrg    };
62035c4bbdfSmrg
62135c4bbdfSmrg    REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
62235c4bbdfSmrg
62305b261ecSmrg    if (client->swapped) {
62435c4bbdfSmrg        swaps(&rep.sequenceNumber);
62535c4bbdfSmrg        swapl(&rep.length);
62605b261ecSmrg    }
62735c4bbdfSmrg    WriteToClient(client, sizeof(xScreenSaverQueryVersionReply), &rep);
6286747b715Smrg    return Success;
62905b261ecSmrg}
63005b261ecSmrg
63105b261ecSmrgstatic int
63235c4bbdfSmrgProcScreenSaverQueryInfo(ClientPtr client)
63305b261ecSmrg{
63405b261ecSmrg    REQUEST(xScreenSaverQueryInfoReq);
63535c4bbdfSmrg    xScreenSaverQueryInfoReply rep;
63635c4bbdfSmrg    int rc;
63735c4bbdfSmrg    ScreenSaverStuffPtr pSaver;
63835c4bbdfSmrg    DrawablePtr pDraw;
63935c4bbdfSmrg    CARD32 lastInput;
64035c4bbdfSmrg    ScreenSaverScreenPrivatePtr pPriv;
64135c4bbdfSmrg
64235c4bbdfSmrg    REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
64305b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
64435c4bbdfSmrg                           DixGetAttrAccess);
6454642e01fSmrg    if (rc != Success)
64635c4bbdfSmrg        return rc;
6474642e01fSmrg    rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
64835c4bbdfSmrg                  DixGetAttrAccess);
64905b261ecSmrg    if (rc != Success)
65035c4bbdfSmrg        return rc;
65105b261ecSmrg
6526747b715Smrg    pSaver = &pDraw->pScreen->screensaver;
65335c4bbdfSmrg    pPriv = GetScreenPrivate(pDraw->pScreen);
65435c4bbdfSmrg
65535c4bbdfSmrg    UpdateCurrentTime();
65635c4bbdfSmrg    lastInput = GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds;
65735c4bbdfSmrg
65835c4bbdfSmrg    rep = (xScreenSaverQueryInfoReply) {
65935c4bbdfSmrg        .type = X_Reply,
66035c4bbdfSmrg        .sequenceNumber = client->sequence,
66135c4bbdfSmrg        .length = 0,
66235c4bbdfSmrg        .window = pSaver->wid
66335c4bbdfSmrg    };
66435c4bbdfSmrg    if (screenIsSaved != SCREEN_SAVER_OFF) {
66535c4bbdfSmrg        rep.state = ScreenSaverOn;
66635c4bbdfSmrg        if (ScreenSaverTime)
66735c4bbdfSmrg            rep.tilOrSince = lastInput - ScreenSaverTime;
66835c4bbdfSmrg        else
66935c4bbdfSmrg            rep.tilOrSince = 0;
67005b261ecSmrg    }
67135c4bbdfSmrg    else {
67235c4bbdfSmrg        if (ScreenSaverTime) {
67335c4bbdfSmrg            rep.state = ScreenSaverOff;
67435c4bbdfSmrg            if (ScreenSaverTime < lastInput)
67535c4bbdfSmrg                rep.tilOrSince = 0;
67635c4bbdfSmrg            else
67735c4bbdfSmrg                rep.tilOrSince = ScreenSaverTime - lastInput;
67835c4bbdfSmrg        }
67935c4bbdfSmrg        else {
68035c4bbdfSmrg            rep.state = ScreenSaverDisabled;
68135c4bbdfSmrg            rep.tilOrSince = 0;
68235c4bbdfSmrg        }
68305b261ecSmrg    }
68405b261ecSmrg    rep.idle = lastInput;
68535c4bbdfSmrg    rep.eventMask = getEventMask(pDraw->pScreen, client);
68605b261ecSmrg    if (pPriv && pPriv->attr)
68735c4bbdfSmrg        rep.kind = ScreenSaverExternal;
68805b261ecSmrg    else if (ScreenSaverBlanking != DontPreferBlanking)
68935c4bbdfSmrg        rep.kind = ScreenSaverBlanked;
69005b261ecSmrg    else
69135c4bbdfSmrg        rep.kind = ScreenSaverInternal;
69235c4bbdfSmrg    if (client->swapped) {
69335c4bbdfSmrg        swaps(&rep.sequenceNumber);
69435c4bbdfSmrg        swapl(&rep.length);
69535c4bbdfSmrg        swapl(&rep.window);
69635c4bbdfSmrg        swapl(&rep.tilOrSince);
69735c4bbdfSmrg        swapl(&rep.idle);
69835c4bbdfSmrg        swapl(&rep.eventMask);
69905b261ecSmrg    }
70035c4bbdfSmrg    WriteToClient(client, sizeof(xScreenSaverQueryInfoReply), &rep);
7016747b715Smrg    return Success;
70205b261ecSmrg}
70305b261ecSmrg
70405b261ecSmrgstatic int
70535c4bbdfSmrgProcScreenSaverSelectInput(ClientPtr client)
70605b261ecSmrg{
70705b261ecSmrg    REQUEST(xScreenSaverSelectInputReq);
70835c4bbdfSmrg    DrawablePtr pDraw;
70935c4bbdfSmrg    int rc;
71005b261ecSmrg
71135c4bbdfSmrg    REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
71235c4bbdfSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
71335c4bbdfSmrg                           DixGetAttrAccess);
7144642e01fSmrg    if (rc != Success)
71535c4bbdfSmrg        return rc;
7164642e01fSmrg
7174642e01fSmrg    rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
71835c4bbdfSmrg                  DixSetAttrAccess);
71905b261ecSmrg    if (rc != Success)
72035c4bbdfSmrg        return rc;
7214642e01fSmrg
72235c4bbdfSmrg    if (!setEventMask(pDraw->pScreen, client, stuff->eventMask))
72335c4bbdfSmrg        return BadAlloc;
72405b261ecSmrg    return Success;
72505b261ecSmrg}
72605b261ecSmrg
72705b261ecSmrgstatic int
72835c4bbdfSmrgScreenSaverSetAttributes(ClientPtr client)
72905b261ecSmrg{
73005b261ecSmrg    REQUEST(xScreenSaverSetAttributesReq);
73135c4bbdfSmrg    DrawablePtr pDraw;
73235c4bbdfSmrg    WindowPtr pParent;
73335c4bbdfSmrg    ScreenPtr pScreen;
73405b261ecSmrg    ScreenSaverScreenPrivatePtr pPriv = 0;
73535c4bbdfSmrg    ScreenSaverAttrPtr pAttr = 0;
73635c4bbdfSmrg    int ret, len, class, bw, depth;
73735c4bbdfSmrg    unsigned long visual;
73835c4bbdfSmrg    int idepth, ivisual;
73935c4bbdfSmrg    Bool fOK;
74035c4bbdfSmrg    DepthPtr pDepth;
74135c4bbdfSmrg    WindowOptPtr ancwopt;
74235c4bbdfSmrg    unsigned int *pVlist;
74335c4bbdfSmrg    unsigned long *values = 0;
74435c4bbdfSmrg    unsigned long tmask, imask;
74535c4bbdfSmrg    unsigned long val;
74635c4bbdfSmrg    Pixmap pixID;
74735c4bbdfSmrg    PixmapPtr pPixmap;
74835c4bbdfSmrg    Cursor cursorID;
74935c4bbdfSmrg    CursorPtr pCursor;
75035c4bbdfSmrg    Colormap cmap;
75135c4bbdfSmrg    ColormapPtr pCmap;
75235c4bbdfSmrg
75335c4bbdfSmrg    REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
75405b261ecSmrg    ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
75535c4bbdfSmrg                            DixGetAttrAccess);
75605b261ecSmrg    if (ret != Success)
75735c4bbdfSmrg        return ret;
75805b261ecSmrg    pScreen = pDraw->pScreen;
7596747b715Smrg    pParent = pScreen->root;
76005b261ecSmrg
7614642e01fSmrg    ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess);
7624642e01fSmrg    if (ret != Success)
76335c4bbdfSmrg        return ret;
7644642e01fSmrg
76535c4bbdfSmrg    len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
76605b261ecSmrg    if (Ones(stuff->mask) != len)
76705b261ecSmrg        return BadLength;
76835c4bbdfSmrg    if (!stuff->width || !stuff->height) {
76935c4bbdfSmrg        client->errorValue = 0;
77005b261ecSmrg        return BadValue;
77105b261ecSmrg    }
77235c4bbdfSmrg    switch (class = stuff->c_class) {
77305b261ecSmrg    case CopyFromParent:
77405b261ecSmrg    case InputOnly:
77505b261ecSmrg    case InputOutput:
77635c4bbdfSmrg        break;
77705b261ecSmrg    default:
77835c4bbdfSmrg        client->errorValue = class;
77935c4bbdfSmrg        return BadValue;
78005b261ecSmrg    }
78105b261ecSmrg    bw = stuff->borderWidth;
78205b261ecSmrg    depth = stuff->depth;
78305b261ecSmrg    visual = stuff->visualID;
78405b261ecSmrg
78505b261ecSmrg    /* copied directly from CreateWindow */
78605b261ecSmrg
78705b261ecSmrg    if (class == CopyFromParent)
78835c4bbdfSmrg        class = pParent->drawable.class;
78905b261ecSmrg
79035c4bbdfSmrg    if ((class != InputOutput) && (class != InputOnly)) {
79135c4bbdfSmrg        client->errorValue = class;
79235c4bbdfSmrg        return BadValue;
79305b261ecSmrg    }
79405b261ecSmrg
79505b261ecSmrg    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
79605b261ecSmrg        return BadMatch;
79705b261ecSmrg
79805b261ecSmrg    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
79905b261ecSmrg        return BadMatch;
80005b261ecSmrg
80105b261ecSmrg    if ((class == InputOutput) && (depth == 0))
80205b261ecSmrg        depth = pParent->drawable.depth;
80305b261ecSmrg    ancwopt = pParent->optional;
80405b261ecSmrg    if (!ancwopt)
80535c4bbdfSmrg        ancwopt = FindWindowWithOptional(pParent)->optional;
80605b261ecSmrg    if (visual == CopyFromParent)
80735c4bbdfSmrg        visual = ancwopt->visual;
80805b261ecSmrg
80905b261ecSmrg    /* Find out if the depth and visual are acceptable for this Screen */
81035c4bbdfSmrg    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
81135c4bbdfSmrg        fOK = FALSE;
81235c4bbdfSmrg        for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
81335c4bbdfSmrg            pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
81435c4bbdfSmrg            if ((depth == pDepth->depth) || (depth == 0)) {
81535c4bbdfSmrg                for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
81635c4bbdfSmrg                    if (visual == pDepth->vids[ivisual]) {
81735c4bbdfSmrg                        fOK = TRUE;
81835c4bbdfSmrg                        break;
81935c4bbdfSmrg                    }
82035c4bbdfSmrg                }
82135c4bbdfSmrg            }
82235c4bbdfSmrg        }
82335c4bbdfSmrg        if (fOK == FALSE)
82435c4bbdfSmrg            return BadMatch;
82505b261ecSmrg    }
82605b261ecSmrg
82705b261ecSmrg    if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
82835c4bbdfSmrg        (class != InputOnly) && (depth != pParent->drawable.depth)) {
82905b261ecSmrg        return BadMatch;
83005b261ecSmrg    }
83105b261ecSmrg
83205b261ecSmrg    if (((stuff->mask & CWColormap) == 0) &&
83335c4bbdfSmrg        (class != InputOnly) &&
83435c4bbdfSmrg        ((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
83535c4bbdfSmrg        return BadMatch;
83605b261ecSmrg    }
83705b261ecSmrg
83805b261ecSmrg    /* end of errors from CreateWindow */
83905b261ecSmrg
84035c4bbdfSmrg    pPriv = GetScreenPrivate(pScreen);
84135c4bbdfSmrg    if (pPriv && pPriv->attr) {
84235c4bbdfSmrg        if (pPriv->attr->client != client)
84335c4bbdfSmrg            return BadAccess;
84405b261ecSmrg    }
84535c4bbdfSmrg    if (!pPriv) {
84635c4bbdfSmrg        pPriv = MakeScreenPrivate(pScreen);
84735c4bbdfSmrg        if (!pPriv)
84835c4bbdfSmrg            return FALSE;
84905b261ecSmrg    }
85035c4bbdfSmrg    pAttr = New(ScreenSaverAttrRec);
85135c4bbdfSmrg    if (!pAttr) {
85235c4bbdfSmrg        ret = BadAlloc;
85335c4bbdfSmrg        goto bail;
85405b261ecSmrg    }
85505b261ecSmrg    /* over allocate for override redirect */
85635c4bbdfSmrg    pAttr->values = values = xallocarray(len + 1, sizeof(unsigned long));
85735c4bbdfSmrg    if (!values) {
85835c4bbdfSmrg        ret = BadAlloc;
85935c4bbdfSmrg        goto bail;
86005b261ecSmrg    }
86105b261ecSmrg    pAttr->screen = pScreen;
86205b261ecSmrg    pAttr->client = client;
86305b261ecSmrg    pAttr->x = stuff->x;
86405b261ecSmrg    pAttr->y = stuff->y;
86505b261ecSmrg    pAttr->width = stuff->width;
86605b261ecSmrg    pAttr->height = stuff->height;
86705b261ecSmrg    pAttr->borderWidth = stuff->borderWidth;
86805b261ecSmrg    pAttr->class = stuff->c_class;
86905b261ecSmrg    pAttr->depth = depth;
87005b261ecSmrg    pAttr->visual = visual;
87105b261ecSmrg    pAttr->colormap = None;
87205b261ecSmrg    pAttr->pCursor = NullCursor;
87305b261ecSmrg    pAttr->pBackgroundPixmap = NullPixmap;
87405b261ecSmrg    pAttr->pBorderPixmap = NullPixmap;
87505b261ecSmrg    /*
87605b261ecSmrg     * go through the mask, checking the values,
87705b261ecSmrg     * looking up pixmaps and cursors and hold a reference
87805b261ecSmrg     * to them.
87905b261ecSmrg     */
88005b261ecSmrg    pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
88105b261ecSmrg    pVlist = (unsigned int *) (stuff + 1);
88205b261ecSmrg    while (tmask) {
88335c4bbdfSmrg        imask = lowbit(tmask);
88435c4bbdfSmrg        tmask &= ~imask;
88535c4bbdfSmrg        switch (imask) {
88635c4bbdfSmrg        case CWBackPixmap:
88735c4bbdfSmrg            pixID = (Pixmap) * pVlist;
88835c4bbdfSmrg            if (pixID == None) {
88935c4bbdfSmrg                *values++ = None;
89035c4bbdfSmrg            }
89135c4bbdfSmrg            else if (pixID == ParentRelative) {
89235c4bbdfSmrg                if (depth != pParent->drawable.depth) {
89335c4bbdfSmrg                    ret = BadMatch;
89435c4bbdfSmrg                    goto PatchUp;
89535c4bbdfSmrg                }
89635c4bbdfSmrg                *values++ = ParentRelative;
89735c4bbdfSmrg            }
89835c4bbdfSmrg            else {
89935c4bbdfSmrg                ret =
90035c4bbdfSmrg                    dixLookupResourceByType((void **) &pPixmap, pixID,
90135c4bbdfSmrg                                            RT_PIXMAP, client, DixReadAccess);
90235c4bbdfSmrg                if (ret == Success) {
90335c4bbdfSmrg                    if ((pPixmap->drawable.depth != depth) ||
90435c4bbdfSmrg                        (pPixmap->drawable.pScreen != pScreen)) {
90535c4bbdfSmrg                        ret = BadMatch;
90635c4bbdfSmrg                        goto PatchUp;
90735c4bbdfSmrg                    }
90835c4bbdfSmrg                    pAttr->pBackgroundPixmap = pPixmap;
90935c4bbdfSmrg                    pPixmap->refcnt++;
91035c4bbdfSmrg                    pAttr->mask &= ~CWBackPixmap;
91135c4bbdfSmrg                }
91235c4bbdfSmrg                else {
91335c4bbdfSmrg                    client->errorValue = pixID;
91435c4bbdfSmrg                    goto PatchUp;
91535c4bbdfSmrg                }
91635c4bbdfSmrg            }
91735c4bbdfSmrg            break;
91835c4bbdfSmrg        case CWBackPixel:
91935c4bbdfSmrg            *values++ = (CARD32) *pVlist;
92035c4bbdfSmrg            break;
92135c4bbdfSmrg        case CWBorderPixmap:
92235c4bbdfSmrg            pixID = (Pixmap) * pVlist;
92335c4bbdfSmrg            if (pixID == CopyFromParent) {
92435c4bbdfSmrg                if (depth != pParent->drawable.depth) {
92535c4bbdfSmrg                    ret = BadMatch;
92635c4bbdfSmrg                    goto PatchUp;
92735c4bbdfSmrg                }
92835c4bbdfSmrg                *values++ = CopyFromParent;
92935c4bbdfSmrg            }
93035c4bbdfSmrg            else {
93135c4bbdfSmrg                ret =
93235c4bbdfSmrg                    dixLookupResourceByType((void **) &pPixmap, pixID,
93335c4bbdfSmrg                                            RT_PIXMAP, client, DixReadAccess);
93435c4bbdfSmrg                if (ret == Success) {
93535c4bbdfSmrg                    if ((pPixmap->drawable.depth != depth) ||
93635c4bbdfSmrg                        (pPixmap->drawable.pScreen != pScreen)) {
93705b261ecSmrg                        ret = BadMatch;
93835c4bbdfSmrg                        goto PatchUp;
93935c4bbdfSmrg                    }
94035c4bbdfSmrg                    pAttr->pBorderPixmap = pPixmap;
94135c4bbdfSmrg                    pPixmap->refcnt++;
94235c4bbdfSmrg                    pAttr->mask &= ~CWBorderPixmap;
94335c4bbdfSmrg                }
94435c4bbdfSmrg                else {
94535c4bbdfSmrg                    client->errorValue = pixID;
94635c4bbdfSmrg                    goto PatchUp;
94735c4bbdfSmrg                }
94835c4bbdfSmrg            }
94935c4bbdfSmrg            break;
95035c4bbdfSmrg        case CWBorderPixel:
95135c4bbdfSmrg            *values++ = (CARD32) *pVlist;
95235c4bbdfSmrg            break;
95335c4bbdfSmrg        case CWBitGravity:
95435c4bbdfSmrg            val = (CARD8) *pVlist;
95535c4bbdfSmrg            if (val > StaticGravity) {
95635c4bbdfSmrg                ret = BadValue;
95735c4bbdfSmrg                client->errorValue = val;
95835c4bbdfSmrg                goto PatchUp;
95935c4bbdfSmrg            }
96035c4bbdfSmrg            *values++ = val;
96135c4bbdfSmrg            break;
96235c4bbdfSmrg        case CWWinGravity:
96335c4bbdfSmrg            val = (CARD8) *pVlist;
96435c4bbdfSmrg            if (val > StaticGravity) {
96535c4bbdfSmrg                ret = BadValue;
96635c4bbdfSmrg                client->errorValue = val;
96735c4bbdfSmrg                goto PatchUp;
96835c4bbdfSmrg            }
96935c4bbdfSmrg            *values++ = val;
97035c4bbdfSmrg            break;
97135c4bbdfSmrg        case CWBackingStore:
97235c4bbdfSmrg            val = (CARD8) *pVlist;
97335c4bbdfSmrg            if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
97435c4bbdfSmrg                ret = BadValue;
97535c4bbdfSmrg                client->errorValue = val;
97635c4bbdfSmrg                goto PatchUp;
97735c4bbdfSmrg            }
97835c4bbdfSmrg            *values++ = val;
97935c4bbdfSmrg            break;
98035c4bbdfSmrg        case CWBackingPlanes:
98135c4bbdfSmrg            *values++ = (CARD32) *pVlist;
98235c4bbdfSmrg            break;
98335c4bbdfSmrg        case CWBackingPixel:
98405b261ecSmrg            *values++ = (CARD32) *pVlist;
98505b261ecSmrg            break;
98635c4bbdfSmrg        case CWSaveUnder:
98735c4bbdfSmrg            val = (BOOL) * pVlist;
98835c4bbdfSmrg            if ((val != xTrue) && (val != xFalse)) {
98935c4bbdfSmrg                ret = BadValue;
99035c4bbdfSmrg                client->errorValue = val;
99135c4bbdfSmrg                goto PatchUp;
99235c4bbdfSmrg            }
99335c4bbdfSmrg            *values++ = val;
99435c4bbdfSmrg            break;
99535c4bbdfSmrg        case CWEventMask:
99635c4bbdfSmrg            *values++ = (CARD32) *pVlist;
99735c4bbdfSmrg            break;
99835c4bbdfSmrg        case CWDontPropagate:
99935c4bbdfSmrg            *values++ = (CARD32) *pVlist;
100035c4bbdfSmrg            break;
100135c4bbdfSmrg        case CWOverrideRedirect:
100235c4bbdfSmrg            if (!(stuff->mask & CWOverrideRedirect))
100335c4bbdfSmrg                pVlist--;
100435c4bbdfSmrg            else {
100535c4bbdfSmrg                val = (BOOL) * pVlist;
100635c4bbdfSmrg                if ((val != xTrue) && (val != xFalse)) {
100735c4bbdfSmrg                    ret = BadValue;
100835c4bbdfSmrg                    client->errorValue = val;
100935c4bbdfSmrg                    goto PatchUp;
101035c4bbdfSmrg                }
101135c4bbdfSmrg            }
101235c4bbdfSmrg            *values++ = xTrue;
101335c4bbdfSmrg            break;
101435c4bbdfSmrg        case CWColormap:
101535c4bbdfSmrg            cmap = (Colormap) * pVlist;
101635c4bbdfSmrg            ret = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP,
101735c4bbdfSmrg                                          client, DixUseAccess);
101835c4bbdfSmrg            if (ret != Success) {
101935c4bbdfSmrg                client->errorValue = cmap;
102035c4bbdfSmrg                goto PatchUp;
102135c4bbdfSmrg            }
102235c4bbdfSmrg            if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) {
102335c4bbdfSmrg                ret = BadMatch;
102435c4bbdfSmrg                goto PatchUp;
102535c4bbdfSmrg            }
102635c4bbdfSmrg            pAttr->colormap = cmap;
102735c4bbdfSmrg            pAttr->mask &= ~CWColormap;
102835c4bbdfSmrg            break;
102935c4bbdfSmrg        case CWCursor:
103035c4bbdfSmrg            cursorID = (Cursor) * pVlist;
103135c4bbdfSmrg            if (cursorID == None) {
103235c4bbdfSmrg                *values++ = None;
103335c4bbdfSmrg            }
103435c4bbdfSmrg            else {
103535c4bbdfSmrg                ret = dixLookupResourceByType((void **) &pCursor, cursorID,
103635c4bbdfSmrg                                              RT_CURSOR, client, DixUseAccess);
103735c4bbdfSmrg                if (ret != Success) {
103835c4bbdfSmrg                    client->errorValue = cursorID;
103935c4bbdfSmrg                    goto PatchUp;
104035c4bbdfSmrg                }
104135c4bbdfSmrg                pAttr->pCursor = RefCursor(pCursor);
104235c4bbdfSmrg                pAttr->mask &= ~CWCursor;
104335c4bbdfSmrg            }
104435c4bbdfSmrg            break;
104535c4bbdfSmrg        default:
104635c4bbdfSmrg            ret = BadValue;
104735c4bbdfSmrg            client->errorValue = stuff->mask;
104835c4bbdfSmrg            goto PatchUp;
104935c4bbdfSmrg        }
105035c4bbdfSmrg        pVlist++;
105105b261ecSmrg    }
105205b261ecSmrg    if (pPriv->attr)
105335c4bbdfSmrg        FreeScreenAttr(pPriv->attr);
105405b261ecSmrg    pPriv->attr = pAttr;
105535c4bbdfSmrg    pAttr->resource = FakeClientID(client->index);
105635c4bbdfSmrg    if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
105735c4bbdfSmrg        return BadAlloc;
105805b261ecSmrg    return Success;
105935c4bbdfSmrg PatchUp:
106035c4bbdfSmrg    FreeAttrs(pAttr);
106135c4bbdfSmrg bail:
106235c4bbdfSmrg    CheckScreenPrivate(pScreen);
106335c4bbdfSmrg    if (pAttr)
106435c4bbdfSmrg        free(pAttr->values);
10656747b715Smrg    free(pAttr);
106605b261ecSmrg    return ret;
106705b261ecSmrg}
106805b261ecSmrg
106905b261ecSmrgstatic int
107035c4bbdfSmrgScreenSaverUnsetAttributes(ClientPtr client)
107105b261ecSmrg{
107205b261ecSmrg    REQUEST(xScreenSaverSetAttributesReq);
107335c4bbdfSmrg    DrawablePtr pDraw;
107435c4bbdfSmrg    ScreenSaverScreenPrivatePtr pPriv;
107535c4bbdfSmrg    int rc;
107605b261ecSmrg
107735c4bbdfSmrg    REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
107805b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
107935c4bbdfSmrg                           DixGetAttrAccess);
108005b261ecSmrg    if (rc != Success)
108135c4bbdfSmrg        return rc;
108235c4bbdfSmrg    pPriv = GetScreenPrivate(pDraw->pScreen);
108335c4bbdfSmrg    if (pPriv && pPriv->attr && pPriv->attr->client == client) {
108435c4bbdfSmrg        FreeResource(pPriv->attr->resource, AttrType);
108535c4bbdfSmrg        FreeScreenAttr(pPriv->attr);
108635c4bbdfSmrg        pPriv->attr = NULL;
108735c4bbdfSmrg        CheckScreenPrivate(pDraw->pScreen);
108805b261ecSmrg    }
108905b261ecSmrg    return Success;
109005b261ecSmrg}
109105b261ecSmrg
109205b261ecSmrgstatic int
109335c4bbdfSmrgProcScreenSaverSetAttributes(ClientPtr client)
109405b261ecSmrg{
109505b261ecSmrg#ifdef PANORAMIX
109635c4bbdfSmrg    if (!noPanoramiXExtension) {
109735c4bbdfSmrg        REQUEST(xScreenSaverSetAttributesReq);
109835c4bbdfSmrg        PanoramiXRes *draw;
109935c4bbdfSmrg        PanoramiXRes *backPix = NULL;
110035c4bbdfSmrg        PanoramiXRes *bordPix = NULL;
110135c4bbdfSmrg        PanoramiXRes *cmap = NULL;
110235c4bbdfSmrg        int i, status, len;
110335c4bbdfSmrg        int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
110435c4bbdfSmrg        XID orig_visual, tmp;
110535c4bbdfSmrg
110635c4bbdfSmrg        REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
110735c4bbdfSmrg
110835c4bbdfSmrg        status = dixLookupResourceByClass((void **) &draw, stuff->drawable,
110935c4bbdfSmrg                                          XRC_DRAWABLE, client, DixWriteAccess);
111035c4bbdfSmrg        if (status != Success)
111135c4bbdfSmrg            return (status == BadValue) ? BadDrawable : status;
111235c4bbdfSmrg
111335c4bbdfSmrg        len =
111435c4bbdfSmrg            stuff->length -
111535c4bbdfSmrg            bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
111635c4bbdfSmrg        if (Ones(stuff->mask) != len)
111735c4bbdfSmrg            return BadLength;
111835c4bbdfSmrg
111935c4bbdfSmrg        if ((Mask) stuff->mask & CWBackPixmap) {
112035c4bbdfSmrg            pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1));
112135c4bbdfSmrg            tmp = *((CARD32 *) &stuff[1] + pback_offset);
112235c4bbdfSmrg            if ((tmp != None) && (tmp != ParentRelative)) {
112335c4bbdfSmrg                status = dixLookupResourceByType((void **) &backPix, tmp,
112435c4bbdfSmrg                                                 XRT_PIXMAP, client,
112535c4bbdfSmrg                                                 DixReadAccess);
112635c4bbdfSmrg                if (status != Success)
112735c4bbdfSmrg                    return status;
112835c4bbdfSmrg            }
112935c4bbdfSmrg        }
113035c4bbdfSmrg
113135c4bbdfSmrg        if ((Mask) stuff->mask & CWBorderPixmap) {
113235c4bbdfSmrg            pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1));
113335c4bbdfSmrg            tmp = *((CARD32 *) &stuff[1] + pbord_offset);
113435c4bbdfSmrg            if (tmp != CopyFromParent) {
113535c4bbdfSmrg                status = dixLookupResourceByType((void **) &bordPix, tmp,
113635c4bbdfSmrg                                                 XRT_PIXMAP, client,
113735c4bbdfSmrg                                                 DixReadAccess);
113835c4bbdfSmrg                if (status != Success)
113935c4bbdfSmrg                    return status;
114035c4bbdfSmrg            }
114135c4bbdfSmrg        }
114235c4bbdfSmrg
114335c4bbdfSmrg        if ((Mask) stuff->mask & CWColormap) {
114435c4bbdfSmrg            cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
114535c4bbdfSmrg            tmp = *((CARD32 *) &stuff[1] + cmap_offset);
114635c4bbdfSmrg            if (tmp != CopyFromParent) {
114735c4bbdfSmrg                status = dixLookupResourceByType((void **) &cmap, tmp,
114835c4bbdfSmrg                                                 XRT_COLORMAP, client,
114935c4bbdfSmrg                                                 DixReadAccess);
115035c4bbdfSmrg                if (status != Success)
115135c4bbdfSmrg                    return status;
115235c4bbdfSmrg            }
115335c4bbdfSmrg        }
115435c4bbdfSmrg
115535c4bbdfSmrg        orig_visual = stuff->visualID;
115635c4bbdfSmrg
115735c4bbdfSmrg        FOR_NSCREENS_BACKWARD(i) {
115835c4bbdfSmrg            stuff->drawable = draw->info[i].id;
115935c4bbdfSmrg            if (backPix)
116035c4bbdfSmrg                *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
116135c4bbdfSmrg            if (bordPix)
116235c4bbdfSmrg                *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
116335c4bbdfSmrg            if (cmap)
116435c4bbdfSmrg                *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
116535c4bbdfSmrg
116635c4bbdfSmrg            if (orig_visual != CopyFromParent)
116735c4bbdfSmrg                stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual);
116835c4bbdfSmrg
116935c4bbdfSmrg            status = ScreenSaverSetAttributes(client);
117035c4bbdfSmrg        }
117135c4bbdfSmrg
117235c4bbdfSmrg        return status;
117305b261ecSmrg    }
117405b261ecSmrg#endif
117505b261ecSmrg
117605b261ecSmrg    return ScreenSaverSetAttributes(client);
117705b261ecSmrg}
117805b261ecSmrg
117905b261ecSmrgstatic int
118035c4bbdfSmrgProcScreenSaverUnsetAttributes(ClientPtr client)
118105b261ecSmrg{
118205b261ecSmrg#ifdef PANORAMIX
118335c4bbdfSmrg    if (!noPanoramiXExtension) {
118435c4bbdfSmrg        REQUEST(xScreenSaverUnsetAttributesReq);
118535c4bbdfSmrg        PanoramiXRes *draw;
118635c4bbdfSmrg        int rc, i;
118705b261ecSmrg
11886e78d31fSmrg        REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
11896e78d31fSmrg
119035c4bbdfSmrg        rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
119135c4bbdfSmrg                                      XRC_DRAWABLE, client, DixWriteAccess);
119235c4bbdfSmrg        if (rc != Success)
119335c4bbdfSmrg            return (rc == BadValue) ? BadDrawable : rc;
119405b261ecSmrg
119535c4bbdfSmrg        for (i = PanoramiXNumScreens - 1; i > 0; i--) {
119605b261ecSmrg            stuff->drawable = draw->info[i].id;
119705b261ecSmrg            ScreenSaverUnsetAttributes(client);
119835c4bbdfSmrg        }
119905b261ecSmrg
120035c4bbdfSmrg        stuff->drawable = draw->info[0].id;
120105b261ecSmrg    }
120205b261ecSmrg#endif
120305b261ecSmrg
120405b261ecSmrg    return ScreenSaverUnsetAttributes(client);
120505b261ecSmrg}
120605b261ecSmrg
120705b261ecSmrgstatic int
120835c4bbdfSmrgProcScreenSaverSuspend(ClientPtr client)
120905b261ecSmrg{
121005b261ecSmrg    ScreenSaverSuspensionPtr *prev, this;
121105b261ecSmrg
121205b261ecSmrg    REQUEST(xScreenSaverSuspendReq);
121305b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
121405b261ecSmrg
121505b261ecSmrg    /* Check if this client is suspending the screensaver */
121605b261ecSmrg    for (prev = &suspendingClients; (this = *prev); prev = &this->next)
121735c4bbdfSmrg        if (this->pClient == client)
121835c4bbdfSmrg            break;
121905b261ecSmrg
122035c4bbdfSmrg    if (this) {
122135c4bbdfSmrg        if (stuff->suspend == TRUE)
122235c4bbdfSmrg            this->count++;
122335c4bbdfSmrg        else if (--this->count == 0)
122435c4bbdfSmrg            FreeResource(this->clientResource, RT_NONE);
122505b261ecSmrg
122635c4bbdfSmrg        return Success;
122705b261ecSmrg    }
122805b261ecSmrg
122905b261ecSmrg    /* If we get to this point, this client isn't suspending the screensaver */
123005b261ecSmrg    if (stuff->suspend == FALSE)
123135c4bbdfSmrg        return Success;
123205b261ecSmrg
123305b261ecSmrg    /*
123405b261ecSmrg     * Allocate a suspension record for the client, and stop the screensaver
123505b261ecSmrg     * if it isn't already suspended by another client. We attach a resource ID
123605b261ecSmrg     * to the record, so the screensaver will be reenabled and the record freed
123705b261ecSmrg     * if the client disconnects without reenabling it first.
123805b261ecSmrg     */
123935c4bbdfSmrg    this = malloc(sizeof(ScreenSaverSuspensionRec));
124005b261ecSmrg
124105b261ecSmrg    if (!this)
124235c4bbdfSmrg        return BadAlloc;
124305b261ecSmrg
124435c4bbdfSmrg    this->next = NULL;
124535c4bbdfSmrg    this->pClient = client;
124635c4bbdfSmrg    this->count = 1;
124735c4bbdfSmrg    this->clientResource = FakeClientID(client->index);
124805b261ecSmrg
124935c4bbdfSmrg    if (!AddResource(this->clientResource, SuspendType, (void *) this)) {
125035c4bbdfSmrg        free(this);
125135c4bbdfSmrg        return BadAlloc;
125205b261ecSmrg    }
125305b261ecSmrg
125405b261ecSmrg    *prev = this;
125535c4bbdfSmrg    if (!screenSaverSuspended) {
125635c4bbdfSmrg        screenSaverSuspended = TRUE;
125735c4bbdfSmrg        FreeScreenSaverTimer();
125805b261ecSmrg    }
125905b261ecSmrg
12606747b715Smrg    return Success;
126105b261ecSmrg}
126205b261ecSmrg
126335c4bbdfSmrgstatic int (*NormalVector[]) (ClientPtr /* client */ ) = {
126435c4bbdfSmrgProcScreenSaverQueryVersion,
126535c4bbdfSmrg        ProcScreenSaverQueryInfo,
126635c4bbdfSmrg        ProcScreenSaverSelectInput,
126735c4bbdfSmrg        ProcScreenSaverSetAttributes,
126835c4bbdfSmrg        ProcScreenSaverUnsetAttributes, ProcScreenSaverSuspend,};
126905b261ecSmrg
127005b261ecSmrg#define NUM_REQUESTS	((sizeof NormalVector) / (sizeof NormalVector[0]))
127105b261ecSmrg
127205b261ecSmrgstatic int
127335c4bbdfSmrgProcScreenSaverDispatch(ClientPtr client)
127405b261ecSmrg{
127505b261ecSmrg    REQUEST(xReq);
127605b261ecSmrg
127705b261ecSmrg    if (stuff->data < NUM_REQUESTS)
127835c4bbdfSmrg        return (*NormalVector[stuff->data]) (client);
127905b261ecSmrg    return BadRequest;
128005b261ecSmrg}
128105b261ecSmrg
128205b261ecSmrgstatic int
128335c4bbdfSmrgSProcScreenSaverQueryVersion(ClientPtr client)
128405b261ecSmrg{
128505b261ecSmrg    REQUEST(xScreenSaverQueryVersionReq);
128635c4bbdfSmrg    swaps(&stuff->length);
128705b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
128835c4bbdfSmrg    return ProcScreenSaverQueryVersion(client);
128905b261ecSmrg}
129005b261ecSmrg
129105b261ecSmrgstatic int
129235c4bbdfSmrgSProcScreenSaverQueryInfo(ClientPtr client)
129305b261ecSmrg{
129405b261ecSmrg    REQUEST(xScreenSaverQueryInfoReq);
129535c4bbdfSmrg    swaps(&stuff->length);
129605b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
129735c4bbdfSmrg    swapl(&stuff->drawable);
129835c4bbdfSmrg    return ProcScreenSaverQueryInfo(client);
129905b261ecSmrg}
130005b261ecSmrg
130105b261ecSmrgstatic int
130235c4bbdfSmrgSProcScreenSaverSelectInput(ClientPtr client)
130305b261ecSmrg{
130405b261ecSmrg    REQUEST(xScreenSaverSelectInputReq);
130535c4bbdfSmrg    swaps(&stuff->length);
130605b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
130735c4bbdfSmrg    swapl(&stuff->drawable);
130835c4bbdfSmrg    swapl(&stuff->eventMask);
130935c4bbdfSmrg    return ProcScreenSaverSelectInput(client);
131005b261ecSmrg}
131105b261ecSmrg
131205b261ecSmrgstatic int
131335c4bbdfSmrgSProcScreenSaverSetAttributes(ClientPtr client)
131405b261ecSmrg{
131505b261ecSmrg    REQUEST(xScreenSaverSetAttributesReq);
131635c4bbdfSmrg    swaps(&stuff->length);
131705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
131835c4bbdfSmrg    swapl(&stuff->drawable);
131935c4bbdfSmrg    swaps(&stuff->x);
132035c4bbdfSmrg    swaps(&stuff->y);
132135c4bbdfSmrg    swaps(&stuff->width);
132235c4bbdfSmrg    swaps(&stuff->height);
132335c4bbdfSmrg    swaps(&stuff->borderWidth);
132435c4bbdfSmrg    swapl(&stuff->visualID);
132535c4bbdfSmrg    swapl(&stuff->mask);
132605b261ecSmrg    SwapRestL(stuff);
132735c4bbdfSmrg    return ProcScreenSaverSetAttributes(client);
132805b261ecSmrg}
132905b261ecSmrg
133005b261ecSmrgstatic int
133135c4bbdfSmrgSProcScreenSaverUnsetAttributes(ClientPtr client)
133205b261ecSmrg{
133305b261ecSmrg    REQUEST(xScreenSaverUnsetAttributesReq);
133435c4bbdfSmrg    swaps(&stuff->length);
133505b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
133635c4bbdfSmrg    swapl(&stuff->drawable);
133735c4bbdfSmrg    return ProcScreenSaverUnsetAttributes(client);
133805b261ecSmrg}
133905b261ecSmrg
134005b261ecSmrgstatic int
134135c4bbdfSmrgSProcScreenSaverSuspend(ClientPtr client)
134205b261ecSmrg{
134305b261ecSmrg    REQUEST(xScreenSaverSuspendReq);
134405b261ecSmrg
134535c4bbdfSmrg    swaps(&stuff->length);
134605b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
134735c4bbdfSmrg    return ProcScreenSaverSuspend(client);
134805b261ecSmrg}
134905b261ecSmrg
135035c4bbdfSmrgstatic int (*SwappedVector[]) (ClientPtr /* client */ ) = {
135135c4bbdfSmrgSProcScreenSaverQueryVersion,
135235c4bbdfSmrg        SProcScreenSaverQueryInfo,
135335c4bbdfSmrg        SProcScreenSaverSelectInput,
135435c4bbdfSmrg        SProcScreenSaverSetAttributes,
135535c4bbdfSmrg        SProcScreenSaverUnsetAttributes, SProcScreenSaverSuspend,};
135605b261ecSmrg
135705b261ecSmrgstatic int
135835c4bbdfSmrgSProcScreenSaverDispatch(ClientPtr client)
135905b261ecSmrg{
136005b261ecSmrg    REQUEST(xReq);
136105b261ecSmrg
136205b261ecSmrg    if (stuff->data < NUM_REQUESTS)
136335c4bbdfSmrg        return (*SwappedVector[stuff->data]) (client);
136405b261ecSmrg    return BadRequest;
136505b261ecSmrg}
13669ace9065Smrg
13679ace9065Smrgvoid
136835c4bbdfSmrgScreenSaverExtensionInit(void)
13699ace9065Smrg{
13709ace9065Smrg    ExtensionEntry *extEntry;
137135c4bbdfSmrg    int i;
137235c4bbdfSmrg    ScreenPtr pScreen;
13739ace9065Smrg
13749ace9065Smrg    if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
137535c4bbdfSmrg        return;
13769ace9065Smrg
13779ace9065Smrg    AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr");
137835c4bbdfSmrg    SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, "SaverEvent");
137935c4bbdfSmrg    SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, "SaverSuspend");
138035c4bbdfSmrg
138135c4bbdfSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
138235c4bbdfSmrg        pScreen = screenInfo.screens[i];
138335c4bbdfSmrg        SetScreenPrivate(pScreen, NULL);
13849ace9065Smrg    }
13859ace9065Smrg    if (AttrType && SaverEventType && SuspendType &&
138635c4bbdfSmrg        (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
138735c4bbdfSmrg                                 ProcScreenSaverDispatch,
138835c4bbdfSmrg                                 SProcScreenSaverDispatch, NULL,
138935c4bbdfSmrg                                 StandardMinorOpcode))) {
139035c4bbdfSmrg        ScreenSaverEventBase = extEntry->eventBase;
139135c4bbdfSmrg        EventSwapVector[ScreenSaverEventBase] =
139235c4bbdfSmrg            (EventSwapPtr) SScreenSaverNotifyEvent;
13939ace9065Smrg    }
13949ace9065Smrg}
1395