XShm.c revision caade7cc
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/shmstr.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 shminfo->shmseg = XAllocID(dpy); 239 LockDisplay(dpy); 240 GetReq(ShmAttach, req); 241 req->reqType = info->codes->major_opcode; 242 req->shmReqType = X_ShmAttach; 243 req->shmseg = shminfo->shmseg; 244 req->shmid = shminfo->shmid; 245 req->readOnly = shminfo->readOnly ? xTrue : xFalse; 246 UnlockDisplay(dpy); 247 SyncHandle(); 248 return 1; 249} 250 251 252Status XShmDetach(Display *dpy, XShmSegmentInfo *shminfo) 253{ 254 XExtDisplayInfo *info = find_display (dpy); 255 register xShmDetachReq *req; 256 257 ShmCheckExtension (dpy, info, 0); 258 259 LockDisplay(dpy); 260 GetReq(ShmDetach, req); 261 req->reqType = info->codes->major_opcode; 262 req->shmReqType = X_ShmDetach; 263 req->shmseg = shminfo->shmseg; 264 UnlockDisplay(dpy); 265 SyncHandle(); 266 return 1; 267} 268 269static int _XShmDestroyImage (XImage *ximage) 270{ 271 Xfree((char *)ximage); 272 return 1; 273} 274 275#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad) - 1)) / (pad)) * (pad)) 276 277XImage *XShmCreateImage ( 278 register Display *dpy, 279 register Visual *visual, 280 unsigned int depth, 281 int format, 282 char *data, 283 XShmSegmentInfo *shminfo, 284 unsigned int width, 285 unsigned int height) 286{ 287 register XImage *image; 288 289 image = (XImage *)Xcalloc(1, (unsigned)sizeof(XImage)); 290 if (!image) 291 return image; 292 image->data = data; 293 image->obdata = (char *)shminfo; 294 image->width = width; 295 image->height = height; 296 image->depth = depth; 297 image->format = format; 298 image->byte_order = dpy->byte_order; 299 image->bitmap_unit = dpy->bitmap_unit; 300 image->bitmap_bit_order = dpy->bitmap_bit_order; 301 image->bitmap_pad = _XGetScanlinePad(dpy, depth); 302 image->xoffset = 0; 303 if (visual) { 304 image->red_mask = visual->red_mask; 305 image->green_mask = visual->green_mask; 306 image->blue_mask = visual->blue_mask; 307 } else { 308 image->red_mask = image->green_mask = image->blue_mask = 0; 309 } 310 if (format == ZPixmap) 311 image->bits_per_pixel = _XGetBitsPerPixel(dpy, (int)depth); 312 else 313 image->bits_per_pixel = 1; 314 image->bytes_per_line = ROUNDUP((image->bits_per_pixel * width), 315 image->bitmap_pad) >> 3; 316 _XInitImageFuncPtrs(image); 317 image->f.destroy_image = _XShmDestroyImage; 318 return image; 319} 320 321Status XShmPutImage ( 322 register Display *dpy, 323 Drawable d, 324 GC gc, 325 register XImage *image, 326 int src_x, int src_y, int dst_x, int dst_y, 327 unsigned int src_width, unsigned int src_height, 328 Bool send_event) 329{ 330 XExtDisplayInfo *info = find_display (dpy); 331 XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata; 332 register xShmPutImageReq *req; 333 334 ShmCheckExtension (dpy, info, 0); 335 if (!shminfo) return 0; 336 337 LockDisplay(dpy); 338 FlushGC(dpy, gc); 339 GetReq(ShmPutImage, req); 340 req->reqType = info->codes->major_opcode; 341 req->shmReqType = X_ShmPutImage; 342 req->drawable = d; 343 req->gc = gc->gid; 344 req->srcX = src_x; 345 req->srcY = src_y; 346 req->srcWidth = src_width; 347 req->srcHeight = src_height; 348 req->dstX = dst_x; 349 req->dstY = dst_y; 350 req->totalWidth = image->width; 351 req->totalHeight = image->height; 352 req->depth = image->depth; 353 req->format = image->format; 354 req->sendEvent = send_event; 355 req->shmseg = shminfo->shmseg; 356 req->offset = image->data - shminfo->shmaddr; 357 UnlockDisplay(dpy); 358 SyncHandle(); 359 return 1; 360} 361 362 363Status XShmGetImage( 364 register Display *dpy, 365 Drawable d, 366 XImage *image, 367 int x, int y, 368 unsigned long plane_mask) 369{ 370 XExtDisplayInfo *info = find_display (dpy); 371 XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata; 372 register xShmGetImageReq *req; 373 xShmGetImageReply rep; 374 register Visual *visual; 375 376 ShmCheckExtension (dpy, info, 0); 377 if (!shminfo) return 0; 378 379 LockDisplay(dpy); 380 GetReq(ShmGetImage, req); 381 req->reqType = info->codes->major_opcode; 382 req->shmReqType = X_ShmGetImage; 383 req->drawable = d; 384 req->x = x; 385 req->y = y; 386 req->width = image->width; 387 req->height = image->height; 388 req->planeMask = plane_mask; 389 req->format = image->format; 390 req->shmseg = shminfo->shmseg; 391 req->offset = image->data - shminfo->shmaddr; 392 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 393 UnlockDisplay(dpy); 394 SyncHandle(); 395 return 0; 396 } 397 visual = _XVIDtoVisual(dpy, rep.visual); 398 if (visual) { 399 image->red_mask = visual->red_mask; 400 image->green_mask = visual->green_mask; 401 image->blue_mask = visual->blue_mask; 402 } else { 403 image->red_mask = image->green_mask = image->blue_mask = 0; 404 } 405 UnlockDisplay(dpy); 406 SyncHandle(); 407 return 1; 408} 409 410Pixmap XShmCreatePixmap ( 411 register Display *dpy, 412 Drawable d, 413 char *data, 414 XShmSegmentInfo *shminfo, 415 unsigned int width, unsigned int height, unsigned int depth) 416{ 417 XExtDisplayInfo *info = find_display (dpy); 418 Pixmap pid; 419 register xShmCreatePixmapReq *req; 420 421 ShmCheckExtension (dpy, info, 0); 422 423 LockDisplay(dpy); 424 GetReq(ShmCreatePixmap, req); 425 req->reqType = info->codes->major_opcode; 426 req->shmReqType = X_ShmCreatePixmap; 427 req->drawable = d; 428 req->width = width; 429 req->height = height; 430 req->depth = depth; 431 req->shmseg = shminfo->shmseg; 432 req->offset = data - shminfo->shmaddr; 433 pid = req->pid = XAllocID(dpy); 434 UnlockDisplay(dpy); 435 SyncHandle(); 436 return pid; 437} 438