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