1531 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1531 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 *
 | 
						|
Copyright (c) 1992  X Consortium
 | 
						|
 | 
						|
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
						|
of this software and associated documentation files (the "Software"), to deal
 | 
						|
in the Software without restriction, including without limitation the rights
 | 
						|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
						|
copies of the Software, and to permit persons to whom the Software is
 | 
						|
furnished to do so, subject to the following conditions:
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be included in
 | 
						|
all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | 
						|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 | 
						|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
						|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
Except as contained in this notice, the name of the X Consortium shall not be
 | 
						|
used in advertising or otherwise to promote the sale, use or other dealings
 | 
						|
in this Software without prior written authorization from the X Consortium.
 | 
						|
 *
 | 
						|
 * Author:  Keith Packard, MIT X Consortium
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "os.h"
 | 
						|
#include "windowstr.h"
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "pixmapstr.h"
 | 
						|
#include "extnsionst.h"
 | 
						|
#include "dixstruct.h"
 | 
						|
#include "resource.h"
 | 
						|
#include "opaque.h"
 | 
						|
#include <X11/extensions/saverproto.h>
 | 
						|
#include "gcstruct.h"
 | 
						|
#include "cursorstr.h"
 | 
						|
#include "colormapst.h"
 | 
						|
#include "xace.h"
 | 
						|
#ifdef PANORAMIX
 | 
						|
#include "panoramiX.h"
 | 
						|
#include "panoramiXsrv.h"
 | 
						|
#endif
 | 
						|
#ifdef DPMSExtension
 | 
						|
#include <X11/extensions/dpmsconst.h>
 | 
						|
#endif
 | 
						|
#include "protocol-versions.h"
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "modinit.h"
 | 
						|
 | 
						|
static int ScreenSaverEventBase = 0;
 | 
						|
 | 
						|
static DISPATCH_PROC(ProcScreenSaverQueryInfo);
 | 
						|
static DISPATCH_PROC(ProcScreenSaverDispatch);
 | 
						|
static DISPATCH_PROC(ProcScreenSaverQueryVersion);
 | 
						|
static DISPATCH_PROC(ProcScreenSaverSelectInput);
 | 
						|
static DISPATCH_PROC(ProcScreenSaverSetAttributes);
 | 
						|
static DISPATCH_PROC(ProcScreenSaverUnsetAttributes);
 | 
						|
static DISPATCH_PROC(ProcScreenSaverSuspend);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverDispatch);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverQueryInfo);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverQueryVersion);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverSelectInput);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverSetAttributes);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverUnsetAttributes);
 | 
						|
static DISPATCH_PROC(SProcScreenSaverSuspend);
 | 
						|
 | 
						|
static Bool ScreenSaverHandle (
 | 
						|
	ScreenPtr /* pScreen */,
 | 
						|
	int /* xstate */,
 | 
						|
	Bool /* force */
 | 
						|
	);
 | 
						|
 | 
						|
static Bool
 | 
						|
CreateSaverWindow (
 | 
						|
	ScreenPtr /* pScreen */
 | 
						|
	);
 | 
						|
 | 
						|
static Bool
 | 
						|
DestroySaverWindow (
 | 
						|
	ScreenPtr /* pScreen */
 | 
						|
	);
 | 
						|
 | 
						|
static void
 | 
						|
UninstallSaverColormap (
 | 
						|
	ScreenPtr /* pScreen */
 | 
						|
	);
 | 
						|
 | 
						|
static void
 | 
						|
CheckScreenPrivate (
 | 
						|
	ScreenPtr /* pScreen */
 | 
						|
	);
 | 
						|
 | 
						|
static void SScreenSaverNotifyEvent (
 | 
						|
	xScreenSaverNotifyEvent * /* from */,
 | 
						|
	xScreenSaverNotifyEvent * /* to */
 | 
						|
	);
 | 
						|
 | 
						|
static RESTYPE SuspendType;  /* resource type for suspension records */
 | 
						|
 | 
						|
typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr;
 | 
						|
 | 
						|
/* List of clients that are suspending the screensaver. */
 | 
						|
static ScreenSaverSuspensionPtr suspendingClients = NULL;
 | 
						|
 | 
						|
/*
 | 
						|
 * clientResource is a resource ID that's added when the record is
 | 
						|
 * allocated, so the record is freed and the screensaver resumed when
 | 
						|
 * the client disconnects. count is the number of times the client has
 | 
						|
 * requested the screensaver be suspended.
 | 
						|
 */
 | 
						|
typedef struct _ScreenSaverSuspension
 | 
						|
{
 | 
						|
    ScreenSaverSuspensionPtr  next;
 | 
						|
    ClientPtr                 pClient;
 | 
						|
    XID                       clientResource;
 | 
						|
    int                       count;
 | 
						|
} ScreenSaverSuspensionRec;
 | 
						|
 | 
						|
static int ScreenSaverFreeSuspend(
 | 
						|
    pointer /*value */,
 | 
						|
    XID /* id */
 | 
						|
);
 | 
						|
 | 
						|
/*
 | 
						|
 * each screen has a list of clients requesting
 | 
						|
 * ScreenSaverNotify events.  Each client has a resource
 | 
						|
 * for each screen it selects ScreenSaverNotify input for,
 | 
						|
 * this resource is used to delete the ScreenSaverNotifyRec
 | 
						|
 * entry from the per-screen queue.
 | 
						|
 */
 | 
						|
 | 
						|
static RESTYPE SaverEventType;   /* resource type for event masks */
 | 
						|
 | 
						|
typedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
 | 
						|
 | 
						|
typedef struct _ScreenSaverEvent {
 | 
						|
    ScreenSaverEventPtr	next;
 | 
						|
    ClientPtr		client;
 | 
						|
    ScreenPtr		screen;
 | 
						|
    XID			resource;
 | 
						|
    CARD32		mask;
 | 
						|
} ScreenSaverEventRec;
 | 
						|
 | 
						|
static int ScreenSaverFreeEvents(
 | 
						|
    pointer /* value */,
 | 
						|
    XID /* id */
 | 
						|
);
 | 
						|
 | 
						|
static Bool setEventMask (
 | 
						|
    ScreenPtr /* pScreen */,
 | 
						|
    ClientPtr /* client */,
 | 
						|
    unsigned long /* mask */
 | 
						|
);
 | 
						|
 | 
						|
static unsigned long getEventMask (
 | 
						|
    ScreenPtr /* pScreen */,
 | 
						|
    ClientPtr /* client */
 | 
						|
);
 | 
						|
 | 
						|
/*
 | 
						|
 * when a client sets the screen saver attributes, a resource is
 | 
						|
 * kept to be freed when the client exits
 | 
						|
 */
 | 
						|
 | 
						|
static RESTYPE AttrType;    /* resource type for attributes */
 | 
						|
 | 
						|
typedef struct _ScreenSaverAttr {
 | 
						|
    ScreenPtr	    screen;
 | 
						|
    ClientPtr	    client;
 | 
						|
    XID		    resource;
 | 
						|
    short	    x, y;
 | 
						|
    unsigned short  width, height, borderWidth;
 | 
						|
    unsigned char   class;
 | 
						|
    unsigned char   depth;
 | 
						|
    VisualID	    visual;
 | 
						|
    CursorPtr	    pCursor;
 | 
						|
    PixmapPtr	    pBackgroundPixmap;
 | 
						|
    PixmapPtr	    pBorderPixmap;
 | 
						|
    Colormap	    colormap;
 | 
						|
    unsigned long   mask;		/* no pixmaps or cursors */
 | 
						|
    unsigned long   *values;
 | 
						|
} ScreenSaverAttrRec, *ScreenSaverAttrPtr;
 | 
						|
 | 
						|
static int ScreenSaverFreeAttr (
 | 
						|
    pointer /* value */,
 | 
						|
    XID /* id */
 | 
						|
);
 | 
						|
 | 
						|
static void FreeAttrs (
 | 
						|
    ScreenSaverAttrPtr	/* pAttr */
 | 
						|
);
 | 
						|
 | 
						|
static void FreeScreenAttr (
 | 
						|
    ScreenSaverAttrPtr	/* pAttr */
 | 
						|
);
 | 
						|
 | 
						|
static void
 | 
						|
SendScreenSaverNotify (
 | 
						|
    ScreenPtr /* pScreen */,
 | 
						|
    int /* state */,
 | 
						|
    Bool /* forced */
 | 
						|
);
 | 
						|
 | 
						|
typedef struct _ScreenSaverScreenPrivate {
 | 
						|
    ScreenSaverEventPtr	    events;
 | 
						|
    ScreenSaverAttrPtr	    attr;
 | 
						|
    Bool		    hasWindow;
 | 
						|
    Colormap		    installedMap;
 | 
						|
} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
 | 
						|
 | 
						|
static ScreenSaverScreenPrivatePtr
 | 
						|
MakeScreenPrivate (
 | 
						|
	ScreenPtr /* pScreen */
 | 
						|
	);
 | 
						|
 | 
						|
static int ScreenPrivateKeyIndex;
 | 
						|
static DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex;
 | 
						|
 | 
						|
#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
 | 
						|
    dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
 | 
						|
#define SetScreenPrivate(s,v) \
 | 
						|
    dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v);
 | 
						|
#define SetupScreen(s)	ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
 | 
						|
 | 
						|
#define New(t)	(malloc(sizeof (t)))
 | 
						|
 | 
						|
/****************
 | 
						|
 * ScreenSaverExtensionInit
 | 
						|
 *
 | 
						|
 * Called from InitExtensions in main() or from QueryExtension() if the
 | 
						|
 * extension is dynamically loaded.
 | 
						|
 *
 | 
						|
 ****************/
 | 
						|
 | 
						|
void
 | 
						|
ScreenSaverExtensionInit(INITARGS)
 | 
						|
{
 | 
						|
    ExtensionEntry *extEntry;
 | 
						|
    int		    i;
 | 
						|
    ScreenPtr	    pScreen;
 | 
						|
 | 
						|
    AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr");
 | 
						|
    SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents,
 | 
						|
					   "SaverEvent");
 | 
						|
    SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend,
 | 
						|
					"SaverSuspend");
 | 
						|
 | 
						|
    for (i = 0; i < screenInfo.numScreens; i++)
 | 
						|
    {
 | 
						|
	pScreen = screenInfo.screens[i];
 | 
						|
	SetScreenPrivate (pScreen, NULL);
 | 
						|
    }
 | 
						|
    if (AttrType && SaverEventType && SuspendType &&
 | 
						|
	(extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
 | 
						|
				 ProcScreenSaverDispatch, SProcScreenSaverDispatch,
 | 
						|
				 NULL, StandardMinorOpcode)))
 | 
						|
    {
 | 
						|
	ScreenSaverEventBase = extEntry->eventBase;
 | 
						|
	EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
CheckScreenPrivate (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    SetupScreen (pScreen);
 | 
						|
 | 
						|
    if (!pPriv)
 | 
						|
	return;
 | 
						|
    if (!pPriv->attr && !pPriv->events &&
 | 
						|
	!pPriv->hasWindow && pPriv->installedMap == None)
 | 
						|
    {
 | 
						|
	free(pPriv);
 | 
						|
	SetScreenPrivate (pScreen, NULL);
 | 
						|
	pScreen->screensaver.ExternalScreenSaver = NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static ScreenSaverScreenPrivatePtr
 | 
						|
MakeScreenPrivate (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    SetupScreen (pScreen);
 | 
						|
 | 
						|
    if (pPriv)
 | 
						|
	return pPriv;
 | 
						|
    pPriv = New (ScreenSaverScreenPrivateRec);
 | 
						|
    if (!pPriv)
 | 
						|
	return 0;
 | 
						|
    pPriv->events = 0;
 | 
						|
    pPriv->attr = 0;
 | 
						|
    pPriv->hasWindow = FALSE;
 | 
						|
    pPriv->installedMap = None;
 | 
						|
    SetScreenPrivate (pScreen, pPriv);
 | 
						|
    pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle;
 | 
						|
    return pPriv;
 | 
						|
}
 | 
						|
 | 
						|
static unsigned long
 | 
						|
getEventMask (ScreenPtr pScreen, ClientPtr client)
 | 
						|
{
 | 
						|
    SetupScreen(pScreen);
 | 
						|
    ScreenSaverEventPtr	pEv;
 | 
						|
 | 
						|
    if (!pPriv)
 | 
						|
	return 0;
 | 
						|
    for (pEv = pPriv->events; pEv; pEv = pEv->next)
 | 
						|
	if (pEv->client == client)
 | 
						|
	    return pEv->mask;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
setEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask)
 | 
						|
{
 | 
						|
    SetupScreen(pScreen);
 | 
						|
    ScreenSaverEventPtr	pEv, *pPrev;
 | 
						|
 | 
						|
    if (getEventMask (pScreen, client) == mask)
 | 
						|
	return TRUE;
 | 
						|
    if (!pPriv)
 | 
						|
    {
 | 
						|
	pPriv = MakeScreenPrivate (pScreen);
 | 
						|
	if (!pPriv)
 | 
						|
	    return FALSE;
 | 
						|
    }
 | 
						|
    for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
 | 
						|
	if (pEv->client == client)
 | 
						|
	    break;
 | 
						|
    if (mask == 0)
 | 
						|
    {
 | 
						|
	FreeResource (pEv->resource, SaverEventType);
 | 
						|
	*pPrev = pEv->next;
 | 
						|
	free(pEv);
 | 
						|
	CheckScreenPrivate (pScreen);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
    	if (!pEv) 
 | 
						|
    	{
 | 
						|
	    pEv = New (ScreenSaverEventRec);
 | 
						|
	    if (!pEv) 
 | 
						|
	    {
 | 
						|
		CheckScreenPrivate (pScreen);
 | 
						|
	    	return FALSE;
 | 
						|
	    }
 | 
						|
    	    *pPrev = pEv;
 | 
						|
    	    pEv->next = NULL;
 | 
						|
    	    pEv->client = client;
 | 
						|
    	    pEv->screen = pScreen;
 | 
						|
    	    pEv->resource = FakeClientID (client->index);
 | 
						|
	    if (!AddResource (pEv->resource, SaverEventType, (pointer) pEv))
 | 
						|
		return FALSE;
 | 
						|
    	}
 | 
						|
	pEv->mask = mask;
 | 
						|
    }
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
FreeAttrs (ScreenSaverAttrPtr pAttr)
 | 
						|
{
 | 
						|
    PixmapPtr	    pPixmap;
 | 
						|
    CursorPtr	    pCursor;
 | 
						|
 | 
						|
    if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
 | 
						|
	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
 | 
						|
    if ((pPixmap = pAttr->pBorderPixmap) != 0)
 | 
						|
	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
 | 
						|
    if ((pCursor = pAttr->pCursor) != 0)
 | 
						|
	FreeCursor (pCursor, (Cursor) 0);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
FreeScreenAttr (ScreenSaverAttrPtr pAttr)
 | 
						|
{
 | 
						|
    FreeAttrs (pAttr);
 | 
						|
    free(pAttr->values);
 | 
						|
    free(pAttr);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ScreenSaverFreeEvents (pointer value, XID id)
 | 
						|
{
 | 
						|
    ScreenSaverEventPtr	pOld = (ScreenSaverEventPtr)value;
 | 
						|
    ScreenPtr pScreen = pOld->screen;
 | 
						|
    SetupScreen (pScreen);
 | 
						|
    ScreenSaverEventPtr	pEv, *pPrev;
 | 
						|
 | 
						|
    if (!pPriv)
 | 
						|
	return TRUE;
 | 
						|
    for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
 | 
						|
	if (pEv == pOld)
 | 
						|
	    break;
 | 
						|
    if (!pEv)
 | 
						|
	return TRUE;
 | 
						|
    *pPrev = pEv->next;
 | 
						|
    free(pEv);
 | 
						|
    CheckScreenPrivate (pScreen);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ScreenSaverFreeAttr (pointer value, XID id)
 | 
						|
{
 | 
						|
    ScreenSaverAttrPtr	pOldAttr = (ScreenSaverAttrPtr)value;
 | 
						|
    ScreenPtr	pScreen = pOldAttr->screen;
 | 
						|
    SetupScreen (pScreen);
 | 
						|
 | 
						|
    if (!pPriv)
 | 
						|
	return TRUE;
 | 
						|
    if (pPriv->attr != pOldAttr)
 | 
						|
	return TRUE;
 | 
						|
    FreeScreenAttr (pOldAttr);
 | 
						|
    pPriv->attr = NULL;
 | 
						|
    if (pPriv->hasWindow)
 | 
						|
    {
 | 
						|
	dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 | 
						|
	dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
 | 
						|
    }
 | 
						|
    CheckScreenPrivate (pScreen);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ScreenSaverFreeSuspend (pointer value, XID id)
 | 
						|
{
 | 
						|
    ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
 | 
						|
    ScreenSaverSuspensionPtr *prev, this;
 | 
						|
 | 
						|
    /* Unlink and free the suspension record for the client */
 | 
						|
    for (prev = &suspendingClients; (this = *prev); prev = &this->next)
 | 
						|
    {
 | 
						|
	if (this == data)
 | 
						|
	{
 | 
						|
	    *prev = this->next;
 | 
						|
	    free(this);
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /* Reenable the screensaver if this was the last client suspending it. */
 | 
						|
    if (screenSaverSuspended && suspendingClients == NULL)
 | 
						|
    {
 | 
						|
	screenSaverSuspended = FALSE;
 | 
						|
 | 
						|
	/* The screensaver could be active, since suspending it (by design)
 | 
						|
	   doesn't prevent it from being forceably activated */
 | 
						|
#ifdef DPMSExtension
 | 
						|
	if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn)
 | 
						|
#else
 | 
						|
	if (screenIsSaved != SCREEN_SAVER_ON)
 | 
						|
#endif
 | 
						|
	{
 | 
						|
	    UpdateCurrentTimeIf();
 | 
						|
	    lastDeviceEventTime = currentTime;
 | 
						|
	    SetScreenSaverTimer();
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
SendScreenSaverNotify (ScreenPtr pScreen, int state, Bool forced)
 | 
						|
{
 | 
						|
    ScreenSaverScreenPrivatePtr	pPriv;
 | 
						|
    ScreenSaverEventPtr		pEv;
 | 
						|
    unsigned long		mask;
 | 
						|
    xScreenSaverNotifyEvent	ev;
 | 
						|
    int				kind;
 | 
						|
 | 
						|
    UpdateCurrentTimeIf ();
 | 
						|
    mask = ScreenSaverNotifyMask;
 | 
						|
    if (state == ScreenSaverCycle)
 | 
						|
	mask = ScreenSaverCycleMask;
 | 
						|
    pScreen = screenInfo.screens[pScreen->myNum];
 | 
						|
    pPriv = GetScreenPrivate(pScreen);
 | 
						|
    if (!pPriv)
 | 
						|
	return;
 | 
						|
    if (pPriv->attr)
 | 
						|
	kind = ScreenSaverExternal;
 | 
						|
    else if (ScreenSaverBlanking != DontPreferBlanking)
 | 
						|
	kind = ScreenSaverBlanked;
 | 
						|
    else
 | 
						|
	kind = ScreenSaverInternal;
 | 
						|
    for (pEv = pPriv->events; pEv; pEv = pEv->next)
 | 
						|
    {
 | 
						|
	if (!(pEv->mask & mask))
 | 
						|
	    continue;
 | 
						|
	ev.type = ScreenSaverNotify + ScreenSaverEventBase;
 | 
						|
	ev.state = state;
 | 
						|
	ev.timestamp = currentTime.milliseconds;
 | 
						|
	ev.root = pScreen->root->drawable.id;
 | 
						|
	ev.window = pScreen->screensaver.wid;
 | 
						|
	ev.kind = kind;
 | 
						|
	ev.forced = forced;
 | 
						|
	WriteEventsToClient (pEv->client, 1, (xEvent *) &ev);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
SScreenSaverNotifyEvent (xScreenSaverNotifyEvent *from,
 | 
						|
                         xScreenSaverNotifyEvent *to)
 | 
						|
{
 | 
						|
    to->type = from->type;
 | 
						|
    to->state = from->state;
 | 
						|
    cpswaps (from->sequenceNumber, to->sequenceNumber);
 | 
						|
    cpswapl (from->timestamp, to->timestamp);    
 | 
						|
    cpswapl (from->root, to->root);    
 | 
						|
    cpswapl (from->window, to->window);    
 | 
						|
    to->kind = from->kind;
 | 
						|
    to->forced = from->forced;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
UninstallSaverColormap (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    SetupScreen(pScreen);
 | 
						|
    ColormapPtr			pCmap;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    if (pPriv && pPriv->installedMap != None)
 | 
						|
    {
 | 
						|
	rc = dixLookupResourceByType((pointer *)&pCmap, pPriv->installedMap,
 | 
						|
				     RT_COLORMAP, serverClient,
 | 
						|
				     DixUninstallAccess);
 | 
						|
	if (rc == Success)
 | 
						|
	    (*pCmap->pScreen->UninstallColormap) (pCmap);
 | 
						|
	pPriv->installedMap = None;
 | 
						|
	CheckScreenPrivate (pScreen);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
CreateSaverWindow (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    SetupScreen (pScreen);
 | 
						|
    ScreenSaverStuffPtr		pSaver;
 | 
						|
    ScreenSaverAttrPtr		pAttr;
 | 
						|
    WindowPtr			pWin;
 | 
						|
    int				result;
 | 
						|
    unsigned long		mask;
 | 
						|
    Colormap			*installedMaps;
 | 
						|
    int				numInstalled;
 | 
						|
    int				i;
 | 
						|
    Colormap			wantMap;
 | 
						|
    ColormapPtr			pCmap;
 | 
						|
 | 
						|
    pSaver = &pScreen->screensaver;
 | 
						|
    if (pSaver->pWindow)
 | 
						|
    {
 | 
						|
	pSaver->pWindow = NullWindow;
 | 
						|
	FreeResource (pSaver->wid, RT_NONE);
 | 
						|
	if (pPriv)
 | 
						|
	{
 | 
						|
	    UninstallSaverColormap (pScreen);
 | 
						|
	    pPriv->hasWindow = FALSE;
 | 
						|
	    CheckScreenPrivate (pScreen);
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    if (!pPriv || !(pAttr = pPriv->attr))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    pPriv->installedMap = None;
 | 
						|
 | 
						|
    if (GrabInProgress && GrabInProgress != pAttr->client->index)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    pWin = CreateWindow (pSaver->wid, pScreen->root,
 | 
						|
			 pAttr->x, pAttr->y, pAttr->width, pAttr->height,
 | 
						|
			 pAttr->borderWidth, pAttr->class, 
 | 
						|
			 pAttr->mask, (XID *)pAttr->values, 
 | 
						|
			 pAttr->depth, serverClient, pAttr->visual, 
 | 
						|
			 &result);
 | 
						|
    if (!pWin)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    mask = 0;
 | 
						|
    if (pAttr->pBackgroundPixmap)
 | 
						|
    {
 | 
						|
	pWin->backgroundState = BackgroundPixmap;
 | 
						|
	pWin->background.pixmap = pAttr->pBackgroundPixmap;
 | 
						|
	pAttr->pBackgroundPixmap->refcnt++;
 | 
						|
	mask |= CWBackPixmap;
 | 
						|
    }
 | 
						|
    if (pAttr->pBorderPixmap)
 | 
						|
    {
 | 
						|
	pWin->borderIsPixel = FALSE;
 | 
						|
	pWin->border.pixmap = pAttr->pBorderPixmap;
 | 
						|
	pAttr->pBorderPixmap->refcnt++;
 | 
						|
	mask |= CWBorderPixmap;
 | 
						|
    }
 | 
						|
    if (pAttr->pCursor)
 | 
						|
    {
 | 
						|
	if (!pWin->optional)
 | 
						|
	    if (!MakeWindowOptional (pWin))
 | 
						|
	    {
 | 
						|
    	    	FreeResource (pWin->drawable.id, RT_NONE);
 | 
						|
    	    	return FALSE;
 | 
						|
	    }
 | 
						|
	pAttr->pCursor->refcnt++;
 | 
						|
	if (pWin->optional->cursor)
 | 
						|
	    FreeCursor (pWin->optional->cursor, (Cursor)0);
 | 
						|
	pWin->optional->cursor = pAttr->pCursor;
 | 
						|
	pWin->cursorIsNone = FALSE;
 | 
						|
	CheckWindowOptionalNeed (pWin);
 | 
						|
	mask |= CWCursor;
 | 
						|
    }
 | 
						|
    if (mask)
 | 
						|
	(*pScreen->ChangeWindowAttributes) (pWin, mask);
 | 
						|
 | 
						|
    if (pAttr->colormap != None)
 | 
						|
	(void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap,
 | 
						|
				       serverClient);
 | 
						|
 | 
						|
    MapWindow (pWin, serverClient);
 | 
						|
 | 
						|
    pPriv->hasWindow = TRUE;
 | 
						|
    pSaver->pWindow = pWin;
 | 
						|
 | 
						|
    /* check and install our own colormap if it isn't installed now */
 | 
						|
    wantMap = wColormap (pWin);
 | 
						|
    if (wantMap == None)
 | 
						|
	return TRUE;
 | 
						|
    installedMaps = malloc(pScreen->maxInstalledCmaps * sizeof (Colormap));
 | 
						|
    numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps)
 | 
						|
						    (pScreen, installedMaps);
 | 
						|
    for (i = 0; i < numInstalled; i++) 
 | 
						|
	if (installedMaps[i] == wantMap)
 | 
						|
	    break;
 | 
						|
 | 
						|
    free((char *) installedMaps);
 | 
						|
 | 
						|
    if (i < numInstalled)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    result = dixLookupResourceByType((pointer *)&pCmap, wantMap, RT_COLORMAP,
 | 
						|
				     serverClient, DixInstallAccess);
 | 
						|
    if (result != Success)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    pPriv->installedMap = wantMap;
 | 
						|
 | 
						|
    (*pCmap->pScreen->InstallColormap) (pCmap);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
DestroySaverWindow (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    SetupScreen(pScreen);
 | 
						|
    ScreenSaverStuffPtr		pSaver;
 | 
						|
 | 
						|
    if (!pPriv || !pPriv->hasWindow)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    pSaver = &pScreen->screensaver;
 | 
						|
    if (pSaver->pWindow)
 | 
						|
    {
 | 
						|
	pSaver->pWindow = NullWindow;
 | 
						|
	FreeResource (pSaver->wid, RT_NONE);
 | 
						|
    }
 | 
						|
    pPriv->hasWindow = FALSE;
 | 
						|
    CheckScreenPrivate (pScreen);
 | 
						|
    UninstallSaverColormap (pScreen);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
ScreenSaverHandle (ScreenPtr pScreen, int xstate, Bool force)
 | 
						|
{
 | 
						|
    int				state = 0;
 | 
						|
    Bool			ret = FALSE;
 | 
						|
    ScreenSaverScreenPrivatePtr	pPriv;
 | 
						|
 | 
						|
    switch (xstate)
 | 
						|
    {
 | 
						|
    case SCREEN_SAVER_ON:	
 | 
						|
	state = ScreenSaverOn;
 | 
						|
	ret = CreateSaverWindow (pScreen);
 | 
						|
	break;
 | 
						|
    case SCREEN_SAVER_OFF:	
 | 
						|
	state = ScreenSaverOff;
 | 
						|
	ret = DestroySaverWindow (pScreen);
 | 
						|
	break;
 | 
						|
    case SCREEN_SAVER_CYCLE:	
 | 
						|
	state = ScreenSaverCycle;
 | 
						|
	pPriv = GetScreenPrivate (pScreen);
 | 
						|
	if (pPriv && pPriv->hasWindow)
 | 
						|
	    ret = TRUE;
 | 
						|
	
 | 
						|
    }
 | 
						|
#ifdef PANORAMIX
 | 
						|
    if(noPanoramiXExtension || !pScreen->myNum)
 | 
						|
#endif
 | 
						|
       SendScreenSaverNotify (pScreen, state, force);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverQueryVersion (ClientPtr client)
 | 
						|
{
 | 
						|
    xScreenSaverQueryVersionReply	rep;
 | 
						|
    int		n;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq);
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.majorVersion = SERVER_SAVER_MAJOR_VERSION;
 | 
						|
    rep.minorVersion = SERVER_SAVER_MINOR_VERSION;
 | 
						|
    if (client->swapped) {
 | 
						|
    	swaps(&rep.sequenceNumber, n);
 | 
						|
    	swapl(&rep.length, n);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverQueryInfo (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverQueryInfoReq);
 | 
						|
    xScreenSaverQueryInfoReply	rep;
 | 
						|
    int		n, rc;
 | 
						|
    ScreenSaverStuffPtr		pSaver;
 | 
						|
    DrawablePtr			pDraw;
 | 
						|
    CARD32			lastInput;
 | 
						|
    ScreenSaverScreenPrivatePtr	pPriv;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq);
 | 
						|
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
 | 
						|
			   DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
    rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
 | 
						|
		  DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
 | 
						|
    pSaver = &pDraw->pScreen->screensaver;
 | 
						|
    pPriv = GetScreenPrivate (pDraw->pScreen);
 | 
						|
 | 
						|
    UpdateCurrentTime ();
 | 
						|
    lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.window = pSaver->wid;
 | 
						|
    if (screenIsSaved != SCREEN_SAVER_OFF)
 | 
						|
    {
 | 
						|
	rep.state = ScreenSaverOn;
 | 
						|
	if (ScreenSaverTime)
 | 
						|
	    rep.tilOrSince = lastInput - ScreenSaverTime;
 | 
						|
	else
 | 
						|
	    rep.tilOrSince = 0;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	if (ScreenSaverTime)
 | 
						|
	{
 | 
						|
	    rep.state = ScreenSaverOff;
 | 
						|
	    if (ScreenSaverTime < lastInput)
 | 
						|
		rep.tilOrSince = 0;
 | 
						|
	    else
 | 
						|
		rep.tilOrSince = ScreenSaverTime - lastInput;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    rep.state = ScreenSaverDisabled;
 | 
						|
	    rep.tilOrSince = 0;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    rep.idle = lastInput;
 | 
						|
    rep.eventMask = getEventMask (pDraw->pScreen, client);
 | 
						|
    if (pPriv && pPriv->attr)
 | 
						|
	rep.kind = ScreenSaverExternal;
 | 
						|
    else if (ScreenSaverBlanking != DontPreferBlanking)
 | 
						|
	rep.kind = ScreenSaverBlanked;
 | 
						|
    else
 | 
						|
	rep.kind = ScreenSaverInternal;
 | 
						|
    if (client->swapped)
 | 
						|
    {
 | 
						|
	swaps (&rep.sequenceNumber, n);
 | 
						|
	swapl (&rep.length, n);
 | 
						|
	swapl (&rep.window, n);
 | 
						|
	swapl (&rep.tilOrSince, n);
 | 
						|
	swapl (&rep.idle, n);
 | 
						|
	swapl (&rep.eventMask, n);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverSelectInput (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverSelectInputReq);
 | 
						|
    DrawablePtr			pDraw;
 | 
						|
    int				rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq);
 | 
						|
    rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0,
 | 
						|
			    DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
 | 
						|
    rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
 | 
						|
		  DixSetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
 | 
						|
    if (!setEventMask (pDraw->pScreen, client, stuff->eventMask))
 | 
						|
	return BadAlloc;
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ScreenSaverSetAttributes (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverSetAttributesReq);
 | 
						|
    DrawablePtr			pDraw;
 | 
						|
    WindowPtr			pParent;
 | 
						|
    ScreenPtr			pScreen;
 | 
						|
    ScreenSaverScreenPrivatePtr pPriv = 0;
 | 
						|
    ScreenSaverAttrPtr		pAttr = 0;
 | 
						|
    int				ret, len, class, bw, depth;
 | 
						|
    unsigned long		visual;
 | 
						|
    int				idepth, ivisual;
 | 
						|
    Bool			fOK;
 | 
						|
    DepthPtr			pDepth;
 | 
						|
    WindowOptPtr		ancwopt;
 | 
						|
    unsigned int		*pVlist;
 | 
						|
    unsigned long		*values = 0;
 | 
						|
    unsigned long		tmask, imask;
 | 
						|
    unsigned long		val;
 | 
						|
    Pixmap			pixID;
 | 
						|
    PixmapPtr			pPixmap;
 | 
						|
    Cursor			cursorID;
 | 
						|
    CursorPtr			pCursor;
 | 
						|
    Colormap			cmap;
 | 
						|
    ColormapPtr			pCmap;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
 | 
						|
    ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
 | 
						|
			    DixGetAttrAccess);
 | 
						|
    if (ret != Success)
 | 
						|
	return ret;
 | 
						|
    pScreen = pDraw->pScreen;
 | 
						|
    pParent = pScreen->root;
 | 
						|
 | 
						|
    ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess);
 | 
						|
    if (ret != Success)
 | 
						|
	return ret;
 | 
						|
 | 
						|
    len = stuff->length -  bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
 | 
						|
    if (Ones(stuff->mask) != len)
 | 
						|
        return BadLength;
 | 
						|
    if (!stuff->width || !stuff->height)
 | 
						|
    {
 | 
						|
	client->errorValue = 0;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    switch (class = stuff->c_class) 
 | 
						|
    {
 | 
						|
    case CopyFromParent:
 | 
						|
    case InputOnly:
 | 
						|
    case InputOutput:
 | 
						|
	break;
 | 
						|
    default:
 | 
						|
	client->errorValue = class;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
    bw = stuff->borderWidth;
 | 
						|
    depth = stuff->depth;
 | 
						|
    visual = stuff->visualID;
 | 
						|
 | 
						|
    /* copied directly from CreateWindow */
 | 
						|
 | 
						|
    if (class == CopyFromParent)
 | 
						|
	class = pParent->drawable.class;
 | 
						|
 | 
						|
    if ((class != InputOutput) && (class != InputOnly))
 | 
						|
    {
 | 
						|
	client->errorValue = class;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
 | 
						|
        return BadMatch;
 | 
						|
 | 
						|
    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
 | 
						|
        return BadMatch;
 | 
						|
 | 
						|
    if ((class == InputOutput) && (depth == 0))
 | 
						|
        depth = pParent->drawable.depth;
 | 
						|
    ancwopt = pParent->optional;
 | 
						|
    if (!ancwopt)
 | 
						|
	ancwopt = FindWindowWithOptional(pParent)->optional;
 | 
						|
    if (visual == CopyFromParent)
 | 
						|
	visual = ancwopt->visual;
 | 
						|
 | 
						|
    /* Find out if the depth and visual are acceptable for this Screen */
 | 
						|
    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
 | 
						|
    {
 | 
						|
	fOK = FALSE;
 | 
						|
	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
 | 
						|
	{
 | 
						|
	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
 | 
						|
	    if ((depth == pDepth->depth) || (depth == 0))
 | 
						|
	    {
 | 
						|
		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
 | 
						|
		{
 | 
						|
		    if (visual == pDepth->vids[ivisual])
 | 
						|
		    {
 | 
						|
			fOK = TRUE;
 | 
						|
			break;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	if (fOK == FALSE)
 | 
						|
	    return BadMatch;
 | 
						|
    }
 | 
						|
 | 
						|
    if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
 | 
						|
	(class != InputOnly) &&
 | 
						|
	(depth != pParent->drawable.depth))
 | 
						|
    {
 | 
						|
        return BadMatch;
 | 
						|
    }
 | 
						|
 | 
						|
    if (((stuff->mask & CWColormap) == 0) &&
 | 
						|
	(class != InputOnly) &&
 | 
						|
	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
 | 
						|
    {
 | 
						|
	return BadMatch;
 | 
						|
    }
 | 
						|
 | 
						|
    /* end of errors from CreateWindow */
 | 
						|
 | 
						|
    pPriv = GetScreenPrivate (pScreen);
 | 
						|
    if (pPriv && pPriv->attr)
 | 
						|
    {
 | 
						|
	if (pPriv->attr->client != client)
 | 
						|
	    return BadAccess;
 | 
						|
    }
 | 
						|
    if (!pPriv)
 | 
						|
    {
 | 
						|
	pPriv = MakeScreenPrivate (pScreen);
 | 
						|
	if (!pPriv)
 | 
						|
	    return FALSE;
 | 
						|
    }
 | 
						|
    pAttr = New (ScreenSaverAttrRec);
 | 
						|
    if (!pAttr)
 | 
						|
    {
 | 
						|
	ret = BadAlloc;
 | 
						|
	goto bail;
 | 
						|
    }
 | 
						|
    /* over allocate for override redirect */
 | 
						|
    values = malloc((len + 1) * sizeof (unsigned long));
 | 
						|
    if (!values)
 | 
						|
    {
 | 
						|
	ret = BadAlloc;
 | 
						|
	goto bail;
 | 
						|
    }
 | 
						|
    pAttr->screen = pScreen;
 | 
						|
    pAttr->client = client;
 | 
						|
    pAttr->x = stuff->x;
 | 
						|
    pAttr->y = stuff->y;
 | 
						|
    pAttr->width = stuff->width;
 | 
						|
    pAttr->height = stuff->height;
 | 
						|
    pAttr->borderWidth = stuff->borderWidth;
 | 
						|
    pAttr->class = stuff->c_class;
 | 
						|
    pAttr->depth = depth;
 | 
						|
    pAttr->visual = visual;
 | 
						|
    pAttr->colormap = None;
 | 
						|
    pAttr->pCursor = NullCursor;
 | 
						|
    pAttr->pBackgroundPixmap = NullPixmap;
 | 
						|
    pAttr->pBorderPixmap = NullPixmap;
 | 
						|
    pAttr->values = values;
 | 
						|
    /*
 | 
						|
     * go through the mask, checking the values,
 | 
						|
     * looking up pixmaps and cursors and hold a reference
 | 
						|
     * to them.
 | 
						|
     */
 | 
						|
    pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
 | 
						|
    pVlist = (unsigned int *) (stuff + 1);
 | 
						|
    while (tmask) {
 | 
						|
	imask = lowbit (tmask);
 | 
						|
	tmask &= ~imask;
 | 
						|
	switch (imask)
 | 
						|
        {
 | 
						|
	case CWBackPixmap:
 | 
						|
	    pixID = (Pixmap )*pVlist;
 | 
						|
	    if (pixID == None)
 | 
						|
	    {
 | 
						|
		*values++ = None;
 | 
						|
	    }
 | 
						|
	    else if (pixID == ParentRelative)
 | 
						|
	    {
 | 
						|
		if (depth != pParent->drawable.depth)
 | 
						|
		{
 | 
						|
		    ret = BadMatch;
 | 
						|
		    goto PatchUp;
 | 
						|
		}
 | 
						|
		*values++ = ParentRelative;
 | 
						|
	    }
 | 
						|
            else
 | 
						|
	    {	
 | 
						|
		ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP,
 | 
						|
					client, DixReadAccess);
 | 
						|
		if (ret == Success)
 | 
						|
		{
 | 
						|
                    if  ((pPixmap->drawable.depth != depth) ||
 | 
						|
			 (pPixmap->drawable.pScreen != pScreen))
 | 
						|
		    {
 | 
						|
                        ret = BadMatch;
 | 
						|
			goto PatchUp;
 | 
						|
		    }
 | 
						|
		    pAttr->pBackgroundPixmap = pPixmap;
 | 
						|
		    pPixmap->refcnt++;
 | 
						|
		    pAttr->mask &= ~CWBackPixmap;
 | 
						|
		}
 | 
						|
	        else
 | 
						|
		{
 | 
						|
		    client->errorValue = pixID;
 | 
						|
		    goto PatchUp;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	case CWBackPixel:
 | 
						|
	    *values++ = (CARD32) *pVlist;
 | 
						|
	    break;
 | 
						|
	case CWBorderPixmap:
 | 
						|
	    pixID = (Pixmap ) *pVlist;
 | 
						|
	    if (pixID == CopyFromParent)
 | 
						|
	    {
 | 
						|
		if (depth != pParent->drawable.depth)
 | 
						|
		{
 | 
						|
		    ret = BadMatch;
 | 
						|
		    goto PatchUp;
 | 
						|
		}
 | 
						|
		*values++ = CopyFromParent;
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {	
 | 
						|
		ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP,
 | 
						|
					client, DixReadAccess);
 | 
						|
		if (ret == Success)
 | 
						|
		{
 | 
						|
                    if  ((pPixmap->drawable.depth != depth) ||
 | 
						|
			 (pPixmap->drawable.pScreen != pScreen))
 | 
						|
		    {
 | 
						|
			ret = BadMatch;
 | 
						|
			goto PatchUp;
 | 
						|
		    }
 | 
						|
		    pAttr->pBorderPixmap = pPixmap;
 | 
						|
		    pPixmap->refcnt++;
 | 
						|
		    pAttr->mask &= ~CWBorderPixmap;
 | 
						|
		}
 | 
						|
    	        else
 | 
						|
		{
 | 
						|
		    client->errorValue = pixID;
 | 
						|
		    goto PatchUp;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	case CWBorderPixel:
 | 
						|
            *values++ = (CARD32) *pVlist;
 | 
						|
            break;
 | 
						|
	case CWBitGravity:
 | 
						|
	    val = (CARD8 )*pVlist;
 | 
						|
	    if (val > StaticGravity)
 | 
						|
	    {
 | 
						|
		ret = BadValue;
 | 
						|
		client->errorValue = val;
 | 
						|
		goto PatchUp;
 | 
						|
	    }
 | 
						|
	    *values++ = val;
 | 
						|
	    break;
 | 
						|
	case CWWinGravity:
 | 
						|
	    val = (CARD8 )*pVlist;
 | 
						|
	    if (val > StaticGravity)
 | 
						|
	    {
 | 
						|
		ret = BadValue;
 | 
						|
		client->errorValue = val;
 | 
						|
		goto PatchUp;
 | 
						|
	    }
 | 
						|
	    *values++ = val;
 | 
						|
	    break;
 | 
						|
	case CWBackingStore:
 | 
						|
	    val = (CARD8 )*pVlist;
 | 
						|
	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
 | 
						|
	    {
 | 
						|
		ret = BadValue;
 | 
						|
		client->errorValue = val;
 | 
						|
		goto PatchUp;
 | 
						|
	    }
 | 
						|
	    *values++ = val;
 | 
						|
	    break;
 | 
						|
	case CWBackingPlanes:
 | 
						|
	    *values++ = (CARD32) *pVlist;
 | 
						|
	    break;
 | 
						|
	case CWBackingPixel:
 | 
						|
	    *values++ = (CARD32) *pVlist;
 | 
						|
	    break;
 | 
						|
	case CWSaveUnder:
 | 
						|
	    val = (BOOL) *pVlist;
 | 
						|
	    if ((val != xTrue) && (val != xFalse))
 | 
						|
	    {
 | 
						|
		ret = BadValue;
 | 
						|
		client->errorValue = val;
 | 
						|
		goto PatchUp;
 | 
						|
	    }
 | 
						|
	    *values++ = val;
 | 
						|
	    break;
 | 
						|
	case CWEventMask:
 | 
						|
	    *values++ = (CARD32) *pVlist;
 | 
						|
	    break;
 | 
						|
	case CWDontPropagate:
 | 
						|
	    *values++ = (CARD32) *pVlist;
 | 
						|
	    break;
 | 
						|
	case CWOverrideRedirect:
 | 
						|
	    if (!(stuff->mask & CWOverrideRedirect))
 | 
						|
		pVlist--;
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
	    	val = (BOOL ) *pVlist;
 | 
						|
	    	if ((val != xTrue) && (val != xFalse))
 | 
						|
	    	{
 | 
						|
		    ret = BadValue;
 | 
						|
		    client->errorValue = val;
 | 
						|
		    goto PatchUp;
 | 
						|
	    	}
 | 
						|
	    }
 | 
						|
	    *values++ = xTrue;
 | 
						|
	    break;
 | 
						|
	case CWColormap:
 | 
						|
	    cmap = (Colormap) *pVlist;
 | 
						|
	    ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP,
 | 
						|
				    client, DixUseAccess);
 | 
						|
	    if (ret != Success)
 | 
						|
	    {
 | 
						|
		client->errorValue = cmap;
 | 
						|
		goto PatchUp;
 | 
						|
	    }
 | 
						|
	    if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen)
 | 
						|
	    {
 | 
						|
		ret = BadMatch;
 | 
						|
		goto PatchUp;
 | 
						|
	    }
 | 
						|
	    pAttr->colormap = cmap;
 | 
						|
	    pAttr->mask &= ~CWColormap;
 | 
						|
	    break;
 | 
						|
	case CWCursor:
 | 
						|
	    cursorID = (Cursor ) *pVlist;
 | 
						|
	    if ( cursorID == None)
 | 
						|
	    {
 | 
						|
		*values++ = None;
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		ret = dixLookupResourceByType((pointer *)&pCursor, cursorID,
 | 
						|
					RT_CURSOR, client, DixUseAccess);
 | 
						|
	    	if (ret != Success)
 | 
						|
	    	{
 | 
						|
		    client->errorValue = cursorID;
 | 
						|
		    goto PatchUp;
 | 
						|
	    	}
 | 
						|
		pCursor->refcnt++;
 | 
						|
		pAttr->pCursor = pCursor;
 | 
						|
		pAttr->mask &= ~CWCursor;
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
     	 default:
 | 
						|
	    ret = BadValue;
 | 
						|
	    client->errorValue = stuff->mask;
 | 
						|
	    goto PatchUp;
 | 
						|
	}
 | 
						|
	pVlist++;
 | 
						|
    }
 | 
						|
    if (pPriv->attr)
 | 
						|
	FreeScreenAttr (pPriv->attr);
 | 
						|
    pPriv->attr = pAttr;
 | 
						|
    pAttr->resource = FakeClientID (client->index);
 | 
						|
    if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr))
 | 
						|
	return BadAlloc;
 | 
						|
    return Success;
 | 
						|
PatchUp:
 | 
						|
    FreeAttrs (pAttr);
 | 
						|
bail:
 | 
						|
    CheckScreenPrivate (pScreen);
 | 
						|
    if (pAttr) free(pAttr->values);
 | 
						|
    free(pAttr);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ScreenSaverUnsetAttributes (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverSetAttributesReq);
 | 
						|
    DrawablePtr			pDraw;
 | 
						|
    ScreenSaverScreenPrivatePtr	pPriv;
 | 
						|
    int				rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq);
 | 
						|
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
 | 
						|
			   DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
    pPriv = GetScreenPrivate (pDraw->pScreen);
 | 
						|
    if (pPriv && pPriv->attr && pPriv->attr->client == client)
 | 
						|
    {
 | 
						|
	FreeResource (pPriv->attr->resource, AttrType);
 | 
						|
    	FreeScreenAttr (pPriv->attr);
 | 
						|
	pPriv->attr = NULL;
 | 
						|
	CheckScreenPrivate (pDraw->pScreen);
 | 
						|
    }
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverSetAttributes (ClientPtr client)
 | 
						|
{
 | 
						|
#ifdef PANORAMIX
 | 
						|
    if(!noPanoramiXExtension) {
 | 
						|
       REQUEST(xScreenSaverSetAttributesReq);
 | 
						|
       PanoramiXRes *draw;
 | 
						|
       PanoramiXRes *backPix = NULL;
 | 
						|
       PanoramiXRes *bordPix = NULL;
 | 
						|
       PanoramiXRes *cmap    = NULL;
 | 
						|
       int i, status, len;
 | 
						|
       int  pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
 | 
						|
       XID orig_visual, tmp;
 | 
						|
 | 
						|
       REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
 | 
						|
 | 
						|
       status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
 | 
						|
					 XRC_DRAWABLE, client, DixWriteAccess);
 | 
						|
       if (status != Success)
 | 
						|
           return (status == BadValue) ? BadDrawable : status;
 | 
						|
 | 
						|
       len = stuff->length -  bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
 | 
						|
       if (Ones(stuff->mask) != len)
 | 
						|
           return BadLength;
 | 
						|
 | 
						|
       if((Mask)stuff->mask & CWBackPixmap) {
 | 
						|
          pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
 | 
						|
          tmp = *((CARD32 *) &stuff[1] + pback_offset);
 | 
						|
          if ((tmp != None) && (tmp != ParentRelative)) {
 | 
						|
	      status = dixLookupResourceByType((pointer *)&backPix, tmp,
 | 
						|
					       XRT_PIXMAP, client,
 | 
						|
					       DixReadAccess);
 | 
						|
	      if (status != Success)
 | 
						|
		  return status;
 | 
						|
          }
 | 
						|
       }
 | 
						|
 | 
						|
       if ((Mask)stuff->mask & CWBorderPixmap) {
 | 
						|
          pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
 | 
						|
          tmp = *((CARD32 *) &stuff[1] + pbord_offset);
 | 
						|
          if (tmp != CopyFromParent) {
 | 
						|
	      status = dixLookupResourceByType((pointer *)&bordPix, tmp,
 | 
						|
					       XRT_PIXMAP, client,
 | 
						|
					       DixReadAccess);
 | 
						|
	      if (status != Success)
 | 
						|
		  return status;
 | 
						|
          }
 | 
						|
       }
 | 
						|
 | 
						|
       if ((Mask)stuff->mask & CWColormap) {
 | 
						|
           cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
 | 
						|
           tmp = *((CARD32 *) &stuff[1] + cmap_offset);
 | 
						|
           if ((tmp != CopyFromParent) && (tmp != None)) {
 | 
						|
	       status = dixLookupResourceByType((pointer *)&cmap, tmp,
 | 
						|
						XRT_COLORMAP, client,
 | 
						|
						DixReadAccess);
 | 
						|
	       if (status != Success)
 | 
						|
		   return status;
 | 
						|
           }
 | 
						|
       }
 | 
						|
 | 
						|
       orig_visual = stuff->visualID;
 | 
						|
 | 
						|
       FOR_NSCREENS_BACKWARD(i) {
 | 
						|
          stuff->drawable = draw->info[i].id;  
 | 
						|
          if (backPix)
 | 
						|
             *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
 | 
						|
          if (bordPix)
 | 
						|
             *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
 | 
						|
          if (cmap)
 | 
						|
             *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
 | 
						|
 | 
						|
          if (orig_visual != CopyFromParent) 
 | 
						|
            stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual);
 | 
						|
 | 
						|
          status = ScreenSaverSetAttributes(client);
 | 
						|
       }
 | 
						|
 | 
						|
       return status;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    return ScreenSaverSetAttributes(client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverUnsetAttributes (ClientPtr client)
 | 
						|
{
 | 
						|
#ifdef PANORAMIX
 | 
						|
    if(!noPanoramiXExtension) {
 | 
						|
       REQUEST(xScreenSaverUnsetAttributesReq);
 | 
						|
       PanoramiXRes *draw;
 | 
						|
       int rc, i;
 | 
						|
 | 
						|
       rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
 | 
						|
				     XRC_DRAWABLE, client, DixWriteAccess);
 | 
						|
       if (rc != Success)
 | 
						|
           return (rc == BadValue) ? BadDrawable : rc;
 | 
						|
 | 
						|
       for(i = PanoramiXNumScreens - 1; i > 0; i--) {
 | 
						|
            stuff->drawable = draw->info[i].id;
 | 
						|
            ScreenSaverUnsetAttributes(client);
 | 
						|
       }
 | 
						|
 | 
						|
       stuff->drawable = draw->info[0].id;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    return ScreenSaverUnsetAttributes(client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverSuspend (ClientPtr client)
 | 
						|
{
 | 
						|
    ScreenSaverSuspensionPtr *prev, this;
 | 
						|
 | 
						|
    REQUEST(xScreenSaverSuspendReq);
 | 
						|
    REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
 | 
						|
 | 
						|
    /* Check if this client is suspending the screensaver */
 | 
						|
    for (prev = &suspendingClients; (this = *prev); prev = &this->next)
 | 
						|
	if (this->pClient == client)
 | 
						|
	    break;
 | 
						|
 | 
						|
    if (this)
 | 
						|
    {
 | 
						|
	if (stuff->suspend == TRUE)
 | 
						|
	   this->count++;
 | 
						|
	else if (--this->count == 0)
 | 
						|
	   FreeResource (this->clientResource, RT_NONE);
 | 
						|
 | 
						|
	return Success;
 | 
						|
    }
 | 
						|
 | 
						|
    /* If we get to this point, this client isn't suspending the screensaver */
 | 
						|
    if (stuff->suspend == FALSE)
 | 
						|
	return Success;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Allocate a suspension record for the client, and stop the screensaver
 | 
						|
     * if it isn't already suspended by another client. We attach a resource ID
 | 
						|
     * to the record, so the screensaver will be reenabled and the record freed
 | 
						|
     * if the client disconnects without reenabling it first.
 | 
						|
     */
 | 
						|
    this = malloc(sizeof (ScreenSaverSuspensionRec));
 | 
						|
 | 
						|
    if (!this)
 | 
						|
	return BadAlloc;
 | 
						|
 | 
						|
    this->next           = NULL;
 | 
						|
    this->pClient        = client;
 | 
						|
    this->count          = 1;
 | 
						|
    this->clientResource = FakeClientID (client->index);
 | 
						|
 | 
						|
    if (!AddResource (this->clientResource, SuspendType, (pointer) this))
 | 
						|
    {
 | 
						|
	free(this);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    *prev = this;
 | 
						|
    if (!screenSaverSuspended)
 | 
						|
    {
 | 
						|
	screenSaverSuspended = TRUE;
 | 
						|
	FreeScreenSaverTimer();
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static DISPATCH_PROC((*NormalVector[])) = {
 | 
						|
    ProcScreenSaverQueryVersion,
 | 
						|
    ProcScreenSaverQueryInfo,
 | 
						|
    ProcScreenSaverSelectInput,
 | 
						|
    ProcScreenSaverSetAttributes,
 | 
						|
    ProcScreenSaverUnsetAttributes,
 | 
						|
    ProcScreenSaverSuspend,
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_REQUESTS	((sizeof NormalVector) / (sizeof NormalVector[0]))
 | 
						|
 | 
						|
static int
 | 
						|
ProcScreenSaverDispatch (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
 | 
						|
    if (stuff->data < NUM_REQUESTS)
 | 
						|
	return (*NormalVector[stuff->data])(client);
 | 
						|
    return BadRequest;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverQueryVersion (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverQueryVersionReq);
 | 
						|
    int	    n;
 | 
						|
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
 | 
						|
    return ProcScreenSaverQueryVersion (client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverQueryInfo (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverQueryInfoReq);
 | 
						|
    int	    n;
 | 
						|
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
 | 
						|
    swapl (&stuff->drawable, n);
 | 
						|
    return ProcScreenSaverQueryInfo (client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverSelectInput (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverSelectInputReq);
 | 
						|
    int	    n;
 | 
						|
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
 | 
						|
    swapl (&stuff->drawable, n);
 | 
						|
    swapl (&stuff->eventMask, n);
 | 
						|
    return ProcScreenSaverSelectInput (client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverSetAttributes (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverSetAttributesReq);
 | 
						|
    int	    n;
 | 
						|
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
 | 
						|
    swapl (&stuff->drawable, n);
 | 
						|
    swaps (&stuff->x, n);
 | 
						|
    swaps (&stuff->y, n);
 | 
						|
    swaps (&stuff->width, n);
 | 
						|
    swaps (&stuff->height, n);
 | 
						|
    swaps (&stuff->borderWidth, n);
 | 
						|
    swapl (&stuff->visualID, n);
 | 
						|
    swapl (&stuff->mask, n);
 | 
						|
    SwapRestL(stuff);
 | 
						|
    return ProcScreenSaverSetAttributes (client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverUnsetAttributes (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xScreenSaverUnsetAttributesReq);
 | 
						|
    int	    n;
 | 
						|
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
 | 
						|
    swapl (&stuff->drawable, n);
 | 
						|
    return ProcScreenSaverUnsetAttributes (client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverSuspend (ClientPtr client)
 | 
						|
{
 | 
						|
    int n;
 | 
						|
    REQUEST(xScreenSaverSuspendReq);
 | 
						|
 | 
						|
    swaps(&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
 | 
						|
    swapl(&stuff->suspend, n);
 | 
						|
    return ProcScreenSaverSuspend (client);
 | 
						|
}
 | 
						|
 | 
						|
static DISPATCH_PROC((*SwappedVector[])) = {
 | 
						|
    SProcScreenSaverQueryVersion,
 | 
						|
    SProcScreenSaverQueryInfo,
 | 
						|
    SProcScreenSaverSelectInput,
 | 
						|
    SProcScreenSaverSetAttributes,
 | 
						|
    SProcScreenSaverUnsetAttributes,
 | 
						|
    SProcScreenSaverSuspend,
 | 
						|
};
 | 
						|
 | 
						|
static int
 | 
						|
SProcScreenSaverDispatch (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
 | 
						|
    if (stuff->data < NUM_REQUESTS)
 | 
						|
	return (*SwappedVector[stuff->data])(client);
 | 
						|
    return BadRequest;
 | 
						|
}
 |