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