XAppgroup.c revision 485f0483
1/* $XFree86: xc/lib/Xext/XAppgroup.c,v 1.11 2002/10/16 02:19:22 dawes Exp $ */
2/*
3
4Copyright 1996, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26*/
27/* $Xorg: XAppgroup.c,v 1.5 2001/02/09 02:03:49 xorgcvs Exp $ */
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#ifdef WIN32
33#include <X11/Xwindows.h>
34#endif
35
36#define NEED_EVENTS
37#define NEED_REPLIES
38#include <X11/Xlibint.h>
39#include <X11/extensions/Xag.h>
40#include <X11/extensions/agproto.h>
41#include <X11/extensions/Xext.h>
42#include <X11/extensions/extutil.h>
43
44#include <stdarg.h>
45
46struct xagstuff {
47    int attrib_mask;
48    Bool app_group_leader;
49    Bool single_screen;
50    Window default_root;
51    VisualID root_visual;
52    Colormap default_colormap;
53    unsigned long black_pixel;
54    unsigned long white_pixel;
55};
56
57static XExtensionInfo _xag_info_data;
58static XExtensionInfo *xag_info = &_xag_info_data;
59static char *xag_extension_name = XAGNAME;
60
61#define XagCheckExtension(dpy,i,val) \
62  XextCheckExtension (dpy, i, xag_extension_name, val)
63
64/*****************************************************************************
65 *                                                                           *
66 *			   private utility routines                          *
67 *                                                                           *
68 *****************************************************************************/
69
70static int close_display(Display *dpy, XExtCodes *codes);
71static /* const */ XExtensionHooks xag_extension_hooks = {
72    NULL,				/* create_gc */
73    NULL,				/* copy_gc */
74    NULL,				/* flush_gc */
75    NULL,				/* free_gc */
76    NULL,				/* create_font */
77    NULL,				/* free_font */
78    close_display,			/* close_display */
79    NULL,				/* wire_to_event */
80    NULL,				/* event_to_wire */
81    NULL,				/* error */
82    NULL,				/* error_string */
83};
84
85static XEXT_GENERATE_FIND_DISPLAY (find_display, xag_info,
86				   xag_extension_name,
87				   &xag_extension_hooks,
88				   0, NULL)
89
90static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xag_info)
91
92
93/*****************************************************************************
94 *                                                                           *
95 *		    public Xag Extension routines                            *
96 *                                                                           *
97 *****************************************************************************/
98
99Bool
100XagQueryVersion(
101    Display *dpy,
102    int *major_version_return,
103    int *minor_version_return)
104{
105    XExtDisplayInfo *info = find_display (dpy);
106    xXagQueryVersionReply rep;
107    xXagQueryVersionReq *req;
108
109    XagCheckExtension (dpy, info, False);
110
111    LockDisplay(dpy);
112    GetReq(XagQueryVersion, req);
113    req->reqType = info->codes->major_opcode;
114    req->xagReqType = X_XagQueryVersion;
115    req->client_major_version = XAG_MAJOR_VERSION;
116    req->client_minor_version = XAG_MINOR_VERSION;
117    if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) {
118	UnlockDisplay(dpy);
119	SyncHandle();
120	return False;
121    }
122    *major_version_return = rep.server_major_version;
123    *minor_version_return = rep.server_minor_version;
124    UnlockDisplay(dpy);
125    SyncHandle();
126    return True;
127}
128
129static void
130StuffToWire (Display *dpy, struct xagstuff *stuff, xXagCreateReq *req)
131{
132    unsigned long values[8];
133    unsigned long* value = values;
134    unsigned int nvalues;
135
136    /* the order these are in is important */
137    if (stuff->attrib_mask & XagSingleScreenMask)
138	*value++ = stuff->single_screen;
139
140    if (stuff->attrib_mask & XagDefaultRootMask)
141	*value++ = stuff->default_root;
142
143    if (stuff->attrib_mask & XagRootVisualMask)
144	*value++ = stuff->root_visual;
145
146    if (stuff->attrib_mask & XagDefaultColormapMask)
147	*value++ = stuff->default_colormap;
148
149    if (stuff->attrib_mask & XagBlackPixelMask)
150	*value++ = stuff->black_pixel;
151
152    if (stuff->attrib_mask & XagWhitePixelMask)
153	*value++ = stuff->white_pixel;
154
155    if (stuff->attrib_mask & XagAppGroupLeaderMask)
156	*value++ = stuff->app_group_leader;
157
158    req->length += (nvalues = value - values);
159
160    nvalues <<= 2;
161    Data32 (dpy, (long*) values, (long) nvalues);
162}
163
164Bool
165XagCreateEmbeddedApplicationGroup(
166    Display* dpy,
167    VisualID root_visual,
168    Colormap default_colormap,
169    unsigned long black_pixel,
170    unsigned long white_pixel,
171    XAppGroup* app_group_return)
172{
173    XExtDisplayInfo *info = find_display (dpy);
174    xXagCreateReq *req;
175    struct xagstuff stuff;
176
177    XagCheckExtension (dpy, info, False);
178
179    LockDisplay(dpy);
180    stuff.app_group_leader = True;
181    stuff.single_screen = True;
182    stuff.default_root = RootWindow (dpy, DefaultScreen(dpy));
183    stuff.root_visual = root_visual;
184    stuff.default_colormap = default_colormap;
185    stuff.attrib_mask =
186	XagAppGroupLeaderMask | XagSingleScreenMask | XagDefaultRootMask |
187	XagRootVisualMask | XagDefaultColormapMask;
188    if (default_colormap != None) {
189	stuff.black_pixel = black_pixel;
190	stuff.white_pixel = white_pixel;
191	stuff.attrib_mask |= XagBlackPixelMask | XagWhitePixelMask;
192    }
193    /* might do some validation here */
194    GetReq(XagCreate, req);
195    req->reqType = info->codes->major_opcode;
196    req->xagReqType = X_XagCreate;
197    *app_group_return = req->app_group = XAllocID(dpy);
198    req->attrib_mask = stuff.attrib_mask;
199    StuffToWire (dpy, &stuff, req);
200    UnlockDisplay(dpy);
201    SyncHandle();
202    return True;
203}
204
205Bool
206XagCreateNonembeddedApplicationGroup(
207    Display* dpy,
208    XAppGroup* app_group_return)
209{
210    XExtDisplayInfo *info = find_display (dpy);
211    xXagCreateReq *req;
212    struct xagstuff stuff;
213
214    XagCheckExtension (dpy, info, False);
215
216    LockDisplay(dpy);
217    stuff.app_group_leader = False;
218    stuff.single_screen = False;
219    stuff.attrib_mask = XagAppGroupLeaderMask | XagSingleScreenMask;
220    /* might do some validation here */
221    GetReq(XagCreate, req);
222    req->reqType = info->codes->major_opcode;
223    req->xagReqType = X_XagCreate;
224    *app_group_return = req->app_group = XAllocID(dpy);
225    req->attrib_mask = stuff.attrib_mask;
226    StuffToWire (dpy, &stuff, req);
227    UnlockDisplay(dpy);
228    SyncHandle();
229    return True;
230}
231
232Bool XagDestroyApplicationGroup(Display* dpy, XAppGroup app_group)
233{
234    XExtDisplayInfo *info = find_display (dpy);
235    xXagDestroyReq *req;
236
237    XagCheckExtension (dpy, info, False);
238
239    LockDisplay(dpy);
240    GetReq(XagDestroy, req);
241    req->reqType = info->codes->major_opcode;
242    req->xagReqType = X_XagDestroy;
243    req->app_group = app_group;
244    UnlockDisplay(dpy);
245    SyncHandle();
246    return True;
247}
248
249Bool
250XagGetApplicationGroupAttributes(Display* dpy, XAppGroup app_group, ...)
251{
252    va_list var;
253    XExtDisplayInfo *info = find_display (dpy);
254    xXagGetAttrReq *req;
255    xXagGetAttrReply rep;
256    int attr;
257
258    XagCheckExtension (dpy, info, False);
259
260    LockDisplay(dpy);
261    GetReq(XagGetAttr, req);
262    req->reqType = info->codes->major_opcode;
263    req->xagReqType = X_XagGetAttr;
264    req->app_group = app_group;
265    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
266	UnlockDisplay(dpy);
267	SyncHandle();
268	return False;
269    }
270    va_start (var, app_group);
271    for (attr = va_arg(var, int); attr != 0; attr = va_arg(var, int)) {
272	void* ptr;
273
274	switch (attr) {
275	case XagNappGroupLeader:
276	    ptr = va_arg(var, void*);
277	    *(Bool*)ptr = rep.app_group_leader;
278	    break;
279	case XagNsingleScreen:
280	    ptr = va_arg(var, void*);
281	    *(Bool*)ptr = rep.single_screen;
282	    break;
283	case XagNdefaultRoot:
284	    ptr = va_arg(var, void*);
285	    *(Window*)ptr = rep.default_root;
286	    break;
287	case XagNrootVisual:
288	    ptr = va_arg(var, void*);
289	    *(VisualID*)ptr = rep.root_visual;
290	    break;
291	case XagNdefaultColormap:
292	    ptr = va_arg(var, void*);
293	    *(Colormap*)ptr = rep.default_colormap;
294	    break;
295	case XagNblackPixel:
296	    ptr = va_arg(var, void*);
297	    *(unsigned long*)ptr = rep.black_pixel;
298	    break;
299	case XagNwhitePixel:
300	    ptr = va_arg(var, void*);
301	    *(unsigned long*)ptr = rep.white_pixel;
302	    break;
303	}
304    }
305    va_end (var);
306    UnlockDisplay(dpy);
307    SyncHandle();
308    return True;
309}
310
311Bool
312XagQueryApplicationGroup(
313    Display* dpy,
314    XID resource,
315    XAppGroup* app_group_return)
316{
317    XExtDisplayInfo *info = find_display (dpy);
318    xXagQueryReq *req;
319    xXagQueryReply rep;
320
321    XagCheckExtension (dpy, info, False);
322
323    LockDisplay(dpy);
324    GetReq(XagQuery, req);
325    req->reqType = info->codes->major_opcode;
326    req->xagReqType = X_XagQuery;
327    req->resource = resource;
328    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
329	UnlockDisplay(dpy);
330	SyncHandle();
331	return False;
332    }
333    *app_group_return = rep.app_group;
334    UnlockDisplay(dpy);
335    SyncHandle();
336    return True;
337
338}
339
340Bool
341XagCreateAssociation(Display* dpy, Window* window_return, void* system_window)
342{
343#ifdef WIN32
344    long tmp = *(HWND*) system_window;
345    XExtDisplayInfo *info = find_display (dpy);
346    xXagCreateAssocReq *req;
347
348    XagCheckExtension (dpy, info, False);
349
350    LockDisplay(dpy);
351    GetReq(XagCreateAssoc, req);
352    req->reqType = info->codes->major_opcode;
353    req->xagReqType = X_XagCreateAssoc;
354    *window_return = req->window = XAllocID(dpy);
355    req->window_type = XagWindowTypeWin32;
356    req->system_window_len = sizeof(HWND);
357    Data32 (dpy, (long*) tmp, 1L);
358    req->length++;
359    UnlockDisplay(dpy);
360    SyncHandle();
361#else
362    /* other platforms go here */
363
364    /* this whole thing could be arranged better, but since X need
365     * only short-circuit the protocol and WIN32 is the only other
366     * platform the XC supports, it will suffice for now.
367     */
368    *window_return = *(Window*)system_window;
369#endif
370    return True;
371}
372
373Bool
374XagDestroyAssociation(Display* dpy, Window window)
375{
376#ifdef WIN32
377    XExtDisplayInfo *info = find_display (dpy);
378    xXagDestroyAssocReq *req;
379
380    XagCheckExtension (dpy, info, False);
381
382    LockDisplay(dpy);
383    GetReq(XagDestroyAssoc, req);
384    req->reqType = info->codes->major_opcode;
385    req->xagReqType = X_XagDestroyAssoc;
386    req->window = window;
387    UnlockDisplay(dpy);
388    SyncHandle();
389#endif
390    return True;
391}
392
393