saver.c revision 4642e01f
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#define NEED_REPLIES
3105b261ecSmrg#define NEED_EVENTS
3205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3305b261ecSmrg#include <dix-config.h>
3405b261ecSmrg#endif
3505b261ecSmrg
3605b261ecSmrg#include <X11/X.h>
3705b261ecSmrg#include <X11/Xproto.h>
3805b261ecSmrg#include "misc.h"
3905b261ecSmrg#include "os.h"
4005b261ecSmrg#include "windowstr.h"
4105b261ecSmrg#include "scrnintstr.h"
4205b261ecSmrg#include "pixmapstr.h"
4305b261ecSmrg#include "extnsionst.h"
4405b261ecSmrg#include "dixstruct.h"
4505b261ecSmrg#include "resource.h"
4605b261ecSmrg#include "opaque.h"
4705b261ecSmrg#include <X11/extensions/saverproto.h>
4805b261ecSmrg#include "gcstruct.h"
4905b261ecSmrg#include "cursorstr.h"
5005b261ecSmrg#include "colormapst.h"
514642e01fSmrg#include "xace.h"
5205b261ecSmrg#ifdef PANORAMIX
5305b261ecSmrg#include "panoramiX.h"
5405b261ecSmrg#include "panoramiXsrv.h"
5505b261ecSmrg#endif
5605b261ecSmrg#ifdef DPMSExtension
5705b261ecSmrg#define DPMS_SERVER
5805b261ecSmrg#include <X11/extensions/dpms.h>
5905b261ecSmrg#endif
6005b261ecSmrg
6105b261ecSmrg#include <stdio.h>
6205b261ecSmrg
6305b261ecSmrg#include "modinit.h"
6405b261ecSmrg
6505b261ecSmrgstatic int ScreenSaverEventBase = 0;
6605b261ecSmrg
6705b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverQueryInfo);
6805b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverDispatch);
6905b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverQueryVersion);
7005b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSelectInput);
7105b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSetAttributes);
7205b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverUnsetAttributes);
7305b261ecSmrgstatic DISPATCH_PROC(ProcScreenSaverSuspend);
7405b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverDispatch);
7505b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverQueryInfo);
7605b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverQueryVersion);
7705b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSelectInput);
7805b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSetAttributes);
7905b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverUnsetAttributes);
8005b261ecSmrgstatic DISPATCH_PROC(SProcScreenSaverSuspend);
8105b261ecSmrg
8205b261ecSmrgstatic Bool ScreenSaverHandle (
8305b261ecSmrg	ScreenPtr /* pScreen */,
8405b261ecSmrg	int /* xstate */,
8505b261ecSmrg	Bool /* force */
8605b261ecSmrg	);
8705b261ecSmrg
8805b261ecSmrgstatic Bool
8905b261ecSmrgCreateSaverWindow (
9005b261ecSmrg	ScreenPtr /* pScreen */
9105b261ecSmrg	);
9205b261ecSmrg
9305b261ecSmrgstatic Bool
9405b261ecSmrgDestroySaverWindow (
9505b261ecSmrg	ScreenPtr /* pScreen */
9605b261ecSmrg	);
9705b261ecSmrg
9805b261ecSmrgstatic void
9905b261ecSmrgUninstallSaverColormap (
10005b261ecSmrg	ScreenPtr /* pScreen */
10105b261ecSmrg	);
10205b261ecSmrg
10305b261ecSmrgstatic void
10405b261ecSmrgCheckScreenPrivate (
10505b261ecSmrg	ScreenPtr /* pScreen */
10605b261ecSmrg	);
10705b261ecSmrg
10805b261ecSmrgstatic void SScreenSaverNotifyEvent (
10905b261ecSmrg	xScreenSaverNotifyEvent * /* from */,
11005b261ecSmrg	xScreenSaverNotifyEvent * /* to */
11105b261ecSmrg	);
11205b261ecSmrg
11305b261ecSmrgstatic RESTYPE SuspendType;  /* resource type for suspension records */
11405b261ecSmrg
11505b261ecSmrgtypedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr;
11605b261ecSmrg
11705b261ecSmrg/* List of clients that are suspending the screensaver. */
11805b261ecSmrgstatic ScreenSaverSuspensionPtr suspendingClients = NULL;
11905b261ecSmrg
12005b261ecSmrg/*
12105b261ecSmrg * clientResource is a resource ID that's added when the record is
12205b261ecSmrg * allocated, so the record is freed and the screensaver resumed when
12305b261ecSmrg * the client disconnects. count is the number of times the client has
12405b261ecSmrg * requested the screensaver be suspended.
12505b261ecSmrg */
12605b261ecSmrgtypedef struct _ScreenSaverSuspension
12705b261ecSmrg{
12805b261ecSmrg    ScreenSaverSuspensionPtr  next;
12905b261ecSmrg    ClientPtr                 pClient;
13005b261ecSmrg    XID                       clientResource;
13105b261ecSmrg    int                       count;
13205b261ecSmrg} ScreenSaverSuspensionRec;
13305b261ecSmrg
13405b261ecSmrgstatic int ScreenSaverFreeSuspend(
13505b261ecSmrg    pointer /*value */,
13605b261ecSmrg    XID /* id */
13705b261ecSmrg);
13805b261ecSmrg
13905b261ecSmrg/*
14005b261ecSmrg * each screen has a list of clients requesting
14105b261ecSmrg * ScreenSaverNotify events.  Each client has a resource
14205b261ecSmrg * for each screen it selects ScreenSaverNotify input for,
14305b261ecSmrg * this resource is used to delete the ScreenSaverNotifyRec
14405b261ecSmrg * entry from the per-screen queue.
14505b261ecSmrg */
14605b261ecSmrg
14705b261ecSmrgstatic RESTYPE EventType;   /* resource type for event masks */
14805b261ecSmrg
14905b261ecSmrgtypedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
15005b261ecSmrg
15105b261ecSmrgtypedef struct _ScreenSaverEvent {
15205b261ecSmrg    ScreenSaverEventPtr	next;
15305b261ecSmrg    ClientPtr		client;
15405b261ecSmrg    ScreenPtr		screen;
15505b261ecSmrg    XID			resource;
15605b261ecSmrg    CARD32		mask;
15705b261ecSmrg} ScreenSaverEventRec;
15805b261ecSmrg
15905b261ecSmrgstatic int ScreenSaverFreeEvents(
16005b261ecSmrg    pointer /* value */,
16105b261ecSmrg    XID /* id */
16205b261ecSmrg);
16305b261ecSmrg
16405b261ecSmrgstatic Bool setEventMask (
16505b261ecSmrg    ScreenPtr /* pScreen */,
16605b261ecSmrg    ClientPtr /* client */,
16705b261ecSmrg    unsigned long /* mask */
16805b261ecSmrg);
16905b261ecSmrg
17005b261ecSmrgstatic unsigned long getEventMask (
17105b261ecSmrg    ScreenPtr /* pScreen */,
17205b261ecSmrg    ClientPtr /* client */
17305b261ecSmrg);
17405b261ecSmrg
17505b261ecSmrg/*
17605b261ecSmrg * when a client sets the screen saver attributes, a resource is
17705b261ecSmrg * kept to be freed when the client exits
17805b261ecSmrg */
17905b261ecSmrg
18005b261ecSmrgstatic RESTYPE AttrType;    /* resource type for attributes */
18105b261ecSmrg
18205b261ecSmrgtypedef struct _ScreenSaverAttr {
18305b261ecSmrg    ScreenPtr	    screen;
18405b261ecSmrg    ClientPtr	    client;
18505b261ecSmrg    XID		    resource;
18605b261ecSmrg    short	    x, y;
18705b261ecSmrg    unsigned short  width, height, borderWidth;
18805b261ecSmrg    unsigned char   class;
18905b261ecSmrg    unsigned char   depth;
19005b261ecSmrg    VisualID	    visual;
19105b261ecSmrg    CursorPtr	    pCursor;
19205b261ecSmrg    PixmapPtr	    pBackgroundPixmap;
19305b261ecSmrg    PixmapPtr	    pBorderPixmap;
19405b261ecSmrg    Colormap	    colormap;
19505b261ecSmrg    unsigned long   mask;		/* no pixmaps or cursors */
19605b261ecSmrg    unsigned long   *values;
19705b261ecSmrg} ScreenSaverAttrRec, *ScreenSaverAttrPtr;
19805b261ecSmrg
19905b261ecSmrgstatic int ScreenSaverFreeAttr (
20005b261ecSmrg    pointer /* value */,
20105b261ecSmrg    XID /* id */
20205b261ecSmrg);
20305b261ecSmrg
20405b261ecSmrgstatic void FreeAttrs (
20505b261ecSmrg    ScreenSaverAttrPtr	/* pAttr */
20605b261ecSmrg);
20705b261ecSmrg
20805b261ecSmrgstatic void FreeScreenAttr (
20905b261ecSmrg    ScreenSaverAttrPtr	/* pAttr */
21005b261ecSmrg);
21105b261ecSmrg
21205b261ecSmrgstatic void
21305b261ecSmrgSendScreenSaverNotify (
21405b261ecSmrg    ScreenPtr /* pScreen */,
21505b261ecSmrg    int /* state */,
21605b261ecSmrg    Bool /* forced */
21705b261ecSmrg);
21805b261ecSmrg
21905b261ecSmrgtypedef struct _ScreenSaverScreenPrivate {
22005b261ecSmrg    ScreenSaverEventPtr	    events;
22105b261ecSmrg    ScreenSaverAttrPtr	    attr;
22205b261ecSmrg    Bool		    hasWindow;
22305b261ecSmrg    Colormap		    installedMap;
22405b261ecSmrg} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
22505b261ecSmrg
22605b261ecSmrgstatic ScreenSaverScreenPrivatePtr
22705b261ecSmrgMakeScreenPrivate (
22805b261ecSmrg	ScreenPtr /* pScreen */
22905b261ecSmrg	);
23005b261ecSmrg
2314642e01fSmrgstatic int ScreenPrivateKeyIndex;
2324642e01fSmrgstatic DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex;
23305b261ecSmrg
2344642e01fSmrg#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
2354642e01fSmrg    dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
2364642e01fSmrg#define SetScreenPrivate(s,v) \
2374642e01fSmrg    dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v);
23805b261ecSmrg#define SetupScreen(s)	ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
23905b261ecSmrg
24005b261ecSmrg#define New(t)	((t *) xalloc (sizeof (t)))
24105b261ecSmrg
24205b261ecSmrg/****************
24305b261ecSmrg * ScreenSaverExtensionInit
24405b261ecSmrg *
24505b261ecSmrg * Called from InitExtensions in main() or from QueryExtension() if the
24605b261ecSmrg * extension is dynamically loaded.
24705b261ecSmrg *
24805b261ecSmrg ****************/
24905b261ecSmrg
25005b261ecSmrgvoid
25105b261ecSmrgScreenSaverExtensionInit(INITARGS)
25205b261ecSmrg{
25305b261ecSmrg    ExtensionEntry *extEntry;
25405b261ecSmrg    int		    i;
25505b261ecSmrg    ScreenPtr	    pScreen;
25605b261ecSmrg
25705b261ecSmrg    AttrType = CreateNewResourceType(ScreenSaverFreeAttr);
25805b261ecSmrg    EventType = CreateNewResourceType(ScreenSaverFreeEvents);
25905b261ecSmrg    SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend);
26005b261ecSmrg
26105b261ecSmrg    for (i = 0; i < screenInfo.numScreens; i++)
26205b261ecSmrg    {
26305b261ecSmrg	pScreen = screenInfo.screens[i];
26405b261ecSmrg	SetScreenPrivate (pScreen, NULL);
26505b261ecSmrg    }
2664642e01fSmrg    if (AttrType && EventType && SuspendType &&
26705b261ecSmrg	(extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
26805b261ecSmrg				 ProcScreenSaverDispatch, SProcScreenSaverDispatch,
2694642e01fSmrg				 NULL, StandardMinorOpcode)))
27005b261ecSmrg    {
27105b261ecSmrg	ScreenSaverEventBase = extEntry->eventBase;
27205b261ecSmrg	EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent;
27305b261ecSmrg    }
27405b261ecSmrg}
27505b261ecSmrg
27605b261ecSmrgstatic void
27705b261ecSmrgCheckScreenPrivate (pScreen)
27805b261ecSmrg    ScreenPtr	pScreen;
27905b261ecSmrg{
28005b261ecSmrg    SetupScreen (pScreen);
28105b261ecSmrg
28205b261ecSmrg    if (!pPriv)
28305b261ecSmrg	return;
28405b261ecSmrg    if (!pPriv->attr && !pPriv->events &&
28505b261ecSmrg	!pPriv->hasWindow && pPriv->installedMap == None)
28605b261ecSmrg    {
28705b261ecSmrg	xfree (pPriv);
28805b261ecSmrg	SetScreenPrivate (pScreen, NULL);
28905b261ecSmrg	savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
29005b261ecSmrg    }
29105b261ecSmrg}
29205b261ecSmrg
29305b261ecSmrgstatic ScreenSaverScreenPrivatePtr
29405b261ecSmrgMakeScreenPrivate (pScreen)
29505b261ecSmrg    ScreenPtr	pScreen;
29605b261ecSmrg{
29705b261ecSmrg    SetupScreen (pScreen);
29805b261ecSmrg
29905b261ecSmrg    if (pPriv)
30005b261ecSmrg	return pPriv;
30105b261ecSmrg    pPriv = New (ScreenSaverScreenPrivateRec);
30205b261ecSmrg    if (!pPriv)
30305b261ecSmrg	return 0;
30405b261ecSmrg    pPriv->events = 0;
30505b261ecSmrg    pPriv->attr = 0;
30605b261ecSmrg    pPriv->hasWindow = FALSE;
30705b261ecSmrg    pPriv->installedMap = None;
30805b261ecSmrg    SetScreenPrivate (pScreen, pPriv);
30905b261ecSmrg    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = ScreenSaverHandle;
31005b261ecSmrg    return pPriv;
31105b261ecSmrg}
31205b261ecSmrg
31305b261ecSmrgstatic unsigned long
31405b261ecSmrggetEventMask (pScreen, client)
31505b261ecSmrg    ScreenPtr	pScreen;
31605b261ecSmrg    ClientPtr	client;
31705b261ecSmrg{
31805b261ecSmrg    SetupScreen(pScreen);
31905b261ecSmrg    ScreenSaverEventPtr	pEv;
32005b261ecSmrg
32105b261ecSmrg    if (!pPriv)
32205b261ecSmrg	return 0;
32305b261ecSmrg    for (pEv = pPriv->events; pEv; pEv = pEv->next)
32405b261ecSmrg	if (pEv->client == client)
32505b261ecSmrg	    return pEv->mask;
32605b261ecSmrg    return 0;
32705b261ecSmrg}
32805b261ecSmrg
32905b261ecSmrgstatic Bool
33005b261ecSmrgsetEventMask (pScreen, client, mask)
33105b261ecSmrg    ScreenPtr	pScreen;
33205b261ecSmrg    ClientPtr	client;
33305b261ecSmrg    unsigned long   mask;
33405b261ecSmrg{
33505b261ecSmrg    SetupScreen(pScreen);
33605b261ecSmrg    ScreenSaverEventPtr	pEv, *pPrev;
33705b261ecSmrg
33805b261ecSmrg    if (getEventMask (pScreen, client) == mask)
33905b261ecSmrg	return TRUE;
34005b261ecSmrg    if (!pPriv)
34105b261ecSmrg    {
34205b261ecSmrg	pPriv = MakeScreenPrivate (pScreen);
34305b261ecSmrg	if (!pPriv)
34405b261ecSmrg	    return FALSE;
34505b261ecSmrg    }
34605b261ecSmrg    for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
34705b261ecSmrg	if (pEv->client == client)
34805b261ecSmrg	    break;
34905b261ecSmrg    if (mask == 0)
35005b261ecSmrg    {
35105b261ecSmrg	FreeResource (pEv->resource, EventType);
35205b261ecSmrg	*pPrev = pEv->next;
35305b261ecSmrg	xfree (pEv);
35405b261ecSmrg	CheckScreenPrivate (pScreen);
35505b261ecSmrg    }
35605b261ecSmrg    else
35705b261ecSmrg    {
35805b261ecSmrg    	if (!pEv)
35905b261ecSmrg    	{
36005b261ecSmrg	    pEv = New (ScreenSaverEventRec);
36105b261ecSmrg	    if (!pEv)
36205b261ecSmrg	    {
36305b261ecSmrg		CheckScreenPrivate (pScreen);
36405b261ecSmrg	    	return FALSE;
36505b261ecSmrg	    }
36605b261ecSmrg    	    *pPrev = pEv;
36705b261ecSmrg    	    pEv->next = NULL;
36805b261ecSmrg    	    pEv->client = client;
36905b261ecSmrg    	    pEv->screen = pScreen;
37005b261ecSmrg    	    pEv->resource = FakeClientID (client->index);
37105b261ecSmrg	    if (!AddResource (pEv->resource, EventType, (pointer) pEv))
37205b261ecSmrg		return FALSE;
37305b261ecSmrg    	}
37405b261ecSmrg	pEv->mask = mask;
37505b261ecSmrg    }
37605b261ecSmrg    return TRUE;
37705b261ecSmrg}
37805b261ecSmrg
37905b261ecSmrgstatic void
38005b261ecSmrgFreeAttrs (pAttr)
38105b261ecSmrg    ScreenSaverAttrPtr	pAttr;
38205b261ecSmrg{
38305b261ecSmrg    PixmapPtr	    pPixmap;
38405b261ecSmrg    CursorPtr	    pCursor;
38505b261ecSmrg
38605b261ecSmrg    if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
38705b261ecSmrg	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
38805b261ecSmrg    if ((pPixmap = pAttr->pBorderPixmap) != 0)
38905b261ecSmrg	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
39005b261ecSmrg    if ((pCursor = pAttr->pCursor) != 0)
39105b261ecSmrg	FreeCursor (pCursor, (Cursor) 0);
39205b261ecSmrg}
39305b261ecSmrg
39405b261ecSmrgstatic void
39505b261ecSmrgFreeScreenAttr (pAttr)
39605b261ecSmrg    ScreenSaverAttrPtr	pAttr;
39705b261ecSmrg{
39805b261ecSmrg    FreeAttrs (pAttr);
39905b261ecSmrg    xfree (pAttr->values);
40005b261ecSmrg    xfree (pAttr);
40105b261ecSmrg}
40205b261ecSmrg
40305b261ecSmrgstatic int
40405b261ecSmrgScreenSaverFreeEvents (value, id)
40505b261ecSmrg    pointer value;
40605b261ecSmrg    XID id;
40705b261ecSmrg{
40805b261ecSmrg    ScreenSaverEventPtr	pOld = (ScreenSaverEventPtr)value;
40905b261ecSmrg    ScreenPtr pScreen = pOld->screen;
41005b261ecSmrg    SetupScreen (pScreen);
41105b261ecSmrg    ScreenSaverEventPtr	pEv, *pPrev;
41205b261ecSmrg
41305b261ecSmrg    if (!pPriv)
41405b261ecSmrg	return TRUE;
41505b261ecSmrg    for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
41605b261ecSmrg	if (pEv == pOld)
41705b261ecSmrg	    break;
41805b261ecSmrg    if (!pEv)
41905b261ecSmrg	return TRUE;
42005b261ecSmrg    *pPrev = pEv->next;
42105b261ecSmrg    xfree (pEv);
42205b261ecSmrg    CheckScreenPrivate (pScreen);
42305b261ecSmrg    return TRUE;
42405b261ecSmrg}
42505b261ecSmrg
42605b261ecSmrgstatic int
42705b261ecSmrgScreenSaverFreeAttr (value, id)
42805b261ecSmrg    pointer value;
42905b261ecSmrg    XID id;
43005b261ecSmrg{
43105b261ecSmrg    ScreenSaverAttrPtr	pOldAttr = (ScreenSaverAttrPtr)value;
43205b261ecSmrg    ScreenPtr	pScreen = pOldAttr->screen;
43305b261ecSmrg    SetupScreen (pScreen);
43405b261ecSmrg
43505b261ecSmrg    if (!pPriv)
43605b261ecSmrg	return TRUE;
43705b261ecSmrg    if (pPriv->attr != pOldAttr)
43805b261ecSmrg	return TRUE;
43905b261ecSmrg    FreeScreenAttr (pOldAttr);
44005b261ecSmrg    pPriv->attr = NULL;
44105b261ecSmrg    if (pPriv->hasWindow)
44205b261ecSmrg    {
4434642e01fSmrg	dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
4444642e01fSmrg	dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
44505b261ecSmrg    }
44605b261ecSmrg    CheckScreenPrivate (pScreen);
44705b261ecSmrg    return TRUE;
44805b261ecSmrg}
44905b261ecSmrg
45005b261ecSmrgstatic int
45105b261ecSmrgScreenSaverFreeSuspend (pointer value, XID id)
45205b261ecSmrg{
45305b261ecSmrg    ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
45405b261ecSmrg    ScreenSaverSuspensionPtr *prev, this;
45505b261ecSmrg
45605b261ecSmrg    /* Unlink and free the suspension record for the client */
45705b261ecSmrg    for (prev = &suspendingClients; (this = *prev); prev = &this->next)
45805b261ecSmrg    {
45905b261ecSmrg	if (this == data)
46005b261ecSmrg	{
46105b261ecSmrg	    *prev = this->next;
46205b261ecSmrg	    xfree (this);
46305b261ecSmrg	    break;
46405b261ecSmrg	}
46505b261ecSmrg    }
46605b261ecSmrg
46705b261ecSmrg    /* Reenable the screensaver if this was the last client suspending it. */
46805b261ecSmrg    if (screenSaverSuspended && suspendingClients == NULL)
46905b261ecSmrg    {
47005b261ecSmrg	screenSaverSuspended = FALSE;
47105b261ecSmrg
47205b261ecSmrg	/* The screensaver could be active, since suspending it (by design)
47305b261ecSmrg	   doesn't prevent it from being forceably activated */
47405b261ecSmrg#ifdef DPMSExtension
47505b261ecSmrg	if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn)
47605b261ecSmrg#else
47705b261ecSmrg	if (screenIsSaved != SCREEN_SAVER_ON)
47805b261ecSmrg#endif
47905b261ecSmrg	{
48005b261ecSmrg	    UpdateCurrentTimeIf();
48105b261ecSmrg	    lastDeviceEventTime = currentTime;
48205b261ecSmrg	    SetScreenSaverTimer();
48305b261ecSmrg	}
48405b261ecSmrg    }
48505b261ecSmrg
48605b261ecSmrg    return Success;
48705b261ecSmrg}
48805b261ecSmrg
48905b261ecSmrgstatic void
49005b261ecSmrgSendScreenSaverNotify (pScreen, state, forced)
49105b261ecSmrg    ScreenPtr			pScreen;
49205b261ecSmrg    int	    state;
49305b261ecSmrg    Bool    forced;
49405b261ecSmrg{
49505b261ecSmrg    ScreenSaverScreenPrivatePtr	pPriv;
49605b261ecSmrg    ScreenSaverEventPtr		pEv;
49705b261ecSmrg    unsigned long		mask;
49805b261ecSmrg    xScreenSaverNotifyEvent	ev;
49905b261ecSmrg    ClientPtr			client;
50005b261ecSmrg    int				kind;
50105b261ecSmrg
50205b261ecSmrg    UpdateCurrentTimeIf ();
50305b261ecSmrg    mask = ScreenSaverNotifyMask;
50405b261ecSmrg    if (state == ScreenSaverCycle)
50505b261ecSmrg	mask = ScreenSaverCycleMask;
50605b261ecSmrg    pScreen = screenInfo.screens[pScreen->myNum];
50705b261ecSmrg    pPriv = GetScreenPrivate(pScreen);
50805b261ecSmrg    if (!pPriv)
50905b261ecSmrg	return;
51005b261ecSmrg    if (pPriv->attr)
51105b261ecSmrg	kind = ScreenSaverExternal;
51205b261ecSmrg    else if (ScreenSaverBlanking != DontPreferBlanking)
51305b261ecSmrg	kind = ScreenSaverBlanked;
51405b261ecSmrg    else
51505b261ecSmrg	kind = ScreenSaverInternal;
51605b261ecSmrg    for (pEv = pPriv->events; pEv; pEv = pEv->next)
51705b261ecSmrg    {
51805b261ecSmrg	client = pEv->client;
51905b261ecSmrg	if (client->clientGone)
52005b261ecSmrg	    continue;
52105b261ecSmrg	if (!(pEv->mask & mask))
52205b261ecSmrg	    continue;
52305b261ecSmrg	ev.type = ScreenSaverNotify + ScreenSaverEventBase;
52405b261ecSmrg	ev.state = state;
52505b261ecSmrg	ev.sequenceNumber = client->sequence;
52605b261ecSmrg	ev.timestamp = currentTime.milliseconds;
52705b261ecSmrg	ev.root = WindowTable[pScreen->myNum]->drawable.id;
52805b261ecSmrg	ev.window = savedScreenInfo[pScreen->myNum].wid;
52905b261ecSmrg	ev.kind = kind;
53005b261ecSmrg	ev.forced = forced;
53105b261ecSmrg	WriteEventsToClient (client, 1, (xEvent *) &ev);
53205b261ecSmrg    }
53305b261ecSmrg}
53405b261ecSmrg
53505b261ecSmrgstatic void
53605b261ecSmrgSScreenSaverNotifyEvent (from, to)
53705b261ecSmrg    xScreenSaverNotifyEvent *from, *to;
53805b261ecSmrg{
53905b261ecSmrg    to->type = from->type;
54005b261ecSmrg    to->state = from->state;
54105b261ecSmrg    cpswaps (from->sequenceNumber, to->sequenceNumber);
54205b261ecSmrg    cpswapl (from->timestamp, to->timestamp);
54305b261ecSmrg    cpswapl (from->root, to->root);
54405b261ecSmrg    cpswapl (from->window, to->window);
54505b261ecSmrg    to->kind = from->kind;
54605b261ecSmrg    to->forced = from->forced;
54705b261ecSmrg}
54805b261ecSmrg
54905b261ecSmrgstatic void
55005b261ecSmrgUninstallSaverColormap (pScreen)
55105b261ecSmrg    ScreenPtr	pScreen;
55205b261ecSmrg{
55305b261ecSmrg    SetupScreen(pScreen);
55405b261ecSmrg    ColormapPtr			pCmap;
55505b261ecSmrg
55605b261ecSmrg    if (pPriv && pPriv->installedMap != None)
55705b261ecSmrg    {
55805b261ecSmrg	pCmap = (ColormapPtr) LookupIDByType (pPriv->installedMap, RT_COLORMAP);
55905b261ecSmrg	if (pCmap)
56005b261ecSmrg	    (*pCmap->pScreen->UninstallColormap) (pCmap);
56105b261ecSmrg	pPriv->installedMap = None;
56205b261ecSmrg	CheckScreenPrivate (pScreen);
56305b261ecSmrg    }
56405b261ecSmrg}
56505b261ecSmrg
56605b261ecSmrgstatic Bool
56705b261ecSmrgCreateSaverWindow (pScreen)
56805b261ecSmrg    ScreenPtr	pScreen;
56905b261ecSmrg{
57005b261ecSmrg    SetupScreen (pScreen);
57105b261ecSmrg    ScreenSaverStuffPtr		pSaver;
57205b261ecSmrg    ScreenSaverAttrPtr		pAttr;
57305b261ecSmrg    WindowPtr			pWin;
57405b261ecSmrg    int				result;
57505b261ecSmrg    unsigned long		mask;
57605b261ecSmrg    Colormap			*installedMaps;
57705b261ecSmrg    int				numInstalled;
57805b261ecSmrg    int				i;
57905b261ecSmrg    Colormap			wantMap;
58005b261ecSmrg    ColormapPtr			pCmap;
58105b261ecSmrg
58205b261ecSmrg    pSaver = &savedScreenInfo[pScreen->myNum];
58305b261ecSmrg    if (pSaver->pWindow)
58405b261ecSmrg    {
58505b261ecSmrg	pSaver->pWindow = NullWindow;
58605b261ecSmrg	FreeResource (pSaver->wid, RT_NONE);
58705b261ecSmrg	if (pPriv)
58805b261ecSmrg	{
58905b261ecSmrg	    UninstallSaverColormap (pScreen);
59005b261ecSmrg	    pPriv->hasWindow = FALSE;
59105b261ecSmrg	    CheckScreenPrivate (pScreen);
59205b261ecSmrg	}
59305b261ecSmrg    }
59405b261ecSmrg
59505b261ecSmrg    if (!pPriv || !(pAttr = pPriv->attr))
59605b261ecSmrg	return FALSE;
59705b261ecSmrg
59805b261ecSmrg    pPriv->installedMap = None;
59905b261ecSmrg
60005b261ecSmrg    if (GrabInProgress && GrabInProgress != pAttr->client->index)
60105b261ecSmrg	return FALSE;
60205b261ecSmrg
60305b261ecSmrg    pWin = CreateWindow (pSaver->wid, WindowTable[pScreen->myNum],
60405b261ecSmrg			 pAttr->x, pAttr->y, pAttr->width, pAttr->height,
60505b261ecSmrg			 pAttr->borderWidth, pAttr->class,
60605b261ecSmrg			 pAttr->mask, (XID *)pAttr->values,
60705b261ecSmrg			 pAttr->depth, serverClient, pAttr->visual,
60805b261ecSmrg			 &result);
60905b261ecSmrg    if (!pWin)
61005b261ecSmrg	return FALSE;
61105b261ecSmrg
61205b261ecSmrg    if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
61305b261ecSmrg	return FALSE;
61405b261ecSmrg
61505b261ecSmrg    mask = 0;
61605b261ecSmrg    if (pAttr->pBackgroundPixmap)
61705b261ecSmrg    {
61805b261ecSmrg	pWin->backgroundState = BackgroundPixmap;
61905b261ecSmrg	pWin->background.pixmap = pAttr->pBackgroundPixmap;
62005b261ecSmrg	pAttr->pBackgroundPixmap->refcnt++;
62105b261ecSmrg	mask |= CWBackPixmap;
62205b261ecSmrg    }
62305b261ecSmrg    if (pAttr->pBorderPixmap)
62405b261ecSmrg    {
62505b261ecSmrg	pWin->borderIsPixel = FALSE;
62605b261ecSmrg	pWin->border.pixmap = pAttr->pBorderPixmap;
62705b261ecSmrg	pAttr->pBorderPixmap->refcnt++;
62805b261ecSmrg	mask |= CWBorderPixmap;
62905b261ecSmrg    }
63005b261ecSmrg    if (pAttr->pCursor)
63105b261ecSmrg    {
63205b261ecSmrg	if (!pWin->optional)
63305b261ecSmrg	    if (!MakeWindowOptional (pWin))
63405b261ecSmrg	    {
63505b261ecSmrg    	    	FreeResource (pWin->drawable.id, RT_NONE);
63605b261ecSmrg    	    	return FALSE;
63705b261ecSmrg	    }
63805b261ecSmrg	if (pWin->optional->cursor)
63905b261ecSmrg	    FreeCursor (pWin->optional->cursor, (Cursor)0);
64005b261ecSmrg	pWin->optional->cursor = pAttr->pCursor;
64105b261ecSmrg	pAttr->pCursor->refcnt++;
64205b261ecSmrg	pWin->cursorIsNone = FALSE;
64305b261ecSmrg	CheckWindowOptionalNeed (pWin);
64405b261ecSmrg	mask |= CWCursor;
64505b261ecSmrg    }
64605b261ecSmrg    if (mask)
64705b261ecSmrg	(*pScreen->ChangeWindowAttributes) (pWin, mask);
64805b261ecSmrg
64905b261ecSmrg    if (pAttr->colormap != None)
65005b261ecSmrg	(void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap,
65105b261ecSmrg				       serverClient);
65205b261ecSmrg
65305b261ecSmrg    MapWindow (pWin, serverClient);
65405b261ecSmrg
65505b261ecSmrg    pPriv->hasWindow = TRUE;
65605b261ecSmrg    pSaver->pWindow = pWin;
65705b261ecSmrg
65805b261ecSmrg    /* check and install our own colormap if it isn't installed now */
65905b261ecSmrg    wantMap = wColormap (pWin);
66005b261ecSmrg    if (wantMap == None)
66105b261ecSmrg	return TRUE;
6624642e01fSmrg    installedMaps = (Colormap *) xalloc (pScreen->maxInstalledCmaps *
66305b261ecSmrg						 sizeof (Colormap));
66405b261ecSmrg    numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps)
66505b261ecSmrg						    (pScreen, installedMaps);
66605b261ecSmrg    for (i = 0; i < numInstalled; i++)
66705b261ecSmrg	if (installedMaps[i] == wantMap)
66805b261ecSmrg	    break;
66905b261ecSmrg
6704642e01fSmrg    xfree ((char *) installedMaps);
67105b261ecSmrg
67205b261ecSmrg    if (i < numInstalled)
67305b261ecSmrg	return TRUE;
67405b261ecSmrg
67505b261ecSmrg    pCmap = (ColormapPtr) LookupIDByType (wantMap, RT_COLORMAP);
67605b261ecSmrg    if (!pCmap)
67705b261ecSmrg	return TRUE;
67805b261ecSmrg
67905b261ecSmrg    pPriv->installedMap = wantMap;
68005b261ecSmrg
68105b261ecSmrg    (*pCmap->pScreen->InstallColormap) (pCmap);
68205b261ecSmrg
68305b261ecSmrg    return TRUE;
68405b261ecSmrg}
68505b261ecSmrg
68605b261ecSmrgstatic Bool
68705b261ecSmrgDestroySaverWindow (pScreen)
68805b261ecSmrg    ScreenPtr	pScreen;
68905b261ecSmrg{
69005b261ecSmrg    SetupScreen(pScreen);
69105b261ecSmrg    ScreenSaverStuffPtr		pSaver;
69205b261ecSmrg
69305b261ecSmrg    if (!pPriv || !pPriv->hasWindow)
69405b261ecSmrg	return FALSE;
69505b261ecSmrg
69605b261ecSmrg    pSaver = &savedScreenInfo[pScreen->myNum];
69705b261ecSmrg    if (pSaver->pWindow)
69805b261ecSmrg    {
69905b261ecSmrg	pSaver->pWindow = NullWindow;
70005b261ecSmrg	FreeResource (pSaver->wid, RT_NONE);
70105b261ecSmrg    }
70205b261ecSmrg    pPriv->hasWindow = FALSE;
70305b261ecSmrg    CheckScreenPrivate (pScreen);
70405b261ecSmrg    UninstallSaverColormap (pScreen);
70505b261ecSmrg    return TRUE;
70605b261ecSmrg}
70705b261ecSmrg
70805b261ecSmrgstatic Bool
70905b261ecSmrgScreenSaverHandle (pScreen, xstate, force)
71005b261ecSmrg    ScreenPtr	pScreen;
71105b261ecSmrg    int		xstate;
71205b261ecSmrg    Bool	force;
71305b261ecSmrg{
71405b261ecSmrg    int				state = 0;
71505b261ecSmrg    Bool			ret = FALSE;
71605b261ecSmrg    ScreenSaverScreenPrivatePtr	pPriv;
71705b261ecSmrg
71805b261ecSmrg    switch (xstate)
71905b261ecSmrg    {
72005b261ecSmrg    case SCREEN_SAVER_ON:
72105b261ecSmrg	state = ScreenSaverOn;
72205b261ecSmrg	ret = CreateSaverWindow (pScreen);
72305b261ecSmrg	break;
72405b261ecSmrg    case SCREEN_SAVER_OFF:
72505b261ecSmrg	state = ScreenSaverOff;
72605b261ecSmrg	ret = DestroySaverWindow (pScreen);
72705b261ecSmrg	break;
72805b261ecSmrg    case SCREEN_SAVER_CYCLE:
72905b261ecSmrg	state = ScreenSaverCycle;
73005b261ecSmrg	pPriv = GetScreenPrivate (pScreen);
73105b261ecSmrg	if (pPriv && pPriv->hasWindow)
73205b261ecSmrg	    ret = TRUE;
73305b261ecSmrg
73405b261ecSmrg    }
73505b261ecSmrg#ifdef PANORAMIX
73605b261ecSmrg    if(noPanoramiXExtension || !pScreen->myNum)
73705b261ecSmrg#endif
73805b261ecSmrg       SendScreenSaverNotify (pScreen, state, force);
73905b261ecSmrg    return ret;
74005b261ecSmrg}
74105b261ecSmrg
74205b261ecSmrgstatic int
74305b261ecSmrgProcScreenSaverQueryVersion (client)
7444642e01fSmrg    ClientPtr	client;
74505b261ecSmrg{
74605b261ecSmrg    xScreenSaverQueryVersionReply	rep;
7474642e01fSmrg    int		n;
74805b261ecSmrg
74905b261ecSmrg    REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq);
75005b261ecSmrg    rep.type = X_Reply;
75105b261ecSmrg    rep.length = 0;
75205b261ecSmrg    rep.sequenceNumber = client->sequence;
75305b261ecSmrg    rep.majorVersion = ScreenSaverMajorVersion;
75405b261ecSmrg    rep.minorVersion = ScreenSaverMinorVersion;
75505b261ecSmrg    if (client->swapped) {
75605b261ecSmrg    	swaps(&rep.sequenceNumber, n);
75705b261ecSmrg    	swapl(&rep.length, n);
75805b261ecSmrg    }
75905b261ecSmrg    WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep);
76005b261ecSmrg    return (client->noClientException);
76105b261ecSmrg}
76205b261ecSmrg
76305b261ecSmrgstatic int
76405b261ecSmrgProcScreenSaverQueryInfo (client)
7654642e01fSmrg    ClientPtr	client;
76605b261ecSmrg{
76705b261ecSmrg    REQUEST(xScreenSaverQueryInfoReq);
76805b261ecSmrg    xScreenSaverQueryInfoReply	rep;
7694642e01fSmrg    int		n, rc;
77005b261ecSmrg    ScreenSaverStuffPtr		pSaver;
77105b261ecSmrg    DrawablePtr			pDraw;
77205b261ecSmrg    CARD32			lastInput;
77305b261ecSmrg    ScreenSaverScreenPrivatePtr	pPriv;
77405b261ecSmrg
77505b261ecSmrg    REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq);
77605b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
7774642e01fSmrg			   DixGetAttrAccess);
7784642e01fSmrg    if (rc != Success)
7794642e01fSmrg	return rc;
7804642e01fSmrg    rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
7814642e01fSmrg		  DixGetAttrAccess);
78205b261ecSmrg    if (rc != Success)
78305b261ecSmrg	return rc;
78405b261ecSmrg
78505b261ecSmrg    pSaver = &savedScreenInfo[pDraw->pScreen->myNum];
78605b261ecSmrg    pPriv = GetScreenPrivate (pDraw->pScreen);
78705b261ecSmrg
78805b261ecSmrg    UpdateCurrentTime ();
78905b261ecSmrg    lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
79005b261ecSmrg
79105b261ecSmrg    rep.type = X_Reply;
79205b261ecSmrg    rep.length = 0;
79305b261ecSmrg    rep.sequenceNumber = client->sequence;
79405b261ecSmrg    rep.window = pSaver->wid;
79505b261ecSmrg    if (screenIsSaved != SCREEN_SAVER_OFF)
79605b261ecSmrg    {
79705b261ecSmrg	rep.state = ScreenSaverOn;
79805b261ecSmrg	if (ScreenSaverTime)
79905b261ecSmrg	    rep.tilOrSince = lastInput - ScreenSaverTime;
80005b261ecSmrg	else
80105b261ecSmrg	    rep.tilOrSince = 0;
80205b261ecSmrg    }
80305b261ecSmrg    else
80405b261ecSmrg    {
80505b261ecSmrg	if (ScreenSaverTime)
80605b261ecSmrg	{
80705b261ecSmrg	    rep.state = ScreenSaverOff;
80805b261ecSmrg	    if (ScreenSaverTime < lastInput)
80905b261ecSmrg		rep.tilOrSince = 0;
81005b261ecSmrg	    else
81105b261ecSmrg		rep.tilOrSince = ScreenSaverTime - lastInput;
81205b261ecSmrg	}
81305b261ecSmrg	else
81405b261ecSmrg	{
81505b261ecSmrg	    rep.state = ScreenSaverDisabled;
81605b261ecSmrg	    rep.tilOrSince = 0;
81705b261ecSmrg	}
81805b261ecSmrg    }
81905b261ecSmrg    rep.idle = lastInput;
82005b261ecSmrg    rep.eventMask = getEventMask (pDraw->pScreen, client);
82105b261ecSmrg    if (pPriv && pPriv->attr)
82205b261ecSmrg	rep.kind = ScreenSaverExternal;
82305b261ecSmrg    else if (ScreenSaverBlanking != DontPreferBlanking)
82405b261ecSmrg	rep.kind = ScreenSaverBlanked;
82505b261ecSmrg    else
82605b261ecSmrg	rep.kind = ScreenSaverInternal;
82705b261ecSmrg    if (client->swapped)
82805b261ecSmrg    {
82905b261ecSmrg	swaps (&rep.sequenceNumber, n);
83005b261ecSmrg	swapl (&rep.length, n);
83105b261ecSmrg	swapl (&rep.window, n);
83205b261ecSmrg	swapl (&rep.tilOrSince, n);
83305b261ecSmrg	swapl (&rep.idle, n);
83405b261ecSmrg	swapl (&rep.eventMask, n);
83505b261ecSmrg    }
83605b261ecSmrg    WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep);
83705b261ecSmrg    return (client->noClientException);
83805b261ecSmrg}
83905b261ecSmrg
84005b261ecSmrgstatic int
84105b261ecSmrgProcScreenSaverSelectInput (client)
8424642e01fSmrg    ClientPtr	client;
84305b261ecSmrg{
84405b261ecSmrg    REQUEST(xScreenSaverSelectInputReq);
84505b261ecSmrg    DrawablePtr			pDraw;
84605b261ecSmrg    int				rc;
84705b261ecSmrg
84805b261ecSmrg    REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq);
84905b261ecSmrg    rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0,
8504642e01fSmrg			    DixGetAttrAccess);
8514642e01fSmrg    if (rc != Success)
8524642e01fSmrg	return rc;
8534642e01fSmrg
8544642e01fSmrg    rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
8554642e01fSmrg		  DixSetAttrAccess);
85605b261ecSmrg    if (rc != Success)
85705b261ecSmrg	return rc;
8584642e01fSmrg
85905b261ecSmrg    if (!setEventMask (pDraw->pScreen, client, stuff->eventMask))
86005b261ecSmrg	return BadAlloc;
86105b261ecSmrg    return Success;
86205b261ecSmrg}
86305b261ecSmrg
86405b261ecSmrgstatic int
86505b261ecSmrgScreenSaverSetAttributes (ClientPtr client)
86605b261ecSmrg{
86705b261ecSmrg    REQUEST(xScreenSaverSetAttributesReq);
86805b261ecSmrg    DrawablePtr			pDraw;
86905b261ecSmrg    WindowPtr			pParent;
87005b261ecSmrg    ScreenPtr			pScreen;
87105b261ecSmrg    ScreenSaverScreenPrivatePtr pPriv = 0;
87205b261ecSmrg    ScreenSaverAttrPtr		pAttr = 0;
87305b261ecSmrg    int				ret, len, class, bw, depth;
87405b261ecSmrg    unsigned long		visual;
87505b261ecSmrg    int				idepth, ivisual;
87605b261ecSmrg    Bool			fOK;
87705b261ecSmrg    DepthPtr			pDepth;
87805b261ecSmrg    WindowOptPtr		ancwopt;
87905b261ecSmrg    unsigned int		*pVlist;
88005b261ecSmrg    unsigned long		*values = 0;
88105b261ecSmrg    unsigned long		tmask, imask;
88205b261ecSmrg    unsigned long		val;
88305b261ecSmrg    Pixmap			pixID;
88405b261ecSmrg    PixmapPtr			pPixmap;
88505b261ecSmrg    Cursor			cursorID;
88605b261ecSmrg    CursorPtr			pCursor;
88705b261ecSmrg    Colormap			cmap;
88805b261ecSmrg    ColormapPtr			pCmap;
88905b261ecSmrg
89005b261ecSmrg    REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
89105b261ecSmrg    ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
8924642e01fSmrg			    DixGetAttrAccess);
89305b261ecSmrg    if (ret != Success)
89405b261ecSmrg	return ret;
89505b261ecSmrg    pScreen = pDraw->pScreen;
89605b261ecSmrg    pParent = WindowTable[pScreen->myNum];
89705b261ecSmrg
8984642e01fSmrg    ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess);
8994642e01fSmrg    if (ret != Success)
9004642e01fSmrg	return ret;
9014642e01fSmrg
90205b261ecSmrg    len = stuff->length -  (sizeof(xScreenSaverSetAttributesReq) >> 2);
90305b261ecSmrg    if (Ones(stuff->mask) != len)
90405b261ecSmrg        return BadLength;
90505b261ecSmrg    if (!stuff->width || !stuff->height)
90605b261ecSmrg    {
90705b261ecSmrg	client->errorValue = 0;
90805b261ecSmrg        return BadValue;
90905b261ecSmrg    }
91005b261ecSmrg    switch (class = stuff->c_class)
91105b261ecSmrg    {
91205b261ecSmrg    case CopyFromParent:
91305b261ecSmrg    case InputOnly:
91405b261ecSmrg    case InputOutput:
91505b261ecSmrg	break;
91605b261ecSmrg    default:
91705b261ecSmrg	client->errorValue = class;
91805b261ecSmrg	return BadValue;
91905b261ecSmrg    }
92005b261ecSmrg    bw = stuff->borderWidth;
92105b261ecSmrg    depth = stuff->depth;
92205b261ecSmrg    visual = stuff->visualID;
92305b261ecSmrg
92405b261ecSmrg    /* copied directly from CreateWindow */
92505b261ecSmrg
92605b261ecSmrg    if (class == CopyFromParent)
92705b261ecSmrg	class = pParent->drawable.class;
92805b261ecSmrg
92905b261ecSmrg    if ((class != InputOutput) && (class != InputOnly))
93005b261ecSmrg    {
93105b261ecSmrg	client->errorValue = class;
93205b261ecSmrg	return BadValue;
93305b261ecSmrg    }
93405b261ecSmrg
93505b261ecSmrg    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
93605b261ecSmrg        return BadMatch;
93705b261ecSmrg
93805b261ecSmrg    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
93905b261ecSmrg        return BadMatch;
94005b261ecSmrg
94105b261ecSmrg    if ((class == InputOutput) && (depth == 0))
94205b261ecSmrg        depth = pParent->drawable.depth;
94305b261ecSmrg    ancwopt = pParent->optional;
94405b261ecSmrg    if (!ancwopt)
94505b261ecSmrg	ancwopt = FindWindowWithOptional(pParent)->optional;
94605b261ecSmrg    if (visual == CopyFromParent)
94705b261ecSmrg	visual = ancwopt->visual;
94805b261ecSmrg
94905b261ecSmrg    /* Find out if the depth and visual are acceptable for this Screen */
95005b261ecSmrg    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
95105b261ecSmrg    {
95205b261ecSmrg	fOK = FALSE;
95305b261ecSmrg	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
95405b261ecSmrg	{
95505b261ecSmrg	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
95605b261ecSmrg	    if ((depth == pDepth->depth) || (depth == 0))
95705b261ecSmrg	    {
95805b261ecSmrg		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
95905b261ecSmrg		{
96005b261ecSmrg		    if (visual == pDepth->vids[ivisual])
96105b261ecSmrg		    {
96205b261ecSmrg			fOK = TRUE;
96305b261ecSmrg			break;
96405b261ecSmrg		    }
96505b261ecSmrg		}
96605b261ecSmrg	    }
96705b261ecSmrg	}
96805b261ecSmrg	if (fOK == FALSE)
96905b261ecSmrg	    return BadMatch;
97005b261ecSmrg    }
97105b261ecSmrg
97205b261ecSmrg    if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
97305b261ecSmrg	(class != InputOnly) &&
97405b261ecSmrg	(depth != pParent->drawable.depth))
97505b261ecSmrg    {
97605b261ecSmrg        return BadMatch;
97705b261ecSmrg    }
97805b261ecSmrg
97905b261ecSmrg    if (((stuff->mask & CWColormap) == 0) &&
98005b261ecSmrg	(class != InputOnly) &&
98105b261ecSmrg	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
98205b261ecSmrg    {
98305b261ecSmrg	return BadMatch;
98405b261ecSmrg    }
98505b261ecSmrg
98605b261ecSmrg    /* end of errors from CreateWindow */
98705b261ecSmrg
98805b261ecSmrg    pPriv = GetScreenPrivate (pScreen);
98905b261ecSmrg    if (pPriv && pPriv->attr)
99005b261ecSmrg    {
99105b261ecSmrg	if (pPriv->attr->client != client)
99205b261ecSmrg	    return BadAccess;
99305b261ecSmrg    }
99405b261ecSmrg    if (!pPriv)
99505b261ecSmrg    {
99605b261ecSmrg	pPriv = MakeScreenPrivate (pScreen);
99705b261ecSmrg	if (!pPriv)
99805b261ecSmrg	    return FALSE;
99905b261ecSmrg    }
100005b261ecSmrg    pAttr = New (ScreenSaverAttrRec);
100105b261ecSmrg    if (!pAttr)
100205b261ecSmrg    {
100305b261ecSmrg	ret = BadAlloc;
100405b261ecSmrg	goto bail;
100505b261ecSmrg    }
100605b261ecSmrg    /* over allocate for override redirect */
100705b261ecSmrg    values = (unsigned long *) xalloc ((len + 1) * sizeof (unsigned long));
100805b261ecSmrg    if (!values)
100905b261ecSmrg    {
101005b261ecSmrg	ret = BadAlloc;
101105b261ecSmrg	goto bail;
101205b261ecSmrg    }
101305b261ecSmrg    pAttr->screen = pScreen;
101405b261ecSmrg    pAttr->client = client;
101505b261ecSmrg    pAttr->x = stuff->x;
101605b261ecSmrg    pAttr->y = stuff->y;
101705b261ecSmrg    pAttr->width = stuff->width;
101805b261ecSmrg    pAttr->height = stuff->height;
101905b261ecSmrg    pAttr->borderWidth = stuff->borderWidth;
102005b261ecSmrg    pAttr->class = stuff->c_class;
102105b261ecSmrg    pAttr->depth = depth;
102205b261ecSmrg    pAttr->visual = visual;
102305b261ecSmrg    pAttr->colormap = None;
102405b261ecSmrg    pAttr->pCursor = NullCursor;
102505b261ecSmrg    pAttr->pBackgroundPixmap = NullPixmap;
102605b261ecSmrg    pAttr->pBorderPixmap = NullPixmap;
102705b261ecSmrg    pAttr->values = values;
102805b261ecSmrg    /*
102905b261ecSmrg     * go through the mask, checking the values,
103005b261ecSmrg     * looking up pixmaps and cursors and hold a reference
103105b261ecSmrg     * to them.
103205b261ecSmrg     */
103305b261ecSmrg    pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
103405b261ecSmrg    pVlist = (unsigned int *) (stuff + 1);
103505b261ecSmrg    while (tmask) {
103605b261ecSmrg	imask = lowbit (tmask);
103705b261ecSmrg	tmask &= ~imask;
103805b261ecSmrg	switch (imask)
103905b261ecSmrg        {
104005b261ecSmrg	case CWBackPixmap:
104105b261ecSmrg	    pixID = (Pixmap )*pVlist;
104205b261ecSmrg	    if (pixID == None)
104305b261ecSmrg	    {
104405b261ecSmrg		*values++ = None;
104505b261ecSmrg	    }
104605b261ecSmrg	    else if (pixID == ParentRelative)
104705b261ecSmrg	    {
104805b261ecSmrg		if (depth != pParent->drawable.depth)
104905b261ecSmrg		{
105005b261ecSmrg		    ret = BadMatch;
105105b261ecSmrg		    goto PatchUp;
105205b261ecSmrg		}
105305b261ecSmrg		*values++ = ParentRelative;
105405b261ecSmrg	    }
105505b261ecSmrg            else
105605b261ecSmrg	    {
10574642e01fSmrg		ret = dixLookupResource((pointer *)&pPixmap, pixID, RT_PIXMAP,
10584642e01fSmrg					client, DixReadAccess);
10594642e01fSmrg		if (ret == Success)
106005b261ecSmrg		{
106105b261ecSmrg                    if  ((pPixmap->drawable.depth != depth) ||
106205b261ecSmrg			 (pPixmap->drawable.pScreen != pScreen))
106305b261ecSmrg		    {
106405b261ecSmrg                        ret = BadMatch;
106505b261ecSmrg			goto PatchUp;
106605b261ecSmrg		    }
106705b261ecSmrg		    pAttr->pBackgroundPixmap = pPixmap;
106805b261ecSmrg		    pPixmap->refcnt++;
106905b261ecSmrg		    pAttr->mask &= ~CWBackPixmap;
107005b261ecSmrg		}
107105b261ecSmrg	        else
107205b261ecSmrg		{
10734642e01fSmrg		    ret = (ret == BadValue) ? BadPixmap : ret;
107405b261ecSmrg		    client->errorValue = pixID;
107505b261ecSmrg		    goto PatchUp;
107605b261ecSmrg		}
107705b261ecSmrg	    }
107805b261ecSmrg	    break;
107905b261ecSmrg	case CWBackPixel:
108005b261ecSmrg	    *values++ = (CARD32) *pVlist;
108105b261ecSmrg	    break;
108205b261ecSmrg	case CWBorderPixmap:
108305b261ecSmrg	    pixID = (Pixmap ) *pVlist;
108405b261ecSmrg	    if (pixID == CopyFromParent)
108505b261ecSmrg	    {
108605b261ecSmrg		if (depth != pParent->drawable.depth)
108705b261ecSmrg		{
108805b261ecSmrg		    ret = BadMatch;
108905b261ecSmrg		    goto PatchUp;
109005b261ecSmrg		}
109105b261ecSmrg		*values++ = CopyFromParent;
109205b261ecSmrg	    }
109305b261ecSmrg	    else
109405b261ecSmrg	    {
10954642e01fSmrg		ret = dixLookupResource((pointer *)&pPixmap, pixID, RT_PIXMAP,
10964642e01fSmrg					client, DixReadAccess);
10974642e01fSmrg		if (ret == Success)
109805b261ecSmrg		{
109905b261ecSmrg                    if  ((pPixmap->drawable.depth != depth) ||
110005b261ecSmrg			 (pPixmap->drawable.pScreen != pScreen))
110105b261ecSmrg		    {
110205b261ecSmrg			ret = BadMatch;
110305b261ecSmrg			goto PatchUp;
110405b261ecSmrg		    }
110505b261ecSmrg		    pAttr->pBorderPixmap = pPixmap;
110605b261ecSmrg		    pPixmap->refcnt++;
110705b261ecSmrg		    pAttr->mask &= ~CWBorderPixmap;
110805b261ecSmrg		}
110905b261ecSmrg    	        else
111005b261ecSmrg		{
11114642e01fSmrg		    ret = (ret == BadValue) ? BadPixmap : ret;
111205b261ecSmrg		    client->errorValue = pixID;
111305b261ecSmrg		    goto PatchUp;
111405b261ecSmrg		}
111505b261ecSmrg	    }
111605b261ecSmrg	    break;
111705b261ecSmrg	case CWBorderPixel:
111805b261ecSmrg            *values++ = (CARD32) *pVlist;
111905b261ecSmrg            break;
112005b261ecSmrg	case CWBitGravity:
112105b261ecSmrg	    val = (CARD8 )*pVlist;
112205b261ecSmrg	    if (val > StaticGravity)
112305b261ecSmrg	    {
112405b261ecSmrg		ret = BadValue;
112505b261ecSmrg		client->errorValue = val;
112605b261ecSmrg		goto PatchUp;
112705b261ecSmrg	    }
112805b261ecSmrg	    *values++ = val;
112905b261ecSmrg	    break;
113005b261ecSmrg	case CWWinGravity:
113105b261ecSmrg	    val = (CARD8 )*pVlist;
113205b261ecSmrg	    if (val > StaticGravity)
113305b261ecSmrg	    {
113405b261ecSmrg		ret = BadValue;
113505b261ecSmrg		client->errorValue = val;
113605b261ecSmrg		goto PatchUp;
113705b261ecSmrg	    }
113805b261ecSmrg	    *values++ = val;
113905b261ecSmrg	    break;
114005b261ecSmrg	case CWBackingStore:
114105b261ecSmrg	    val = (CARD8 )*pVlist;
114205b261ecSmrg	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
114305b261ecSmrg	    {
114405b261ecSmrg		ret = BadValue;
114505b261ecSmrg		client->errorValue = val;
114605b261ecSmrg		goto PatchUp;
114705b261ecSmrg	    }
114805b261ecSmrg	    *values++ = val;
114905b261ecSmrg	    break;
115005b261ecSmrg	case CWBackingPlanes:
115105b261ecSmrg	    *values++ = (CARD32) *pVlist;
115205b261ecSmrg	    break;
115305b261ecSmrg	case CWBackingPixel:
115405b261ecSmrg	    *values++ = (CARD32) *pVlist;
115505b261ecSmrg	    break;
115605b261ecSmrg	case CWSaveUnder:
115705b261ecSmrg	    val = (BOOL) *pVlist;
115805b261ecSmrg	    if ((val != xTrue) && (val != xFalse))
115905b261ecSmrg	    {
116005b261ecSmrg		ret = BadValue;
116105b261ecSmrg		client->errorValue = val;
116205b261ecSmrg		goto PatchUp;
116305b261ecSmrg	    }
116405b261ecSmrg	    *values++ = val;
116505b261ecSmrg	    break;
116605b261ecSmrg	case CWEventMask:
116705b261ecSmrg	    *values++ = (CARD32) *pVlist;
116805b261ecSmrg	    break;
116905b261ecSmrg	case CWDontPropagate:
117005b261ecSmrg	    *values++ = (CARD32) *pVlist;
117105b261ecSmrg	    break;
117205b261ecSmrg	case CWOverrideRedirect:
117305b261ecSmrg	    if (!(stuff->mask & CWOverrideRedirect))
117405b261ecSmrg		pVlist--;
117505b261ecSmrg	    else
117605b261ecSmrg	    {
117705b261ecSmrg	    	val = (BOOL ) *pVlist;
117805b261ecSmrg	    	if ((val != xTrue) && (val != xFalse))
117905b261ecSmrg	    	{
118005b261ecSmrg		    ret = BadValue;
118105b261ecSmrg		    client->errorValue = val;
118205b261ecSmrg		    goto PatchUp;
118305b261ecSmrg	    	}
118405b261ecSmrg	    }
118505b261ecSmrg	    *values++ = xTrue;
118605b261ecSmrg	    break;
118705b261ecSmrg	case CWColormap:
118805b261ecSmrg	    cmap = (Colormap) *pVlist;
11894642e01fSmrg	    ret = dixLookupResource((pointer *)&pCmap, cmap, RT_COLORMAP,
11904642e01fSmrg				    client, DixUseAccess);
11914642e01fSmrg	    if (ret != Success)
119205b261ecSmrg	    {
11934642e01fSmrg		ret = (ret == BadValue) ? BadColor : ret;
119405b261ecSmrg		client->errorValue = cmap;
119505b261ecSmrg		goto PatchUp;
119605b261ecSmrg	    }
119705b261ecSmrg	    if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen)
119805b261ecSmrg	    {
119905b261ecSmrg		ret = BadMatch;
120005b261ecSmrg		goto PatchUp;
120105b261ecSmrg	    }
120205b261ecSmrg	    pAttr->colormap = cmap;
120305b261ecSmrg	    pAttr->mask &= ~CWColormap;
120405b261ecSmrg	    break;
120505b261ecSmrg	case CWCursor:
120605b261ecSmrg	    cursorID = (Cursor ) *pVlist;
120705b261ecSmrg	    if ( cursorID == None)
120805b261ecSmrg	    {
120905b261ecSmrg		*values++ = None;
121005b261ecSmrg	    }
121105b261ecSmrg	    else
121205b261ecSmrg	    {
12134642e01fSmrg		ret = dixLookupResource((pointer *)&pCursor, cursorID,
12144642e01fSmrg					RT_CURSOR, client, DixUseAccess);
12154642e01fSmrg	    	if (ret != Success)
121605b261ecSmrg	    	{
12174642e01fSmrg		    ret = (ret == BadValue) ? BadCursor : ret;
121805b261ecSmrg		    client->errorValue = cursorID;
121905b261ecSmrg		    goto PatchUp;
122005b261ecSmrg	    	}
122105b261ecSmrg		pCursor->refcnt++;
122205b261ecSmrg		pAttr->pCursor = pCursor;
122305b261ecSmrg		pAttr->mask &= ~CWCursor;
122405b261ecSmrg	    }
122505b261ecSmrg	    break;
122605b261ecSmrg     	 default:
122705b261ecSmrg	    ret = BadValue;
122805b261ecSmrg	    client->errorValue = stuff->mask;
122905b261ecSmrg	    goto PatchUp;
123005b261ecSmrg	}
123105b261ecSmrg	pVlist++;
123205b261ecSmrg    }
123305b261ecSmrg    if (pPriv->attr)
123405b261ecSmrg	FreeScreenAttr (pPriv->attr);
123505b261ecSmrg    pPriv->attr = pAttr;
123605b261ecSmrg    pAttr->resource = FakeClientID (client->index);
123705b261ecSmrg    if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr))
123805b261ecSmrg	return BadAlloc;
123905b261ecSmrg    return Success;
124005b261ecSmrgPatchUp:
124105b261ecSmrg    FreeAttrs (pAttr);
124205b261ecSmrgbail:
124305b261ecSmrg    CheckScreenPrivate (pScreen);
124405b261ecSmrg    if (pAttr) xfree (pAttr->values);
124505b261ecSmrg    xfree (pAttr);
124605b261ecSmrg    return ret;
124705b261ecSmrg}
124805b261ecSmrg
124905b261ecSmrgstatic int
125005b261ecSmrgScreenSaverUnsetAttributes (ClientPtr client)
125105b261ecSmrg{
125205b261ecSmrg    REQUEST(xScreenSaverSetAttributesReq);
125305b261ecSmrg    DrawablePtr			pDraw;
125405b261ecSmrg    ScreenSaverScreenPrivatePtr	pPriv;
125505b261ecSmrg    int				rc;
125605b261ecSmrg
125705b261ecSmrg    REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq);
125805b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
12594642e01fSmrg			   DixGetAttrAccess);
126005b261ecSmrg    if (rc != Success)
126105b261ecSmrg	return rc;
126205b261ecSmrg    pPriv = GetScreenPrivate (pDraw->pScreen);
126305b261ecSmrg    if (pPriv && pPriv->attr && pPriv->attr->client == client)
126405b261ecSmrg    {
126505b261ecSmrg	FreeResource (pPriv->attr->resource, AttrType);
126605b261ecSmrg    	FreeScreenAttr (pPriv->attr);
126705b261ecSmrg	pPriv->attr = NULL;
126805b261ecSmrg	CheckScreenPrivate (pDraw->pScreen);
126905b261ecSmrg    }
127005b261ecSmrg    return Success;
127105b261ecSmrg}
127205b261ecSmrg
127305b261ecSmrgstatic int
127405b261ecSmrgProcScreenSaverSetAttributes (ClientPtr client)
127505b261ecSmrg{
127605b261ecSmrg#ifdef PANORAMIX
127705b261ecSmrg    if(!noPanoramiXExtension) {
127805b261ecSmrg       REQUEST(xScreenSaverSetAttributesReq);
127905b261ecSmrg       PanoramiXRes *draw;
128005b261ecSmrg       PanoramiXRes *backPix = NULL;
128105b261ecSmrg       PanoramiXRes *bordPix = NULL;
128205b261ecSmrg       PanoramiXRes *cmap    = NULL;
128305b261ecSmrg       int i, status = 0, len;
128405b261ecSmrg       int  pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
128505b261ecSmrg       XID orig_visual, tmp;
128605b261ecSmrg
128705b261ecSmrg       REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
128805b261ecSmrg
128905b261ecSmrg       if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
129005b261ecSmrg                   client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
129105b261ecSmrg           return BadDrawable;
129205b261ecSmrg
129305b261ecSmrg       len = stuff->length -  (sizeof(xScreenSaverSetAttributesReq) >> 2);
129405b261ecSmrg       if (Ones(stuff->mask) != len)
129505b261ecSmrg           return BadLength;
129605b261ecSmrg
129705b261ecSmrg       if((Mask)stuff->mask & CWBackPixmap) {
129805b261ecSmrg          pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
129905b261ecSmrg          tmp = *((CARD32 *) &stuff[1] + pback_offset);
130005b261ecSmrg          if ((tmp != None) && (tmp != ParentRelative)) {
130105b261ecSmrg             if(!(backPix = (PanoramiXRes*) SecurityLookupIDByType(
130205b261ecSmrg                  client, tmp, XRT_PIXMAP, DixReadAccess)))
130305b261ecSmrg                return BadPixmap;
130405b261ecSmrg          }
130505b261ecSmrg       }
130605b261ecSmrg
130705b261ecSmrg       if ((Mask)stuff->mask & CWBorderPixmap) {
130805b261ecSmrg          pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
130905b261ecSmrg          tmp = *((CARD32 *) &stuff[1] + pbord_offset);
131005b261ecSmrg          if (tmp != CopyFromParent) {
131105b261ecSmrg             if(!(bordPix = (PanoramiXRes*) SecurityLookupIDByType(
131205b261ecSmrg                  client, tmp, XRT_PIXMAP, DixReadAccess)))
131305b261ecSmrg                return BadPixmap;
131405b261ecSmrg          }
131505b261ecSmrg       }
131605b261ecSmrg
131705b261ecSmrg       if ((Mask)stuff->mask & CWColormap) {
131805b261ecSmrg           cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
131905b261ecSmrg           tmp = *((CARD32 *) &stuff[1] + cmap_offset);
132005b261ecSmrg           if ((tmp != CopyFromParent) && (tmp != None)) {
132105b261ecSmrg             if(!(cmap = (PanoramiXRes*) SecurityLookupIDByType(
132205b261ecSmrg                  client, tmp, XRT_COLORMAP, DixReadAccess)))
132305b261ecSmrg                 return BadColor;
132405b261ecSmrg           }
132505b261ecSmrg       }
132605b261ecSmrg
132705b261ecSmrg       orig_visual = stuff->visualID;
132805b261ecSmrg
132905b261ecSmrg       FOR_NSCREENS_BACKWARD(i) {
133005b261ecSmrg          stuff->drawable = draw->info[i].id;
133105b261ecSmrg          if (backPix)
133205b261ecSmrg             *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
133305b261ecSmrg          if (bordPix)
133405b261ecSmrg             *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
133505b261ecSmrg          if (cmap)
133605b261ecSmrg             *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
133705b261ecSmrg
133805b261ecSmrg          if (orig_visual != CopyFromParent)
13394642e01fSmrg            stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual);
134005b261ecSmrg
134105b261ecSmrg          status = ScreenSaverSetAttributes(client);
134205b261ecSmrg       }
134305b261ecSmrg
134405b261ecSmrg       return status;
134505b261ecSmrg    }
134605b261ecSmrg#endif
134705b261ecSmrg
134805b261ecSmrg    return ScreenSaverSetAttributes(client);
134905b261ecSmrg}
135005b261ecSmrg
135105b261ecSmrgstatic int
135205b261ecSmrgProcScreenSaverUnsetAttributes (ClientPtr client)
135305b261ecSmrg{
135405b261ecSmrg#ifdef PANORAMIX
135505b261ecSmrg    if(!noPanoramiXExtension) {
135605b261ecSmrg       REQUEST(xScreenSaverUnsetAttributesReq);
135705b261ecSmrg       PanoramiXRes *draw;
135805b261ecSmrg       int i;
135905b261ecSmrg
136005b261ecSmrg       if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
136105b261ecSmrg                   client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
136205b261ecSmrg           return BadDrawable;
136305b261ecSmrg
136405b261ecSmrg       for(i = PanoramiXNumScreens - 1; i > 0; i--) {
136505b261ecSmrg            stuff->drawable = draw->info[i].id;
136605b261ecSmrg            ScreenSaverUnsetAttributes(client);
136705b261ecSmrg       }
136805b261ecSmrg
136905b261ecSmrg       stuff->drawable = draw->info[0].id;
137005b261ecSmrg    }
137105b261ecSmrg#endif
137205b261ecSmrg
137305b261ecSmrg    return ScreenSaverUnsetAttributes(client);
137405b261ecSmrg}
137505b261ecSmrg
137605b261ecSmrgstatic int
137705b261ecSmrgProcScreenSaverSuspend (ClientPtr client)
137805b261ecSmrg{
137905b261ecSmrg    ScreenSaverSuspensionPtr *prev, this;
138005b261ecSmrg
138105b261ecSmrg    REQUEST(xScreenSaverSuspendReq);
138205b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
138305b261ecSmrg
138405b261ecSmrg    /* Check if this client is suspending the screensaver */
138505b261ecSmrg    for (prev = &suspendingClients; (this = *prev); prev = &this->next)
138605b261ecSmrg	if (this->pClient == client)
138705b261ecSmrg	    break;
138805b261ecSmrg
138905b261ecSmrg    if (this)
139005b261ecSmrg    {
139105b261ecSmrg	if (stuff->suspend == TRUE)
139205b261ecSmrg	   this->count++;
139305b261ecSmrg	else if (--this->count == 0)
139405b261ecSmrg	   FreeResource (this->clientResource, RT_NONE);
139505b261ecSmrg
139605b261ecSmrg	return Success;
139705b261ecSmrg    }
139805b261ecSmrg
139905b261ecSmrg    /* If we get to this point, this client isn't suspending the screensaver */
140005b261ecSmrg    if (stuff->suspend == FALSE)
140105b261ecSmrg	return Success;
140205b261ecSmrg
140305b261ecSmrg    /*
140405b261ecSmrg     * Allocate a suspension record for the client, and stop the screensaver
140505b261ecSmrg     * if it isn't already suspended by another client. We attach a resource ID
140605b261ecSmrg     * to the record, so the screensaver will be reenabled and the record freed
140705b261ecSmrg     * if the client disconnects without reenabling it first.
140805b261ecSmrg     */
140905b261ecSmrg    this = (ScreenSaverSuspensionPtr) xalloc (sizeof (ScreenSaverSuspensionRec));
141005b261ecSmrg
141105b261ecSmrg    if (!this)
141205b261ecSmrg	return BadAlloc;
141305b261ecSmrg
141405b261ecSmrg    this->next           = NULL;
141505b261ecSmrg    this->pClient        = client;
141605b261ecSmrg    this->count          = 1;
141705b261ecSmrg    this->clientResource = FakeClientID (client->index);
141805b261ecSmrg
141905b261ecSmrg    if (!AddResource (this->clientResource, SuspendType, (pointer) this))
142005b261ecSmrg    {
142105b261ecSmrg	xfree (this);
142205b261ecSmrg	return BadAlloc;
142305b261ecSmrg    }
142405b261ecSmrg
142505b261ecSmrg    *prev = this;
142605b261ecSmrg    if (!screenSaverSuspended)
142705b261ecSmrg    {
142805b261ecSmrg	screenSaverSuspended = TRUE;
142905b261ecSmrg	FreeScreenSaverTimer();
143005b261ecSmrg    }
143105b261ecSmrg
143205b261ecSmrg    return (client->noClientException);
143305b261ecSmrg}
143405b261ecSmrg
143505b261ecSmrgstatic DISPATCH_PROC((*NormalVector[])) = {
143605b261ecSmrg    ProcScreenSaverQueryVersion,
143705b261ecSmrg    ProcScreenSaverQueryInfo,
143805b261ecSmrg    ProcScreenSaverSelectInput,
143905b261ecSmrg    ProcScreenSaverSetAttributes,
144005b261ecSmrg    ProcScreenSaverUnsetAttributes,
144105b261ecSmrg    ProcScreenSaverSuspend,
144205b261ecSmrg};
144305b261ecSmrg
144405b261ecSmrg#define NUM_REQUESTS	((sizeof NormalVector) / (sizeof NormalVector[0]))
144505b261ecSmrg
144605b261ecSmrgstatic int
144705b261ecSmrgProcScreenSaverDispatch (client)
144805b261ecSmrg    ClientPtr	client;
144905b261ecSmrg{
145005b261ecSmrg    REQUEST(xReq);
145105b261ecSmrg
145205b261ecSmrg    if (stuff->data < NUM_REQUESTS)
145305b261ecSmrg	return (*NormalVector[stuff->data])(client);
145405b261ecSmrg    return BadRequest;
145505b261ecSmrg}
145605b261ecSmrg
145705b261ecSmrgstatic int
145805b261ecSmrgSProcScreenSaverQueryVersion (client)
145905b261ecSmrg    ClientPtr	client;
146005b261ecSmrg{
146105b261ecSmrg    REQUEST(xScreenSaverQueryVersionReq);
146205b261ecSmrg    int	    n;
146305b261ecSmrg
146405b261ecSmrg    swaps (&stuff->length, n);
146505b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
146605b261ecSmrg    return ProcScreenSaverQueryVersion (client);
146705b261ecSmrg}
146805b261ecSmrg
146905b261ecSmrgstatic int
147005b261ecSmrgSProcScreenSaverQueryInfo (client)
147105b261ecSmrg    ClientPtr	client;
147205b261ecSmrg{
147305b261ecSmrg    REQUEST(xScreenSaverQueryInfoReq);
147405b261ecSmrg    int	    n;
147505b261ecSmrg
147605b261ecSmrg    swaps (&stuff->length, n);
147705b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
147805b261ecSmrg    swapl (&stuff->drawable, n);
147905b261ecSmrg    return ProcScreenSaverQueryInfo (client);
148005b261ecSmrg}
148105b261ecSmrg
148205b261ecSmrgstatic int
148305b261ecSmrgSProcScreenSaverSelectInput (client)
148405b261ecSmrg    ClientPtr	client;
148505b261ecSmrg{
148605b261ecSmrg    REQUEST(xScreenSaverSelectInputReq);
148705b261ecSmrg    int	    n;
148805b261ecSmrg
148905b261ecSmrg    swaps (&stuff->length, n);
149005b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
149105b261ecSmrg    swapl (&stuff->drawable, n);
149205b261ecSmrg    swapl (&stuff->eventMask, n);
149305b261ecSmrg    return ProcScreenSaverSelectInput (client);
149405b261ecSmrg}
149505b261ecSmrg
149605b261ecSmrgstatic int
149705b261ecSmrgSProcScreenSaverSetAttributes (client)
149805b261ecSmrg    ClientPtr	client;
149905b261ecSmrg{
150005b261ecSmrg    REQUEST(xScreenSaverSetAttributesReq);
150105b261ecSmrg    int	    n;
150205b261ecSmrg
150305b261ecSmrg    swaps (&stuff->length, n);
150405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
150505b261ecSmrg    swapl (&stuff->drawable, n);
150605b261ecSmrg    swaps (&stuff->x, n);
150705b261ecSmrg    swaps (&stuff->y, n);
150805b261ecSmrg    swaps (&stuff->width, n);
150905b261ecSmrg    swaps (&stuff->height, n);
151005b261ecSmrg    swaps (&stuff->borderWidth, n);
151105b261ecSmrg    swapl (&stuff->visualID, n);
151205b261ecSmrg    swapl (&stuff->mask, n);
151305b261ecSmrg    SwapRestL(stuff);
151405b261ecSmrg    return ProcScreenSaverSetAttributes (client);
151505b261ecSmrg}
151605b261ecSmrg
151705b261ecSmrgstatic int
151805b261ecSmrgSProcScreenSaverUnsetAttributes (client)
151905b261ecSmrg    ClientPtr	client;
152005b261ecSmrg{
152105b261ecSmrg    REQUEST(xScreenSaverUnsetAttributesReq);
152205b261ecSmrg    int	    n;
152305b261ecSmrg
152405b261ecSmrg    swaps (&stuff->length, n);
152505b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
152605b261ecSmrg    swapl (&stuff->drawable, n);
152705b261ecSmrg    return ProcScreenSaverUnsetAttributes (client);
152805b261ecSmrg}
152905b261ecSmrg
153005b261ecSmrgstatic int
153105b261ecSmrgSProcScreenSaverSuspend (ClientPtr client)
153205b261ecSmrg{
153305b261ecSmrg    int n;
153405b261ecSmrg    REQUEST(xScreenSaverSuspendReq);
153505b261ecSmrg
153605b261ecSmrg    swaps(&stuff->length, n);
153705b261ecSmrg    REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
153805b261ecSmrg    swapl(&stuff->suspend, n);
153905b261ecSmrg    return ProcScreenSaverSuspend (client);
154005b261ecSmrg}
154105b261ecSmrg
154205b261ecSmrgstatic DISPATCH_PROC((*SwappedVector[])) = {
154305b261ecSmrg    SProcScreenSaverQueryVersion,
154405b261ecSmrg    SProcScreenSaverQueryInfo,
154505b261ecSmrg    SProcScreenSaverSelectInput,
154605b261ecSmrg    SProcScreenSaverSetAttributes,
154705b261ecSmrg    SProcScreenSaverUnsetAttributes,
154805b261ecSmrg    SProcScreenSaverSuspend,
154905b261ecSmrg};
155005b261ecSmrg
155105b261ecSmrgstatic int
155205b261ecSmrgSProcScreenSaverDispatch (client)
155305b261ecSmrg    ClientPtr	client;
155405b261ecSmrg{
155505b261ecSmrg    REQUEST(xReq);
155605b261ecSmrg
155705b261ecSmrg    if (stuff->data < NUM_REQUESTS)
155805b261ecSmrg	return (*SwappedVector[stuff->data])(client);
155905b261ecSmrg    return BadRequest;
156005b261ecSmrg}
1561