1caade7ccSmrg/******************************************************************************
2af9a7ee5Smrg *
3caade7ccSmrg * Copyright (c) 1994, 1995  Hewlett-Packard Company
4caade7ccSmrg *
5caade7ccSmrg * Permission is hereby granted, free of charge, to any person obtaining
6caade7ccSmrg * a copy of this software and associated documentation files (the
7caade7ccSmrg * "Software"), to deal in the Software without restriction, including
8caade7ccSmrg * without limitation the rights to use, copy, modify, merge, publish,
9caade7ccSmrg * distribute, sublicense, and/or sell copies of the Software, and to
10caade7ccSmrg * permit persons to whom the Software is furnished to do so, subject to
11caade7ccSmrg * the following conditions:
12af9a7ee5Smrg *
13caade7ccSmrg * The above copyright notice and this permission notice shall be included
14caade7ccSmrg * in all copies or substantial portions of the Software.
15af9a7ee5Smrg *
16caade7ccSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17caade7ccSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18caade7ccSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19caade7ccSmrg * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
20caade7ccSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21caade7ccSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22caade7ccSmrg * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23af9a7ee5Smrg *
24caade7ccSmrg * Except as contained in this notice, the name of the Hewlett-Packard
25caade7ccSmrg * Company shall not be used in advertising or otherwise to promote the
26caade7ccSmrg * sale, use or other dealings in this Software without prior written
27caade7ccSmrg * authorization from the Hewlett-Packard Company.
28af9a7ee5Smrg *
29caade7ccSmrg *     Xlib DBE code
30caade7ccSmrg *
31caade7ccSmrg *****************************************************************************/
32caade7ccSmrg
33caade7ccSmrg#ifdef HAVE_CONFIG_H
34caade7ccSmrg#include <config.h>
35caade7ccSmrg#endif
36caade7ccSmrg#include <stdio.h>
37caade7ccSmrg#include <X11/Xlibint.h>
38caade7ccSmrg#include <X11/extensions/Xext.h>
39caade7ccSmrg#include <X11/extensions/extutil.h>
40caade7ccSmrg#include <X11/extensions/Xdbe.h>
41485f0483Smrg#include <X11/extensions/dbeproto.h>
42af9a7ee5Smrg#include <limits.h>
430760f5d2Smrg#include "reallocarray.h"
44caade7ccSmrg
45caade7ccSmrgstatic XExtensionInfo _dbe_info_data;
46caade7ccSmrgstatic XExtensionInfo *dbe_info = &_dbe_info_data;
47af9a7ee5Smrgstatic const char *dbe_extension_name = DBE_PROTOCOL_NAME;
48caade7ccSmrg
49caade7ccSmrg#define DbeCheckExtension(dpy,i,val) \
50caade7ccSmrg  XextCheckExtension (dpy, i, dbe_extension_name, val)
51caade7ccSmrg#define DbeSimpleCheckExtension(dpy,i) \
52caade7ccSmrg  XextSimpleCheckExtension (dpy, i, dbe_extension_name)
53caade7ccSmrg
54caade7ccSmrg#define DbeGetReq(name,req,info) GetReq (name, req); \
55caade7ccSmrg        req->reqType = info->codes->major_opcode; \
56caade7ccSmrg        req->dbeReqType = X_##name;
57caade7ccSmrg
58caade7ccSmrg
59caade7ccSmrg/*****************************************************************************
60caade7ccSmrg *                                                                           *
61caade7ccSmrg *			   private utility routines                          *
62caade7ccSmrg *                                                                           *
63caade7ccSmrg *****************************************************************************/
64caade7ccSmrg
65caade7ccSmrg/*
66caade7ccSmrg * find_display - locate the display info block
67caade7ccSmrg */
68caade7ccSmrgstatic int close_display(Display *dpy, XExtCodes *codes);
69caade7ccSmrgstatic char *error_string(Display *dpy, int code, XExtCodes *codes,
70caade7ccSmrg			  char *buf, int n);
71caade7ccSmrgstatic XExtensionHooks dbe_extension_hooks = {
72caade7ccSmrg    NULL,                               /* create_gc */
73caade7ccSmrg    NULL,                               /* copy_gc */
74caade7ccSmrg    NULL,                               /* flush_gc */
75caade7ccSmrg    NULL,                               /* free_gc */
76caade7ccSmrg    NULL,                               /* create_font */
77caade7ccSmrg    NULL,                               /* free_font */
78caade7ccSmrg    close_display,                      /* close_display */
79caade7ccSmrg    NULL,                               /* wire_to_event */
80caade7ccSmrg    NULL,                               /* event_to_wire */
81caade7ccSmrg    NULL,                               /* error */
82caade7ccSmrg    error_string,                       /* error_string */
83caade7ccSmrg};
84caade7ccSmrg
85af9a7ee5Smrgstatic const char *dbe_error_list[] = {
86caade7ccSmrg    "BadBuffer",			/* DbeBadBuffer */
87caade7ccSmrg};
88caade7ccSmrg
89caade7ccSmrgstatic XEXT_GENERATE_FIND_DISPLAY (find_display, dbe_info,
90af9a7ee5Smrg				   dbe_extension_name,
91af9a7ee5Smrg				   &dbe_extension_hooks,
92caade7ccSmrg				   DbeNumberEvents, NULL)
93caade7ccSmrg
94caade7ccSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (close_display, dbe_info)
95caade7ccSmrg
96caade7ccSmrgstatic XEXT_GENERATE_ERROR_STRING (error_string, dbe_extension_name,
97af9a7ee5Smrg				   DbeNumberErrors,
98caade7ccSmrg				   dbe_error_list)
99caade7ccSmrg
100caade7ccSmrg
101caade7ccSmrg/*****************************************************************************
102caade7ccSmrg *                                                                           *
103caade7ccSmrg *		       Double-Buffering public interfaces                    *
104caade7ccSmrg *                                                                           *
105caade7ccSmrg *****************************************************************************/
106caade7ccSmrg
107af9a7ee5Smrg/*
108caade7ccSmrg * XdbeQueryExtension -
109caade7ccSmrg *	Sets major_version_return and minor_verion_return to the major and
110caade7ccSmrg *	minor DBE protocol version supported by the server.  If the DBE
111caade7ccSmrg *	library is compatible with the version returned by the server, this
112caade7ccSmrg *	function returns non-zero.  If dpy does not support the DBE
113caade7ccSmrg *	extension, or if there was an error during communication with the
114caade7ccSmrg *	server, or if the server and library protocol versions are
115caade7ccSmrg *	incompatible, this functions returns zero.  No other Xdbe functions
116caade7ccSmrg *	may be called before this function.   If a client violates this rule,
117caade7ccSmrg *	the effects of all subsequent Xdbe calls are undefined.
118caade7ccSmrg */
119caade7ccSmrgStatus XdbeQueryExtension (
120caade7ccSmrg    Display *dpy,
121caade7ccSmrg    int *major_version_return,
122caade7ccSmrg    int *minor_version_return)
123caade7ccSmrg{
124caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
125caade7ccSmrg    xDbeGetVersionReply rep;
126caade7ccSmrg    register xDbeGetVersionReq *req;
127caade7ccSmrg
128caade7ccSmrg    if (!XextHasExtension (info))
129caade7ccSmrg        return (Status)0; /* failure */
130caade7ccSmrg
131caade7ccSmrg    LockDisplay (dpy);
132caade7ccSmrg    DbeGetReq (DbeGetVersion, req, info);
133caade7ccSmrg    req->majorVersion = DBE_MAJOR_VERSION;
134caade7ccSmrg    req->minorVersion = DBE_MINOR_VERSION;
135caade7ccSmrg
136caade7ccSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
137caade7ccSmrg	UnlockDisplay (dpy);
138caade7ccSmrg	SyncHandle ();
139caade7ccSmrg	return (Status)0; /* failure */
140caade7ccSmrg    }
141caade7ccSmrg    *major_version_return = rep.majorVersion;
142caade7ccSmrg    *minor_version_return = rep.minorVersion;
143caade7ccSmrg    UnlockDisplay (dpy);
144caade7ccSmrg
145caade7ccSmrg    SyncHandle ();
146caade7ccSmrg
147caade7ccSmrg    if (*major_version_return != DBE_MAJOR_VERSION)
148caade7ccSmrg        return (Status)0; /* failure */
149caade7ccSmrg    else
150caade7ccSmrg        return (Status)1; /* success */
151caade7ccSmrg}
152caade7ccSmrg
153caade7ccSmrg
154caade7ccSmrg/*
155caade7ccSmrg * XdbeAllocateBackBuffer -
156caade7ccSmrg *	This function returns a drawable ID used to refer to the back buffer
157caade7ccSmrg *	of the specified window.  The swap_action is a hint to indicate the
158caade7ccSmrg *	swap action that will likely be used in subsequent calls to
159caade7ccSmrg *	XdbeSwapBuffers.  The actual swap action used in calls to
160caade7ccSmrg *	XdbeSwapBuffers does not have to be the same as the swap_action
161caade7ccSmrg *	passed to this function, though clients are encouraged to provide
162caade7ccSmrg *	accurate information whenever possible.
163caade7ccSmrg */
164caade7ccSmrg
165caade7ccSmrgXdbeBackBuffer XdbeAllocateBackBufferName(
166caade7ccSmrg    Display *dpy,
167caade7ccSmrg    Window window,
168caade7ccSmrg    XdbeSwapAction swap_action)
169caade7ccSmrg{
170caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
171caade7ccSmrg    register xDbeAllocateBackBufferNameReq *req;
172caade7ccSmrg    XdbeBackBuffer buffer;
173caade7ccSmrg
174caade7ccSmrg    /* make sure extension is available; if not, return the
175caade7ccSmrg     * third parameter (0).
176caade7ccSmrg     */
177caade7ccSmrg    DbeCheckExtension (dpy, info, (XdbeBackBuffer)0);
178caade7ccSmrg
179caade7ccSmrg    LockDisplay(dpy);
180caade7ccSmrg    DbeGetReq(DbeAllocateBackBufferName, req, info);
181caade7ccSmrg    req->window = window;
182caade7ccSmrg    req->swapAction = (unsigned char)swap_action;
183b9b4fd27Smrg    req->buffer = buffer = XAllocID (dpy);
184caade7ccSmrg
185caade7ccSmrg    UnlockDisplay (dpy);
186caade7ccSmrg    SyncHandle ();
187caade7ccSmrg    return buffer;
188caade7ccSmrg
189caade7ccSmrg} /* XdbeAllocateBackBufferName() */
190caade7ccSmrg
191caade7ccSmrg/*
192af9a7ee5Smrg * XdbeDeallocateBackBufferName -
193caade7ccSmrg *	This function frees a drawable ID, buffer, that was obtained via
194caade7ccSmrg *	XdbeAllocateBackBufferName.  The buffer must refer to the back buffer
195caade7ccSmrg *	of the specified window, or a protocol error results.
196caade7ccSmrg */
197caade7ccSmrgStatus XdbeDeallocateBackBufferName (
198caade7ccSmrg    Display *dpy,
199caade7ccSmrg    XdbeBackBuffer buffer)
200caade7ccSmrg{
201caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
202caade7ccSmrg    register xDbeDeallocateBackBufferNameReq *req;
203caade7ccSmrg
204caade7ccSmrg    DbeCheckExtension (dpy, info, (Status)0 /* failure */);
205caade7ccSmrg
206caade7ccSmrg    LockDisplay (dpy);
207caade7ccSmrg    DbeGetReq (DbeDeallocateBackBufferName, req, info);
208caade7ccSmrg    req->buffer = buffer;
209caade7ccSmrg    UnlockDisplay (dpy);
210caade7ccSmrg    SyncHandle ();
211caade7ccSmrg
212caade7ccSmrg    return (Status)1; /* success */
213caade7ccSmrg}
214caade7ccSmrg
215caade7ccSmrg
216caade7ccSmrg/*
217af9a7ee5Smrg * XdbeSwapBuffers -
218caade7ccSmrg *	This function swaps the front and back buffers for a list of windows.
219caade7ccSmrg *	The argument num_windows specifies how many windows are to have their
220caade7ccSmrg *	buffers swapped; it is the number of elements in the swap_info array.
221caade7ccSmrg *	The argument swap_info specifies the information needed per window
222caade7ccSmrg *	to do the swap.
223caade7ccSmrg */
224caade7ccSmrgStatus XdbeSwapBuffers (
225caade7ccSmrg    Display *dpy,
226caade7ccSmrg    XdbeSwapInfo *swap_info,
227caade7ccSmrg    int num_windows)
228caade7ccSmrg{
229caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
230caade7ccSmrg    register xDbeSwapBuffersReq *req;
231caade7ccSmrg    int i;
232caade7ccSmrg
233caade7ccSmrg    DbeCheckExtension (dpy, info, (Status)0 /* failure */);
234caade7ccSmrg
235caade7ccSmrg    LockDisplay (dpy);
236caade7ccSmrg    DbeGetReq (DbeSwapBuffers, req, info);
237caade7ccSmrg    req->length += 2*num_windows;
238caade7ccSmrg    req->n = num_windows;
239caade7ccSmrg
240caade7ccSmrg    /* We need to handle 64-bit machines, where we can not use PackData32
241caade7ccSmrg     * directly because info would be lost in translating from 32- to 64-bit.
242caade7ccSmrg     * Instead we send data via a loop that accounts for the translation.
243caade7ccSmrg     */
244caade7ccSmrg    for (i = 0; i < num_windows; i++)
245caade7ccSmrg    {
246caade7ccSmrg        char tmp[4];
247caade7ccSmrg        Data32 (dpy, (long *)&swap_info[i].swap_window, 4);
248caade7ccSmrg        tmp[0] = swap_info[i].swap_action;
249caade7ccSmrg        Data (dpy, (char *)tmp, 4);
250caade7ccSmrg    }
251caade7ccSmrg
252caade7ccSmrg    UnlockDisplay (dpy);
253caade7ccSmrg    SyncHandle ();
254caade7ccSmrg
255caade7ccSmrg
256caade7ccSmrg    return (Status)1; /* success */
257caade7ccSmrg
258caade7ccSmrg} /* XdbeSwapBuffers() */
259caade7ccSmrg
260caade7ccSmrg
261caade7ccSmrg/*
262caade7ccSmrg * XdbeBeginIdiom -
263caade7ccSmrg *	This function marks the beginning of an idiom sequence.
264caade7ccSmrg */
265caade7ccSmrgStatus XdbeBeginIdiom (Display *dpy)
266caade7ccSmrg{
267caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
268caade7ccSmrg    register xDbeBeginIdiomReq *req;
269caade7ccSmrg
270caade7ccSmrg    DbeCheckExtension (dpy, info, (Status)0 /* failure */);
271caade7ccSmrg
272caade7ccSmrg    LockDisplay (dpy);
273caade7ccSmrg    DbeGetReq (DbeBeginIdiom, req, info);
274caade7ccSmrg    UnlockDisplay (dpy);
275caade7ccSmrg    SyncHandle ();
276caade7ccSmrg
277caade7ccSmrg    return (Status)1; /* success */
278caade7ccSmrg}
279caade7ccSmrg
280caade7ccSmrg
281caade7ccSmrg/*
282caade7ccSmrg * XdbeEndIdiom -
283caade7ccSmrg *	This function marks the end of an idiom sequence.
284caade7ccSmrg */
285caade7ccSmrgStatus XdbeEndIdiom (Display *dpy)
286caade7ccSmrg{
287caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
288caade7ccSmrg    register xDbeEndIdiomReq *req;
289caade7ccSmrg
290caade7ccSmrg    DbeCheckExtension (dpy, info, (Status)0 /* failure */);
291caade7ccSmrg
292caade7ccSmrg    LockDisplay (dpy);
293caade7ccSmrg    DbeGetReq (DbeEndIdiom, req, info);
294caade7ccSmrg    UnlockDisplay (dpy);
295caade7ccSmrg    SyncHandle ();
296caade7ccSmrg
297caade7ccSmrg    return (Status)1; /* success */
298caade7ccSmrg}
299caade7ccSmrg
300caade7ccSmrg
301caade7ccSmrg/*
302caade7ccSmrg * XdbeGetVisualInfo -
303caade7ccSmrg *	This function returns information about which visuals support
304caade7ccSmrg *	double buffering.  The argument num_screens specifies how many
305caade7ccSmrg *	elements there are in the screen_specifiers list.  Each drawable
306caade7ccSmrg *	in screen_specifiers designates a screen for which the supported
307caade7ccSmrg *	visuals are being requested.  If num_screens is zero, information
308caade7ccSmrg *	for all screens is requested.  In this case, upon return from this
309caade7ccSmrg *	function, num_screens will be set to the number of screens that were
310caade7ccSmrg *	found.  If an error occurs, this function returns NULL, else it returns
311caade7ccSmrg *	a pointer to a list of XdbeScreenVisualInfo structures of length
312caade7ccSmrg *	num_screens.  The nth element in the returned list corresponds to the
313caade7ccSmrg *	nth drawable in the screen_specifiers list, unless num_screens was
314caade7ccSmrg *	passed in with the value zero, in which case the nth element in the
315caade7ccSmrg *	returned list corresponds to the nth screen of the server, starting
316caade7ccSmrg *	with screen zero.
317caade7ccSmrg */
318caade7ccSmrgXdbeScreenVisualInfo *XdbeGetVisualInfo (
319caade7ccSmrg    Display        *dpy,
320caade7ccSmrg    Drawable       *screen_specifiers,
321caade7ccSmrg    int            *num_screens)  /* SEND and RETURN */
322caade7ccSmrg{
323caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
324caade7ccSmrg    register xDbeGetVisualInfoReq *req;
325caade7ccSmrg    xDbeGetVisualInfoReply rep;
326caade7ccSmrg    XdbeScreenVisualInfo *scrVisInfo;
327caade7ccSmrg    int i;
328caade7ccSmrg
329caade7ccSmrg    DbeCheckExtension (dpy, info, (XdbeScreenVisualInfo *)NULL);
330caade7ccSmrg
331caade7ccSmrg    LockDisplay (dpy);
332caade7ccSmrg
333caade7ccSmrg    DbeGetReq(DbeGetVisualInfo, req, info);
334caade7ccSmrg    req->length = 2 + *num_screens;
335caade7ccSmrg    req->n      = *num_screens;
336caade7ccSmrg    Data32 (dpy, screen_specifiers, (*num_screens * sizeof (CARD32)));
337caade7ccSmrg
338caade7ccSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
339caade7ccSmrg        UnlockDisplay (dpy);
340caade7ccSmrg        SyncHandle ();
341caade7ccSmrg        return NULL;
342caade7ccSmrg    }
343caade7ccSmrg
344caade7ccSmrg    /* return the number of screens actually found if we
345caade7ccSmrg     * requested information about all screens (*num_screens == 0)
346caade7ccSmrg     */
347caade7ccSmrg    if (*num_screens == 0)
348caade7ccSmrg       *num_screens = rep.m;
349caade7ccSmrg
350caade7ccSmrg    /* allocate list of visual information to be returned */
351af9a7ee5Smrg    if ((*num_screens > 0) && (*num_screens < 65536))
3520760f5d2Smrg        scrVisInfo = Xcalloc(*num_screens, sizeof(XdbeScreenVisualInfo));
353af9a7ee5Smrg    else
354af9a7ee5Smrg        scrVisInfo = NULL;
355af9a7ee5Smrg    if (scrVisInfo == NULL) {
356af9a7ee5Smrg        _XEatDataWords(dpy, rep.length);
357caade7ccSmrg        UnlockDisplay (dpy);
358caade7ccSmrg        SyncHandle ();
359caade7ccSmrg        return NULL;
360caade7ccSmrg    }
361caade7ccSmrg
362caade7ccSmrg    for (i = 0; i < *num_screens; i++)
363caade7ccSmrg    {
364caade7ccSmrg        int j;
365af9a7ee5Smrg        unsigned long c;
366caade7ccSmrg
367af9a7ee5Smrg        _XRead32 (dpy, (long *) &c, sizeof(CARD32));
368caade7ccSmrg
369af9a7ee5Smrg        if (c < 65536) {
370af9a7ee5Smrg            scrVisInfo[i].count = c;
3710760f5d2Smrg            scrVisInfo[i].visinfo = Xmallocarray(c, sizeof(XdbeVisualInfo));
372af9a7ee5Smrg        } else
373af9a7ee5Smrg            scrVisInfo[i].visinfo = NULL;
374caade7ccSmrg
375caade7ccSmrg        /* if we can not allocate the list of visual/depth info
3760760f5d2Smrg         * then free the lists that we already allocated as well
377caade7ccSmrg         * as the visual info list itself
378caade7ccSmrg         */
379af9a7ee5Smrg        if (scrVisInfo[i].visinfo == NULL) {
380caade7ccSmrg            for (j = 0; j < i; j++) {
3810760f5d2Smrg                Xfree (scrVisInfo[j].visinfo);
382caade7ccSmrg            }
3830760f5d2Smrg            Xfree (scrVisInfo);
384af9a7ee5Smrg            _XEatDataWords(dpy, rep.length);
385caade7ccSmrg            UnlockDisplay (dpy);
386caade7ccSmrg            SyncHandle ();
387caade7ccSmrg            return NULL;
388caade7ccSmrg        }
389af9a7ee5Smrg
390caade7ccSmrg        /* Read the visual info item into the wire structure.  Then copy each
391caade7ccSmrg         * element into the library structure.  The element sizes and/or
392caade7ccSmrg         * padding may be different in the two structures.
393caade7ccSmrg         */
394caade7ccSmrg        for (j = 0; j < scrVisInfo[i].count; j++) {
395caade7ccSmrg            xDbeVisInfo xvi;
396caade7ccSmrg
397caade7ccSmrg            _XRead (dpy, (char *)&xvi, sizeof(xDbeVisInfo));
398caade7ccSmrg            scrVisInfo[i].visinfo[j].visual    = xvi.visualID;
399caade7ccSmrg            scrVisInfo[i].visinfo[j].depth     = xvi.depth;
400caade7ccSmrg            scrVisInfo[i].visinfo[j].perflevel = xvi.perfLevel;
401caade7ccSmrg        }
402caade7ccSmrg
403caade7ccSmrg    }
404caade7ccSmrg
405caade7ccSmrg    UnlockDisplay (dpy);
406caade7ccSmrg    SyncHandle ();
407caade7ccSmrg    return scrVisInfo;
408caade7ccSmrg
409caade7ccSmrg} /* XdbeGetVisualInfo() */
410caade7ccSmrg
411caade7ccSmrg
412caade7ccSmrg/*
413caade7ccSmrg * XdbeFreeVisualInfo -
414caade7ccSmrg *	This function frees the list of XdbeScreenVisualInfo returned by the
415caade7ccSmrg *	function XdbeGetVisualInfo.
416caade7ccSmrg */
417caade7ccSmrgvoid XdbeFreeVisualInfo(XdbeScreenVisualInfo *visual_info)
418caade7ccSmrg{
419caade7ccSmrg    if (visual_info == NULL) {
420caade7ccSmrg        return;
421caade7ccSmrg    }
422caade7ccSmrg
423caade7ccSmrg    if (visual_info->visinfo) {
424caade7ccSmrg        XFree(visual_info->visinfo);
425caade7ccSmrg    }
426caade7ccSmrg
427caade7ccSmrg    XFree(visual_info);
428caade7ccSmrg}
429caade7ccSmrg
430caade7ccSmrg
431caade7ccSmrg/*
432caade7ccSmrg * XdbeGetBackBufferAttributes -
433caade7ccSmrg *	This function returns the attributes associated with the specified
434caade7ccSmrg *	buffer.
435caade7ccSmrg */
436caade7ccSmrgXdbeBackBufferAttributes *XdbeGetBackBufferAttributes(
437caade7ccSmrg    Display *dpy,
438caade7ccSmrg    XdbeBackBuffer buffer)
439caade7ccSmrg{
440caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
441caade7ccSmrg    register xDbeGetBackBufferAttributesReq *req;
442caade7ccSmrg    xDbeGetBackBufferAttributesReply rep;
443caade7ccSmrg    XdbeBackBufferAttributes *attr;
444caade7ccSmrg
445caade7ccSmrg    DbeCheckExtension(dpy, info, (XdbeBackBufferAttributes *)NULL);
446caade7ccSmrg
4470760f5d2Smrg    if (!(attr = Xmalloc(sizeof(XdbeBackBufferAttributes)))) {
448caade7ccSmrg        return NULL;
449caade7ccSmrg    }
450caade7ccSmrg
451caade7ccSmrg    LockDisplay(dpy);
452caade7ccSmrg    DbeGetReq(DbeGetBackBufferAttributes, req, info);
453caade7ccSmrg    req->buffer = buffer;
454caade7ccSmrg
455caade7ccSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
456caade7ccSmrg        UnlockDisplay (dpy);
457caade7ccSmrg        SyncHandle ();
458caade7ccSmrg	Xfree(attr);
459caade7ccSmrg        return NULL;
460caade7ccSmrg    }
461caade7ccSmrg    attr->window = rep.attributes;
462caade7ccSmrg
463caade7ccSmrg    UnlockDisplay (dpy);
464caade7ccSmrg    SyncHandle ();
465caade7ccSmrg
466caade7ccSmrg    return attr;
467caade7ccSmrg}
468caade7ccSmrg
469