776 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			776 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
Copyright 1996, 1998, 2001  The Open Group
 | 
						|
 | 
						|
Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
documentation for any purpose is hereby granted without fee, provided that
 | 
						|
the above copyright notice appear in all copies and that both that
 | 
						|
copyright notice and this permission notice appear in supporting
 | 
						|
documentation.
 | 
						|
 | 
						|
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 OPEN GROUP 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 Open Group 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 Open Group.
 | 
						|
*/
 | 
						|
 | 
						|
#define NEED_REPLIES
 | 
						|
#define NEED_EVENTS
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "dixstruct.h"
 | 
						|
#include "extnsionst.h"
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "windowstr.h"
 | 
						|
#include "colormapst.h"
 | 
						|
#include "servermd.h"
 | 
						|
#define _XAG_SERVER_
 | 
						|
#include <X11/extensions/Xagstr.h>
 | 
						|
#include "xacestr.h"
 | 
						|
#include "securitysrv.h"
 | 
						|
#include <X11/Xfuncproto.h>
 | 
						|
 | 
						|
#define XSERV_t
 | 
						|
#include <X11/Xtrans/Xtrans.h>
 | 
						|
#include "../os/osdep.h"
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "modinit.h"
 | 
						|
#include "appgroup.h"
 | 
						|
 | 
						|
typedef struct _AppGroupRec {
 | 
						|
    struct _AppGroupRec* next;
 | 
						|
    XID			appgroupId;
 | 
						|
    ClientPtr*		clients;
 | 
						|
    int			nclients;
 | 
						|
    ClientPtr		leader;
 | 
						|
    Bool		single_screen;
 | 
						|
    Window		default_root;
 | 
						|
    VisualID		root_visual;
 | 
						|
    Colormap		default_colormap;    
 | 
						|
    Pixel		black_pixel;
 | 
						|
    Pixel		white_pixel;
 | 
						|
    xConnSetupPrefix	connSetupPrefix;
 | 
						|
    char*		ConnectionInfo;
 | 
						|
} AppGroupRec, *AppGroupPtr;
 | 
						|
 | 
						|
static int		ProcXagDispatch(ClientPtr client);
 | 
						|
static int              SProcXagDispatch(ClientPtr client);
 | 
						|
static void		XagResetProc(ExtensionEntry* extEntry);
 | 
						|
 | 
						|
static int		XagCallbackRefCount = 0;
 | 
						|
 | 
						|
static RESTYPE		RT_APPGROUP;
 | 
						|
static AppGroupPtr	appGrpList = NULL;
 | 
						|
 | 
						|
extern xConnSetupPrefix connSetupPrefix;
 | 
						|
extern char* ConnectionInfo;
 | 
						|
extern int connBlockScreenStart;
 | 
						|
 | 
						|
static 
 | 
						|
int XagAppGroupFree(
 | 
						|
    pointer what,
 | 
						|
    XID id) /* unused */
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    AppGroupPtr pAppGrp = (AppGroupPtr) what;
 | 
						|
 | 
						|
    if (pAppGrp->leader)
 | 
						|
	for (i = 0; i < pAppGrp->nclients; i++) {
 | 
						|
	    if (pAppGrp->clients[i] == NULL) continue;
 | 
						|
	    CloseDownClient (pAppGrp->clients[i]);
 | 
						|
	}
 | 
						|
 | 
						|
    if (pAppGrp == appGrpList)
 | 
						|
	appGrpList = appGrpList->next;
 | 
						|
    else {
 | 
						|
	AppGroupPtr tpAppGrp;
 | 
						|
	for (tpAppGrp = appGrpList; 
 | 
						|
	    tpAppGrp->next != NULL; 
 | 
						|
	    tpAppGrp = tpAppGrp->next) {
 | 
						|
	    if (tpAppGrp->next == pAppGrp) {
 | 
						|
		tpAppGrp->next = tpAppGrp->next->next;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    (void) xfree (pAppGrp->clients);
 | 
						|
    (void) xfree (pAppGrp->ConnectionInfo);
 | 
						|
    (void) xfree (what);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static void XagClientStateChange(
 | 
						|
    CallbackListPtr* pcbl,
 | 
						|
    pointer nulldata,
 | 
						|
    pointer calldata)
 | 
						|
{
 | 
						|
    NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
 | 
						|
    ClientPtr pClient = pci->client;
 | 
						|
    AppGroupPtr pAppGrp = pClient->appgroup;
 | 
						|
    int slot;
 | 
						|
 | 
						|
    if (!pAppGrp)
 | 
						|
	return;
 | 
						|
 | 
						|
    switch (pClient->clientState) {
 | 
						|
    case ClientStateAuthenticating:
 | 
						|
    case ClientStateRunning: 
 | 
						|
    case ClientStateCheckingSecurity:
 | 
						|
	break;
 | 
						|
 | 
						|
    case ClientStateInitial: 
 | 
						|
    case ClientStateCheckedSecurity:
 | 
						|
	slot = -1;
 | 
						|
	/* see the comment above about Initial vs. CheckedSecurity */
 | 
						|
	if (pAppGrp->nclients != 0) {
 | 
						|
	    /* if this client already in AppGroup, don't add it again */
 | 
						|
	    int i;
 | 
						|
	    for (i = 0; i < pAppGrp->nclients; i++)
 | 
						|
		if (pClient == pAppGrp->clients[i]) return;
 | 
						|
		if (slot == -1 && pAppGrp->clients[i] == NULL)
 | 
						|
			slot = i;
 | 
						|
	}
 | 
						|
	if (slot == -1) {
 | 
						|
	    slot = pAppGrp->nclients++;
 | 
						|
	    pAppGrp->clients = (ClientPtr*) xrealloc (pAppGrp->clients, 
 | 
						|
				pAppGrp->nclients * sizeof (ClientPtr));
 | 
						|
	}
 | 
						|
	pAppGrp->clients[slot] = pClient;
 | 
						|
	pClient->appgroup = pAppGrp;
 | 
						|
	break;
 | 
						|
 | 
						|
    case ClientStateGone:
 | 
						|
    case ClientStateRetained: /* client disconnected, dump it */
 | 
						|
	{
 | 
						|
	    int i;
 | 
						|
	    for (i = 0; i < pAppGrp->nclients; i++)
 | 
						|
		if (pAppGrp->clients[i] == pClient) {
 | 
						|
		    pAppGrp->clients[i] = NULL;
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	pClient->appgroup = NULL; /* redundant, pClient will be freed */
 | 
						|
	break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static 
 | 
						|
void XagResetProc(
 | 
						|
    ExtensionEntry* extEntry)
 | 
						|
{
 | 
						|
    DeleteCallback (&ClientStateCallback, XagClientStateChange, NULL);
 | 
						|
    XagCallbackRefCount = 0;
 | 
						|
    while (appGrpList) XagAppGroupFree ((pointer) appGrpList, 0);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int ProcXagQueryVersion(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST (xXagQueryVersionReq); */
 | 
						|
    xXagQueryVersionReply rep;
 | 
						|
    register int n;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xXagQueryVersionReq);
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequence_number = client->sequence;
 | 
						|
    rep.server_major_version = XAG_MAJOR_VERSION;
 | 
						|
    rep.server_minor_version = XAG_MINOR_VERSION;
 | 
						|
    if (client->swapped) {
 | 
						|
    	swaps (&rep.sequence_number, n);
 | 
						|
    	swapl (&rep.length, n);
 | 
						|
    	swaps (&rep.server_major_version, n);
 | 
						|
    	swaps (&rep.server_minor_version, n);
 | 
						|
    }
 | 
						|
    WriteToClient (client, sizeof (xXagQueryVersionReply), (char *)&rep);
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
void ProcessAttr(
 | 
						|
    AppGroupPtr pAppGrp,
 | 
						|
    ClientPtr client,
 | 
						|
    unsigned int attrib_mask,
 | 
						|
    CARD32* attribs)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i <= XagNappGroupLeader; i++) {
 | 
						|
	switch (attrib_mask & (1 << i)) {
 | 
						|
	case XagSingleScreenMask:
 | 
						|
	    pAppGrp->single_screen = *attribs;
 | 
						|
	    break;
 | 
						|
	case XagDefaultRootMask:
 | 
						|
	    pAppGrp->default_root = *attribs;
 | 
						|
	    break;
 | 
						|
	case XagRootVisualMask:
 | 
						|
	    pAppGrp->root_visual = *attribs;
 | 
						|
	    break;
 | 
						|
	case XagDefaultColormapMask:
 | 
						|
	    pAppGrp->default_colormap = *attribs;
 | 
						|
	    break;
 | 
						|
	case XagBlackPixelMask:
 | 
						|
	    pAppGrp->black_pixel = *attribs;
 | 
						|
	    break;
 | 
						|
	case XagWhitePixelMask:
 | 
						|
	    pAppGrp->white_pixel = *attribs;
 | 
						|
	    break;
 | 
						|
	case XagAppGroupLeaderMask:
 | 
						|
	    pAppGrp->leader = client;
 | 
						|
	    break;
 | 
						|
	default: continue;
 | 
						|
	}
 | 
						|
	attribs++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
void CreateConnectionInfo(
 | 
						|
    AppGroupPtr pAppGrp)
 | 
						|
{
 | 
						|
    xWindowRoot* rootp;
 | 
						|
    xWindowRoot* roots[MAXSCREENS];
 | 
						|
    unsigned int rootlens[MAXSCREENS];
 | 
						|
    xDepth* depth;
 | 
						|
    int olen;
 | 
						|
    int snum, i;
 | 
						|
 | 
						|
    rootp = (xWindowRoot*) (ConnectionInfo + connBlockScreenStart);
 | 
						|
    for (snum = 0; snum < screenInfo.numScreens; snum++) {
 | 
						|
 | 
						|
	rootlens[snum] = sizeof (xWindowRoot);
 | 
						|
	roots[snum] = rootp;
 | 
						|
 | 
						|
	depth = (xDepth*) (rootp + 1);
 | 
						|
	for (i = 0; i < rootp->nDepths; i++) {
 | 
						|
	    rootlens[snum] += sizeof (xDepth) + 
 | 
						|
			      depth->nVisuals * sizeof (xVisualType);
 | 
						|
	    depth = (xDepth *)(((char*)(depth + 1)) +
 | 
						|
		depth->nVisuals * sizeof (xVisualType));
 | 
						|
	}
 | 
						|
	rootp = (xWindowRoot*) depth;
 | 
						|
    }
 | 
						|
    snum = 0;
 | 
						|
    if (pAppGrp->default_root) {
 | 
						|
	for (; snum < screenInfo.numVideoScreens; snum++) {
 | 
						|
	    if (roots[snum]->windowId == pAppGrp->default_root)
 | 
						|
		break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    olen = connBlockScreenStart + rootlens[snum];
 | 
						|
    for (i = screenInfo.numVideoScreens; i < screenInfo.numScreens; i++)
 | 
						|
	olen += rootlens[i];
 | 
						|
    pAppGrp->ConnectionInfo = (char*) xalloc (olen);
 | 
						|
    if (!pAppGrp->ConnectionInfo)
 | 
						|
	return;
 | 
						|
    memmove (pAppGrp->ConnectionInfo, ConnectionInfo, connBlockScreenStart);
 | 
						|
    ((xConnSetup*) (pAppGrp->ConnectionInfo))->numRoots = 
 | 
						|
	1 + screenInfo.numScreens - screenInfo.numVideoScreens;
 | 
						|
    memmove (pAppGrp->ConnectionInfo + connBlockScreenStart,
 | 
						|
	     (void*) roots[snum], rootlens[snum]);
 | 
						|
    rootp = (xWindowRoot*) (pAppGrp->ConnectionInfo + connBlockScreenStart);
 | 
						|
    if (pAppGrp->default_colormap) {
 | 
						|
	rootp->defaultColormap = pAppGrp->default_colormap;
 | 
						|
	rootp->whitePixel = pAppGrp->white_pixel;
 | 
						|
	rootp->blackPixel = pAppGrp->black_pixel;
 | 
						|
    }
 | 
						|
    if (pAppGrp->root_visual)
 | 
						|
	rootp->rootVisualID = pAppGrp->root_visual;
 | 
						|
    rootp = (xWindowRoot*) (((char*)rootp) + rootlens[snum]);
 | 
						|
    for (i = screenInfo.numVideoScreens; i < screenInfo.numScreens; i++) {
 | 
						|
	memmove ((void*) rootp, (void*) roots[i], rootlens[i]);
 | 
						|
	rootp = (xWindowRoot*) (((char*) rootp) + rootlens[i]);
 | 
						|
    }
 | 
						|
    pAppGrp->connSetupPrefix = connSetupPrefix;
 | 
						|
    pAppGrp->connSetupPrefix.length = olen >> 2;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
AppGroupPtr CreateAppGroup(
 | 
						|
    ClientPtr client,
 | 
						|
    XID appgroupId,
 | 
						|
    unsigned int attrib_mask,
 | 
						|
    CARD32* attribs)
 | 
						|
{
 | 
						|
    AppGroupPtr pAppGrp;
 | 
						|
 | 
						|
    pAppGrp = (AppGroupPtr) xalloc (sizeof(AppGroupRec));
 | 
						|
    if (pAppGrp) {
 | 
						|
	pAppGrp->next = appGrpList;
 | 
						|
	appGrpList = pAppGrp;
 | 
						|
	pAppGrp->appgroupId = appgroupId;
 | 
						|
	pAppGrp->clients = (ClientPtr*) xalloc (0);
 | 
						|
	pAppGrp->nclients = 0;
 | 
						|
	pAppGrp->leader = NULL;
 | 
						|
	pAppGrp->default_root = 0;
 | 
						|
	pAppGrp->root_visual = 0;
 | 
						|
	pAppGrp->default_colormap = 0;
 | 
						|
	pAppGrp->black_pixel = -1;
 | 
						|
	pAppGrp->white_pixel = -1;
 | 
						|
	pAppGrp->ConnectionInfo = NULL;
 | 
						|
	ProcessAttr (pAppGrp, client, attrib_mask, attribs);
 | 
						|
    }
 | 
						|
    return pAppGrp;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int AttrValidate(
 | 
						|
    ClientPtr client,
 | 
						|
    int attrib_mask,
 | 
						|
    AppGroupPtr pAppGrp)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
    int idepth, ivids, found, rc;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
    DepthPtr pDepth;
 | 
						|
    ColormapPtr pColormap;
 | 
						|
 | 
						|
    rc = dixLookupWindow(&pWin, pAppGrp->default_root, client,
 | 
						|
			 DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
    pScreen = pWin->drawable.pScreen;
 | 
						|
    if (WindowTable[pScreen->myNum]->drawable.id != pAppGrp->default_root)
 | 
						|
	return BadWindow;
 | 
						|
    pDepth = pScreen->allowedDepths;
 | 
						|
    if (pAppGrp->root_visual) {
 | 
						|
	found = FALSE;
 | 
						|
	for (idepth = 0; idepth < pScreen->numDepths; idepth++, pDepth++) {
 | 
						|
	    for (ivids = 0; ivids < pDepth->numVids; ivids++) {
 | 
						|
		if (pAppGrp->root_visual == pDepth->vids[ivids]) {
 | 
						|
		    found = TRUE;
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	if (!found)
 | 
						|
	    return BadMatch;
 | 
						|
    }
 | 
						|
    if (pAppGrp->default_colormap) {
 | 
						|
 | 
						|
	rc = dixLookupResource((pointer *)&pColormap, pAppGrp->default_colormap,
 | 
						|
			       RT_COLORMAP, client, DixUseAccess);
 | 
						|
	if (rc != Success)
 | 
						|
	    return rc;
 | 
						|
	if (pColormap->pScreen != pScreen)
 | 
						|
	    return BadColor;
 | 
						|
	if (pColormap->pVisual->vid != (pAppGrp->root_visual ? pAppGrp->root_visual : pScreen->rootVisual))
 | 
						|
	    return BadMatch;
 | 
						|
    }
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static int ProcXagCreate (
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST (xXagCreateReq);
 | 
						|
    AppGroupPtr pAppGrp;
 | 
						|
    int ret;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE (xXagCreateReq);
 | 
						|
 | 
						|
    LEGAL_NEW_RESOURCE (stuff->app_group, client);
 | 
						|
    pAppGrp = CreateAppGroup (client, stuff->app_group, 
 | 
						|
		stuff->attrib_mask, (CARD32*) &stuff[1]);
 | 
						|
    if (!pAppGrp)
 | 
						|
	return BadAlloc;
 | 
						|
    ret = AttrValidate (client, stuff->attrib_mask, pAppGrp);
 | 
						|
    if (ret != Success) {
 | 
						|
	XagAppGroupFree ((pointer)pAppGrp, (XID)0);
 | 
						|
	return ret;
 | 
						|
    }
 | 
						|
    if (pAppGrp->single_screen) {
 | 
						|
	CreateConnectionInfo (pAppGrp);
 | 
						|
	if (!pAppGrp->ConnectionInfo)
 | 
						|
	    return BadAlloc;
 | 
						|
    }
 | 
						|
    if (!AddResource (stuff->app_group, RT_APPGROUP, (pointer)pAppGrp))
 | 
						|
	return BadAlloc;
 | 
						|
    if (XagCallbackRefCount++ == 0)
 | 
						|
	(void) AddCallback (&ClientStateCallback, XagClientStateChange, NULL);
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static int ProcXagDestroy(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    AppGroupPtr pAppGrp;
 | 
						|
    REQUEST (xXagDestroyReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xXagDestroyReq);
 | 
						|
    pAppGrp = (AppGroupPtr)SecurityLookupIDByType (client, 
 | 
						|
		(XID)stuff->app_group, RT_APPGROUP, DixReadAccess);
 | 
						|
    if (!pAppGrp) return XagBadAppGroup;
 | 
						|
    FreeResource ((XID)stuff->app_group, RT_NONE);
 | 
						|
    if (--XagCallbackRefCount == 0)
 | 
						|
	(void) DeleteCallback (&ClientStateCallback, XagClientStateChange, NULL);
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int ProcXagGetAttr(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    AppGroupPtr pAppGrp;
 | 
						|
    REQUEST (xXagGetAttrReq);
 | 
						|
    xXagGetAttrReply rep;
 | 
						|
    int n;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xXagGetAttrReq);
 | 
						|
    pAppGrp = (AppGroupPtr)SecurityLookupIDByType (client, 
 | 
						|
		(XID)stuff->app_group, RT_APPGROUP, DixReadAccess);
 | 
						|
    if (!pAppGrp) return XagBadAppGroup;
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequence_number = client->sequence;
 | 
						|
    rep.default_root = pAppGrp->default_root;
 | 
						|
    rep.root_visual = pAppGrp->root_visual;
 | 
						|
    rep.default_colormap = pAppGrp->default_colormap;
 | 
						|
    rep.black_pixel = pAppGrp->black_pixel;
 | 
						|
    rep.white_pixel = pAppGrp->white_pixel;
 | 
						|
    rep.single_screen = pAppGrp->single_screen;
 | 
						|
    rep.app_group_leader = (pAppGrp->leader) ? 1 : 0;
 | 
						|
    if (client->swapped) {
 | 
						|
    	swaps (&rep.sequence_number, n);
 | 
						|
    	swapl (&rep.length, n);
 | 
						|
    	swapl (&rep.default_root, n);
 | 
						|
    	swapl (&rep.root_visual, n);
 | 
						|
    	swapl (&rep.default_colormap, n);
 | 
						|
    	swapl (&rep.black_pixel, n);
 | 
						|
    	swapl (&rep.white_pixel, n);
 | 
						|
    }
 | 
						|
    WriteToClient (client, sizeof (xXagGetAttrReply), (char *)&rep);
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int ProcXagQuery(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    ClientPtr pClient;
 | 
						|
    AppGroupPtr pAppGrp;
 | 
						|
    REQUEST (xXagQueryReq);
 | 
						|
    int n, rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xXagQueryReq);
 | 
						|
    rc = dixLookupClient(&pClient, stuff->resource, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
	return rc;
 | 
						|
 | 
						|
    for (pAppGrp = appGrpList; pAppGrp != NULL; pAppGrp = pAppGrp->next)
 | 
						|
	for (n = 0; n < pAppGrp->nclients; n++)
 | 
						|
	    if (pAppGrp->clients[n] == pClient) {
 | 
						|
		xXagQueryReply rep;
 | 
						|
 | 
						|
		rep.type = X_Reply;
 | 
						|
		rep.length = 0;
 | 
						|
		rep.sequence_number = client->sequence;
 | 
						|
		rep.app_group = pAppGrp->appgroupId;
 | 
						|
		if (client->swapped) {
 | 
						|
		    swaps (&rep.sequence_number, n);
 | 
						|
		    swapl (&rep.length, n);
 | 
						|
		    swapl (&rep.app_group, n);
 | 
						|
		}
 | 
						|
		WriteToClient (client, sizeof (xXagQueryReply), (char *)&rep);
 | 
						|
		return client->noClientException;
 | 
						|
	    }
 | 
						|
 | 
						|
    return BadMatch;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int ProcXagCreateAssoc(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST (xXagCreateAssocReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xXagCreateAssocReq);
 | 
						|
#ifdef WIN32
 | 
						|
    if (stuff->window_type != XagWindowTypeWin32)
 | 
						|
#else
 | 
						|
    if (stuff->window_type != XagWindowTypeX11)
 | 
						|
#endif
 | 
						|
	return BadMatch;
 | 
						|
#if defined(WIN32) || defined(__CYGWIN__) /* and Mac, etc */
 | 
						|
    if (!LocalClient (client))
 | 
						|
	return BadAccess;
 | 
						|
#endif
 | 
						|
 | 
						|
/* Macintosh, OS/2, and MS-Windows servers have some work to do here */
 | 
						|
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int ProcXagDestroyAssoc(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST (xXagDestroyAssocReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH (xXagDestroyAssocReq);
 | 
						|
/* Macintosh, OS/2, and MS-Windows servers have some work to do here */
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int ProcXagDispatch (
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST (xReq);
 | 
						|
    switch (stuff->data)
 | 
						|
    {
 | 
						|
    case X_XagQueryVersion:
 | 
						|
	return ProcXagQueryVersion (client);
 | 
						|
    case X_XagCreate:
 | 
						|
	return ProcXagCreate (client);
 | 
						|
    case X_XagDestroy:
 | 
						|
	return ProcXagDestroy (client);
 | 
						|
    case X_XagGetAttr:
 | 
						|
	return ProcXagGetAttr (client);
 | 
						|
    case X_XagQuery:
 | 
						|
	return ProcXagQuery (client);
 | 
						|
    case X_XagCreateAssoc:
 | 
						|
	return ProcXagCreateAssoc (client);
 | 
						|
    case X_XagDestroyAssoc:
 | 
						|
	return ProcXagDestroyAssoc (client);
 | 
						|
    default:
 | 
						|
	return BadRequest;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagQueryVersion(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST(xXagQueryVersionReq);
 | 
						|
    swaps(&stuff->length, n);
 | 
						|
    return ProcXagQueryVersion(client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagCreate(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST (xXagCreateReq);
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_AT_LEAST_SIZE (xXagCreateReq);
 | 
						|
    swapl (&stuff->app_group, n);
 | 
						|
    swapl (&stuff->attrib_mask, n);
 | 
						|
    SwapRestL (stuff);
 | 
						|
    return ProcXagCreate (client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagDestroy(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST (xXagDestroyReq);
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH (xXagDestroyReq);
 | 
						|
    swapl (&stuff->app_group, n);
 | 
						|
    return ProcXagDestroy (client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagGetAttr(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST (xXagGetAttrReq);
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH (xXagGetAttrReq);
 | 
						|
    swapl (&stuff->app_group, n);
 | 
						|
    return ProcXagGetAttr (client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagQuery(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST (xXagQueryReq);
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH (xXagQueryReq);
 | 
						|
    swapl (&stuff->resource, n);
 | 
						|
    return ProcXagQuery (client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagCreateAssoc(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST (xXagCreateAssocReq);
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH (xXagCreateAssocReq);
 | 
						|
    swapl (&stuff->window, n);
 | 
						|
    swapl (&stuff->window_type, n);
 | 
						|
    swaps (&stuff->system_window_len, n);
 | 
						|
    return ProcXagCreateAssoc (client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagDestroyAssoc(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST (xXagDestroyAssocReq);
 | 
						|
    swaps (&stuff->length, n);
 | 
						|
    REQUEST_SIZE_MATCH (xXagDestroyAssocReq);
 | 
						|
    swapl (&stuff->window, n);
 | 
						|
    return ProcXagDestroyAssoc (client);
 | 
						|
}
 | 
						|
 | 
						|
static 
 | 
						|
int SProcXagDispatch(
 | 
						|
    register ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
    switch (stuff->data)
 | 
						|
    {
 | 
						|
    case X_XagQueryVersion:
 | 
						|
	return SProcXagQueryVersion (client);
 | 
						|
    case X_XagCreate:
 | 
						|
	return SProcXagCreate (client);
 | 
						|
    case X_XagDestroy:
 | 
						|
	return SProcXagDestroy (client);
 | 
						|
    case X_XagGetAttr:
 | 
						|
	return SProcXagGetAttr (client);
 | 
						|
    case X_XagQuery:
 | 
						|
	return SProcXagQuery (client);
 | 
						|
    case X_XagCreateAssoc:
 | 
						|
	return SProcXagCreateAssoc (client);
 | 
						|
    case X_XagDestroyAssoc:
 | 
						|
	return SProcXagDestroyAssoc (client);
 | 
						|
    default:
 | 
						|
	return BadRequest;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
Colormap XagDefaultColormap(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    return (client->appgroup ? client->appgroup->default_colormap : None);
 | 
						|
}
 | 
						|
 | 
						|
VisualID XagRootVisual(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    return (client->appgroup ? client->appgroup->root_visual : 0);
 | 
						|
}
 | 
						|
 | 
						|
ClientPtr XagLeader(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    return (client->appgroup ? client->appgroup->leader : NULL);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return whether the Map request event should be sent to the appgroup leader.
 | 
						|
 * We don't want to send it to the leader when the window is on a different
 | 
						|
 * screen, e.g. a print screen.
 | 
						|
 */
 | 
						|
Bool XagIsControlledRoot(
 | 
						|
    ClientPtr client,
 | 
						|
    WindowPtr pParent)
 | 
						|
{
 | 
						|
    if (client->appgroup) {
 | 
						|
	if (client->appgroup->single_screen && 
 | 
						|
	    pParent->drawable.id == client->appgroup->default_root)
 | 
						|
	    return TRUE;
 | 
						|
	else if (!pParent->parent)
 | 
						|
	    return TRUE;
 | 
						|
	else
 | 
						|
	    return FALSE;
 | 
						|
    }
 | 
						|
    return FALSE; 
 | 
						|
}
 | 
						|
 | 
						|
void XagConnectionInfo(
 | 
						|
    ClientPtr client,
 | 
						|
    xConnSetupPrefix** conn_prefix,
 | 
						|
    char** conn_info,
 | 
						|
    int* num_screen)
 | 
						|
{
 | 
						|
    if (client->appgroup && client->appgroup->ConnectionInfo) {
 | 
						|
	*conn_prefix = &client->appgroup->connSetupPrefix;
 | 
						|
	*conn_info = client->appgroup->ConnectionInfo;
 | 
						|
	*num_screen = ((xConnSetup*)(client->appgroup->ConnectionInfo))->numRoots;
 | 
						|
    } 
 | 
						|
}
 | 
						|
 | 
						|
XID XagId(
 | 
						|
    ClientPtr client)
 | 
						|
{
 | 
						|
    return (client->appgroup ? client->appgroup->appgroupId : 0);
 | 
						|
}
 | 
						|
 | 
						|
static void XagCallClientStateChange(
 | 
						|
    CallbackListPtr *pcbl,
 | 
						|
    pointer nulldata,
 | 
						|
    pointer calldata)
 | 
						|
{
 | 
						|
    XaceAuthAvailRec* rec = (XaceAuthAvailRec*) calldata;
 | 
						|
    ClientPtr pClient = rec->client;
 | 
						|
 | 
						|
    if (!pClient->appgroup) {
 | 
						|
	SecurityAuthorizationPtr pAuth;
 | 
						|
	XID authId = rec->authId;
 | 
						|
 | 
						|
	/* can't use SecurityLookupIDByType here -- client
 | 
						|
	 * security state hasn't been setup yet.
 | 
						|
	 */
 | 
						|
	pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
 | 
						|
				SecurityAuthorizationResType);
 | 
						|
	if (!pAuth)
 | 
						|
	    return;
 | 
						|
 | 
						|
	pClient->appgroup = (AppGroupPtr)LookupIDByType(pAuth->group,
 | 
						|
							RT_APPGROUP);
 | 
						|
    }
 | 
						|
 | 
						|
    if (pClient->appgroup) {
 | 
						|
	NewClientInfoRec clientinfo;
 | 
						|
 | 
						|
	clientinfo.client = pClient;
 | 
						|
	XagClientStateChange (NULL, NULL, (pointer)&clientinfo);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
XagExtensionInit(INITARGS)
 | 
						|
{
 | 
						|
    if (AddExtension (XAGNAME,
 | 
						|
		      0,
 | 
						|
		      XagNumberErrors,
 | 
						|
		      ProcXagDispatch,
 | 
						|
		      SProcXagDispatch,
 | 
						|
		      XagResetProc,
 | 
						|
		      StandardMinorOpcode)) {
 | 
						|
	RT_APPGROUP = CreateNewResourceType (XagAppGroupFree);
 | 
						|
	XaceRegisterCallback(XACE_AUTH_AVAIL, XagCallClientStateChange, NULL);
 | 
						|
    }
 | 
						|
}
 |