3 Copyright 1989, 1998 The Open Group
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
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
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.
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.
25 * Author: Bob Scheifler and Keith Packard, MIT X Consortium
28 /* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
34 #include <X11/Xlibint.h>
35 #include <X11/ImUtil.h>
36 #include <X11/extensions/XShm.h>
37 #include <X11/extensions/shmproto.h>
38 #include <X11/extensions/Xext.h>
39 #include <X11/extensions/extutil.h>
41 static XExtensionInfo _shm_info_data;
42 static XExtensionInfo *shm_info = &_shm_info_data;
43 static /* const */ char *shm_extension_name = SHMNAME;
45 #define ShmCheckExtension(dpy,i,val) \
46 XextCheckExtension (dpy, i, shm_extension_name, val)
48 /*****************************************************************************
50 * private utility routines *
52 *****************************************************************************/
54 static int close_display(Display *dpy, XExtCodes *codes);
55 static char *error_string(Display *dpy, int code, XExtCodes *codes,
57 static Bool wire_to_event (Display *dpy, XEvent *re, xEvent *event);
58 static Status event_to_wire (Display *dpy, XEvent *re, xEvent *event);
59 static /* const */ XExtensionHooks shm_extension_hooks = {
64 NULL, /* create_font */
66 close_display, /* close_display */
67 wire_to_event, /* wire_to_event */
68 event_to_wire, /* event_to_wire */
70 error_string, /* error_string */
73 static /* const */ char *shm_error_list[] = {
74 "BadShmSeg", /* BadShmSeg */
77 static XEXT_GENERATE_FIND_DISPLAY (find_display, shm_info, shm_extension_name,
78 &shm_extension_hooks, ShmNumberEvents, NULL)
80 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, shm_info)
82 static XEXT_GENERATE_ERROR_STRING (error_string, shm_extension_name,
83 ShmNumberErrors, shm_error_list)
87 wire_to_event (Display *dpy, XEvent *re, xEvent *event)
89 XExtDisplayInfo *info = find_display (dpy);
90 XShmCompletionEvent *se;
91 xShmCompletionEvent *sevent;
93 ShmCheckExtension (dpy, info, False);
95 switch ((event->u.u.type & 0x7f) - info->codes->first_event) {
97 se = (XShmCompletionEvent *) re;
98 sevent = (xShmCompletionEvent *) event;
99 se->type = sevent->type & 0x7f;
100 se->serial = _XSetLastRequestRead(dpy,(xGenericReply *) event);
101 se->send_event = (sevent->type & 0x80) != 0;
103 se->drawable = sevent->drawable;
104 se->major_code = sevent->majorEvent;
105 se->minor_code = sevent->minorEvent;
106 se->shmseg = sevent->shmseg;
107 se->offset = sevent->offset;
114 event_to_wire (Display *dpy, XEvent *re, xEvent *event)
116 XExtDisplayInfo *info = find_display (dpy);
117 XShmCompletionEvent *se;
118 xShmCompletionEvent *sevent;
120 ShmCheckExtension (dpy, info, 0);
122 switch ((re->type & 0x7f) - info->codes->first_event) {
124 se = (XShmCompletionEvent *) re;
125 sevent = (xShmCompletionEvent *) event;
126 sevent->type = se->type | (se->send_event ? 0x80 : 0);
127 sevent->sequenceNumber = se->serial & 0xffff;
128 sevent->drawable = se->drawable;
129 sevent->majorEvent = se->major_code;
130 sevent->minorEvent = se->minor_code;
131 sevent->shmseg = se->shmseg;
132 sevent->offset = se->offset;
138 /*****************************************************************************
140 * public Shared Memory Extension routines *
142 *****************************************************************************/
144 Bool XShmQueryExtension (Display *dpy /* int *event_basep, *error_basep */)
146 XExtDisplayInfo *info = find_display (dpy);
148 if (XextHasExtension(info)) {
149 /* *event_basep = info->codes->first_event;
150 *error_basep = info->codes->error_event; */
158 int XShmGetEventBase(Display *dpy)
160 XExtDisplayInfo *info = find_display (dpy);
162 if (XextHasExtension(info)) {
163 return info->codes->first_event;
170 Bool XShmQueryVersion(
176 XExtDisplayInfo *info = find_display (dpy);
177 xShmQueryVersionReply rep;
178 register xShmQueryVersionReq *req;
180 ShmCheckExtension (dpy, info, False);
183 GetReq(ShmQueryVersion, req);
184 req->reqType = info->codes->major_opcode;
185 req->shmReqType = X_ShmQueryVersion;
186 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
191 *majorVersion = rep.majorVersion;
192 *minorVersion = rep.minorVersion;
193 *sharedPixmaps = rep.sharedPixmaps ? True : False;
200 int XShmPixmapFormat(Display *dpy)
202 XExtDisplayInfo *info = find_display (dpy);
203 xShmQueryVersionReply rep;
204 register xShmQueryVersionReq *req;
206 ShmCheckExtension (dpy, info, False);
209 GetReq(ShmQueryVersion, req);
210 req->reqType = info->codes->major_opcode;
211 req->shmReqType = X_ShmQueryVersion;
212 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
219 if (rep.sharedPixmaps &&
220 (rep.majorVersion > 1 || rep.minorVersion > 0))
221 return rep.pixmapFormat;
226 Status XShmAttach(Display *dpy, XShmSegmentInfo *shminfo)
228 XExtDisplayInfo *info = find_display (dpy);
229 register xShmAttachReq *req;
231 ShmCheckExtension (dpy, info, 0);
234 GetReq(ShmAttach, req);
235 req->reqType = info->codes->major_opcode;
236 req->shmReqType = X_ShmAttach;
237 req->shmseg = shminfo->shmseg = XAllocID(dpy);
238 req->shmid = shminfo->shmid;
239 req->readOnly = shminfo->readOnly ? xTrue : xFalse;
246 Status XShmDetach(Display *dpy, XShmSegmentInfo *shminfo)
248 XExtDisplayInfo *info = find_display (dpy);
249 register xShmDetachReq *req;
251 ShmCheckExtension (dpy, info, 0);
254 GetReq(ShmDetach, req);
255 req->reqType = info->codes->major_opcode;
256 req->shmReqType = X_ShmDetach;
257 req->shmseg = shminfo->shmseg;
263 static int _XShmDestroyImage (XImage *ximage)
265 Xfree((char *)ximage);
269 #define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad) - 1)) / (pad)) * (pad))
271 XImage *XShmCreateImage (
272 register Display *dpy,
273 register Visual *visual,
277 XShmSegmentInfo *shminfo,
281 register XImage *image;
283 image = (XImage *)Xcalloc(1, (unsigned)sizeof(XImage));
287 image->obdata = (char *)shminfo;
288 image->width = width;
289 image->height = height;
290 image->depth = depth;
291 image->format = format;
292 image->byte_order = dpy->byte_order;
293 image->bitmap_unit = dpy->bitmap_unit;
294 image->bitmap_bit_order = dpy->bitmap_bit_order;
295 image->bitmap_pad = _XGetScanlinePad(dpy, depth);
298 image->red_mask = visual->red_mask;
299 image->green_mask = visual->green_mask;
300 image->blue_mask = visual->blue_mask;
302 image->red_mask = image->green_mask = image->blue_mask = 0;
304 if (format == ZPixmap)
305 image->bits_per_pixel = _XGetBitsPerPixel(dpy, (int)depth);
307 image->bits_per_pixel = 1;
308 image->bytes_per_line = ROUNDUP((image->bits_per_pixel * width),
309 image->bitmap_pad) >> 3;
310 _XInitImageFuncPtrs(image);
311 image->f.destroy_image = _XShmDestroyImage;
315 Status XShmPutImage (
316 register Display *dpy,
319 register XImage *image,
320 int src_x, int src_y, int dst_x, int dst_y,
321 unsigned int src_width, unsigned int src_height,
324 XExtDisplayInfo *info = find_display (dpy);
325 XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
326 register xShmPutImageReq *req;
328 ShmCheckExtension (dpy, info, 0);
329 if (!shminfo) return 0;
333 GetReq(ShmPutImage, req);
334 req->reqType = info->codes->major_opcode;
335 req->shmReqType = X_ShmPutImage;
340 req->srcWidth = src_width;
341 req->srcHeight = src_height;
344 req->totalWidth = image->width;
345 req->totalHeight = image->height;
346 req->depth = image->depth;
347 req->format = image->format;
348 req->sendEvent = send_event;
349 req->shmseg = shminfo->shmseg;
350 req->offset = image->data - shminfo->shmaddr;
358 register Display *dpy,
362 unsigned long plane_mask)
364 XExtDisplayInfo *info = find_display (dpy);
365 XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
366 register xShmGetImageReq *req;
367 xShmGetImageReply rep;
368 register Visual *visual;
370 ShmCheckExtension (dpy, info, 0);
371 if (!shminfo) return 0;
374 GetReq(ShmGetImage, req);
375 req->reqType = info->codes->major_opcode;
376 req->shmReqType = X_ShmGetImage;
380 req->width = image->width;
381 req->height = image->height;
382 req->planeMask = plane_mask;
383 req->format = image->format;
384 req->shmseg = shminfo->shmseg;
385 req->offset = image->data - shminfo->shmaddr;
386 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
391 visual = _XVIDtoVisual(dpy, rep.visual);
393 image->red_mask = visual->red_mask;
394 image->green_mask = visual->green_mask;
395 image->blue_mask = visual->blue_mask;
397 image->red_mask = image->green_mask = image->blue_mask = 0;
404 Pixmap XShmCreatePixmap (
405 register Display *dpy,
408 XShmSegmentInfo *shminfo,
409 unsigned int width, unsigned int height, unsigned int depth)
411 XExtDisplayInfo *info = find_display (dpy);
413 register xShmCreatePixmapReq *req;
415 ShmCheckExtension (dpy, info, 0);
418 GetReq(ShmCreatePixmap, req);
419 req->reqType = info->codes->major_opcode;
420 req->shmReqType = X_ShmCreatePixmap;
423 req->height = height;
425 req->shmseg = shminfo->shmseg;
426 req->offset = data - shminfo->shmaddr;
427 pid = req->pid = XAllocID(dpy);