upload tizen2.0 source
[framework/uifw/xorg/lib/libxext.git] / src / Xdbe.c
1 /******************************************************************************
2  *
3  * Copyright (c) 1994, 1995  Hewlett-Packard Company
4  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
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.
23  *
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.
28  *
29  *     Xlib DBE code
30  *
31  *****************************************************************************/
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 #include <stdio.h>
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>
42
43 static XExtensionInfo _dbe_info_data;
44 static XExtensionInfo *dbe_info = &_dbe_info_data;
45 static const char *dbe_extension_name = DBE_PROTOCOL_NAME;
46
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)
51
52 #if !defined(UNIXCPP)
53 #define DbeGetReq(name,req,info) GetReq (name, req); \
54         req->reqType = info->codes->major_opcode; \
55         req->dbeReqType = X_##name;
56 #else
57 #define DbeGetReq(name,req,info) GetReq (name, req); \
58         req->reqType = info->codes->major_opcode; \
59         req->dbeReqType = X_/**/name;
60 #endif
61
62
63 /*****************************************************************************
64  *                                                                           *
65  *                         private utility routines                          *
66  *                                                                           *
67  *****************************************************************************/
68
69 /*
70  * find_display - locate the display info block
71  */
72 static int close_display(Display *dpy, XExtCodes *codes);
73 static char *error_string(Display *dpy, int code, XExtCodes *codes,
74                           char *buf, int n);
75 static XExtensionHooks dbe_extension_hooks = {
76     NULL,                               /* create_gc */
77     NULL,                               /* copy_gc */
78     NULL,                               /* flush_gc */
79     NULL,                               /* free_gc */
80     NULL,                               /* create_font */
81     NULL,                               /* free_font */
82     close_display,                      /* close_display */
83     NULL,                               /* wire_to_event */
84     NULL,                               /* event_to_wire */
85     NULL,                               /* error */
86     error_string,                       /* error_string */
87 };
88
89 static const char *dbe_error_list[] = {
90     "BadBuffer",                        /* DbeBadBuffer */
91 };
92
93 static XEXT_GENERATE_FIND_DISPLAY (find_display, dbe_info,
94                                    dbe_extension_name,
95                                    &dbe_extension_hooks,
96                                    DbeNumberEvents, NULL)
97
98 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, dbe_info)
99
100 static XEXT_GENERATE_ERROR_STRING (error_string, dbe_extension_name,
101                                    DbeNumberErrors,
102                                    dbe_error_list)
103
104
105 /*****************************************************************************
106  *                                                                           *
107  *                     Double-Buffering public interfaces                    *
108  *                                                                           *
109  *****************************************************************************/
110
111 /*
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.
122  */
123 Status XdbeQueryExtension (
124     Display *dpy,
125     int *major_version_return,
126     int *minor_version_return)
127 {
128     XExtDisplayInfo *info = find_display (dpy);
129     xDbeGetVersionReply rep;
130     register xDbeGetVersionReq *req;
131
132     if (!XextHasExtension (info))
133         return (Status)0; /* failure */
134
135     LockDisplay (dpy);
136     DbeGetReq (DbeGetVersion, req, info);
137     req->majorVersion = DBE_MAJOR_VERSION;
138     req->minorVersion = DBE_MINOR_VERSION;
139
140     if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
141         UnlockDisplay (dpy);
142         SyncHandle ();
143         return (Status)0; /* failure */
144     }
145     *major_version_return = rep.majorVersion;
146     *minor_version_return = rep.minorVersion;
147     UnlockDisplay (dpy);
148
149     SyncHandle ();
150
151     if (*major_version_return != DBE_MAJOR_VERSION)
152         return (Status)0; /* failure */
153     else
154         return (Status)1; /* success */
155 }
156
157
158 /*
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.
167  */
168
169 XdbeBackBuffer XdbeAllocateBackBufferName(
170     Display *dpy,
171     Window window,
172     XdbeSwapAction swap_action)
173 {
174     XExtDisplayInfo *info = find_display (dpy);
175     register xDbeAllocateBackBufferNameReq *req;
176     XdbeBackBuffer buffer;
177
178     /* make sure extension is available; if not, return the
179      * third parameter (0).
180      */
181     DbeCheckExtension (dpy, info, (XdbeBackBuffer)0);
182
183     LockDisplay(dpy);
184     DbeGetReq(DbeAllocateBackBufferName, req, info);
185     req->window = window;
186     req->swapAction = (unsigned char)swap_action;
187     req->buffer = buffer = XAllocID (dpy);
188
189     UnlockDisplay (dpy);
190     SyncHandle ();
191     return buffer;
192
193 } /* XdbeAllocateBackBufferName() */
194
195 /*
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.
200  */
201 Status XdbeDeallocateBackBufferName (
202     Display *dpy,
203     XdbeBackBuffer buffer)
204 {
205     XExtDisplayInfo *info = find_display (dpy);
206     register xDbeDeallocateBackBufferNameReq *req;
207
208     DbeCheckExtension (dpy, info, (Status)0 /* failure */);
209
210     LockDisplay (dpy);
211     DbeGetReq (DbeDeallocateBackBufferName, req, info);
212     req->buffer = buffer;
213     UnlockDisplay (dpy);
214     SyncHandle ();
215
216     return (Status)1; /* success */
217 }
218
219
220 /*
221  * XdbeSwapBuffers -
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
226  *      to do the swap.
227  */
228 Status XdbeSwapBuffers (
229     Display *dpy,
230     XdbeSwapInfo *swap_info,
231     int num_windows)
232 {
233     XExtDisplayInfo *info = find_display (dpy);
234     register xDbeSwapBuffersReq *req;
235     int i;
236
237     DbeCheckExtension (dpy, info, (Status)0 /* failure */);
238
239     LockDisplay (dpy);
240     DbeGetReq (DbeSwapBuffers, req, info);
241     req->length += 2*num_windows;
242     req->n = num_windows;
243
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.
247      */
248     for (i = 0; i < num_windows; i++)
249     {
250         char tmp[4];
251         Data32 (dpy, (long *)&swap_info[i].swap_window, 4);
252         tmp[0] = swap_info[i].swap_action;
253         Data (dpy, (char *)tmp, 4);
254     }
255
256     UnlockDisplay (dpy);
257     SyncHandle ();
258
259
260     return (Status)1; /* success */
261
262 } /* XdbeSwapBuffers() */
263
264
265 /*
266  * XdbeBeginIdiom -
267  *      This function marks the beginning of an idiom sequence.
268  */
269 Status XdbeBeginIdiom (Display *dpy)
270 {
271     XExtDisplayInfo *info = find_display(dpy);
272     register xDbeBeginIdiomReq *req;
273
274     DbeCheckExtension (dpy, info, (Status)0 /* failure */);
275
276     LockDisplay (dpy);
277     DbeGetReq (DbeBeginIdiom, req, info);
278     UnlockDisplay (dpy);
279     SyncHandle ();
280
281     return (Status)1; /* success */
282 }
283
284
285 /*
286  * XdbeEndIdiom -
287  *      This function marks the end of an idiom sequence.
288  */
289 Status XdbeEndIdiom (Display *dpy)
290 {
291     XExtDisplayInfo *info = find_display(dpy);
292     register xDbeEndIdiomReq *req;
293
294     DbeCheckExtension (dpy, info, (Status)0 /* failure */);
295
296     LockDisplay (dpy);
297     DbeGetReq (DbeEndIdiom, req, info);
298     UnlockDisplay (dpy);
299     SyncHandle ();
300
301     return (Status)1; /* success */
302 }
303
304
305 /*
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
320  *      with screen zero.
321  */
322 XdbeScreenVisualInfo *XdbeGetVisualInfo (
323     Display        *dpy,
324     Drawable       *screen_specifiers,
325     int            *num_screens)  /* SEND and RETURN */
326 {
327     XExtDisplayInfo *info = find_display(dpy);
328     register xDbeGetVisualInfoReq *req;
329     xDbeGetVisualInfoReply rep;
330     XdbeScreenVisualInfo *scrVisInfo;
331     int i;
332
333     DbeCheckExtension (dpy, info, (XdbeScreenVisualInfo *)NULL);
334
335     LockDisplay (dpy);
336
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)));
341
342     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
343         UnlockDisplay (dpy);
344         SyncHandle ();
345         return NULL;
346     }
347
348     /* return the number of screens actually found if we
349      * requested information about all screens (*num_screens == 0)
350      */
351     if (*num_screens == 0)
352        *num_screens = rep.m;
353
354     /* allocate list of visual information to be returned */
355     if (!(scrVisInfo =
356         (XdbeScreenVisualInfo *)Xmalloc(
357         (unsigned)(*num_screens * sizeof(XdbeScreenVisualInfo))))) {
358         UnlockDisplay (dpy);
359         SyncHandle ();
360         return NULL;
361     }
362
363     for (i = 0; i < *num_screens; i++)
364     {
365         int nbytes;
366         int j;
367         long c;
368
369         _XRead32 (dpy, &c, sizeof(CARD32));
370         scrVisInfo[i].count = c;
371
372         nbytes = scrVisInfo[i].count * sizeof(XdbeVisualInfo);
373
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
377          */
378         if (!(scrVisInfo[i].visinfo = (XdbeVisualInfo *)Xmalloc(
379             (unsigned)nbytes))) {
380             for (j = 0; j < i; j++) {
381                 Xfree ((char *)scrVisInfo[j].visinfo);
382             }
383             Xfree ((char *)scrVisInfo);
384             UnlockDisplay (dpy);
385             SyncHandle ();
386             return NULL;
387         }
388
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.
392          */
393         for (j = 0; j < scrVisInfo[i].count; j++) {
394             xDbeVisInfo xvi;
395
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;
400         }
401
402     }
403
404     UnlockDisplay (dpy);
405     SyncHandle ();
406     return scrVisInfo;
407
408 } /* XdbeGetVisualInfo() */
409
410
411 /*
412  * XdbeFreeVisualInfo -
413  *      This function frees the list of XdbeScreenVisualInfo returned by the
414  *      function XdbeGetVisualInfo.
415  */
416 void XdbeFreeVisualInfo(XdbeScreenVisualInfo *visual_info)
417 {
418     if (visual_info == NULL) {
419         return;
420     }
421
422     if (visual_info->visinfo) {
423         XFree(visual_info->visinfo);
424     }
425
426     XFree(visual_info);
427 }
428
429
430 /*
431  * XdbeGetBackBufferAttributes -
432  *      This function returns the attributes associated with the specified
433  *      buffer.
434  */
435 XdbeBackBufferAttributes *XdbeGetBackBufferAttributes(
436     Display *dpy,
437     XdbeBackBuffer buffer)
438 {
439     XExtDisplayInfo *info = find_display(dpy);
440     register xDbeGetBackBufferAttributesReq *req;
441     xDbeGetBackBufferAttributesReply rep;
442     XdbeBackBufferAttributes *attr;
443
444     DbeCheckExtension(dpy, info, (XdbeBackBufferAttributes *)NULL);
445
446     if (!(attr =
447        (XdbeBackBufferAttributes *)Xmalloc(sizeof(XdbeBackBufferAttributes)))) {
448         return NULL;
449     }
450
451     LockDisplay(dpy);
452     DbeGetReq(DbeGetBackBufferAttributes, req, info);
453     req->buffer = buffer;
454
455     if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
456         UnlockDisplay (dpy);
457         SyncHandle ();
458         Xfree(attr);
459         return NULL;
460     }
461     attr->window = rep.attributes;
462
463     UnlockDisplay (dpy);
464     SyncHandle ();
465
466     return attr;
467 }
468