static void setup_shm(struct test *t) { XShmSegmentInfo shm; int size; shm.shmid = -1; if (!(t->ref.has_shm_pixmaps && t->out.has_shm_pixmaps)) return; size = t->ref.width * t->ref.height * 4; size = (size + 4095) & -4096; shm.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0666); if (shm.shmid == -1) return; shm.shmaddr = shmat(shm.shmid, 0, 0); if (shm.shmaddr == (char *) -1) { shmctl(shm.shmid, IPC_RMID, NULL); shm.shmid = -1; return; } shm.readOnly = False; shmref = shm; XShmAttach(t->ref.dpy, &shmref); XSync(t->ref.dpy, True); shmout = shm; XShmAttach(t->out.dpy, &shmout); XSync(t->out.dpy, True); }
void R_init_shm_image(struct R_imgage *image, int pmap) { img->xim = XShmCreateImage(attr->disp, attr->vis, attr->depth, ZPixmap, NULL, &image->shmimg.ximseg, image->width, image->height); if (!image->shmimg->xim) { fprintf(stderr, "cannot allocate image structure\n"); exit(1); } image->shmimg->shmid = R_init_shm_seg(image->w * image->h * 4, &image->shmimg.ximseg); img->xim->data = image->shmimg.ximseg.shmaddr; if (image->shmseg->shmid < 0) { exit(1); } XShmAttach(attr->disp, &image->shmseg->ximseg); if (pmap) { image->shmsegpmap->shmid = R_init_shm_seg(img->width * img->height * 4, &img->pmapseg); if (image->shmsegpmap->shmid < 0) { exit(1); } XShmAttach(attr->disp, &image->shmseg.pmapseg); image->shmsegpmap = XShmCreatePixmap(attr->disp, attr->win, image->shmseg.pmapseg.shmaddr, &image->shmseg.pmapseg, image->shmsegwidth, image->shmsegheight, attr->depth); if (!image->shmseg.pmap) { fprintf(stderr, "cannot create pixmap\n"); exit(1); } } return; }
void BC_Resources::init_shm(BC_WindowBase *window) { use_shm = 0; int (*old_handler)(Display *, XErrorEvent *) = XSetErrorHandler(BC_Resources::x_error_handler); if(XShmQueryExtension(window->display)) { XShmSegmentInfo test_shm; memset(&test_shm,0,sizeof(test_shm)); XImage *test_image = XShmCreateImage(window->display, window->vis, window->default_depth, ZPixmap, (char*)NULL, &test_shm, 5, 5); BC_Resources::error = 0; test_shm.shmid = shmget(IPC_PRIVATE, 5 * test_image->bytes_per_line, (IPC_CREAT | 0600)); if(test_shm.shmid != -1) { char *data = (char *)shmat(test_shm.shmid, NULL, 0); if(data != (void *)-1) { shmctl(test_shm.shmid, IPC_RMID, 0); test_shm.shmaddr = data; test_shm.readOnly = 0; if(XShmAttach(window->display, &test_shm)) { XSync(window->display, False); use_shm = 1; } shmdt(data); } } XDestroyImage(test_image); if(BC_Resources::error) use_shm = 0; } XSetErrorHandler(old_handler); }
BC_XShmImage::BC_XShmImage(BC_Bitmap *bitmap, int index, int w, int h, int color_model) : BC_BitmapImage(bitmap, index) { Display *display = top_level->display; Visual *visual = top_level->vis; int default_depth = bitmap->get_default_depth(); ximage = XShmCreateImage(display, visual, default_depth, default_depth == 1 ? XYBitmap : ZPixmap, (char*)NULL, &shm_info, w, h); // Create shared memory bytesPerLine = ximage->bytes_per_line; bitsPerPixel = ximage->bits_per_pixel; dataSize = h * bytesPerLine; shm_info.shmid = shmget(IPC_PRIVATE, dataSize + 8, IPC_CREAT | 0777); if(shm_info.shmid < 0) perror("BC_XShmImage::BC_XShmImage shmget"); data = (unsigned char *)shmat(shm_info.shmid, NULL, 0); // This causes it to automatically delete when the program exits. shmctl(shm_info.shmid, IPC_RMID, 0); ximage->data = shm_info.shmaddr = (char*)data; shm_info.readOnly = 0; // Get the real parameters if(!XShmAttach(top_level->display, &shm_info)) perror("BC_XShmImage::BC_XShmImage XShmAttach"); row_data = new unsigned char*[h]; for( int i=0; i<h; ++i ) row_data[i] = &data[i*bytesPerLine]; }
BC_XvShmImage::BC_XvShmImage(BC_Bitmap *bitmap, int index, int w, int h, int color_model) : BC_BitmapImage(bitmap, index) { Display *display = top_level->get_display(); int id = BC_CModels::bc_to_x(color_model); // Create the XvImage xv_image = XvShmCreateImage(display, bitmap->xv_portid, id, 0, w, h, &shm_info); dataSize = xv_image->data_size; // Create the shared memory shm_info.shmid = shmget(IPC_PRIVATE, dataSize + 8, IPC_CREAT | 0777); if(shm_info.shmid < 0) perror("BC_XvShmImage::BC_XvShmImage shmget"); data = (unsigned char *)shmat(shm_info.shmid, NULL, 0); // This causes it to automatically delete when the program exits. shmctl(shm_info.shmid, IPC_RMID, 0); // setting ximage->data stops BadValue xv_image->data = shm_info.shmaddr = (char*)data; shm_info.readOnly = 0; // Get the real parameters w = xv_image->width; h = xv_image->height; if(!XShmAttach(top_level->display, &shm_info)) perror("BC_XvShmImage::BC_XvShmImage XShmAttach"); if( color_model == BC_YUV422 ) { bytesPerLine = w*2; bitsPerPixel = 12; row_data = new unsigned char*[h]; for( int i=0; i<h; ++i ) row_data[i] = &data[i*bytesPerLine]; } }
void QXlibWindowSurface::resizeShmImage(int width, int height) { QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window()); QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow()); #ifdef DONT_USE_MIT_SHM shm_img = QImage(width, height, win->format()); #else if (image_info) image_info->destroy(); else image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay()); XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0, &image_info->shminfo, width, height); image_info->shminfo.shmid = shmget (IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777); image_info->shminfo.shmaddr = image->data = (char*)shmat (image_info->shminfo.shmid, 0, 0); image_info->shminfo.readOnly = False; image_info->image = image; Status shm_attach_status = XShmAttach(screen->display()->nativeDisplay(), &image_info->shminfo); Q_ASSERT(shm_attach_status == True); shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() ); #endif painted = false; }
static int setup_shm(AVFormatContext *s, Display *dpy, XImage **image) { X11GrabContext *g = s->priv_data; int scr = XDefaultScreen(dpy); XImage *img = XShmCreateImage(dpy, DefaultVisual(dpy, scr), DefaultDepth(dpy, scr), ZPixmap, NULL, &g->shminfo, g->width, g->height); g->shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT | 0777); if (g->shminfo.shmid == -1) { av_log(s, AV_LOG_ERROR, "Cannot get shared memory!\n"); return AVERROR(ENOMEM); } g->shminfo.shmaddr = img->data = shmat(g->shminfo.shmid, 0, 0); g->shminfo.readOnly = False; if (!XShmAttach(dpy, &g->shminfo)) { av_log(s, AV_LOG_ERROR, "Failed to attach shared memory!\n"); /* needs some better error subroutine :) */ return AVERROR(EIO); } *image = img; return 0; }
void X11_InitXShm(void){ XImage *ximage; X11_shminfo=calloc(1,sizeof(XShmSegmentInfo)); ximage=XShmCreateImage( x11_display, (Visual *)DefaultVisual(x11_display,x11_screen), (unsigned int)DefaultDepth(x11_display,x11_screen), (int)XYPixmap, (char *)NULL, X11_shminfo, (unsigned int)DisplayWidth(x11_display,x11_screen), (unsigned int)(DisplayHeight(x11_display,x11_screen)) ); X11_shminfo->shmid=shmget( IPC_PRIVATE, ximage->bytes_per_line * ximage->height, IPC_CREAT|0777 ); X11_shminfo->shmaddr=ximage->data=shmat(X11_shminfo->shmid,0,0); X11_shminfo->readOnly=False; XShmAttach(x11_display,X11_shminfo); }
bool prepareImage(int w, int h) { if (xv_image_width == w && xv_image_height == h && xv_image) return true; xv_image_width = w; xv_image_height = h; #ifdef _XSHM_H_ if (use_shm) { xv_image = XvShmCreateImage(display, xv_port, format_id, 0, xv_image_width, xv_image_height, &shm); shm.shmid = shmget(IPC_PRIVATE, xv_image->data_size, IPC_CREAT | 0777); if (shm.shmid < 0) { qCritical("get shm failed. try to use none shm"); use_shm = false; } else { shm.shmaddr = (char *)shmat(shm.shmid, 0, 0); xv_image->data = shm.shmaddr; shm.readOnly = 0; if (XShmAttach(display, &shm)) { XSync(display, false); shmctl(shm.shmid, IPC_RMID, 0); } else { qCritical("Attach to shm failed! try to use none shm"); use_shm = false; } } } #endif //_XSHM_H_ if (!use_shm) { xv_image = XvCreateImage(display, xv_port, format_id, 0, xv_image_width, xv_image_height); // malloc if use copy (e.g. shm) xv_image->data = (char*)malloc(xv_image->data_size); } return true; }
static void try_mitshm(_THIS, SDL_Surface *screen) { if(!use_mitshm) return; shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, IPC_CREAT | 0777); if ( shminfo.shmid >= 0 ) { shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); shminfo.readOnly = False; if ( shminfo.shmaddr != (char *)-1 ) { shm_error = False; X_handler = XSetErrorHandler(shm_errhandler); XShmAttach(SDL_Display, &shminfo); XSync(SDL_Display, True); XSetErrorHandler(X_handler); if ( shm_error ) shmdt(shminfo.shmaddr); } else { shm_error = True; } shmctl(shminfo.shmid, IPC_RMID, NULL); } else { shm_error = True; } if ( shm_error ) use_mitshm = 0; if ( use_mitshm ) screen->pixels = shminfo.shmaddr; }
void X11Grabber::setupResources() { if(_XShmAvailable && !_useXGetImage) { _xImage = XShmCreateImage(_x11Display, _windowAttr.visual, _windowAttr.depth, ZPixmap, NULL, &_shminfo, _croppedWidth, _croppedHeight); _shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777); _xImage->data = (char*)shmat(_shminfo.shmid,0,0); _shminfo.shmaddr = _xImage->data; _shminfo.readOnly = False; XShmAttach(_x11Display, &_shminfo); } if (_XRenderAvailable && !_useXGetImage) { if(_XShmPixmapAvailable) { _pixmap = XShmCreatePixmap(_x11Display, _window, _xImage->data, &_shminfo, _croppedWidth, _croppedHeight, _windowAttr.depth); } else { _pixmap = XCreatePixmap(_x11Display, _window, _croppedWidth, _croppedHeight, _windowAttr.depth); } _srcFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual); _dstFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual); _srcPicture = XRenderCreatePicture(_x11Display, _window, _srcFormat, CPRepeat, &_pictAttr); _dstPicture = XRenderCreatePicture(_x11Display, _pixmap, _dstFormat, CPRepeat, &_pictAttr); XRenderSetPictureFilter(_x11Display, _srcPicture, FilterBilinear, NULL, 0); } }
int bg_x11_window_create_shm(bg_x11_window_t * win, XShmSegmentInfo * shminfo, int size) { shmerror = 0; shminfo->shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); if (shminfo->shmid == -1) goto error; shminfo->shmaddr = (char *) shmat (shminfo->shmid, 0, 0); if (shminfo->shmaddr == (char *)-1) goto error; XSync (win->dpy, False); XSetErrorHandler (handle_error); shminfo->readOnly = True; if(!(XShmAttach (win->dpy, shminfo))) shmerror = 1; XSync (win->dpy, False); XSetErrorHandler(NULL); if(shmerror) { error: bg_log(BG_LOG_DEBUG, LOG_DOMAIN, "Cannot create shared memory"); return 0; } return 1; }
static Bool NestedClientTryXShm(NestedClientPrivatePtr pPriv, int scrnIndex, int width, int height, int depth) { int shmMajor, shmMinor; Bool hasSharedPixmaps; if (!XShmQueryExtension(pPriv->display)) { xf86DrvMsg(scrnIndex, X_INFO, "XShmQueryExtension failed. Dropping XShm support.\n"); return FALSE; } if (XShmQueryVersion(pPriv->display, &shmMajor, &shmMinor, &hasSharedPixmaps)) { xf86DrvMsg(scrnIndex, X_INFO, "XShm extension version %d.%d %s shared pixmaps\n", shmMajor, shmMinor, (hasSharedPixmaps) ? "with" : "without"); } pPriv->img = XShmCreateImage(pPriv->display, DefaultVisualOfScreen(pPriv->screen), depth, ZPixmap, NULL, /* data */ &pPriv->shminfo, width, height); if (!pPriv->img) { xf86DrvMsg(scrnIndex, X_ERROR, "XShmCreateImage failed. Dropping XShm support.\n"); return FALSE; } /* XXX: change the 0777 mask? */ pPriv->shminfo.shmid = shmget(IPC_PRIVATE, pPriv->img->bytes_per_line * pPriv->img->height, IPC_CREAT | 0777); if (pPriv->shminfo.shmid == -1) { xf86DrvMsg(scrnIndex, X_ERROR, "shmget failed. Dropping XShm support.\n"); XDestroyImage(pPriv->img); return FALSE; } pPriv->shminfo.shmaddr = (char *)shmat(pPriv->shminfo.shmid, NULL, 0); if (pPriv->shminfo.shmaddr == (char *) -1) { xf86DrvMsg(scrnIndex, X_ERROR, "shmaddr failed. Dropping XShm support.\n"); XDestroyImage(pPriv->img); return FALSE; } pPriv->img->data = pPriv->shminfo.shmaddr; pPriv->shminfo.readOnly = FALSE; XShmAttach(pPriv->display, &pPriv->shminfo); pPriv->usingShm = TRUE; return TRUE; }
static Bool XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy) { if (pdp->ximage) { XDestroyImage(pdp->ximage); pdp->ximage = NULL; } if (!xshm_error && shmid >= 0) { pdp->shminfo.shmid = shmid; pdp->ximage = XShmCreateImage(dpy, pdp->visinfo->visual, pdp->visinfo->depth, ZPixmap, /* format */ NULL, /* data */ &pdp->shminfo, /* shminfo */ 0, 0); /* width, height */ if (pdp->ximage != NULL) { int (*old_handler)(Display *, XErrorEvent *); /* dispatch pending errors */ XSync(dpy, False); old_handler = XSetErrorHandler(handle_xerror); /* This may trigger the X protocol error we're ready to catch: */ XShmAttach(dpy, &pdp->shminfo); XSync(dpy, False); if (xshm_error) { /* we are on a remote display, this error is normal, don't print it */ XDestroyImage(pdp->ximage); pdp->ximage = NULL; } (void) XSetErrorHandler(old_handler); } } if (pdp->ximage == NULL) { pdp->shminfo.shmid = -1; pdp->ximage = XCreateImage(dpy, pdp->visinfo->visual, pdp->visinfo->depth, ZPixmap, 0, /* format, offset */ NULL, /* data */ 0, 0, /* width, height */ 32, /* bitmap_pad */ 0); /* bytes_per_line */ } /** * swrast does not handle 24-bit depth with 24 bpp, so let X do the * the conversion for us. */ if (pdp->ximage->bits_per_pixel == 24) pdp->ximage->bits_per_pixel = 32; return True; }
DFBResult dfb_x11_image_init_handler( x11Image *image ) { XImage *ximage; D_MAGIC_ASSERT( image, x11Image ); XLockDisplay( dfb_x11->display ); ximage = XShmCreateImage( dfb_x11->display, image->visual, image->depth, ZPixmap, NULL, &image->seginfo, image->width, image->height ); if (!ximage) { D_ERROR( "X11/ShmImage: Error creating shared image (XShmCreateImage)!\n"); XUnlockDisplay( dfb_x11->display ); return DFB_FAILURE; } /* we firstly create our shared memory segment with the size we need, and correct permissions for the owner, the group and the world --> 0777 */ image->seginfo.shmid = shmget( IPC_PRIVATE, ximage->bytes_per_line * ximage->height, IPC_CREAT | 0777 ); if (image->seginfo.shmid < 0) goto error; /* Then, we have to attach the segment to our process, and we let the function search the correct memory place --> NULL. It's safest ! */ image->seginfo.shmaddr = shmat( image->seginfo.shmid, NULL, 0 ); if (!image->seginfo.shmaddr) goto error_shmat; ximage->data = image->seginfo.shmaddr; /* We set the buffer in Read and Write mode */ image->seginfo.readOnly = False; if (!XShmAttach( dfb_x11->display, &image->seginfo )) goto error_xshmattach; image->ximage = ximage; XUnlockDisplay( dfb_x11->display ); return DFB_OK; error_xshmattach: shmdt( image->seginfo.shmaddr ); error_shmat: shmctl( image->seginfo.shmid, IPC_RMID, NULL ); error: XDestroyImage( ximage ); XUnlockDisplay( dfb_x11->display ); return DFB_FAILURE; }
QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /* isTextBuffer */, QWidget *widget) : xshmimg(0), xshmpm(0) { if (!X11->use_mitshm) { image = QImage(width, height, format); // follow good coding practice and set xshminfo attributes, though values not used in this case xshminfo.readOnly = true; xshminfo.shmaddr = 0; xshminfo.shmid = 0; xshminfo.shmseg = 0; return; } QX11Info info = widget->x11Info(); int dd = info.depth(); Visual *vis = (Visual*) info.visual(); xshmimg = XShmCreateImage(X11->display, vis, dd, ZPixmap, 0, &xshminfo, width, height); if (!xshmimg) { qWarning("QNativeImage: Unable to create shared XImage."); return; } bool ok; xshminfo.shmid = shmget(IPC_PRIVATE, xshmimg->bytes_per_line * xshmimg->height, IPC_CREAT | 0777); ok = xshminfo.shmid != -1; if (ok) { xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0); xshminfo.shmaddr = xshmimg->data; ok = (xshminfo.shmaddr != (char*)-1); if (ok) image = QImage((uchar *)xshmimg->data, width, height, systemFormat()); } xshminfo.readOnly = false; if (ok) ok = XShmAttach(X11->display, &xshminfo); if (!ok) { qWarning() << "QNativeImage: Unable to attach to shared memory segment."; if (xshmimg->data) { free(xshmimg->data); xshmimg->data = 0; } XDestroyImage(xshmimg); xshmimg = 0; if (xshminfo.shmaddr) shmdt(xshminfo.shmaddr); if (xshminfo.shmid != -1) shmctl(xshminfo.shmid, IPC_RMID, 0); return; } xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data, &xshminfo, width, height, dd); if (!xshmpm) { qWarning() << "QNativeImage: Unable to create shared Pixmap."; } }
x11_shm_image_class * x11_shm_extension_actual_class::create_shm_image(Display * display, Window window, GC gc, Visual * X_visual, int visual_depth, w16 &width, w16 &height) // actual width and height set by X are returned { width=(width+3)&(~3); x11_shm_image_actual_class * im=new x11_shm_image_actual_class(display,window,gc); im->im = XShmCreateImage(display, X_visual, visual_depth, ZPixmap, 0, &im->X_shminfo, width, height ); // create the shared memory segment im->X_shminfo.shmid = shmget( IPC_PRIVATE, width*height*((visual_depth+7)/8), IPC_CREAT | 0777 ); if (im->X_shminfo.shmid<0) { i4_error("x11_shm_extension_actual_class::create_shm_image() - shmget() failed"); } im->X_shminfo.readOnly=False; // attach to the shared memory segment to us im->im->data = im->X_shminfo.shmaddr = (char *) shmat(im->X_shminfo.shmid, 0, 0); if (!im->im->data) { i4_error("x11_shm_extension_actual_class::create_shm_image() - shmget() failed"); } // get the X server to attach to it to the X server if (!XShmAttach(display, &im->X_shminfo)) { i4_error("x11_shm_extension_actual_class::create_shm_image() - XShmAttach() failed"); } XSync(display,False); // make sure segment gets attached if (shmctl(im->X_shminfo.shmid,IPC_RMID,NULL)!=0) { i4_error("x11_shm_extension_actual_class::create_shm_image() - shmctl() failed"); } im->data=(w8 *) (im->im->data); return im; }
void XWindow::ShmAttach(int imageWidth, int imageHeight) { if (_useShm) { _XImage = XShmCreateImage(_display, _XVInfo.visual, _depth, ZPixmap, NULL, &_XShmInfo, imageWidth, imageHeight); if (_XImage == NULL) { PTRACE(1, "X11\tXShmCreateImage failed"); _useShm = FALSE; } } if (_useShm) { _XShmInfo.shmid = shmget(IPC_PRIVATE, _XImage->bytes_per_line * _XImage->height, IPC_CREAT | 0777); if (_XShmInfo.shmid < 0) { XDestroyImage(_XImage); _XImage = NULL; PTRACE(1, "X11\tshmget failed"); //strerror(errno) _useShm = FALSE; } } if (_useShm) { _XShmInfo.shmaddr = (char *) shmat(_XShmInfo.shmid, 0, 0); if (_XShmInfo.shmaddr == ((char *) -1)) { XDestroyImage(_XImage); _XImage = NULL; PTRACE(1, "X11\tshmat failed"); //strerror(errno) _useShm = FALSE; } } if (_useShm) { _XImage->data = _XShmInfo.shmaddr; _XShmInfo.readOnly = False; // Attaching the shared memory to the display XErrorHandler oldHandler = XSetErrorHandler((XErrorHandler) catchXShmError); Status status = XShmAttach (_display, &_XShmInfo); XSync(_display, False); XSetErrorHandler((XErrorHandler) oldHandler); if ( (status != True) || (_shmError) ) { XDestroyImage(_XImage); _XImage = NULL; if (_XShmInfo.shmaddr != ((char *) -1)) { shmdt(_XShmInfo.shmaddr); } PTRACE(1, "X11\t XShmAttach failed"); if ( (status == True) && (_shmError) ) { PTRACE(1, "X11\t X server supports SHM but apparently we are remotely connected..."); } _useShm = false; } } if (_useShm) { shmctl(_XShmInfo.shmid, IPC_RMID, 0); } }
XvImage* create_yuv_image(Display* display, XvPortID port, fourcc_t format, int width, int height, XShmSegmentInfo* shminfo) { XvImage* image; if (shminfo) { if (!(image = XvShmCreateImage(display, port, format.id, NULL, width, height, shminfo))) { printf("Unable to create shm XvImage\n"); return NULL; } if ((shminfo->shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777)) == -1) { printf("Unable to allocate shared memory\n"); XFree(image); return NULL; } if (!(shminfo->shmaddr = shmat(shminfo->shmid, 0, 0))) { printf("Unable to attach shared memory\n"); XFree(image); shmctl(shminfo->shmid, IPC_RMID, 0); return NULL; } shminfo->readOnly = False; image->data = shminfo->shmaddr; if (!XShmAttach(display, shminfo)) { printf("XShmAttach failed\n"); XFree(image); shmctl(shminfo->shmid, IPC_RMID, 0); shmdt(shminfo->shmaddr); return NULL; } /* Send image to X server. This instruction is required, since having * built a Shm XImage and not using it causes an error on XCloseDisplay. */ XSync(display, False); /* Mark the segment to be automatically removed when the last attachment is broken (i.e. on shmdt or process exit). */ shmctl(shminfo->shmid, IPC_RMID, 0); } else { if (!(image = XvCreateImage(display, port, format.id, NULL, width, height))) { printf("Unable to create XvImage\n"); return NULL; } image->data = malloc(image->data_size); } return image; }
static void GetShmPixmap () { shared_len = xWidth*xHeight; shminfo.shmid = shmget (IPC_PRIVATE, shared_len, IPC_CREAT | 0777); if (shminfo.shmid < 0) { fprintf (stderr, "Couldn't get X shared memory.\n"); exit (-1); } /* We need to protect our shared memory against orphanage if we are killed in this function. */ shminfo.shmaddr = (char *) shmat (shminfo.shmid, 0, 0); shared_mem = (char *) shminfo.shmaddr; if (shminfo.shmaddr == (char *) -1) { fprintf (stderr, "Couldn't attach to X shared memory.\n"); shmctl (shminfo.shmid, IPC_RMID, 0); exit (-1); } shminfo.readOnly = False; /* Now try to attach it to the X Server */ haderror = False; origErrorHandler = XSetErrorHandler (shmErrorHandler); if (!XShmAttach (dp, &shminfo)) { printf ("attach failed"); } XSync (dp, True); /* wait for error or ok */ XSync (dp, False); /* wait for error or ok */ XSetErrorHandler (origErrorHandler); if (haderror) { if (shmdt (shminfo.shmaddr) < 0) perror ("X shmdt() error"); if (shmctl (shminfo.shmid, IPC_RMID, 0) < 0) perror ("get:X shmctl rmid() error"); exit (-1); } /*memset((void *)backbuf, 0, shared_len); */ memset ((void *) shared_mem, 0, shared_len); /* Create the shared memory Pixmap */ pixmap = (XShmCreatePixmap (dp, wi, shared_mem, &shminfo, xWidth, xHeight, 8)); signal (SIGHUP, XSignalErrorHandler); signal (SIGINT, XSignalErrorHandler); signal (SIGTRAP, XSignalErrorHandler); signal (SIGABRT, XSignalErrorHandler); signal (SIGSEGV, XSignalErrorHandler); signal (SIGQUIT, XSignalErrorHandler); signal (SIGFPE, XSignalErrorHandler); signal (SIGTERM, XSignalErrorHandler); signal (SIGBUS, XSignalErrorHandler); signal (SIGIOT, XSignalErrorHandler); signal (SIGILL, XSignalErrorHandler); }
static char* captureScreenShotX(int* pwidth, int* pheight, screenshot_data* sdata) { Window root; // Atom atom_rotation; sdata->dpy = XOpenDisplay(NULL); if(unlikely(sdata->dpy == NULL)) { // XOpenDisplay failed! return NULL; } *pwidth = DisplayWidth(sdata->dpy, DefaultScreen(sdata->dpy)); *pheight = DisplayHeight(sdata->dpy, DefaultScreen(sdata->dpy)); root = RootWindow(sdata->dpy, DefaultScreen(sdata->dpy)); sdata->ximage = XShmCreateImage(sdata->dpy, DefaultVisualOfScreen (DefaultScreenOfDisplay (sdata->dpy)), 24, ZPixmap, NULL, &sdata->x_shm_info, (unsigned int)*pwidth, (unsigned int)*pheight); if(sdata->ximage != NULL) { sdata->x_shm_info.shmid = shmget(IPC_PRIVATE, sdata->ximage->bytes_per_line * sdata->ximage->height, IPC_CREAT | 0777); sdata->x_shm_info.shmaddr = sdata->ximage->data = shmat(sdata->x_shm_info.shmid, 0, 0); sdata->x_shm_info.readOnly = False; if(XShmAttach(sdata->dpy, &sdata->x_shm_info)) { if(XShmGetImage(sdata->dpy, root, sdata->ximage, 0, 0, AllPlanes)) { XSync (sdata->dpy, False); return sdata->ximage->data; } else { ; // XShmGetImage failed ! } XShmDetach (sdata->dpy, &sdata->x_shm_info); } else { ; // XShmAttach failed ! } shmdt (sdata->x_shm_info.shmaddr); shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL); XDestroyImage(sdata->ximage); sdata->ximage = NULL; } else { ; // XShmCreateImage failed! } return NULL; }
static bool allocate_xvimage(struct vo *vo, int foo) { struct xvctx *ctx = vo->priv; struct vo_x11_state *x11 = vo->x11; // align it for faster OSD rendering (draw_bmp.c swscale usage) int aligned_w = FFALIGN(ctx->image_width, 32); #if HAVE_SHM if (x11->display_is_local && XShmQueryExtension(x11->display)) { ctx->Shmem_Flag = 1; x11->ShmCompletionEvent = XShmGetEventBase(x11->display) + ShmCompletion; } else { ctx->Shmem_Flag = 0; MP_INFO(vo, "Shared memory not supported\nReverting to normal Xv.\n"); } if (ctx->Shmem_Flag) { ctx->xvimage[foo] = (XvImage *) XvShmCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height, &ctx->Shminfo[foo]); if (!ctx->xvimage[foo]) return false; ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE, ctx->xvimage[foo]->data_size, IPC_CREAT | 0777); ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, 0); if (ctx->Shminfo[foo].shmaddr == (void *)-1) return false; ctx->Shminfo[foo].readOnly = False; ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; XShmAttach(x11->display, &ctx->Shminfo[foo]); XSync(x11->display, False); shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { ctx->xvimage[foo] = (XvImage *) XvCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height); if (!ctx->xvimage[foo]) return false; ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size); if (!ctx->xvimage[foo]->data) return false; XSync(x11->display, False); } struct mp_image img = get_xv_buffer(vo, foo); img.w = aligned_w; mp_image_clear(&img, 0, 0, img.w, img.h); return true; }
static int tc_x11source_init_shm(TCX11Source *handle) { Status ret; ret = XMatchVisualInfo(handle->dpy, handle->screen, handle->depth, DirectColor, &handle->vis_info); if (!ret) { tc_log_error(__FILE__, "Can't match visual information"); goto xshm_failed; } handle->image = XShmCreateImage(handle->dpy, handle->vis_info.visual, handle->depth, ZPixmap, NULL, &handle->shm_info, handle->width, handle->height); if (handle->image == NULL) { tc_log_error(__FILE__, "XShmCreateImage failed."); goto xshm_failed_image; } handle->shm_info.shmid = shmget(IPC_PRIVATE, handle->image->bytes_per_line * handle->image->height, IPC_CREAT | 0777); if (handle->shm_info.shmid < 0) { tc_log_error(__FILE__, "failed to create shared memory segment"); goto xshm_failed_image; } handle->shm_info.shmaddr = shmat(handle->shm_info.shmid, NULL, 0); if (handle->shm_info.shmaddr == (void*)-1) { tc_log_error(__FILE__, "failed to attach shared memory segment"); goto xshm_failed_image; } shmctl(handle->shm_info.shmid, IPC_RMID, 0); /* XXX */ handle->image->data = handle->shm_info.shmaddr; handle->shm_info.readOnly = False; ret = XShmAttach(handle->dpy, &handle->shm_info); if (!ret) { tc_log_error(__FILE__, "failed to attach SHM to Xserver"); goto xshm_failed_image; } XSync(handle->dpy, False); handle->mode = TC_X11_MODE_SHM; handle->acquire_image = tc_x11source_acquire_image_shm; handle->fini = tc_x11source_fini_shm; return 0; xshm_failed_image: XDestroyImage(handle->image); handle->image = NULL; xshm_failed: return -1; }
// ---------------------------------------------------------------------------------------------- // Put 'Image' to window. // ---------------------------------------------------------------------------------------------- void wsImageCreate(wsWindow *win, int w, int h) { #ifdef HAVE_SHM if (wsUseXShm) { win->xImage = XShmCreateImage(wsDisplay, win->VisualInfo.visual, win->VisualInfo.depth, ZPixmap, NULL, &win->Shminfo, w, h); if (win->xImage == NULL) { mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } win->Shminfo.shmid = shmget(IPC_PRIVATE, win->xImage->bytes_per_line * win->xImage->height, IPC_CREAT | 0777); if (win->Shminfo.shmid < 0) { XDestroyImage(win->xImage); mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } win->Shminfo.shmaddr = (char *)shmat(win->Shminfo.shmid, 0, 0); if (win->Shminfo.shmaddr == ((char *)-1)) { XDestroyImage(win->xImage); if (win->Shminfo.shmaddr != ((char *)-1)) shmdt(win->Shminfo.shmaddr); mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } win->xImage->data = win->Shminfo.shmaddr; win->Shminfo.readOnly = False; XShmAttach(wsDisplay, &win->Shminfo); XSync(wsDisplay, False); shmctl(win->Shminfo.shmid, IPC_RMID, 0); } else #endif { win->xImage = XCreateImage(wsDisplay, win->VisualInfo.visual, win->VisualInfo.depth, ZPixmap, 0, 0, w, h, (wsScreenDepth == 3) ? 32 : wsScreenDepth, 0); if ((win->xImage->data = malloc(win->xImage->bytes_per_line * win->xImage->height)) == NULL) { mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_NotEnoughMemoryDrawBuffer); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } } win->ImageData = (unsigned char *)win->xImage->data; win->ImageDataw = (unsigned short int *)win->xImage->data; win->ImageDatadw = (unsigned int *)win->xImage->data; }
int vs_show (void *ctx, const uint8_t *const data[4], int stride[4]) { // 首选检查 sws 是否有效, 根据当前窗口大小决定 Ctx *c = (Ctx*)ctx; Window root; int x, y; unsigned int cx, cy, border, depth; XGetGeometry(c->display, c->window, &root, &x, &y, &cx, &cy, &border, &depth); if (cx != c->curr_width || cy != c->curr_height) { avpicture_free(&c->pic_target); sws_freeContext(c->sws); c->sws = sws_getContext(c->v_width, c->v_height, PIX_FMT_YUV420P, cx, cy, c->target_pixfmt, SWS_FAST_BILINEAR, 0, 0, 0); avpicture_alloc(&c->pic_target, c->target_pixfmt, cx, cy); c->curr_width = cx; c->curr_height = cy; // re create image XShmDetach(c->display, &c->segment); shmdt(c->segment.shmaddr); shmctl(c->segment.shmid, IPC_RMID, 0); XDestroyImage(c->image); c->image = XShmCreateImage(c->display, c->vinfo.visual, depth, ZPixmap, 0, &c->segment, cx, cy); c->segment.shmid = shmget(IPC_PRIVATE, c->image->bytes_per_line * c->image->height, IPC_CREAT | 0777); c->segment.shmaddr = (char*)shmat(c->segment.shmid, 0, 0); c->image->data = c->segment.shmaddr; c->segment.readOnly = 0; XShmAttach(c->display, &c->segment); } // sws_scale(c->sws, data, stride, 0, c->v_height, c->pic_target.data, c->pic_target.linesize); // cp to image unsigned char *p = c->pic_target.data[0], *q = (unsigned char*)c->image->data; int xx = MIN(c->image->bytes_per_line, c->pic_target.linesize[0]); for (int i = 0; i < c->curr_height; i++) { memcpy(q, p, xx); p += c->image->bytes_per_line; q += c->pic_target.linesize[0]; } // 显示到 X 上 XShmPutImage(c->display, c->window, c->gc, c->image, 0, 0, 0, 0, c->curr_width, c->curr_height, 1); return 1; }
/* Allocate a pixmap for internal representation * of the given bitmap, using SHM if possible. */ g_error x11_new_bitmap_pixmap(struct x11bitmap *xb) { g_error e; /* Nothing to create? */ if (!(xb->sb.w && xb->sb.h && xb->sb.bpp)) return success; if (x11_using_shm) { /* FIXME: This assumes that the pitch is padded to the * nearest DWORD, like it is in current implementations * of XFree86. This should instead use an XImage * to determine the proper pitch. */ xb->sb.pitch = (((xb->sb.w * xb->sb.bpp)>>3) + 3) & ~3; /* Set up us the SHM segment! * FIXME: These SHM segments are insecure! Is there any way to have the X server, * pgserver, and the client all share the segments without making them * accessable to everyone? */ memset(&xb->shminfo, 0, sizeof(xb->shminfo)); e = os_shm_alloc(&xb->sb.bits, xb->sb.pitch * xb->sb.h, &xb->sb.shm_id, &xb->shm_key, 0); errorcheck; xb->shminfo.shmaddr = xb->sb.bits; xb->shminfo.shmid = xb->sb.shm_id; xb->shminfo.readOnly = False; /* Get the X server to attach this segment to a pixmap */ XShmAttach(x11_display, &xb->shminfo); xb->d = XShmCreatePixmap(x11_display, RootWindow(x11_display, x11_screen), xb->sb.bits,&xb->shminfo,xb->sb.w,xb->sb.h, DefaultDepth(x11_display,x11_screen)); /* Set the VBL used to draw to the SHM bitmap directly */ switch (xb->sb.bpp) { #ifdef CONFIG_VBL_LINEAR16 case 16: xb->lib = &x11_vbl_linear16; break; #endif #ifdef CONFIG_VBL_LINEAR32 case 32: xb->lib = &x11_vbl_linear32; break; #endif default: xb->lib = NULL; } } else {
void createShmImage(int w, int h, XShmSegmentInfo * sinfo, XShmSegmentInfo * tinfo, Display * sdpy, Display * tdpy, int sscr, int tscr, XImage ** simage, XImage ** timage) { sinfo->shmid=tinfo->shmid=shmget(IPC_PRIVATE,w*h*sizeof(unsigned),IPC_CREAT|0666 ); sinfo->shmaddr=tinfo->shmaddr=(char*)shmat(sinfo->shmid,0,0); sinfo->readOnly=tinfo->readOnly=False; printf("%d %d\n",DefaultDepth(sdpy,sscr),DefaultDepth(tdpy,tscr)); *simage = XShmCreateImage( sdpy, DefaultVisual(sdpy,sscr), DefaultDepth(sdpy,sscr), ZPixmap/*format*/, (char *)sinfo->shmaddr, sinfo, w,h /*width,height*/ ); *timage = XShmCreateImage( tdpy, DefaultVisual(tdpy,tscr), DefaultDepth(tdpy,tscr), ZPixmap/*format*/, (char *)tinfo->shmaddr, tinfo, w,h /*width,height*/ ); XShmAttach(sdpy, sinfo); XShmAttach(tdpy, tinfo); }
static int shminit(void) { static int ntries; shmimage = XShmCreateImage( display, visual, DefaultDepth(display, 0), ZPixmap, NULL, &shminfo, width, height ); if(shmimage == NULL){ fprintf(stderr, "shminit: cannot create shmimage\n"); return -1; } shminfo.shmid = shmget( IPC_PRIVATE, shmimage->bytes_per_line*shmimage->height, IPC_CREAT | 0600 ); if(shminfo.shmid == -1){ fprintf(stderr, "shminit: shmget fail, tries %d, errno %d: %s\n", ntries, errno, strerror(errno)); fprintf(stderr, "If you are on a mac, this is probably due to sysctls kern.sysv.shmmax and kern.sysv.shmall being too small\n"); fprintf(stderr, "Try something like kern.sysv.shmmax=67108864 and kern.sysv.shmall=16384\n"); XDestroyImage(shmimage); return -1; } shminfo.shmaddr = shmimage->data = shmat(shminfo.shmid, NULL, 0); if(shminfo.shmaddr == (void *)-1){ fprintf(stderr, "shminit: shmat fail, errno %d: %s\n", errno, strerror(errno)); return -1; } shminfo.readOnly = False; XShmAttach(display, &shminfo); framebuffer = (uchar *)shmimage->data; stride = shmimage->bytes_per_line; if(shmimage->bits_per_pixel < 24){ screen.r = rect(0,0,shmimage->width,shmimage->height); screen.stride = shmimage->width*4; screen.len = shmimage->height*screen.stride; screen.img = malloc(screen.len); } else { screen.r = rect(0,0,shmimage->width,shmimage->height); screen.stride = shmimage->bytes_per_line; screen.img = (uchar *)shmimage->data; screen.len = shmimage->bytes_per_line*shmimage->height; } ntries++; return 0; }
// gcc -Wall x11shot2.c -o x11shot2 -lX11 -lX11ext -lpng;./x11shot2 <wid> >/tmp/screenshot.png int main(int argc,char* argv[]){ if(argc<2){ fprintf(stderr, "usage:x11shot2 <wid> >/tmp/screenshot.png\n"); exit(1); } int wid=(int)strtol(argv[1], NULL, 0); sscanf(argv[1], "%x", &wid); XShmSegmentInfo shminfo; int x_off=0,y_off=0; Display *dpy=XOpenDisplay(getenv("DISPLAY")); XImage *image; XWindowAttributes wattr; if (dpy == NULL) { fprintf(stderr, "Cannot open display\n"); exit(1); } XGetWindowAttributes(dpy,wid,&wattr); fprintf(stderr,"wid:0x%x wattr x:%d y:%d w:%d h:%d begin capture\n" ,wid ,wattr.x,wattr.y ,wattr.width,wattr.height); if(!XShmQueryExtension(dpy)){ fprintf(stderr, "can't not use shm!\n"); exit(1); } int scr = XDefaultScreen(dpy); image = XShmCreateImage(dpy, DefaultVisual(dpy, scr), DefaultDepth(dpy, scr), ZPixmap, NULL, &shminfo, wattr.width,wattr.height); shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777); shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0); shminfo.readOnly = False; if (!XShmAttach(dpy, &shminfo)) { fprintf(stderr, "Fatal: Failed to attach shared memory!\n"); exit(1); } if(!XShmGetImage(dpy,wid,image,x_off,y_off,AllPlanes)) { die("Can't get image"); } pngstdout(image); XDestroyImage(image); return 0; };
void QGstXvImageBufferPool::doAlloc() { //should be always called from the main thread with m_poolMutex locked //Q_ASSERT(QThread::currentThread() == thread()); XSync(QX11Info::display(), false); QGstXvImageBuffer *xvBuffer = (QGstXvImageBuffer *)gst_mini_object_new(QGstXvImageBuffer::get_type()); quint64 portId = m_format.property("portId").toULongLong(); int xvFormatId = m_format.property("xvFormatId").toInt(); xvBuffer->xvImage = XvShmCreateImage( QX11Info::display(), portId, xvFormatId, 0, m_format.frameWidth(), m_format.frameHeight(), &xvBuffer->shmInfo ); if (!xvBuffer->xvImage) { qWarning() << "QGstXvImageBufferPool: XvShmCreateImage failed"; return; } XSync(QX11Info::display(), false); xvBuffer->shmInfo.shmid = shmget(IPC_PRIVATE, xvBuffer->xvImage->data_size, IPC_CREAT | 0777); xvBuffer->shmInfo.shmaddr = xvBuffer->xvImage->data = (char*)shmat(xvBuffer->shmInfo.shmid, 0, 0); xvBuffer->shmInfo.readOnly = False; if (!XShmAttach(QX11Info::display(), &xvBuffer->shmInfo)) { qWarning() << "QGstXvImageBufferPool: XShmAttach failed"; return; } XSync(QX11Info::display(), false); shmctl (xvBuffer->shmInfo.shmid, IPC_RMID, NULL); xvBuffer->pool = this; GST_MINI_OBJECT_CAST(xvBuffer)->flags = 0; gst_buffer_set_caps(GST_BUFFER_CAST(xvBuffer), m_caps); GST_BUFFER_DATA(xvBuffer) = (uchar*)xvBuffer->xvImage->data; GST_BUFFER_SIZE(xvBuffer) = xvBuffer->xvImage->data_size; m_allBuffers.append(xvBuffer); m_pool.append(xvBuffer); XSync(QX11Info::display(), false); }