2 Copyright 1996, 1998, 2001 The Open Group
4 Permission to use, copy, modify, distribute, and sell this software and its
5 documentation for any purpose is hereby granted without fee, provided that
6 the above copyright notice appear in all copies and that both that
7 copyright notice and this permission notice appear in supporting
10 The above copyright notice and this permission notice shall be included
11 in all copies or substantial portions of the Software.
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall
22 not be used in advertising or otherwise to promote the sale, use or
23 other dealings in this Software without prior written authorization
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
34 #include <X11/Xproto.h>
36 #include "dixstruct.h"
37 #include "extnsionst.h"
38 #include "scrnintstr.h"
39 #include "windowstr.h"
40 #include "colormapst.h"
43 #include <X11/extensions/Xagstr.h>
45 #include "securitysrv.h"
46 #include <X11/Xfuncproto.h>
49 #include <X11/Xtrans/Xtrans.h>
50 #include "../os/osdep.h"
57 typedef struct _AppGroupRec
{
58 struct _AppGroupRec
* next
;
66 Colormap default_colormap
;
69 xConnSetupPrefix connSetupPrefix
;
71 } AppGroupRec
, *AppGroupPtr
;
73 static int ProcXagDispatch(ClientPtr client
);
74 static int SProcXagDispatch(ClientPtr client
);
75 static void XagResetProc(ExtensionEntry
* extEntry
);
77 static int XagCallbackRefCount
= 0;
79 static RESTYPE RT_APPGROUP
;
80 static AppGroupPtr appGrpList
= NULL
;
82 extern xConnSetupPrefix connSetupPrefix
;
83 extern char* ConnectionInfo
;
84 extern int connBlockScreenStart
;
92 AppGroupPtr pAppGrp
= (AppGroupPtr
) what
;
95 for (i
= 0; i
< pAppGrp
->nclients
; i
++) {
96 if (pAppGrp
->clients
[i
] == NULL
) continue;
97 CloseDownClient (pAppGrp
->clients
[i
]);
100 if (pAppGrp
== appGrpList
)
101 appGrpList
= appGrpList
->next
;
103 AppGroupPtr tpAppGrp
;
104 for (tpAppGrp
= appGrpList
;
105 tpAppGrp
->next
!= NULL
;
106 tpAppGrp
= tpAppGrp
->next
) {
107 if (tpAppGrp
->next
== pAppGrp
) {
108 tpAppGrp
->next
= tpAppGrp
->next
->next
;
113 (void) xfree (pAppGrp
->clients
);
114 (void) xfree (pAppGrp
->ConnectionInfo
);
119 static void XagClientStateChange(
120 CallbackListPtr
* pcbl
,
124 NewClientInfoRec
* pci
= (NewClientInfoRec
*) calldata
;
125 ClientPtr pClient
= pci
->client
;
126 AppGroupPtr pAppGrp
= pClient
->appgroup
;
132 switch (pClient
->clientState
) {
133 case ClientStateAuthenticating
:
134 case ClientStateRunning
:
135 case ClientStateCheckingSecurity
:
138 case ClientStateInitial
:
139 case ClientStateCheckedSecurity
:
141 /* see the comment above about Initial vs. CheckedSecurity */
142 if (pAppGrp
->nclients
!= 0) {
143 /* if this client already in AppGroup, don't add it again */
145 for (i
= 0; i
< pAppGrp
->nclients
; i
++)
146 if (pClient
== pAppGrp
->clients
[i
]) return;
147 if (slot
== -1 && pAppGrp
->clients
[i
] == NULL
)
151 slot
= pAppGrp
->nclients
++;
152 pAppGrp
->clients
= (ClientPtr
*) xrealloc (pAppGrp
->clients
,
153 pAppGrp
->nclients
* sizeof (ClientPtr
));
155 pAppGrp
->clients
[slot
] = pClient
;
156 pClient
->appgroup
= pAppGrp
;
159 case ClientStateGone
:
160 case ClientStateRetained
: /* client disconnected, dump it */
163 for (i
= 0; i
< pAppGrp
->nclients
; i
++)
164 if (pAppGrp
->clients
[i
] == pClient
) {
165 pAppGrp
->clients
[i
] = NULL
;
169 pClient
->appgroup
= NULL
; /* redundant, pClient will be freed */
177 ExtensionEntry
* extEntry
)
179 DeleteCallback (&ClientStateCallback
, XagClientStateChange
, NULL
);
180 XagCallbackRefCount
= 0;
181 while (appGrpList
) XagAppGroupFree ((pointer
) appGrpList
, 0);
185 int ProcXagQueryVersion(
186 register ClientPtr client
)
188 /* REQUEST (xXagQueryVersionReq); */
189 xXagQueryVersionReply rep
;
192 REQUEST_SIZE_MATCH (xXagQueryVersionReq
);
195 rep
.sequence_number
= client
->sequence
;
196 rep
.server_major_version
= XAG_MAJOR_VERSION
;
197 rep
.server_minor_version
= XAG_MINOR_VERSION
;
198 if (client
->swapped
) {
199 swaps (&rep
.sequence_number
, n
);
200 swapl (&rep
.length
, n
);
201 swaps (&rep
.server_major_version
, n
);
202 swaps (&rep
.server_minor_version
, n
);
204 WriteToClient (client
, sizeof (xXagQueryVersionReply
), (char *)&rep
);
205 return client
->noClientException
;
212 unsigned int attrib_mask
,
217 for (i
= 0; i
<= XagNappGroupLeader
; i
++) {
218 switch (attrib_mask
& (1 << i
)) {
219 case XagSingleScreenMask
:
220 pAppGrp
->single_screen
= *attribs
;
222 case XagDefaultRootMask
:
223 pAppGrp
->default_root
= *attribs
;
225 case XagRootVisualMask
:
226 pAppGrp
->root_visual
= *attribs
;
228 case XagDefaultColormapMask
:
229 pAppGrp
->default_colormap
= *attribs
;
231 case XagBlackPixelMask
:
232 pAppGrp
->black_pixel
= *attribs
;
234 case XagWhitePixelMask
:
235 pAppGrp
->white_pixel
= *attribs
;
237 case XagAppGroupLeaderMask
:
238 pAppGrp
->leader
= client
;
247 void CreateConnectionInfo(
251 xWindowRoot
* roots
[MAXSCREENS
];
252 unsigned int rootlens
[MAXSCREENS
];
257 rootp
= (xWindowRoot
*) (ConnectionInfo
+ connBlockScreenStart
);
258 for (snum
= 0; snum
< screenInfo
.numScreens
; snum
++) {
260 rootlens
[snum
] = sizeof (xWindowRoot
);
263 depth
= (xDepth
*) (rootp
+ 1);
264 for (i
= 0; i
< rootp
->nDepths
; i
++) {
265 rootlens
[snum
] += sizeof (xDepth
) +
266 depth
->nVisuals
* sizeof (xVisualType
);
267 depth
= (xDepth
*)(((char*)(depth
+ 1)) +
268 depth
->nVisuals
* sizeof (xVisualType
));
270 rootp
= (xWindowRoot
*) depth
;
273 if (pAppGrp
->default_root
) {
274 for (; snum
< screenInfo
.numVideoScreens
; snum
++) {
275 if (roots
[snum
]->windowId
== pAppGrp
->default_root
)
279 olen
= connBlockScreenStart
+ rootlens
[snum
];
280 for (i
= screenInfo
.numVideoScreens
; i
< screenInfo
.numScreens
; i
++)
282 pAppGrp
->ConnectionInfo
= (char*) xalloc (olen
);
283 if (!pAppGrp
->ConnectionInfo
)
285 memmove (pAppGrp
->ConnectionInfo
, ConnectionInfo
, connBlockScreenStart
);
286 ((xConnSetup
*) (pAppGrp
->ConnectionInfo
))->numRoots
=
287 1 + screenInfo
.numScreens
- screenInfo
.numVideoScreens
;
288 memmove (pAppGrp
->ConnectionInfo
+ connBlockScreenStart
,
289 (void*) roots
[snum
], rootlens
[snum
]);
290 rootp
= (xWindowRoot
*) (pAppGrp
->ConnectionInfo
+ connBlockScreenStart
);
291 if (pAppGrp
->default_colormap
) {
292 rootp
->defaultColormap
= pAppGrp
->default_colormap
;
293 rootp
->whitePixel
= pAppGrp
->white_pixel
;
294 rootp
->blackPixel
= pAppGrp
->black_pixel
;
296 if (pAppGrp
->root_visual
)
297 rootp
->rootVisualID
= pAppGrp
->root_visual
;
298 rootp
= (xWindowRoot
*) (((char*)rootp
) + rootlens
[snum
]);
299 for (i
= screenInfo
.numVideoScreens
; i
< screenInfo
.numScreens
; i
++) {
300 memmove ((void*) rootp
, (void*) roots
[i
], rootlens
[i
]);
301 rootp
= (xWindowRoot
*) (((char*) rootp
) + rootlens
[i
]);
303 pAppGrp
->connSetupPrefix
= connSetupPrefix
;
304 pAppGrp
->connSetupPrefix
.length
= olen
>> 2;
308 AppGroupPtr
CreateAppGroup(
311 unsigned int attrib_mask
,
316 pAppGrp
= (AppGroupPtr
) xalloc (sizeof(AppGroupRec
));
318 pAppGrp
->next
= appGrpList
;
319 appGrpList
= pAppGrp
;
320 pAppGrp
->appgroupId
= appgroupId
;
321 pAppGrp
->clients
= (ClientPtr
*) xalloc (0);
322 pAppGrp
->nclients
= 0;
323 pAppGrp
->leader
= NULL
;
324 pAppGrp
->default_root
= 0;
325 pAppGrp
->root_visual
= 0;
326 pAppGrp
->default_colormap
= 0;
327 pAppGrp
->black_pixel
= -1;
328 pAppGrp
->white_pixel
= -1;
329 pAppGrp
->ConnectionInfo
= NULL
;
330 ProcessAttr (pAppGrp
, client
, attrib_mask
, attribs
);
342 int idepth
, ivids
, found
, rc
;
345 ColormapPtr pColormap
;
347 rc
= dixLookupWindow(&pWin
, pAppGrp
->default_root
, client
,
351 pScreen
= pWin
->drawable
.pScreen
;
352 if (WindowTable
[pScreen
->myNum
]->drawable
.id
!= pAppGrp
->default_root
)
354 pDepth
= pScreen
->allowedDepths
;
355 if (pAppGrp
->root_visual
) {
357 for (idepth
= 0; idepth
< pScreen
->numDepths
; idepth
++, pDepth
++) {
358 for (ivids
= 0; ivids
< pDepth
->numVids
; ivids
++) {
359 if (pAppGrp
->root_visual
== pDepth
->vids
[ivids
]) {
368 if (pAppGrp
->default_colormap
) {
370 pColormap
= (ColormapPtr
)LookupIDByType (pAppGrp
->default_colormap
, RT_COLORMAP
);
371 /* XXX check that pColormap is not NULL */
372 if (pColormap
->pScreen
!= pScreen
)
374 if (pColormap
->pVisual
->vid
!= (pAppGrp
->root_visual
? pAppGrp
->root_visual
: pScreen
->rootVisual
))
377 return client
->noClientException
;
380 static int ProcXagCreate (
381 register ClientPtr client
)
383 REQUEST (xXagCreateReq
);
387 REQUEST_AT_LEAST_SIZE (xXagCreateReq
);
389 LEGAL_NEW_RESOURCE (stuff
->app_group
, client
);
390 pAppGrp
= CreateAppGroup (client
, stuff
->app_group
,
391 stuff
->attrib_mask
, (CARD32
*) &stuff
[1]);
394 ret
= AttrValidate (client
, stuff
->attrib_mask
, pAppGrp
);
395 if (ret
!= Success
) {
396 XagAppGroupFree ((pointer
)pAppGrp
, (XID
)0);
399 if (pAppGrp
->single_screen
) {
400 CreateConnectionInfo (pAppGrp
);
401 if (!pAppGrp
->ConnectionInfo
)
404 if (!AddResource (stuff
->app_group
, RT_APPGROUP
, (pointer
)pAppGrp
))
406 if (XagCallbackRefCount
++ == 0)
407 (void) AddCallback (&ClientStateCallback
, XagClientStateChange
, NULL
);
408 return client
->noClientException
;
411 static int ProcXagDestroy(
412 register ClientPtr client
)
415 REQUEST (xXagDestroyReq
);
417 REQUEST_SIZE_MATCH (xXagDestroyReq
);
418 pAppGrp
= (AppGroupPtr
)SecurityLookupIDByType (client
,
419 (XID
)stuff
->app_group
, RT_APPGROUP
, DixReadAccess
);
420 if (!pAppGrp
) return XagBadAppGroup
;
421 FreeResource ((XID
)stuff
->app_group
, RT_NONE
);
422 if (--XagCallbackRefCount
== 0)
423 (void) DeleteCallback (&ClientStateCallback
, XagClientStateChange
, NULL
);
424 return client
->noClientException
;
429 register ClientPtr client
)
432 REQUEST (xXagGetAttrReq
);
433 xXagGetAttrReply rep
;
436 REQUEST_SIZE_MATCH (xXagGetAttrReq
);
437 pAppGrp
= (AppGroupPtr
)SecurityLookupIDByType (client
,
438 (XID
)stuff
->app_group
, RT_APPGROUP
, DixReadAccess
);
439 if (!pAppGrp
) return XagBadAppGroup
;
442 rep
.sequence_number
= client
->sequence
;
443 rep
.default_root
= pAppGrp
->default_root
;
444 rep
.root_visual
= pAppGrp
->root_visual
;
445 rep
.default_colormap
= pAppGrp
->default_colormap
;
446 rep
.black_pixel
= pAppGrp
->black_pixel
;
447 rep
.white_pixel
= pAppGrp
->white_pixel
;
448 rep
.single_screen
= pAppGrp
->single_screen
;
449 rep
.app_group_leader
= (pAppGrp
->leader
) ? 1 : 0;
450 if (client
->swapped
) {
451 swaps (&rep
.sequence_number
, n
);
452 swapl (&rep
.length
, n
);
453 swapl (&rep
.default_root
, n
);
454 swapl (&rep
.root_visual
, n
);
455 swapl (&rep
.default_colormap
, n
);
456 swapl (&rep
.black_pixel
, n
);
457 swapl (&rep
.white_pixel
, n
);
459 WriteToClient (client
, sizeof (xXagGetAttrReply
), (char *)&rep
);
460 return client
->noClientException
;
465 register ClientPtr client
)
469 REQUEST (xXagQueryReq
);
472 REQUEST_SIZE_MATCH (xXagQueryReq
);
473 rc
= dixLookupClient(&pClient
, stuff
->resource
, client
, DixUnknownAccess
);
477 for (pAppGrp
= appGrpList
; pAppGrp
!= NULL
; pAppGrp
= pAppGrp
->next
)
478 for (n
= 0; n
< pAppGrp
->nclients
; n
++)
479 if (pAppGrp
->clients
[n
] == pClient
) {
484 rep
.sequence_number
= client
->sequence
;
485 rep
.app_group
= pAppGrp
->appgroupId
;
486 if (client
->swapped
) {
487 swaps (&rep
.sequence_number
, n
);
488 swapl (&rep
.length
, n
);
489 swapl (&rep
.app_group
, n
);
491 WriteToClient (client
, sizeof (xXagQueryReply
), (char *)&rep
);
492 return client
->noClientException
;
499 int ProcXagCreateAssoc(
500 register ClientPtr client
)
502 REQUEST (xXagCreateAssocReq
);
504 REQUEST_SIZE_MATCH (xXagCreateAssocReq
);
506 if (stuff
->window_type
!= XagWindowTypeWin32
)
508 if (stuff
->window_type
!= XagWindowTypeX11
)
511 #if defined(WIN32) || defined(__CYGWIN__) /* and Mac, etc */
512 if (!LocalClient (client
))
516 /* Macintosh, OS/2, and MS-Windows servers have some work to do here */
518 return client
->noClientException
;
522 int ProcXagDestroyAssoc(
523 register ClientPtr client
)
525 /* REQUEST (xXagDestroyAssocReq); */
527 REQUEST_SIZE_MATCH (xXagDestroyAssocReq
);
528 /* Macintosh, OS/2, and MS-Windows servers have some work to do here */
529 return client
->noClientException
;
533 int ProcXagDispatch (
534 register ClientPtr client
)
539 case X_XagQueryVersion
:
540 return ProcXagQueryVersion (client
);
542 return ProcXagCreate (client
);
544 return ProcXagDestroy (client
);
546 return ProcXagGetAttr (client
);
548 return ProcXagQuery (client
);
549 case X_XagCreateAssoc
:
550 return ProcXagCreateAssoc (client
);
551 case X_XagDestroyAssoc
:
552 return ProcXagDestroyAssoc (client
);
559 int SProcXagQueryVersion(
560 register ClientPtr client
)
563 REQUEST(xXagQueryVersionReq
);
564 swaps(&stuff
->length
, n
);
565 return ProcXagQueryVersion(client
);
573 REQUEST (xXagCreateReq
);
574 swaps (&stuff
->length
, n
);
575 REQUEST_AT_LEAST_SIZE (xXagCreateReq
);
576 swapl (&stuff
->app_group
, n
);
577 swapl (&stuff
->attrib_mask
, n
);
579 return ProcXagCreate (client
);
587 REQUEST (xXagDestroyReq
);
588 swaps (&stuff
->length
, n
);
589 REQUEST_SIZE_MATCH (xXagDestroyReq
);
590 swapl (&stuff
->app_group
, n
);
591 return ProcXagDestroy (client
);
599 REQUEST (xXagGetAttrReq
);
600 swaps (&stuff
->length
, n
);
601 REQUEST_SIZE_MATCH (xXagGetAttrReq
);
602 swapl (&stuff
->app_group
, n
);
603 return ProcXagGetAttr (client
);
611 REQUEST (xXagQueryReq
);
612 swaps (&stuff
->length
, n
);
613 REQUEST_SIZE_MATCH (xXagQueryReq
);
614 swapl (&stuff
->resource
, n
);
615 return ProcXagQuery (client
);
619 int SProcXagCreateAssoc(
623 REQUEST (xXagCreateAssocReq
);
624 swaps (&stuff
->length
, n
);
625 REQUEST_SIZE_MATCH (xXagCreateAssocReq
);
626 swapl (&stuff
->window
, n
);
627 swapl (&stuff
->window_type
, n
);
628 swaps (&stuff
->system_window_len
, n
);
629 return ProcXagCreateAssoc (client
);
633 int SProcXagDestroyAssoc(
637 REQUEST (xXagDestroyAssocReq
);
638 swaps (&stuff
->length
, n
);
639 REQUEST_SIZE_MATCH (xXagDestroyAssocReq
);
640 swapl (&stuff
->window
, n
);
641 return ProcXagDestroyAssoc (client
);
645 int SProcXagDispatch(
646 register ClientPtr client
)
651 case X_XagQueryVersion
:
652 return SProcXagQueryVersion (client
);
654 return SProcXagCreate (client
);
656 return SProcXagDestroy (client
);
658 return SProcXagGetAttr (client
);
660 return SProcXagQuery (client
);
661 case X_XagCreateAssoc
:
662 return SProcXagCreateAssoc (client
);
663 case X_XagDestroyAssoc
:
664 return SProcXagDestroyAssoc (client
);
670 Colormap
XagDefaultColormap(
673 return (client
->appgroup
? client
->appgroup
->default_colormap
: None
);
676 VisualID
XagRootVisual(
679 return (client
->appgroup
? client
->appgroup
->root_visual
: 0);
685 return (client
->appgroup
? client
->appgroup
->leader
: NULL
);
689 * Return whether the Map request event should be sent to the appgroup leader.
690 * We don't want to send it to the leader when the window is on a different
691 * screen, e.g. a print screen.
693 Bool
XagIsControlledRoot(
697 if (client
->appgroup
) {
698 if (client
->appgroup
->single_screen
&&
699 pParent
->drawable
.id
== client
->appgroup
->default_root
)
701 else if (!pParent
->parent
)
709 void XagConnectionInfo(
711 xConnSetupPrefix
** conn_prefix
,
715 if (client
->appgroup
&& client
->appgroup
->ConnectionInfo
) {
716 *conn_prefix
= &client
->appgroup
->connSetupPrefix
;
717 *conn_info
= client
->appgroup
->ConnectionInfo
;
718 *num_screen
= ((xConnSetup
*)(client
->appgroup
->ConnectionInfo
))->numRoots
;
725 return (client
->appgroup
? client
->appgroup
->appgroupId
: 0);
728 static void XagCallClientStateChange(
729 CallbackListPtr
*pcbl
,
733 XaceAuthAvailRec
* rec
= (XaceAuthAvailRec
*) calldata
;
734 ClientPtr pClient
= rec
->client
;
736 if (!pClient
->appgroup
) {
737 SecurityAuthorizationPtr pAuth
;
738 XID authId
= rec
->authId
;
740 /* can't use SecurityLookupIDByType here -- client
741 * security state hasn't been setup yet.
743 pAuth
= (SecurityAuthorizationPtr
)LookupIDByType(authId
,
744 SecurityAuthorizationResType
);
748 pClient
->appgroup
= (AppGroupPtr
)LookupIDByType(pAuth
->group
,
752 if (pClient
->appgroup
) {
753 NewClientInfoRec clientinfo
;
755 clientinfo
.client
= pClient
;
756 XagClientStateChange (NULL
, NULL
, (pointer
)&clientinfo
);
761 XagExtensionInit(INITARGS
)
763 if (AddExtension (XAGNAME
,
769 StandardMinorOpcode
)) {
770 RT_APPGROUP
= CreateNewResourceType (XagAppGroupFree
);
771 XaceRegisterCallback(XACE_AUTH_AVAIL
, XagCallClientStateChange
, NULL
);