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