upload tizen2.0 source
[framework/uifw/xorg/lib/libxext.git] / src / XMultibuf.c
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
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  */
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
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  */
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  */
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  */
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  */
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  */
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  */
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             _XEatData(dpy, (unsigned long) nbytes);
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  */
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  */
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  */
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  */
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  */
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
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