774 lines
20 KiB
C
774 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,
|
|
DixUnknownAccess);
|
|
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) {
|
|
|
|
pColormap = (ColormapPtr)LookupIDByType (pAppGrp->default_colormap, RT_COLORMAP);
|
|
/* XXX check that pColormap is not NULL */
|
|
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, DixUnknownAccess);
|
|
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);
|
|
}
|
|
}
|