1 /******************************************************************************
3 * Copyright (c) 1994, 1995 Hewlett-Packard Company
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Except as contained in this notice, the name of the Hewlett-Packard
25 * Company shall not be used in advertising or otherwise to promote the
26 * sale, use or other dealings in this Software without prior written
27 * authorization from the Hewlett-Packard Company.
31 *****************************************************************************/
37 #include <X11/Xlibint.h>
38 #include <X11/extensions/Xext.h>
39 #include <X11/extensions/extutil.h>
40 #include <X11/extensions/Xdbe.h>
41 #include <X11/extensions/dbeproto.h>
43 static XExtensionInfo _dbe_info_data;
44 static XExtensionInfo *dbe_info = &_dbe_info_data;
45 static const char *dbe_extension_name = DBE_PROTOCOL_NAME;
47 #define DbeCheckExtension(dpy,i,val) \
48 XextCheckExtension (dpy, i, dbe_extension_name, val)
49 #define DbeSimpleCheckExtension(dpy,i) \
50 XextSimpleCheckExtension (dpy, i, dbe_extension_name)
53 #define DbeGetReq(name,req,info) GetReq (name, req); \
54 req->reqType = info->codes->major_opcode; \
55 req->dbeReqType = X_##name;
57 #define DbeGetReq(name,req,info) GetReq (name, req); \
58 req->reqType = info->codes->major_opcode; \
59 req->dbeReqType = X_/**/name;
63 /*****************************************************************************
65 * private utility routines *
67 *****************************************************************************/
70 * find_display - locate the display info block
72 static int close_display(Display *dpy, XExtCodes *codes);
73 static char *error_string(Display *dpy, int code, XExtCodes *codes,
75 static XExtensionHooks dbe_extension_hooks = {
80 NULL, /* create_font */
82 close_display, /* close_display */
83 NULL, /* wire_to_event */
84 NULL, /* event_to_wire */
86 error_string, /* error_string */
89 static const char *dbe_error_list[] = {
90 "BadBuffer", /* DbeBadBuffer */
93 static XEXT_GENERATE_FIND_DISPLAY (find_display, dbe_info,
96 DbeNumberEvents, NULL)
98 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, dbe_info)
100 static XEXT_GENERATE_ERROR_STRING (error_string, dbe_extension_name,
105 /*****************************************************************************
107 * Double-Buffering public interfaces *
109 *****************************************************************************/
112 * XdbeQueryExtension -
113 * Sets major_version_return and minor_verion_return to the major and
114 * minor DBE protocol version supported by the server. If the DBE
115 * library is compatible with the version returned by the server, this
116 * function returns non-zero. If dpy does not support the DBE
117 * extension, or if there was an error during communication with the
118 * server, or if the server and library protocol versions are
119 * incompatible, this functions returns zero. No other Xdbe functions
120 * may be called before this function. If a client violates this rule,
121 * the effects of all subsequent Xdbe calls are undefined.
123 Status XdbeQueryExtension (
125 int *major_version_return,
126 int *minor_version_return)
128 XExtDisplayInfo *info = find_display (dpy);
129 xDbeGetVersionReply rep;
130 register xDbeGetVersionReq *req;
132 if (!XextHasExtension (info))
133 return (Status)0; /* failure */
136 DbeGetReq (DbeGetVersion, req, info);
137 req->majorVersion = DBE_MAJOR_VERSION;
138 req->minorVersion = DBE_MINOR_VERSION;
140 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
143 return (Status)0; /* failure */
145 *major_version_return = rep.majorVersion;
146 *minor_version_return = rep.minorVersion;
151 if (*major_version_return != DBE_MAJOR_VERSION)
152 return (Status)0; /* failure */
154 return (Status)1; /* success */
159 * XdbeAllocateBackBuffer -
160 * This function returns a drawable ID used to refer to the back buffer
161 * of the specified window. The swap_action is a hint to indicate the
162 * swap action that will likely be used in subsequent calls to
163 * XdbeSwapBuffers. The actual swap action used in calls to
164 * XdbeSwapBuffers does not have to be the same as the swap_action
165 * passed to this function, though clients are encouraged to provide
166 * accurate information whenever possible.
169 XdbeBackBuffer XdbeAllocateBackBufferName(
172 XdbeSwapAction swap_action)
174 XExtDisplayInfo *info = find_display (dpy);
175 register xDbeAllocateBackBufferNameReq *req;
176 XdbeBackBuffer buffer;
178 /* make sure extension is available; if not, return the
179 * third parameter (0).
181 DbeCheckExtension (dpy, info, (XdbeBackBuffer)0);
184 DbeGetReq(DbeAllocateBackBufferName, req, info);
185 req->window = window;
186 req->swapAction = (unsigned char)swap_action;
187 req->buffer = buffer = XAllocID (dpy);
193 } /* XdbeAllocateBackBufferName() */
196 * XdbeDeallocateBackBufferName -
197 * This function frees a drawable ID, buffer, that was obtained via
198 * XdbeAllocateBackBufferName. The buffer must refer to the back buffer
199 * of the specified window, or a protocol error results.
201 Status XdbeDeallocateBackBufferName (
203 XdbeBackBuffer buffer)
205 XExtDisplayInfo *info = find_display (dpy);
206 register xDbeDeallocateBackBufferNameReq *req;
208 DbeCheckExtension (dpy, info, (Status)0 /* failure */);
211 DbeGetReq (DbeDeallocateBackBufferName, req, info);
212 req->buffer = buffer;
216 return (Status)1; /* success */
222 * This function swaps the front and back buffers for a list of windows.
223 * The argument num_windows specifies how many windows are to have their
224 * buffers swapped; it is the number of elements in the swap_info array.
225 * The argument swap_info specifies the information needed per window
228 Status XdbeSwapBuffers (
230 XdbeSwapInfo *swap_info,
233 XExtDisplayInfo *info = find_display (dpy);
234 register xDbeSwapBuffersReq *req;
237 DbeCheckExtension (dpy, info, (Status)0 /* failure */);
240 DbeGetReq (DbeSwapBuffers, req, info);
241 req->length += 2*num_windows;
242 req->n = num_windows;
244 /* We need to handle 64-bit machines, where we can not use PackData32
245 * directly because info would be lost in translating from 32- to 64-bit.
246 * Instead we send data via a loop that accounts for the translation.
248 for (i = 0; i < num_windows; i++)
251 Data32 (dpy, (long *)&swap_info[i].swap_window, 4);
252 tmp[0] = swap_info[i].swap_action;
253 Data (dpy, (char *)tmp, 4);
260 return (Status)1; /* success */
262 } /* XdbeSwapBuffers() */
267 * This function marks the beginning of an idiom sequence.
269 Status XdbeBeginIdiom (Display *dpy)
271 XExtDisplayInfo *info = find_display(dpy);
272 register xDbeBeginIdiomReq *req;
274 DbeCheckExtension (dpy, info, (Status)0 /* failure */);
277 DbeGetReq (DbeBeginIdiom, req, info);
281 return (Status)1; /* success */
287 * This function marks the end of an idiom sequence.
289 Status XdbeEndIdiom (Display *dpy)
291 XExtDisplayInfo *info = find_display(dpy);
292 register xDbeEndIdiomReq *req;
294 DbeCheckExtension (dpy, info, (Status)0 /* failure */);
297 DbeGetReq (DbeEndIdiom, req, info);
301 return (Status)1; /* success */
306 * XdbeGetVisualInfo -
307 * This function returns information about which visuals support
308 * double buffering. The argument num_screens specifies how many
309 * elements there are in the screen_specifiers list. Each drawable
310 * in screen_specifiers designates a screen for which the supported
311 * visuals are being requested. If num_screens is zero, information
312 * for all screens is requested. In this case, upon return from this
313 * function, num_screens will be set to the number of screens that were
314 * found. If an error occurs, this function returns NULL, else it returns
315 * a pointer to a list of XdbeScreenVisualInfo structures of length
316 * num_screens. The nth element in the returned list corresponds to the
317 * nth drawable in the screen_specifiers list, unless num_screens was
318 * passed in with the value zero, in which case the nth element in the
319 * returned list corresponds to the nth screen of the server, starting
322 XdbeScreenVisualInfo *XdbeGetVisualInfo (
324 Drawable *screen_specifiers,
325 int *num_screens) /* SEND and RETURN */
327 XExtDisplayInfo *info = find_display(dpy);
328 register xDbeGetVisualInfoReq *req;
329 xDbeGetVisualInfoReply rep;
330 XdbeScreenVisualInfo *scrVisInfo;
333 DbeCheckExtension (dpy, info, (XdbeScreenVisualInfo *)NULL);
337 DbeGetReq(DbeGetVisualInfo, req, info);
338 req->length = 2 + *num_screens;
339 req->n = *num_screens;
340 Data32 (dpy, screen_specifiers, (*num_screens * sizeof (CARD32)));
342 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
348 /* return the number of screens actually found if we
349 * requested information about all screens (*num_screens == 0)
351 if (*num_screens == 0)
352 *num_screens = rep.m;
354 /* allocate list of visual information to be returned */
356 (XdbeScreenVisualInfo *)Xmalloc(
357 (unsigned)(*num_screens * sizeof(XdbeScreenVisualInfo))))) {
363 for (i = 0; i < *num_screens; i++)
369 _XRead32 (dpy, &c, sizeof(CARD32));
370 scrVisInfo[i].count = c;
372 nbytes = scrVisInfo[i].count * sizeof(XdbeVisualInfo);
374 /* if we can not allocate the list of visual/depth info
375 * then free the lists that we already allocate as well
376 * as the visual info list itself
378 if (!(scrVisInfo[i].visinfo = (XdbeVisualInfo *)Xmalloc(
379 (unsigned)nbytes))) {
380 for (j = 0; j < i; j++) {
381 Xfree ((char *)scrVisInfo[j].visinfo);
383 Xfree ((char *)scrVisInfo);
389 /* Read the visual info item into the wire structure. Then copy each
390 * element into the library structure. The element sizes and/or
391 * padding may be different in the two structures.
393 for (j = 0; j < scrVisInfo[i].count; j++) {
396 _XRead (dpy, (char *)&xvi, sizeof(xDbeVisInfo));
397 scrVisInfo[i].visinfo[j].visual = xvi.visualID;
398 scrVisInfo[i].visinfo[j].depth = xvi.depth;
399 scrVisInfo[i].visinfo[j].perflevel = xvi.perfLevel;
408 } /* XdbeGetVisualInfo() */
412 * XdbeFreeVisualInfo -
413 * This function frees the list of XdbeScreenVisualInfo returned by the
414 * function XdbeGetVisualInfo.
416 void XdbeFreeVisualInfo(XdbeScreenVisualInfo *visual_info)
418 if (visual_info == NULL) {
422 if (visual_info->visinfo) {
423 XFree(visual_info->visinfo);
431 * XdbeGetBackBufferAttributes -
432 * This function returns the attributes associated with the specified
435 XdbeBackBufferAttributes *XdbeGetBackBufferAttributes(
437 XdbeBackBuffer buffer)
439 XExtDisplayInfo *info = find_display(dpy);
440 register xDbeGetBackBufferAttributesReq *req;
441 xDbeGetBackBufferAttributesReply rep;
442 XdbeBackBufferAttributes *attr;
444 DbeCheckExtension(dpy, info, (XdbeBackBufferAttributes *)NULL);
447 (XdbeBackBufferAttributes *)Xmalloc(sizeof(XdbeBackBufferAttributes)))) {
452 DbeGetReq(DbeGetBackBufferAttributes, req, info);
453 req->buffer = buffer;
455 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
461 attr->window = rep.attributes;