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