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