1 /*
2 *
3 Copyright 1989, 1998 The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24 *
25 * Authors: Jim Fulton, MIT X Consortium
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <X11/Xlibint.h>
32 #include <stdio.h>
33 #include <X11/extensions/Xext.h>
34 #include <X11/extensions/extutil.h>
35 #include <X11/extensions/multibufproto.h>
36 #include <X11/extensions/multibuf.h>
37
38 static XExtensionInfo _multibuf_info_data;
39 static XExtensionInfo *multibuf_info = &_multibuf_info_data;
40 static const char *multibuf_extension_name = MULTIBUFFER_PROTOCOL_NAME;
41
42 #define MbufCheckExtension(dpy,i,val) \
43 XextCheckExtension (dpy, i, multibuf_extension_name, val)
44 #define MbufSimpleCheckExtension(dpy,i) \
45 XextSimpleCheckExtension (dpy, i, multibuf_extension_name)
46
47
48 /*****************************************************************************
49 * *
50 * private utility routines *
51 * *
52 *****************************************************************************/
53
54 /*
55 * find_display - locate the display info block
56 */
57 static int close_display(Display *dpy, XExtCodes *codes);
58 static char *error_string(Display *dpy, int code, XExtCodes *codes, char *buf, int n);
59 static Bool wire_to_event(Display *dpy, XEvent *libevent, xEvent *netevent);
60 static Status event_to_wire(Display *dpy, XEvent *libevent, xEvent *netevent);
61 static /* const */ XExtensionHooks multibuf_extension_hooks = {
62 NULL, /* create_gc */
63 NULL, /* copy_gc */
64 NULL, /* flush_gc */
65 NULL, /* free_gc */
66 NULL, /* create_font */
67 NULL, /* free_font */
68 close_display, /* close_display */
69 wire_to_event, /* wire_to_event */
70 event_to_wire, /* event_to_wire */
71 NULL, /* error */
72 error_string, /* error_string */
73 };
74
75 static const char *multibuf_error_list[] = {
76 "BadBuffer", /* MultibufferBadBuffer */
77 };
78
79 static XEXT_GENERATE_FIND_DISPLAY (find_display, multibuf_info,
80 multibuf_extension_name,
81 &multibuf_extension_hooks,
82 MultibufferNumberEvents, NULL)
83
XEXT_GENERATE_CLOSE_DISPLAY(close_display,multibuf_info)84 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, multibuf_info)
85
86 static XEXT_GENERATE_ERROR_STRING (error_string, multibuf_extension_name,
87 MultibufferNumberErrors,
88 multibuf_error_list)
89
90 /*
91 * wire_to_event - convert a wire event in network format to a C
92 * event structure
93 */
94 static Bool wire_to_event (Display *dpy, XEvent *libevent, xEvent *netevent)
95 {
96 XExtDisplayInfo *info = find_display (dpy);
97
98 MbufCheckExtension (dpy, info, False);
99
100 switch ((netevent->u.u.type & 0x7f) - info->codes->first_event) {
101 case MultibufferClobberNotify:
102 {
103 XmbufClobberNotifyEvent *ev;
104 xMbufClobberNotifyEvent *event;
105
106 ev = (XmbufClobberNotifyEvent *) libevent;
107 event = (xMbufClobberNotifyEvent *) netevent;
108 ev->type = event->type & 0x7f;
109 ev->serial = _XSetLastRequestRead(dpy,(xGenericReply *) netevent);
110 ev->send_event = ((event->type & 0x80) != 0);
111 ev->display = dpy;
112 ev->buffer = event->buffer;
113 ev->state = event->state;
114 return True;
115 }
116 case MultibufferUpdateNotify:
117 {
118 XmbufUpdateNotifyEvent *ev;
119 xMbufUpdateNotifyEvent *event;
120
121 ev = (XmbufUpdateNotifyEvent *) libevent;
122 event = (xMbufUpdateNotifyEvent *) netevent;
123 ev->type = event->type & 0x7f;
124 ev->serial = _XSetLastRequestRead(dpy,(xGenericReply *) netevent);
125 ev->send_event = ((event->type & 0x80) != 0);
126 ev->display = dpy;
127 ev->buffer = event->buffer;
128 return True;
129 }
130 }
131 return False;
132 }
133
134
135 /*
136 * event_to_wire - convert a C event structure to a wire event in
137 * network format
138 */
event_to_wire(Display * dpy,XEvent * libevent,xEvent * netevent)139 static Status event_to_wire (Display *dpy, XEvent *libevent, xEvent *netevent)
140 {
141 XExtDisplayInfo *info = find_display (dpy);
142
143 MbufCheckExtension (dpy, info, 0);
144
145 switch ((libevent->type & 0x7f) - info->codes->first_event) {
146 case MultibufferClobberNotify:
147 {
148 XmbufClobberNotifyEvent *ev;
149 xMbufClobberNotifyEvent *event;
150
151 ev = (XmbufClobberNotifyEvent *) libevent;
152 event = (xMbufClobberNotifyEvent *) netevent;
153 event->type = ev->type;
154 event->sequenceNumber = (ev->serial & 0xffff);
155 event->buffer = ev->buffer;
156 event->state = ev->state;
157 return 1;
158 }
159 case MultibufferUpdateNotify:
160 {
161 XmbufUpdateNotifyEvent *ev;
162 xMbufUpdateNotifyEvent *event;
163
164 ev = (XmbufUpdateNotifyEvent *) libevent;
165 event = (xMbufUpdateNotifyEvent *) netevent;
166 event->type = ev->type;
167 event->sequenceNumber = (ev->serial & 0xffff);
168 event->buffer = ev->buffer;
169 return 1;
170 }
171 }
172 return 0;
173 }
174
175
176 /*
177 * read_buffer_info - read Buffer Info descriptors from the net; if unable
178 * to allocate memory, read junk to make sure that stream is clear.
179 */
180 #define TALLOC(type,count) ((type *) Xmalloc ((unsigned) count * sizeof(type)))
181
read_buffer_info(Display * dpy,int nbufs)182 static XmbufBufferInfo *read_buffer_info (Display *dpy, int nbufs)
183 {
184 xMbufBufferInfo *netbuf = TALLOC (xMbufBufferInfo, nbufs);
185 XmbufBufferInfo *bufinfo = NULL;
186 long netbytes = nbufs * SIZEOF(xMbufBufferInfo);
187
188 if (netbuf) {
189 _XRead (dpy, (char *) netbuf, netbytes);
190
191 bufinfo = TALLOC (XmbufBufferInfo, nbufs);
192 if (bufinfo) {
193 register XmbufBufferInfo *c;
194 register xMbufBufferInfo *net;
195 register int i;
196
197 for (i = 0, c = bufinfo, net = netbuf; i < nbufs;
198 i++, c++, net++) {
199 c->visualid = net->visualID;
200 c->max_buffers = net->maxBuffers;
201 c->depth = net->depth;
202 }
203 }
204 Xfree ((char *) netbuf);
205 } else { /* eat the data */
206 while (netbytes > 0) {
207 char dummy[256]; /* stack size vs loops tradeoff */
208 long nbytes = sizeof dummy;
209
210 if (nbytes > netbytes) nbytes = netbytes;
211 _XRead (dpy, dummy, nbytes);
212 netbytes -= nbytes;
213 }
214 }
215
216 return bufinfo;
217 }
218
219 #undef TALLOC
220
221
222 /*****************************************************************************
223 * *
224 * Multibuffering/stereo public interfaces *
225 * *
226 *****************************************************************************/
227
228
229 /*
230 * XmbufQueryExtension -
231 * Returns True if the multibuffering/stereo extension is available
232 * on the given display. If the extension exists, the value of the
233 * first event code (which should be added to the event type constants
234 * MultibufferClobberNotify and MultibufferUpdateNotify to get the
235 * actual values) is stored into event_base and the value of the first
236 * error code (which should be added to the error type constant
237 * MultibufferBadBuffer to get the actual value) is stored into
238 * error_base.
239 */
XmbufQueryExtension(Display * dpy,int * event_base_return,int * error_base_return)240 Bool XmbufQueryExtension (
241 Display *dpy,
242 int *event_base_return, int *error_base_return)
243 {
244 XExtDisplayInfo *info = find_display (dpy);
245
246 if (XextHasExtension (info)) {
247 *event_base_return = info->codes->first_event;
248 *error_base_return = info->codes->first_error;
249 return True;
250 } else {
251 return False;
252 }
253 }
254
255
256 /*
257 * XmbufGetVersion -
258 * Gets the major and minor version numbers of the extension. The return
259 * value is zero if an error occurs or non-zero if no error happens.
260 */
XmbufGetVersion(Display * dpy,int * major_version_return,int * minor_version_return)261 Status XmbufGetVersion (
262 Display *dpy,
263 int *major_version_return, int *minor_version_return)
264 {
265 XExtDisplayInfo *info = find_display (dpy);
266 xMbufGetBufferVersionReply rep;
267 register xMbufGetBufferVersionReq *req;
268
269 MbufCheckExtension (dpy, info, 0);
270
271 LockDisplay (dpy);
272 MbufGetReq (MbufGetBufferVersion, req, info);
273 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
274 UnlockDisplay (dpy);
275 SyncHandle ();
276 return 0;
277 }
278 *major_version_return = rep.majorVersion;
279 *minor_version_return = rep.minorVersion;
280 UnlockDisplay (dpy);
281
282 SyncHandle ();
283 return 1;
284 }
285
286
287 /*
288 * XmbufCreateBuffers -
289 * Requests that "count" buffers be created with the given update_action
290 * and update_hint and be associated with the indicated window. The
291 * number of buffers created is returned (zero if an error occurred)
292 * and buffers_return is filled in with that many Multibuffer identifiers.
293 */
XmbufCreateBuffers(Display * dpy,Window w,int count,int update_action,int update_hint,Multibuffer * buffers)294 int XmbufCreateBuffers (
295 Display *dpy,
296 Window w,
297 int count,
298 int update_action, int update_hint,
299 Multibuffer *buffers)
300 {
301 XExtDisplayInfo *info = find_display (dpy);
302 xMbufCreateImageBuffersReply rep;
303 register xMbufCreateImageBuffersReq *req;
304 int result;
305
306 MbufCheckExtension (dpy, info, 0);
307
308 LockDisplay (dpy);
309
310 XAllocIDs(dpy, buffers, count);
311 MbufGetReq (MbufCreateImageBuffers, req, info);
312 req->window = w;
313 req->updateAction = update_action;
314 req->updateHint = update_hint;
315 req->length += count;
316 count <<= 2;
317 PackData32 (dpy, buffers, count);
318 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
319 UnlockDisplay (dpy);
320 SyncHandle ();
321 return 0;
322 }
323 result = rep.numberBuffer;
324 UnlockDisplay (dpy);
325
326 SyncHandle ();
327 return result;
328 }
329
330
331 /*
332 * XmbufDestroyBuffers -
333 * Destroys the buffers associated with the given window.
334 */
XmbufDestroyBuffers(Display * dpy,Window window)335 void XmbufDestroyBuffers (Display *dpy, Window window)
336 {
337 XExtDisplayInfo *info = find_display (dpy);
338 register xMbufDestroyImageBuffersReq *req;
339
340 MbufSimpleCheckExtension (dpy, info);
341
342 LockDisplay (dpy);
343 MbufGetReq (MbufDestroyImageBuffers, req, info);
344 req->window = window;
345 UnlockDisplay (dpy);
346 SyncHandle ();
347 }
348
349
350 /*
351 * XmbufDisplayBuffers -
352 * Displays the indicated buffers their appropriate windows within
353 * max_delay milliseconds after min_delay milliseconds have passed.
354 * No two buffers may be associated with the same window or else a Match
355 * error is generated.
356 */
XmbufDisplayBuffers(Display * dpy,int count,Multibuffer * buffers,int min_delay,int max_delay)357 void XmbufDisplayBuffers (
358 Display *dpy,
359 int count,
360 Multibuffer *buffers,
361 int min_delay, int max_delay)
362 {
363 XExtDisplayInfo *info = find_display (dpy);
364 register xMbufDisplayImageBuffersReq *req;
365
366 MbufSimpleCheckExtension (dpy, info);
367
368 LockDisplay (dpy);
369 MbufGetReq (MbufDisplayImageBuffers, req, info);
370 req->minDelay = min_delay;
371 req->maxDelay = max_delay;
372 req->length += count;
373 count <<= 2;
374 PackData32 (dpy, buffers, count);
375 UnlockDisplay (dpy);
376 SyncHandle();
377 }
378
379
380 /*
381 * XmbufGetWindowAttributes -
382 * Gets the multibuffering attributes that apply to all buffers associated
383 * with the given window. Returns non-zero on success and zero if an
384 * error occurs.
385 */
XmbufGetWindowAttributes(Display * dpy,Window w,XmbufWindowAttributes * attr)386 Status XmbufGetWindowAttributes (
387 Display *dpy,
388 Window w,
389 XmbufWindowAttributes *attr)
390 {
391 XExtDisplayInfo *info = find_display (dpy);
392 register xMbufGetMBufferAttributesReq *req;
393 xMbufGetMBufferAttributesReply rep;
394
395 MbufCheckExtension (dpy, info, 0);
396
397 LockDisplay (dpy);
398 MbufGetReq (MbufGetMBufferAttributes, req, info);
399 req->window = w;
400 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
401 UnlockDisplay (dpy);
402 SyncHandle ();
403 return 0;
404 }
405 attr->buffers = (Multibuffer *) NULL;
406 if ((attr->nbuffers = rep.length)) {
407 int nbytes = rep.length * sizeof(Multibuffer);
408 attr->buffers = (Multibuffer *) Xmalloc((unsigned) nbytes);
409 nbytes = rep.length << 2;
410 if (! attr->buffers) {
411 _XEatDataWords(dpy, rep.length);
412 UnlockDisplay(dpy);
413 SyncHandle();
414 return (0);
415 }
416 _XRead32 (dpy, (long *) attr->buffers, nbytes);
417 }
418 attr->displayed_index = rep.displayedBuffer;
419 attr->update_action = rep.updateAction;
420 attr->update_hint = rep.updateHint;
421 attr->window_mode = rep.windowMode;
422
423 UnlockDisplay (dpy);
424 SyncHandle();
425 return 1;
426 }
427
428
429 /*
430 * XmbufChangeWindowAttributes -
431 * Sets the multibuffering attributes that apply to all buffers associated
432 * with the given window. This is currently limited to the update_hint.
433 */
XmbufChangeWindowAttributes(Display * dpy,Window w,unsigned long valuemask,XmbufSetWindowAttributes * attr)434 void XmbufChangeWindowAttributes (
435 Display *dpy,
436 Window w,
437 unsigned long valuemask,
438 XmbufSetWindowAttributes *attr)
439 {
440 XExtDisplayInfo *info = find_display (dpy);
441 register xMbufSetMBufferAttributesReq *req;
442
443 MbufSimpleCheckExtension (dpy, info);
444
445 LockDisplay (dpy);
446 MbufGetReq (MbufSetMBufferAttributes, req, info);
447 req->window = w;
448 if ((req->valueMask = valuemask)) { /* stolen from lib/X/XWindow.c */
449 unsigned long values[1]; /* one per element in if stmts below */
450 unsigned long *v = values;
451 unsigned int nvalues;
452
453 if (valuemask & MultibufferWindowUpdateHint)
454 *v++ = attr->update_hint;
455 req->length += (nvalues = v - values);
456 nvalues <<= 2; /* watch out for macros... */
457 Data32 (dpy, (long *) values, (long)nvalues);
458 }
459 UnlockDisplay (dpy);
460 SyncHandle();
461 }
462
463
464 /*
465 * XmbufGetBufferAttributes -
466 * Gets the attributes for the indicated buffer. Returns non-zero on
467 * success and zero if an error occurs.
468 */
XmbufGetBufferAttributes(Display * dpy,Multibuffer b,XmbufBufferAttributes * attr)469 Status XmbufGetBufferAttributes (
470 Display *dpy,
471 Multibuffer b,
472 XmbufBufferAttributes *attr)
473 {
474 XExtDisplayInfo *info = find_display (dpy);
475 register xMbufGetBufferAttributesReq *req;
476 xMbufGetBufferAttributesReply rep;
477
478 MbufCheckExtension (dpy, info, 0);
479
480 LockDisplay (dpy);
481 MbufGetReq (MbufGetBufferAttributes, req, info);
482 req->buffer = b;
483 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
484 UnlockDisplay (dpy);
485 SyncHandle ();
486 return 0;
487 }
488 attr->window = rep.window;
489 attr->event_mask = rep.eventMask;
490 attr->buffer_index = rep.bufferIndex;
491 attr->side = rep.side;
492
493 UnlockDisplay (dpy);
494 SyncHandle();
495 return 1;
496 }
497
498
499 /*
500 * XmbufChangeBufferAttributes -
501 * Sets the attributes for the indicated buffer. This is currently
502 * limited to the event_mask.
503 */
XmbufChangeBufferAttributes(Display * dpy,Multibuffer b,unsigned long valuemask,XmbufSetBufferAttributes * attr)504 void XmbufChangeBufferAttributes (
505 Display *dpy,
506 Multibuffer b,
507 unsigned long valuemask,
508 XmbufSetBufferAttributes *attr)
509 {
510 XExtDisplayInfo *info = find_display (dpy);
511 register xMbufSetBufferAttributesReq *req;
512
513 MbufSimpleCheckExtension (dpy, info);
514
515 LockDisplay (dpy);
516 MbufGetReq (MbufSetBufferAttributes, req, info);
517 req->buffer = b;
518 if ((req->valueMask = valuemask)) { /* stolen from lib/X/XWindow.c */
519 unsigned long values[1]; /* one per element in if stmts below */
520 unsigned long *v = values;
521 unsigned int nvalues;
522
523 if (valuemask & MultibufferBufferEventMask)
524 *v++ = attr->event_mask;
525 req->length += (nvalues = v - values);
526 nvalues <<= 2; /* watch out for macros... */
527 Data32 (dpy, (long *) values, (long)nvalues);
528 }
529 UnlockDisplay (dpy);
530 SyncHandle();
531 }
532
533
534
535 /*
536 * XmbufGetScreenInfo -
537 * Gets the parameters controlling how mono and stereo windows may be
538 * created on the indicated screen. The numbers of sets of visual and
539 * depths are returned in nmono_return and nstereo_return. If
540 * nmono_return is greater than zero, then mono_info_return is set to
541 * the address of an array of XmbufBufferInfo structures describing the
542 * various visuals and depths that may be used. Otherwise,
543 * mono_info_return is set to NULL. Similarly, stereo_info_return is
544 * set according to nstereo_return. The storage returned in
545 * mono_info_return and stereo_info_return may be released by XFree.
546 * If no errors are encounted, non-zero will be returned.
547 */
XmbufGetScreenInfo(Display * dpy,Drawable d,int * nmono_return,XmbufBufferInfo ** mono_info_return,int * nstereo_return,XmbufBufferInfo ** stereo_info_return)548 Status XmbufGetScreenInfo (
549 Display *dpy,
550 Drawable d,
551 int *nmono_return,
552 XmbufBufferInfo **mono_info_return,
553 int *nstereo_return,
554 XmbufBufferInfo **stereo_info_return)
555 {
556 XExtDisplayInfo *info = find_display (dpy);
557 register xMbufGetBufferInfoReq *req;
558 xMbufGetBufferInfoReply rep;
559 int nmono, nstereo;
560 XmbufBufferInfo *minfo, *sinfo;
561
562 MbufCheckExtension (dpy, info, 0);
563
564 LockDisplay (dpy);
565 MbufGetReq (MbufGetBufferInfo, req, info);
566 req->drawable = d;
567 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
568 UnlockDisplay (dpy);
569 SyncHandle ();
570 return 0;
571 }
572 nmono = rep.normalInfo;
573 nstereo = rep.stereoInfo;
574 minfo = ((nmono > 0) ? read_buffer_info (dpy, nmono) : NULL);
575 sinfo = ((nstereo > 0) ? read_buffer_info (dpy, nstereo) : NULL);
576
577 /* check for bad reads indicating we need to return an error */
578 if ((nmono > 0 && !minfo) || (nstereo > 0 && !sinfo)) {
579 if (minfo) Xfree ((char *) minfo);
580 if (sinfo) Xfree ((char *) sinfo);
581 UnlockDisplay (dpy);
582 SyncHandle();
583 return 0;
584 }
585
586 *nmono_return = nmono;
587 *mono_info_return = minfo;
588 *nstereo_return = nstereo;
589 *stereo_info_return = sinfo;
590
591 UnlockDisplay (dpy);
592 SyncHandle();
593 return 1;
594 }
595
596
597 /*
598 * XmbufCreateStereoWindow -
599 * Creates a stereo window in the same way that XCreateWindow creates
600 * a mono window (in fact, use the same code, except for the request)
601 * and returns the left and right buffers that may be
602 */
XmbufCreateStereoWindow(Display * dpy,Window parent,int x,int y,unsigned int width,unsigned int height,unsigned int border_width,int depth,unsigned int class,Visual * visual,unsigned long valuemask,XSetWindowAttributes * attr,Multibuffer * leftp,Multibuffer * rightp)603 Window XmbufCreateStereoWindow (
604 Display *dpy,
605 Window parent,
606 int x, int y,
607 unsigned int width, unsigned int height, unsigned int border_width,
608 int depth,
609 unsigned int class,
610 Visual *visual,
611 unsigned long valuemask,
612 XSetWindowAttributes *attr,
613 Multibuffer *leftp, Multibuffer *rightp)
614 {
615 XExtDisplayInfo *info = find_display (dpy);
616 Window wid;
617 register xMbufCreateStereoWindowReq *req;
618
619 MbufCheckExtension (dpy, info, None);
620
621 LockDisplay(dpy);
622 MbufGetReq(MbufCreateStereoWindow, req, info);
623 wid = req->wid = XAllocID(dpy);
624 req->parent = parent;
625 req->left = *leftp = XAllocID (dpy);
626 req->right = *rightp = XAllocID (dpy);
627 req->x = x;
628 req->y = y;
629 req->width = width;
630 req->height = height;
631 req->borderWidth = border_width;
632 req->depth = depth;
633 req->class = class;
634 if (visual == (Visual *)CopyFromParent)
635 req->visual = CopyFromParent;
636 else
637 req->visual = visual->visualid;
638 valuemask &= (CWBackPixmap|CWBackPixel|CWBorderPixmap|
639 CWBorderPixel|CWBitGravity|CWWinGravity|
640 CWBackingStore|CWBackingPlanes|CWBackingPixel|
641 CWOverrideRedirect|CWSaveUnder|CWEventMask|
642 CWDontPropagate|CWColormap|CWCursor);
643 if ((req->mask = valuemask)) {
644 unsigned long values[32];
645 register unsigned long *value = values;
646 unsigned int nvalues;
647
648 if (valuemask & CWBackPixmap)
649 *value++ = attr->background_pixmap;
650 if (valuemask & CWBackPixel)
651 *value++ = attr->background_pixel;
652 if (valuemask & CWBorderPixmap)
653 *value++ = attr->border_pixmap;
654 if (valuemask & CWBorderPixel)
655 *value++ = attr->border_pixel;
656 if (valuemask & CWBitGravity)
657 *value++ = attr->bit_gravity;
658 if (valuemask & CWWinGravity)
659 *value++ = attr->win_gravity;
660 if (valuemask & CWBackingStore)
661 *value++ = attr->backing_store;
662 if (valuemask & CWBackingPlanes)
663 *value++ = attr->backing_planes;
664 if (valuemask & CWBackingPixel)
665 *value++ = attr->backing_pixel;
666 if (valuemask & CWOverrideRedirect)
667 *value++ = attr->override_redirect;
668 if (valuemask & CWSaveUnder)
669 *value++ = attr->save_under;
670 if (valuemask & CWEventMask)
671 *value++ = attr->event_mask;
672 if (valuemask & CWDontPropagate)
673 *value++ = attr->do_not_propagate_mask;
674 if (valuemask & CWColormap)
675 *value++ = attr->colormap;
676 if (valuemask & CWCursor)
677 *value++ = attr->cursor;
678 req->length += (nvalues = value - values);
679
680 nvalues <<= 2; /* watch out for macros... */
681 Data32 (dpy, (long *) values, (long)nvalues);
682 }
683 UnlockDisplay(dpy);
684 SyncHandle();
685 return wid;
686 }
687
XmbufClearBufferArea(Display * dpy,Multibuffer buffer,int x,int y,unsigned int width,unsigned int height,Bool exposures)688 void XmbufClearBufferArea (
689 Display *dpy,
690 Multibuffer buffer,
691 int x, int y,
692 unsigned int width, unsigned int height,
693 Bool exposures)
694 {
695 XExtDisplayInfo *info = find_display (dpy);
696 register xMbufClearImageBufferAreaReq *req;
697
698 MbufSimpleCheckExtension (dpy, info);
699
700 LockDisplay (dpy);
701 MbufGetReq (MbufClearImageBufferArea, req, info);
702 req->buffer = buffer;
703 req->x = x;
704 req->y = y;
705 req->width = width;
706 req->height = height;
707 req->exposures = exposures;
708 UnlockDisplay (dpy);
709 SyncHandle();
710 }
711
712