1 /* $Xorg: Xdbe.c,v 1.4 2000/08/17 19:45:53 cpqbld Exp $ */
2 /******************************************************************************
4 * Copyright (c) 1994, 1995 Hewlett-Packard Company
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Except as contained in this notice, the name of the Hewlett-Packard
26 * Company shall not be used in advertising or otherwise to promote the
27 * sale, use or other dealings in this Software without prior written
28 * authorization from the Hewlett-Packard Company.
32 *****************************************************************************/
33 /* $XFree86: xc/lib/Xext/Xdbe.c,v 3.7 2002/10/16 02:19:22 dawes Exp $ */
41 #include <X11/Xlibint.h>
42 #include <X11/extensions/Xext.h>
43 #include <X11/extensions/extutil.h>
44 #define NEED_DBE_PROTOCOL
45 #include <X11/extensions/Xdbe.h>
47 static XExtensionInfo _dbe_info_data
;
48 static XExtensionInfo
*dbe_info
= &_dbe_info_data
;
49 static char *dbe_extension_name
= DBE_PROTOCOL_NAME
;
51 #define DbeCheckExtension(dpy,i,val) \
52 XextCheckExtension (dpy, i, dbe_extension_name, val)
53 #define DbeSimpleCheckExtension(dpy,i) \
54 XextSimpleCheckExtension (dpy, i, dbe_extension_name)
57 #define DbeGetReq(name,req,info) GetReq (name, req); \
58 req->reqType = info->codes->major_opcode; \
59 req->dbeReqType = X_##name;
61 #define DbeGetReq(name,req,info) GetReq (name, req); \
62 req->reqType = info->codes->major_opcode; \
63 req->dbeReqType = X_/**/name;
67 /*****************************************************************************
69 * private utility routines *
71 *****************************************************************************/
74 * find_display - locate the display info block
76 static int close_display(Display
*dpy
, XExtCodes
*codes
);
77 static char *error_string(Display
*dpy
, int code
, XExtCodes
*codes
,
79 static XExtensionHooks dbe_extension_hooks
= {
84 NULL
, /* create_font */
86 close_display
, /* close_display */
87 NULL
, /* wire_to_event */
88 NULL
, /* event_to_wire */
90 error_string
, /* error_string */
93 static char *dbe_error_list
[] = {
94 "BadBuffer", /* DbeBadBuffer */
97 static XEXT_GENERATE_FIND_DISPLAY (find_display
, dbe_info
,
100 DbeNumberEvents
, NULL
)
102 static XEXT_GENERATE_CLOSE_DISPLAY (close_display
, dbe_info
)
104 static XEXT_GENERATE_ERROR_STRING (error_string
, dbe_extension_name
,
109 /*****************************************************************************
111 * Double-Buffering public interfaces *
113 *****************************************************************************/
116 * XdbeQueryExtension -
117 * Sets major_version_return and minor_verion_return to the major and
118 * minor DBE protocol version supported by the server. If the DBE
119 * library is compatible with the version returned by the server, this
120 * function returns non-zero. If dpy does not support the DBE
121 * extension, or if there was an error during communication with the
122 * server, or if the server and library protocol versions are
123 * incompatible, this functions returns zero. No other Xdbe functions
124 * may be called before this function. If a client violates this rule,
125 * the effects of all subsequent Xdbe calls are undefined.
127 Status
XdbeQueryExtension (
129 int *major_version_return
,
130 int *minor_version_return
)
132 XExtDisplayInfo
*info
= find_display (dpy
);
133 xDbeGetVersionReply rep
;
134 register xDbeGetVersionReq
*req
;
136 if (!XextHasExtension (info
))
137 return (Status
)0; /* failure */
140 DbeGetReq (DbeGetVersion
, req
, info
);
141 req
->majorVersion
= DBE_MAJOR_VERSION
;
142 req
->minorVersion
= DBE_MINOR_VERSION
;
144 if (!_XReply (dpy
, (xReply
*) &rep
, 0, xTrue
)) {
147 return (Status
)0; /* failure */
149 *major_version_return
= rep
.majorVersion
;
150 *minor_version_return
= rep
.minorVersion
;
155 if (*major_version_return
!= DBE_MAJOR_VERSION
)
156 return (Status
)0; /* failure */
158 return (Status
)1; /* success */
163 * XdbeAllocateBackBuffer -
164 * This function returns a drawable ID used to refer to the back buffer
165 * of the specified window. The swap_action is a hint to indicate the
166 * swap action that will likely be used in subsequent calls to
167 * XdbeSwapBuffers. The actual swap action used in calls to
168 * XdbeSwapBuffers does not have to be the same as the swap_action
169 * passed to this function, though clients are encouraged to provide
170 * accurate information whenever possible.
173 XdbeBackBuffer
XdbeAllocateBackBufferName(
176 XdbeSwapAction swap_action
)
178 XExtDisplayInfo
*info
= find_display (dpy
);
179 register xDbeAllocateBackBufferNameReq
*req
;
180 XdbeBackBuffer buffer
;
182 /* make sure extension is available; if not, return the
183 * third parameter (0).
185 DbeCheckExtension (dpy
, info
, (XdbeBackBuffer
)0);
187 /* allocate the id */
188 buffer
= XAllocID (dpy
);
191 DbeGetReq(DbeAllocateBackBufferName
, req
, info
);
192 req
->window
= window
;
193 req
->swapAction
= (unsigned char)swap_action
;
194 req
->buffer
= buffer
;
200 } /* XdbeAllocateBackBufferName() */
203 * XdbeDeallocateBackBufferName -
204 * This function frees a drawable ID, buffer, that was obtained via
205 * XdbeAllocateBackBufferName. The buffer must refer to the back buffer
206 * of the specified window, or a protocol error results.
208 Status
XdbeDeallocateBackBufferName (
210 XdbeBackBuffer buffer
)
212 XExtDisplayInfo
*info
= find_display (dpy
);
213 register xDbeDeallocateBackBufferNameReq
*req
;
215 DbeCheckExtension (dpy
, info
, (Status
)0 /* failure */);
218 DbeGetReq (DbeDeallocateBackBufferName
, req
, info
);
219 req
->buffer
= buffer
;
223 return (Status
)1; /* success */
229 * This function swaps the front and back buffers for a list of windows.
230 * The argument num_windows specifies how many windows are to have their
231 * buffers swapped; it is the number of elements in the swap_info array.
232 * The argument swap_info specifies the information needed per window
235 Status
XdbeSwapBuffers (
237 XdbeSwapInfo
*swap_info
,
240 XExtDisplayInfo
*info
= find_display (dpy
);
241 register xDbeSwapBuffersReq
*req
;
244 DbeCheckExtension (dpy
, info
, (Status
)0 /* failure */);
247 DbeGetReq (DbeSwapBuffers
, req
, info
);
248 req
->length
+= 2*num_windows
;
249 req
->n
= num_windows
;
251 /* We need to handle 64-bit machines, where we can not use PackData32
252 * directly because info would be lost in translating from 32- to 64-bit.
253 * Instead we send data via a loop that accounts for the translation.
255 for (i
= 0; i
< num_windows
; i
++)
258 Data32 (dpy
, (long *)&swap_info
[i
].swap_window
, 4);
259 tmp
[0] = swap_info
[i
].swap_action
;
260 Data (dpy
, (char *)tmp
, 4);
267 return (Status
)1; /* success */
269 } /* XdbeSwapBuffers() */
274 * This function marks the beginning of an idiom sequence.
276 Status
XdbeBeginIdiom (Display
*dpy
)
278 XExtDisplayInfo
*info
= find_display(dpy
);
279 register xDbeBeginIdiomReq
*req
;
281 DbeCheckExtension (dpy
, info
, (Status
)0 /* failure */);
284 DbeGetReq (DbeBeginIdiom
, req
, info
);
288 return (Status
)1; /* success */
294 * This function marks the end of an idiom sequence.
296 Status
XdbeEndIdiom (Display
*dpy
)
298 XExtDisplayInfo
*info
= find_display(dpy
);
299 register xDbeEndIdiomReq
*req
;
301 DbeCheckExtension (dpy
, info
, (Status
)0 /* failure */);
304 DbeGetReq (DbeEndIdiom
, req
, info
);
308 return (Status
)1; /* success */
313 * XdbeGetVisualInfo -
314 * This function returns information about which visuals support
315 * double buffering. The argument num_screens specifies how many
316 * elements there are in the screen_specifiers list. Each drawable
317 * in screen_specifiers designates a screen for which the supported
318 * visuals are being requested. If num_screens is zero, information
319 * for all screens is requested. In this case, upon return from this
320 * function, num_screens will be set to the number of screens that were
321 * found. If an error occurs, this function returns NULL, else it returns
322 * a pointer to a list of XdbeScreenVisualInfo structures of length
323 * num_screens. The nth element in the returned list corresponds to the
324 * nth drawable in the screen_specifiers list, unless num_screens was
325 * passed in with the value zero, in which case the nth element in the
326 * returned list corresponds to the nth screen of the server, starting
329 XdbeScreenVisualInfo
*XdbeGetVisualInfo (
331 Drawable
*screen_specifiers
,
332 int *num_screens
) /* SEND and RETURN */
334 XExtDisplayInfo
*info
= find_display(dpy
);
335 register xDbeGetVisualInfoReq
*req
;
336 xDbeGetVisualInfoReply rep
;
337 XdbeScreenVisualInfo
*scrVisInfo
;
340 DbeCheckExtension (dpy
, info
, (XdbeScreenVisualInfo
*)NULL
);
344 DbeGetReq(DbeGetVisualInfo
, req
, info
);
345 req
->length
= 2 + *num_screens
;
346 req
->n
= *num_screens
;
347 Data32 (dpy
, screen_specifiers
, (*num_screens
* sizeof (CARD32
)));
349 if (!_XReply (dpy
, (xReply
*) &rep
, 0, xFalse
)) {
355 /* return the number of screens actually found if we
356 * requested information about all screens (*num_screens == 0)
358 if (*num_screens
== 0)
359 *num_screens
= rep
.m
;
361 /* allocate list of visual information to be returned */
363 (XdbeScreenVisualInfo
*)Xmalloc(
364 (unsigned)(*num_screens
* sizeof(XdbeScreenVisualInfo
))))) {
370 for (i
= 0; i
< *num_screens
; i
++)
376 _XRead32 (dpy
, &c
, sizeof(CARD32
));
377 scrVisInfo
[i
].count
= c
;
379 nbytes
= scrVisInfo
[i
].count
* sizeof(XdbeVisualInfo
);
381 /* if we can not allocate the list of visual/depth info
382 * then free the lists that we already allocate as well
383 * as the visual info list itself
385 if (!(scrVisInfo
[i
].visinfo
= (XdbeVisualInfo
*)Xmalloc(
386 (unsigned)nbytes
))) {
387 for (j
= 0; j
< i
; j
++) {
388 Xfree ((char *)scrVisInfo
[j
].visinfo
);
390 Xfree ((char *)scrVisInfo
);
396 /* Read the visual info item into the wire structure. Then copy each
397 * element into the library structure. The element sizes and/or
398 * padding may be different in the two structures.
400 for (j
= 0; j
< scrVisInfo
[i
].count
; j
++) {
403 _XRead (dpy
, (char *)&xvi
, sizeof(xDbeVisInfo
));
404 scrVisInfo
[i
].visinfo
[j
].visual
= xvi
.visualID
;
405 scrVisInfo
[i
].visinfo
[j
].depth
= xvi
.depth
;
406 scrVisInfo
[i
].visinfo
[j
].perflevel
= xvi
.perfLevel
;
415 } /* XdbeGetVisualInfo() */
419 * XdbeFreeVisualInfo -
420 * This function frees the list of XdbeScreenVisualInfo returned by the
421 * function XdbeGetVisualInfo.
423 void XdbeFreeVisualInfo(XdbeScreenVisualInfo
*visual_info
)
425 if (visual_info
== NULL
) {
429 if (visual_info
->visinfo
) {
430 XFree(visual_info
->visinfo
);
438 * XdbeGetBackBufferAttributes -
439 * This function returns the attributes associated with the specified
442 XdbeBackBufferAttributes
*XdbeGetBackBufferAttributes(
444 XdbeBackBuffer buffer
)
446 XExtDisplayInfo
*info
= find_display(dpy
);
447 register xDbeGetBackBufferAttributesReq
*req
;
448 xDbeGetBackBufferAttributesReply rep
;
449 XdbeBackBufferAttributes
*attr
;
451 DbeCheckExtension(dpy
, info
, (XdbeBackBufferAttributes
*)NULL
);
454 (XdbeBackBufferAttributes
*)Xmalloc(sizeof(XdbeBackBufferAttributes
)))) {
459 DbeGetReq(DbeGetBackBufferAttributes
, req
, info
);
460 req
->buffer
= buffer
;
462 if (!_XReply (dpy
, (xReply
*) &rep
, 0, xTrue
)) {
468 attr
->window
= rep
.attributes
;