XShm.c revision caade7cc
1caade7ccSmrg/* $XdotOrg: $ */
2caade7ccSmrg/*
3caade7ccSmrg * $Xorg: XShm.c,v 1.4 2001/02/09 02:03:49 xorgcvs Exp $
4caade7ccSmrg *
5caade7ccSmrgCopyright 1989, 1998  The Open Group
6caade7ccSmrg
7caade7ccSmrgPermission to use, copy, modify, distribute, and sell this software and its
8caade7ccSmrgdocumentation for any purpose is hereby granted without fee, provided that
9caade7ccSmrgthe above copyright notice appear in all copies and that both that
10caade7ccSmrgcopyright notice and this permission notice appear in supporting
11caade7ccSmrgdocumentation.
12caade7ccSmrg
13caade7ccSmrgThe above copyright notice and this permission notice shall be included in
14caade7ccSmrgall copies or substantial portions of the Software.
15caade7ccSmrg
16caade7ccSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17caade7ccSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18caade7ccSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19caade7ccSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20caade7ccSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21caade7ccSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22caade7ccSmrg
23caade7ccSmrgExcept as contained in this notice, the name of The Open Group shall not be
24caade7ccSmrgused in advertising or otherwise to promote the sale, use or other dealings
25caade7ccSmrgin this Software without prior written authorization from The Open Group.
26caade7ccSmrg *
27caade7ccSmrg * Author:  Bob Scheifler and Keith Packard, MIT X Consortium
28caade7ccSmrg */
29caade7ccSmrg/* $XFree86: xc/lib/Xext/XShm.c,v 1.6 2002/10/16 02:19:22 dawes Exp $ */
30caade7ccSmrg
31caade7ccSmrg/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
32caade7ccSmrg
33caade7ccSmrg#define NEED_EVENTS
34caade7ccSmrg#define NEED_REPLIES
35caade7ccSmrg#ifdef HAVE_CONFIG_H
36caade7ccSmrg#include <config.h>
37caade7ccSmrg#endif
38caade7ccSmrg#include <stdio.h>
39caade7ccSmrg#include <X11/Xlibint.h>
40caade7ccSmrg#include <X11/ImUtil.h>
41caade7ccSmrg#include <X11/extensions/XShm.h>
42caade7ccSmrg#include <X11/extensions/shmstr.h>
43caade7ccSmrg#include <X11/extensions/Xext.h>
44caade7ccSmrg#include <X11/extensions/extutil.h>
45caade7ccSmrg
46caade7ccSmrgstatic XExtensionInfo _shm_info_data;
47caade7ccSmrgstatic XExtensionInfo *shm_info = &_shm_info_data;
48caade7ccSmrgstatic /* const */ char *shm_extension_name = SHMNAME;
49caade7ccSmrg
50caade7ccSmrg#define ShmCheckExtension(dpy,i,val) \
51caade7ccSmrg  XextCheckExtension (dpy, i, shm_extension_name, val)
52caade7ccSmrg
53caade7ccSmrg/*****************************************************************************
54caade7ccSmrg *                                                                           *
55caade7ccSmrg *			   private utility routines                          *
56caade7ccSmrg *                                                                           *
57caade7ccSmrg *****************************************************************************/
58caade7ccSmrg
59caade7ccSmrgstatic int close_display(Display *dpy, XExtCodes *codes);
60caade7ccSmrgstatic char *error_string(Display *dpy, int code, XExtCodes *codes,
61caade7ccSmrg			  char *buf, int n);
62caade7ccSmrgstatic Bool wire_to_event (Display *dpy, XEvent *re, xEvent *event);
63caade7ccSmrgstatic Status event_to_wire (Display *dpy, XEvent *re, xEvent *event);
64caade7ccSmrgstatic /* const */ XExtensionHooks shm_extension_hooks = {
65caade7ccSmrg    NULL,				/* create_gc */
66caade7ccSmrg    NULL,				/* copy_gc */
67caade7ccSmrg    NULL,				/* flush_gc */
68caade7ccSmrg    NULL,				/* free_gc */
69caade7ccSmrg    NULL,				/* create_font */
70caade7ccSmrg    NULL,				/* free_font */
71caade7ccSmrg    close_display,			/* close_display */
72caade7ccSmrg    wire_to_event,			/* wire_to_event */
73caade7ccSmrg    event_to_wire,			/* event_to_wire */
74caade7ccSmrg    NULL,				/* error */
75caade7ccSmrg    error_string,			/* error_string */
76caade7ccSmrg};
77caade7ccSmrg
78caade7ccSmrgstatic /* const */ char *shm_error_list[] = {
79caade7ccSmrg    "BadShmSeg",			/* BadShmSeg */
80caade7ccSmrg};
81caade7ccSmrg
82caade7ccSmrgstatic XEXT_GENERATE_FIND_DISPLAY (find_display, shm_info, shm_extension_name,
83caade7ccSmrg				   &shm_extension_hooks, ShmNumberEvents, NULL)
84caade7ccSmrg
85caade7ccSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (close_display, shm_info)
86caade7ccSmrg
87caade7ccSmrgstatic XEXT_GENERATE_ERROR_STRING (error_string, shm_extension_name,
88caade7ccSmrg				   ShmNumberErrors, shm_error_list)
89caade7ccSmrg
90caade7ccSmrg
91caade7ccSmrgstatic Bool
92caade7ccSmrgwire_to_event (Display *dpy, XEvent *re, xEvent *event)
93caade7ccSmrg{
94caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
95caade7ccSmrg    XShmCompletionEvent	*se;
96caade7ccSmrg    xShmCompletionEvent	*sevent;
97caade7ccSmrg
98caade7ccSmrg    ShmCheckExtension (dpy, info, False);
99caade7ccSmrg
100caade7ccSmrg    switch ((event->u.u.type & 0x7f) - info->codes->first_event) {
101caade7ccSmrg    case ShmCompletion:
102caade7ccSmrg	se = (XShmCompletionEvent *) re;
103caade7ccSmrg	sevent = (xShmCompletionEvent *) event;
104caade7ccSmrg	se->type = sevent->type & 0x7f;
105caade7ccSmrg	se->serial = _XSetLastRequestRead(dpy,(xGenericReply *) event);
106caade7ccSmrg	se->send_event = (sevent->type & 0x80) != 0;
107caade7ccSmrg	se->display = dpy;
108caade7ccSmrg	se->drawable = sevent->drawable;
109caade7ccSmrg	se->major_code = sevent->majorEvent;
110caade7ccSmrg	se->minor_code = sevent->minorEvent;
111caade7ccSmrg	se->shmseg = sevent->shmseg;
112caade7ccSmrg	se->offset = sevent->offset;
113caade7ccSmrg    	return True;
114caade7ccSmrg    }
115caade7ccSmrg    return False;
116caade7ccSmrg}
117caade7ccSmrg
118caade7ccSmrgstatic Status
119caade7ccSmrgevent_to_wire (Display *dpy, XEvent *re, xEvent *event)
120caade7ccSmrg{
121caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
122caade7ccSmrg    XShmCompletionEvent	*se;
123caade7ccSmrg    xShmCompletionEvent	*sevent;
124caade7ccSmrg
125caade7ccSmrg    ShmCheckExtension (dpy, info, 0);
126caade7ccSmrg
127caade7ccSmrg    switch ((re->type & 0x7f) - info->codes->first_event) {
128caade7ccSmrg    case ShmCompletion:
129caade7ccSmrg    	se = (XShmCompletionEvent *) re;
130caade7ccSmrg	sevent = (xShmCompletionEvent *) event;
131caade7ccSmrg    	sevent->type = se->type | (se->send_event ? 0x80 : 0);
132caade7ccSmrg    	sevent->sequenceNumber = se->serial & 0xffff;
133caade7ccSmrg    	sevent->drawable = se->drawable;
134caade7ccSmrg    	sevent->majorEvent = se->major_code;
135caade7ccSmrg    	sevent->minorEvent = se->minor_code;
136caade7ccSmrg    	sevent->shmseg = se->shmseg;
137caade7ccSmrg    	sevent->offset = se->offset;
138caade7ccSmrg    	return True;
139caade7ccSmrg    }
140caade7ccSmrg    return False;
141caade7ccSmrg}
142caade7ccSmrg
143caade7ccSmrg/*****************************************************************************
144caade7ccSmrg *                                                                           *
145caade7ccSmrg *		    public Shared Memory Extension routines                  *
146caade7ccSmrg *                                                                           *
147caade7ccSmrg *****************************************************************************/
148caade7ccSmrg
149caade7ccSmrgBool XShmQueryExtension (Display *dpy /*  int *event_basep, *error_basep */)
150caade7ccSmrg{
151caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
152caade7ccSmrg
153caade7ccSmrg    if (XextHasExtension(info)) {
154caade7ccSmrg/*	*event_basep = info->codes->first_event;
155caade7ccSmrg	*error_basep = info->codes->error_event; */
156caade7ccSmrg	return True;
157caade7ccSmrg    } else {
158caade7ccSmrg	return False;
159caade7ccSmrg    }
160caade7ccSmrg}
161caade7ccSmrg
162caade7ccSmrg
163caade7ccSmrgint XShmGetEventBase(Display *dpy)
164caade7ccSmrg{
165caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
166caade7ccSmrg
167caade7ccSmrg    if (XextHasExtension(info)) {
168caade7ccSmrg	return info->codes->first_event;
169caade7ccSmrg    } else {
170caade7ccSmrg	return -1;
171caade7ccSmrg    }
172caade7ccSmrg}
173caade7ccSmrg
174caade7ccSmrg
175caade7ccSmrgBool XShmQueryVersion(
176caade7ccSmrg    Display *dpy,
177caade7ccSmrg    int *majorVersion,
178caade7ccSmrg    int *minorVersion,
179caade7ccSmrg    Bool *sharedPixmaps)
180caade7ccSmrg{
181caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
182caade7ccSmrg    xShmQueryVersionReply rep;
183caade7ccSmrg    register xShmQueryVersionReq *req;
184caade7ccSmrg
185caade7ccSmrg    ShmCheckExtension (dpy, info, False);
186caade7ccSmrg
187caade7ccSmrg    LockDisplay(dpy);
188caade7ccSmrg    GetReq(ShmQueryVersion, req);
189caade7ccSmrg    req->reqType = info->codes->major_opcode;
190caade7ccSmrg    req->shmReqType = X_ShmQueryVersion;
191caade7ccSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
192caade7ccSmrg	UnlockDisplay(dpy);
193caade7ccSmrg	SyncHandle();
194caade7ccSmrg	return False;
195caade7ccSmrg    }
196caade7ccSmrg    *majorVersion = rep.majorVersion;
197caade7ccSmrg    *minorVersion = rep.minorVersion;
198caade7ccSmrg    *sharedPixmaps = rep.sharedPixmaps ? True : False;
199caade7ccSmrg    UnlockDisplay(dpy);
200caade7ccSmrg    SyncHandle();
201caade7ccSmrg    return True;
202caade7ccSmrg}
203caade7ccSmrg
204caade7ccSmrg
205caade7ccSmrgint XShmPixmapFormat(Display *dpy)
206caade7ccSmrg{
207caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
208caade7ccSmrg    xShmQueryVersionReply rep;
209caade7ccSmrg    register xShmQueryVersionReq *req;
210caade7ccSmrg
211caade7ccSmrg    ShmCheckExtension (dpy, info, False);
212caade7ccSmrg
213caade7ccSmrg    LockDisplay(dpy);
214caade7ccSmrg    GetReq(ShmQueryVersion, req);
215caade7ccSmrg    req->reqType = info->codes->major_opcode;
216caade7ccSmrg    req->shmReqType = X_ShmQueryVersion;
217caade7ccSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
218caade7ccSmrg	UnlockDisplay(dpy);
219caade7ccSmrg	SyncHandle();
220caade7ccSmrg	return 0;
221caade7ccSmrg    }
222caade7ccSmrg    UnlockDisplay(dpy);
223caade7ccSmrg    SyncHandle();
224caade7ccSmrg    if (rep.sharedPixmaps &&
225caade7ccSmrg	(rep.majorVersion > 1 || rep.minorVersion > 0))
226caade7ccSmrg	return rep.pixmapFormat;
227caade7ccSmrg    return 0;
228caade7ccSmrg}
229caade7ccSmrg
230caade7ccSmrg
231caade7ccSmrgStatus XShmAttach(Display *dpy, XShmSegmentInfo *shminfo)
232caade7ccSmrg{
233caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
234caade7ccSmrg    register xShmAttachReq *req;
235caade7ccSmrg
236caade7ccSmrg    ShmCheckExtension (dpy, info, 0);
237caade7ccSmrg
238caade7ccSmrg    shminfo->shmseg = XAllocID(dpy);
239caade7ccSmrg    LockDisplay(dpy);
240caade7ccSmrg    GetReq(ShmAttach, req);
241caade7ccSmrg    req->reqType = info->codes->major_opcode;
242caade7ccSmrg    req->shmReqType = X_ShmAttach;
243caade7ccSmrg    req->shmseg = shminfo->shmseg;
244caade7ccSmrg    req->shmid = shminfo->shmid;
245caade7ccSmrg    req->readOnly = shminfo->readOnly ? xTrue : xFalse;
246caade7ccSmrg    UnlockDisplay(dpy);
247caade7ccSmrg    SyncHandle();
248caade7ccSmrg    return 1;
249caade7ccSmrg}
250caade7ccSmrg
251caade7ccSmrg
252caade7ccSmrgStatus XShmDetach(Display *dpy, XShmSegmentInfo *shminfo)
253caade7ccSmrg{
254caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
255caade7ccSmrg    register xShmDetachReq *req;
256caade7ccSmrg
257caade7ccSmrg    ShmCheckExtension (dpy, info, 0);
258caade7ccSmrg
259caade7ccSmrg    LockDisplay(dpy);
260caade7ccSmrg    GetReq(ShmDetach, req);
261caade7ccSmrg    req->reqType = info->codes->major_opcode;
262caade7ccSmrg    req->shmReqType = X_ShmDetach;
263caade7ccSmrg    req->shmseg = shminfo->shmseg;
264caade7ccSmrg    UnlockDisplay(dpy);
265caade7ccSmrg    SyncHandle();
266caade7ccSmrg    return 1;
267caade7ccSmrg}
268caade7ccSmrg
269caade7ccSmrgstatic int _XShmDestroyImage (XImage *ximage)
270caade7ccSmrg{
271caade7ccSmrg	Xfree((char *)ximage);
272caade7ccSmrg	return 1;
273caade7ccSmrg}
274caade7ccSmrg
275caade7ccSmrg#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad) - 1)) / (pad)) * (pad))
276caade7ccSmrg
277caade7ccSmrgXImage *XShmCreateImage (
278caade7ccSmrg    register Display *dpy,
279caade7ccSmrg    register Visual *visual,
280caade7ccSmrg    unsigned int depth,
281caade7ccSmrg    int format,
282caade7ccSmrg    char *data,
283caade7ccSmrg    XShmSegmentInfo *shminfo,
284caade7ccSmrg    unsigned int width,
285caade7ccSmrg    unsigned int height)
286caade7ccSmrg{
287caade7ccSmrg    register XImage *image;
288caade7ccSmrg
289caade7ccSmrg    image = (XImage *)Xcalloc(1, (unsigned)sizeof(XImage));
290caade7ccSmrg    if (!image)
291caade7ccSmrg	return image;
292caade7ccSmrg    image->data = data;
293caade7ccSmrg    image->obdata = (char *)shminfo;
294caade7ccSmrg    image->width = width;
295caade7ccSmrg    image->height = height;
296caade7ccSmrg    image->depth = depth;
297caade7ccSmrg    image->format = format;
298caade7ccSmrg    image->byte_order = dpy->byte_order;
299caade7ccSmrg    image->bitmap_unit = dpy->bitmap_unit;
300caade7ccSmrg    image->bitmap_bit_order = dpy->bitmap_bit_order;
301caade7ccSmrg    image->bitmap_pad = _XGetScanlinePad(dpy, depth);
302caade7ccSmrg    image->xoffset = 0;
303caade7ccSmrg    if (visual) {
304caade7ccSmrg	image->red_mask = visual->red_mask;
305caade7ccSmrg	image->green_mask = visual->green_mask;
306caade7ccSmrg	image->blue_mask = visual->blue_mask;
307caade7ccSmrg    } else {
308caade7ccSmrg	image->red_mask = image->green_mask = image->blue_mask = 0;
309caade7ccSmrg    }
310caade7ccSmrg    if (format == ZPixmap)
311caade7ccSmrg	image->bits_per_pixel = _XGetBitsPerPixel(dpy, (int)depth);
312caade7ccSmrg    else
313caade7ccSmrg	image->bits_per_pixel = 1;
314caade7ccSmrg    image->bytes_per_line = ROUNDUP((image->bits_per_pixel * width),
315caade7ccSmrg				    image->bitmap_pad) >> 3;
316caade7ccSmrg    _XInitImageFuncPtrs(image);
317caade7ccSmrg    image->f.destroy_image = _XShmDestroyImage;
318caade7ccSmrg    return image;
319caade7ccSmrg}
320caade7ccSmrg
321caade7ccSmrgStatus XShmPutImage (
322caade7ccSmrg    register Display *dpy,
323caade7ccSmrg    Drawable d,
324caade7ccSmrg    GC gc,
325caade7ccSmrg    register XImage *image,
326caade7ccSmrg    int src_x, int src_y, int dst_x, int dst_y,
327caade7ccSmrg    unsigned int src_width, unsigned int src_height,
328caade7ccSmrg    Bool send_event)
329caade7ccSmrg{
330caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
331caade7ccSmrg    XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
332caade7ccSmrg    register xShmPutImageReq *req;
333caade7ccSmrg
334caade7ccSmrg    ShmCheckExtension (dpy, info, 0);
335caade7ccSmrg    if (!shminfo) return 0;
336caade7ccSmrg
337caade7ccSmrg    LockDisplay(dpy);
338caade7ccSmrg    FlushGC(dpy, gc);
339caade7ccSmrg    GetReq(ShmPutImage, req);
340caade7ccSmrg    req->reqType = info->codes->major_opcode;
341caade7ccSmrg    req->shmReqType = X_ShmPutImage;
342caade7ccSmrg    req->drawable = d;
343caade7ccSmrg    req->gc = gc->gid;
344caade7ccSmrg    req->srcX = src_x;
345caade7ccSmrg    req->srcY = src_y;
346caade7ccSmrg    req->srcWidth = src_width;
347caade7ccSmrg    req->srcHeight = src_height;
348caade7ccSmrg    req->dstX = dst_x;
349caade7ccSmrg    req->dstY = dst_y;
350caade7ccSmrg    req->totalWidth = image->width;
351caade7ccSmrg    req->totalHeight = image->height;
352caade7ccSmrg    req->depth = image->depth;
353caade7ccSmrg    req->format = image->format;
354caade7ccSmrg    req->sendEvent = send_event;
355caade7ccSmrg    req->shmseg = shminfo->shmseg;
356caade7ccSmrg    req->offset = image->data - shminfo->shmaddr;
357caade7ccSmrg    UnlockDisplay(dpy);
358caade7ccSmrg    SyncHandle();
359caade7ccSmrg    return 1;
360caade7ccSmrg}
361caade7ccSmrg
362caade7ccSmrg
363caade7ccSmrgStatus XShmGetImage(
364caade7ccSmrg    register Display *dpy,
365caade7ccSmrg    Drawable d,
366caade7ccSmrg    XImage *image,
367caade7ccSmrg    int x, int y,
368caade7ccSmrg    unsigned long plane_mask)
369caade7ccSmrg{
370caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
371caade7ccSmrg    XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
372caade7ccSmrg    register xShmGetImageReq *req;
373caade7ccSmrg    xShmGetImageReply rep;
374caade7ccSmrg    register Visual *visual;
375caade7ccSmrg
376caade7ccSmrg    ShmCheckExtension (dpy, info, 0);
377caade7ccSmrg    if (!shminfo) return 0;
378caade7ccSmrg
379caade7ccSmrg    LockDisplay(dpy);
380caade7ccSmrg    GetReq(ShmGetImage, req);
381caade7ccSmrg    req->reqType = info->codes->major_opcode;
382caade7ccSmrg    req->shmReqType = X_ShmGetImage;
383caade7ccSmrg    req->drawable = d;
384caade7ccSmrg    req->x = x;
385caade7ccSmrg    req->y = y;
386caade7ccSmrg    req->width = image->width;
387caade7ccSmrg    req->height = image->height;
388caade7ccSmrg    req->planeMask = plane_mask;
389caade7ccSmrg    req->format = image->format;
390caade7ccSmrg    req->shmseg = shminfo->shmseg;
391caade7ccSmrg    req->offset = image->data - shminfo->shmaddr;
392caade7ccSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
393caade7ccSmrg	UnlockDisplay(dpy);
394caade7ccSmrg	SyncHandle();
395caade7ccSmrg	return 0;
396caade7ccSmrg    }
397caade7ccSmrg    visual = _XVIDtoVisual(dpy, rep.visual);
398caade7ccSmrg    if (visual) {
399caade7ccSmrg    	image->red_mask = visual->red_mask;
400caade7ccSmrg    	image->green_mask = visual->green_mask;
401caade7ccSmrg    	image->blue_mask = visual->blue_mask;
402caade7ccSmrg    } else {
403caade7ccSmrg	image->red_mask = image->green_mask = image->blue_mask = 0;
404caade7ccSmrg    }
405caade7ccSmrg    UnlockDisplay(dpy);
406caade7ccSmrg    SyncHandle();
407caade7ccSmrg    return 1;
408caade7ccSmrg}
409caade7ccSmrg
410caade7ccSmrgPixmap XShmCreatePixmap (
411caade7ccSmrg    register Display *dpy,
412caade7ccSmrg    Drawable d,
413caade7ccSmrg    char *data,
414caade7ccSmrg    XShmSegmentInfo *shminfo,
415caade7ccSmrg    unsigned int width, unsigned int height, unsigned int depth)
416caade7ccSmrg{
417caade7ccSmrg    XExtDisplayInfo *info = find_display (dpy);
418caade7ccSmrg    Pixmap pid;
419caade7ccSmrg    register xShmCreatePixmapReq *req;
420caade7ccSmrg
421caade7ccSmrg    ShmCheckExtension (dpy, info, 0);
422caade7ccSmrg
423caade7ccSmrg    LockDisplay(dpy);
424caade7ccSmrg    GetReq(ShmCreatePixmap, req);
425caade7ccSmrg    req->reqType = info->codes->major_opcode;
426caade7ccSmrg    req->shmReqType = X_ShmCreatePixmap;
427caade7ccSmrg    req->drawable = d;
428caade7ccSmrg    req->width = width;
429caade7ccSmrg    req->height = height;
430caade7ccSmrg    req->depth = depth;
431caade7ccSmrg    req->shmseg = shminfo->shmseg;
432caade7ccSmrg    req->offset = data - shminfo->shmaddr;
433caade7ccSmrg    pid = req->pid = XAllocID(dpy);
434caade7ccSmrg    UnlockDisplay(dpy);
435caade7ccSmrg    SyncHandle();
436caade7ccSmrg    return pid;
437caade7ccSmrg}
438