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