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