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