void* icvVideoRender(void* data) { int cameraid = (int)data; CvVideoCamera *const camera = &(cameras[cameraid]); Display* display; int screen_num; GC gc; char* display_name = NULL; Window window = camera->window; XWindowAttributes windowattr; Visual* visual; int windowdepth; XImage* image; XShmSegmentInfo xshmseg; int width = (camera->renderwidth>0)?camera->renderwidth:camera->videopp.width; int height = camera->renderheight?camera->renderheight:camera->videopp.height; int picturedepth = camera->videopp.picture.depth; int pixelsize; XGCValues values; IplImage* iplimage; time_t start, now; int frames = 0; float rate = 0; Status XShm; uchar* imgdata = NULL; uchar* tmpbuff = NULL; pthread_mutex_lock(&(camera->capturestatemutex)); if(camera->capturestate != CAPTURING) { pthread_mutex_unlock(&(camera->capturestatemutex)); pthread_exit( NULL ); } camera->renderstate=1; pthread_cond_signal(&(camera->capturestatecond)); pthread_mutex_unlock(&(camera->capturestatemutex)); XInitThreads(); if ( (display=XOpenDisplay(display_name)) == NULL ) { fprintf( stderr, "cvVideo: cannot connect to X server %s\n", XDisplayName(display_name)); pthread_exit( NULL ); } screen_num = DefaultScreen(display); if (XGetWindowAttributes(display, window, &windowattr) == 0) { fprintf(stderr, "icvVideoRender: failed to get window attributes.\n" ); pthread_exit(NULL); } if(windowattr.map_state == IsUnmapped) { fprintf(stderr, "icvVideoRender: window is not mapped \n" ); pthread_exit(NULL); } windowdepth = windowattr.depth; visual = windowattr.visual; pixelsize = icvVideoWindowPixelsize(windowdepth); XShm = XShmQueryExtension(display); if(XShm) { image = XShmCreateImage(display, visual, windowdepth, ZPixmap, NULL, &xshmseg, width, height ); assert(image); xshmseg.shmid = shmget (IPC_PRIVATE, width*height*pixelsize, IPC_CREAT|0777); assert(xshmseg.shmid != -1); xshmseg.shmaddr = image->data=(char*)shmat (xshmseg.shmid, 0, 0) ; xshmseg.readOnly = False; XShmAttach (display, &xshmseg); } else { imgdata = (uchar*)malloc(width*height*icvVideoWindowPixelsize(windowdepth)) ; image = XCreateImage(display, visual, windowdepth, ZPixmap, 0, (char*)imgdata, width, height, 8, icvVideoWindowPixelsize(windowdepth) *width); assert(image); XInitImage(image); } gc = XCreateGC(display,window,0, &values ); #ifdef RENDER_FRAMERATE start = time(NULL); #endif pthread_mutex_lock(&(camera->capturestatemutex)); while((camera->capturestate == CAPTURING) && (camera->rendered)) { pthread_mutex_unlock(&(camera->capturestatemutex)); pthread_mutex_lock(&(camera->updatedmutex)); while(camera->updated == 0) pthread_cond_wait(&(camera->updatedcond), &(camera->updatedmutex)); camera->updated = 0; pthread_mutex_unlock(&(camera->updatedmutex)); if(cvcamGetProperty(cameraid, "raw_image",&iplimage )) { assert(image->data); if(camera->callback != NULL) camera->callback(iplimage); if((width==camera->videopp.width)&& (height==camera->videopp.height)) { icvvConvert(width, height, width*picturedepth/8, picturedepth, iplimage->imageData, width*pixelsize, pixelsize*8, image->data ); cvReleaseImage(&iplimage); } else { tmpbuff = (uchar*)malloc(camera->videopp.width*camera->videopp.height* pixelsize) ; icvvConvert(camera->videopp.width, camera->videopp.height, camera->videopp.width*picturedepth/8, picturedepth, iplimage->imageData, camera->videopp.width*pixelsize, pixelsize*8, (char*)tmpbuff); cvReleaseImage(&iplimage); icvvResizeImage(camera->videopp.width, camera->videopp.height, (camera->videopp.width)*pixelsize, (char*)tmpbuff, width, height,width*pixelsize, image->data, pixelsize*8); free(tmpbuff); } //fprintf(stdout, "cvVideoRendering:image converted!!!!\n"); if(XShm) { XShmPutImage(display, window, gc, image,0,0,0,0, width, height, False); } else { XPutImage(display, window, gc, image,0,0,0,0, width, height); } XSync(display, False); #ifdef RENDER_FRAMERATE now = time(NULL); frames++; if (now-start) rate = frames/(float)(now-start); if((frames%30) == 0) fprintf(stdout, "camera %d fps = %f\n", cameraid, rate); #endif }//if(cvcamGetProperty(CAMERA, "raw_image",&image )) // stop here if we're paused pthread_mutex_lock(&(camera->pausemutex)); pthread_mutex_unlock(&(camera->pausemutex)); pthread_mutex_lock(&(camera->capturestatemutex)); }//while (camera->state == CAPTURING && camera->rendered) pthread_mutex_unlock(&(camera->capturestatemutex)); pthread_mutex_lock(&(camera->capturestatemutex)); #if 0 if(camera->state != CAPTURING) { // we ended because the camera is not capturing anymore while (camera->capturestate != FINISHED ) { pthread_cond_wait(&(camera->capturestatecond),&(camera->capturestatemutex)); } } #endif camera->renderstate=0; pthread_cond_signal(&(camera->capturestatecond)); pthread_mutex_unlock(&(camera->capturestatemutex)); XShmDetach (display, &xshmseg); XDestroyImage (image); XFreeGC(display,gc); shmdt (xshmseg.shmaddr); shmctl (xshmseg.shmid, IPC_RMID, 0); if(imgdata) free(imgdata); pthread_exit(NULL); }
DFBResult dfb_x11_image_destroy_handler( DFBX11 *x11, x11Image *image ) { D_MAGIC_ASSERT( image, x11Image ); XLockDisplay( x11->display ); XFreeGC( x11->display, image->gc ); XFreePixmap( x11->display, image->pixmap ); XShmDetach( x11->display, &image->seginfo ); XDestroyImage( image->ximage ); XUnlockDisplay( x11->display ); shmdt( image->seginfo.shmaddr ); shmctl( image->seginfo.shmid, IPC_RMID, NULL ); return DFB_OK; }
int BC_Capture::delete_data() { if(!display) return 1; if(data) { if(use_shm) { XShmDetach(display, &shm_info); XDestroyImage(ximage); shmdt(shm_info.shmaddr); } else { XDestroyImage(ximage); } // data is automatically freed by XDestroyImage data = 0; delete row_data; } return 0; }
void XvMCOSD::DeleteBuffer() { if (!osd_subpict_alloc) return; X11L; XvMCDestroySubpicture(XJ_disp, &osd_subpict); XShmDetach(XJ_disp, &XJ_osd_shm_info); shmdt(XJ_osd_shm_info.shmaddr); osd_subpict_alloc = false; XFree(osd_xv_image); XFlush(XJ_disp); X11U; usleep(50); X11S(XSync(XJ_disp, false)); if (osd_palette) delete [] osd_palette; }
static void TakedownImage (void) { if (GUI.snes_buffer) { free(GUI.snes_buffer); GUI.snes_buffer = NULL; } if (GUI.filter_buffer) { free(GUI.filter_buffer); GUI.filter_buffer = NULL; } if (GUI.image) { #ifdef MITSHM if (GUI.use_shared_memory) { XShmDetach(GUI.display, &GUI.sm_info); GUI.image->data = NULL; XDestroyImage(GUI.image); if (GUI.sm_info.shmaddr) shmdt(GUI.sm_info.shmaddr); if (GUI.sm_info.shmid >= 0) shmctl(GUI.sm_info.shmid, IPC_RMID, 0); GUI.image = NULL; } else #endif { XDestroyImage(GUI.image); GUI.image = NULL; } } S9xGraphicsDeinit(); }
static void X11_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; X11_TextureData *data = (X11_TextureData *) texture->driverdata; if (!data) { return; } if (data->yuv) { SDL_SW_DestroyYUVTexture(data->yuv); } if (data->pixmap != None) { XFreePixmap(renderdata->display, data->pixmap); } if (data->image) { data->image->data = NULL; XDestroyImage(data->image); } #ifndef NO_SHARED_MEMORY if (data->shminfo.shmaddr) { XShmDetach(renderdata->display, &data->shminfo); XSync(renderdata->display, False); shmdt(data->shminfo.shmaddr); data->pixels = NULL; } #endif if (data->scaling_image) { SDL_free(data->scaling_image->data); data->scaling_image->data = NULL; XDestroyImage(data->scaling_image); } if (data->pixels) { SDL_free(data->pixels); } SDL_free(data); texture->driverdata = NULL; }
static void deallocate_xvimage(struct vo *vo, int foo) { struct xvctx *ctx = vo->priv; #if HAVE_SHM if (ctx->Shmem_Flag) { XShmDetach(vo->x11->display, &ctx->Shminfo[foo]); shmdt(ctx->Shminfo[foo].shmaddr); } else #endif { av_free(ctx->xvimage[foo]->data); } if (ctx->xvimage[foo]) XFree(ctx->xvimage[foo]); ctx->xvimage[foo] = NULL; #if HAVE_SHM ctx->Shminfo[foo] = (XShmSegmentInfo){0}; #endif XSync(vo->x11->display, False); return; }
x11_shm_image_actual_class::~x11_shm_image_actual_class() { XFlush(display); XSync(display,False); // maker sure anything with this image is drawn! // Dettach the memory from the server if (!XShmDetach(display, &X_shminfo)) { i4_error("x11_shm_image_actual_class::~x11_shm_image_actual_class() - XShmDetach() failed"); } XSync(display,False); // maker sure server detached // detach the memory from us, it will be deleted! if (shmdt(X_shminfo.shmaddr)<0) { i4_error("x11_shm_image_actual_class::~x11_shm_image_actual_class() - shmdt() failed"); } im->data=0; // tell X not to try to free the memory, cause we already did. XDestroyImage(im); }
static void up_x11uninitX(void) { fprintf(stderr, "Uninitalizing X\n"); if (g_x11initialized) { #ifndef CONFIG_SIM_X11NOSHM if (g_shmcheckpoint > 4) { XShmDetach(g_display, &g_xshminfo); } if (g_shmcheckpoint > 3) { shmdt(g_xshminfo.shmaddr); } if (g_shmcheckpoint > 2) { shmctl(g_xshminfo.shmid, IPC_RMID, 0); } #endif if (g_shmcheckpoint > 1) { XDestroyImage(g_image); } /* Un-grab the mouse buttons */ #ifdef CONFIG_SIM_TOUCHSCREEN XUngrabButton(g_display, Button1, AnyModifier, g_window); #endif g_x11initialized = 0; } XCloseDisplay(g_display); }
XVWindow::~XVWindow() { unsigned int i = 0; XLockDisplay (_display); #ifdef HAVE_SHM if (_useShm) { for (i = 0; i < NUM_BUFFERS; i++) if (_isInitialized && _XShmInfo[i].shmaddr) { XShmDetach (_display, &_XShmInfo[i]); shmdt (_XShmInfo[i].shmaddr); } } else #endif { for (i = 0; i < NUM_BUFFERS; i++) if ((_XVImage[i]) && (_XVImage[i]->data)) { free (_XVImage[i]->data); _XVImage[i]->data = NULL; } } for (i = 0; i < NUM_BUFFERS; i++) if (_XVImage[i]) { XFree (_XVImage[i]); _XVImage[i] = NULL; } if (_XVPort) { XvUngrabPort (_display, _XVPort, CurrentTime); grabbedPorts.erase(_XVPort); _XVPort = 0; } XUnlockDisplay(_display); }
int image_destroy( IMAGE_CONTEXT *img_ctx ) { if ( img_ctx->xImage == NULL ) return 0; if( img_ctx->isShared ) { if( img_ctx->shmInfo.shmid >= 0 ) { XShmDetach( img_ctx->display, &( img_ctx->shmInfo ) ); shmdt( img_ctx->shmInfo.shmaddr ); img_ctx->shmInfo.shmaddr = NULL; shmctl( img_ctx->shmInfo.shmid, IPC_RMID, 0 ); img_ctx->shmInfo.shmid = -1; } } img_ctx->xImage->data = NULL; XDestroyImage( img_ctx->xImage ); img_ctx->xImage = NULL; if( img_ctx->sharedPixmap != None ) { XFreePixmap( img_ctx->display, img_ctx->sharedPixmap ); img_ctx->sharedPixmap = None; } if( img_ctx->display != NULL ) { XFreeGC( img_ctx->display, img_ctx->gc ); XDestroyWindow( img_ctx->display, img_ctx->window ); img_ctx->display = NULL; } return 0; }
Bool dfb_x11_open_window( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format ) { XWindow *xw; XSetWindowAttributes attr = { .background_pixmap = 0 }; void *old_error_handler = 0; unsigned int cw_mask = CWEventMask; D_DEBUG_AT( X11_Window, "Creating %4dx%4d %s window...\n", iWidth, iHeight, dfb_pixelformat_name(format) ); xw = D_CALLOC( 1, sizeof(XWindow) ); if (!xw) return D_OOM(); /* We set the structure as needed for our window */ xw->width = iWidth; xw->height = iHeight; xw->display = x11->display; xw->screenptr = DefaultScreenOfDisplay(xw->display); xw->screennum = DefaultScreen(xw->display); xw->depth = DefaultDepthOfScreen(xw->screenptr); xw->visual = DefaultVisualOfScreen(xw->screenptr); attr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask; if (dfb_config->x11_borderless) { attr.override_redirect = True; cw_mask |= CWOverrideRedirect; } XLockDisplay( x11->display ); old_error_handler = XSetErrorHandler( error_handler ); error_code = 0; xw->window = XCreateWindow( xw->display, RootWindowOfScreen(xw->screenptr), iXPos, iYPos, iWidth, iHeight, 0, xw->depth, InputOutput, xw->visual, cw_mask, &attr ); XSync( xw->display, False ); if (!xw->window || error_code) { D_FREE( xw ); XUnlockDisplay( x11->display ); return False; } XSizeHints Hints; /* * Here we inform the function of what we are going to change for the * window (there's also PPosition but it's obsolete) */ Hints.flags = PSize | PMinSize | PMaxSize; /* * Now we set the structure to the values we need for width & height. * For esthetic reasons we set Width=MinWidth=MaxWidth. * The same goes for Height. You can try whith differents values, or * let's use Hints.flags=Psize; and resize your window.. */ Hints.min_width = Hints.max_width = Hints.base_width = xw->width; Hints.min_height = Hints.max_height = Hints.base_height = xw->height; /* Now we can set the size hints for the specified window */ XSetWMNormalHints(xw->display,xw->window,&Hints); /* We change the title of the window (default:Untitled) */ XStoreName(xw->display,xw->window,"DFB X11 system window"); xw->gc = XCreateGC(xw->display, xw->window, 0, NULL); #if 0 // Create a null cursor Pixmap pixmp1; Pixmap pixmp2; XColor fore; XColor back; char zero = 0; pixmp1 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 ); pixmp2 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 ); xw->NullCursor = XCreatePixmapCursor( xw->display, pixmp1, pixmp2, &fore, &back, 0, 0 ); XFreePixmap ( xw->display, pixmp1 ); XFreePixmap ( xw->display, pixmp2 ); XDefineCursor( xw->display, xw->window, xw->NullCursor ); #endif /* maps the window and raises it to the top of the stack */ XMapRaised( xw->display, xw->window ); if (x11->use_shm) { // Shared memory xw->shmseginfo=(XShmSegmentInfo *)D_CALLOC(1, sizeof(XShmSegmentInfo)); if (!xw->shmseginfo) { x11->use_shm = false; goto no_shm; } xw->ximage=XShmCreateImage(xw->display, xw->visual, xw->depth, ZPixmap, NULL,xw->shmseginfo, xw->width, xw->height * 2); XSync( xw->display, False ); if (!xw->ximage || error_code) { D_ERROR("X11: Error creating shared image (XShmCreateImage) \n"); x11->use_shm = false; D_FREE(xw->shmseginfo); error_code = 0; goto no_shm; } xw->bpp = (xw->ximage->bits_per_pixel + 7) / 8; /* we firstly create our shared memory segment with the size we need, and correct permissions for the owner, the group and the world --> 0777 */ xw->shmseginfo->shmid=shmget(IPC_PRIVATE, xw->ximage->bytes_per_line * xw->ximage->height * 2, IPC_CREAT|0777); if (xw->shmseginfo->shmid<0) { x11->use_shm = false; XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); goto no_shm; } /* Then, we have to attach the segment to our process, and we let the function search the correct memory place --> NULL. It's safest ! */ xw->shmseginfo->shmaddr = shmat( xw->shmseginfo->shmid, NULL, 0 ); if (!xw->shmseginfo->shmaddr) { x11->use_shm = false; shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL); XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); goto no_shm; } /* We set the buffer in Read and Write mode */ xw->shmseginfo->readOnly=False; xw->virtualscreen= xw->ximage->data = xw->shmseginfo->shmaddr; XSetErrorHandler( error_handler_shm ); XShmAttach(x11->display,xw->shmseginfo); XShmPutImage(x11->display, xw->window, xw->gc, xw->ximage, 0, 0, 0, 0, 1, 1, False); XSync(x11->display, False); XSetErrorHandler( error_handler ); if (!x11->use_shm) { shmdt(xw->shmseginfo->shmaddr); shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL); XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); } } no_shm: if (!x11->use_shm) { int pitch; xw->bpp = (xw->depth > 16) ? 4 : (xw->depth > 8) ? 2 : 1; pitch = (xw->bpp * xw->width + 3) & ~3; /* Use malloc(), not D_MALLOC() here, because XCreateImage() * will call free() on this data. */ xw->virtualscreen = malloc ( 2 * xw->height * pitch ); xw->ximage = XCreateImage( xw->display, xw->visual, xw->depth, ZPixmap, 0, xw->virtualscreen, xw->width, xw->height * 2, 32, pitch ); XSync( xw->display, False ); if (!xw->ximage || error_code) { D_ERROR( "X11/Window: XCreateImage( Visual %02lu, depth %d, size %dx%d, buffer %p [%d] ) failed!\n", xw->visual->visualid, xw->depth, xw->width, xw->height * 2, xw->virtualscreen, pitch ); XFreeGC(xw->display,xw->gc); XDestroyWindow(xw->display,xw->window); XSetErrorHandler( old_error_handler ); XUnlockDisplay( x11->display ); D_FREE( xw ); return False; } } XSetErrorHandler( old_error_handler ); XUnlockDisplay( x11->display ); D_INFO( "X11/Display: %ssing XShm.\n", x11->use_shm ? "U" : "Not u" ); (*ppXW) = xw; return True; } void dfb_x11_close_window( DFBX11 *x11, XWindow* xw ) { if (x11->use_shm) { XShmDetach( xw->display, xw->shmseginfo ); shmdt( xw->shmseginfo->shmaddr ); shmctl( xw->shmseginfo->shmid, IPC_RMID, NULL ); D_FREE( xw->shmseginfo ); } XDestroyImage( xw->ximage ); XFreeGC( xw->display, xw->gc ); XDestroyWindow( xw->display, xw->window ); #if 0 XFreeCursor( xw->display, xw->NullCursor ); #endif D_FREE( xw ); }
static int x11_reset(struct vidisp_st *st, const struct vidsz *sz) { XWindowAttributes attrs; XGCValues gcv; size_t bufsz, pixsz; int err = 0; if (!XGetWindowAttributes(st->disp, st->win, &attrs)) { warning("x11: cant't get window attributes\n"); return EINVAL; } switch (attrs.depth) { case 24: st->pixfmt = VID_FMT_RGB32; pixsz = 4; break; case 16: st->pixfmt = VID_FMT_RGB565; pixsz = 2; break; case 15: st->pixfmt = VID_FMT_RGB555; pixsz = 2; break; default: warning("x11: colordepth not supported: %d\n", attrs.depth); return ENOSYS; } bufsz = sz->w * sz->h * pixsz; if (st->image) { XDestroyImage(st->image); st->image = NULL; } if (st->xshmat) XShmDetach(st->disp, &st->shm); if (st->shm.shmaddr != (char *)-1) shmdt(st->shm.shmaddr); if (st->shm.shmid >= 0) shmctl(st->shm.shmid, IPC_RMID, NULL); st->shm.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0777); if (st->shm.shmid < 0) { warning("x11: failed to allocate shared memory\n"); return ENOMEM; } st->shm.shmaddr = shmat(st->shm.shmid, NULL, 0); if (st->shm.shmaddr == (char *)-1) { warning("x11: failed to attach to shared memory\n"); return ENOMEM; } st->shm.readOnly = true; x11.shm_error = 0; x11.errorh = XSetErrorHandler(error_handler); if (!XShmAttach(st->disp, &st->shm)) { warning("x11: failed to attach X to shared memory\n"); return ENOMEM; } XSync(st->disp, False); XSetErrorHandler(x11.errorh); if (x11.shm_error) info("x11: shared memory disabled\n"); else st->xshmat = true; gcv.graphics_exposures = false; st->gc = XCreateGC(st->disp, st->win, GCGraphicsExposures, &gcv); if (!st->gc) { warning("x11: failed to create graphics context\n"); return ENOMEM; } if (st->xshmat) { st->image = XShmCreateImage(st->disp, attrs.visual, attrs.depth, ZPixmap, st->shm.shmaddr, &st->shm, sz->w, sz->h); } else { st->image = XCreateImage(st->disp, attrs.visual, attrs.depth, ZPixmap, 0, st->shm.shmaddr, sz->w, sz->h, 32, 0); } if (!st->image) { warning("x11: Failed to create X image\n"); return ENOMEM; } XResizeWindow(st->disp, st->win, sz->w, sz->h); st->size = *sz; return err; }
/* FIXME: check for errors. */ int R_render_image_imlib2(struct R_image *image, struct R_window *window, int w, int h, int flags) { unsigned int rendw = 0; unsigned int rendh = 0; int winw = 0; int winh = 0; int copyx = 0; int copyy = 0; int copyw; int copyh; int dummyi; int nx; int ny; unsigned int dummyui; Window dummywin; Pixmap pixmap; int x = 0; int y = 0; static GC rendgc = NULL; #if (USE_XSHM) int shmid; XShmSegmentInfo *shmseg; #endif long factor; int xofs = 0; int yofs = 0; #if 0 if (!image || !image->orig || !window->id) { return -1; } #endif R_free_image_imlib2(image); if (image->flags & R_IMAGE_STATIC_FLAG) { if (image->pixmap) { #if (USE_XSHM) if (image->hasshm) { shmseg = &image->shmseg; XShmDetach(image->app->display, shmseg); shmdt(shmseg->shmaddr); shmctl(shmseg->shmid, IPC_RMID, NULL); shmseg->shmid = -1; shmseg->shmaddr = NULL; image->hasshm = 0; } else { imlib_free_pixmap_and_mask(image->pixmap); } #else imlib_free_pixmap_and_mask(image->pixmap); #endif image->pixmap = image->mask = None; } } imlib_context_set_drawable(window->id); imlib_context_set_image(image->orig); imlib_context_set_mask(image->mask); imlib_context_set_blend(image->flags & R_IMAGE_BLEND_FLAG); if ((flags & R_IMAGE_STRETCH_FLAG) || (flags & R_IMAGE_FILL_FLAG) || w == R_TILE_FIT_IMAGE || h == R_TILE_FIT_IMAGE || w == R_INTEGER_TILE_IMAGE || h == R_INTEGER_TILE_IMAGE || w == R_FIT_IMAGE || h == R_FIT_IMAGE || (flags & R_IMAGE_FIT_FLAG)) { XGetGeometry(image->app->display, window->id, &dummywin, &dummyi, &dummyi, &winw, &winh, &dummyui, &dummyui); } if (flags & R_IMAGE_STRETCH_FLAG) { rendw = winw; rendh = winh; } else { if (w == R_INTEGER_TILE_IMAGE) { long tmp1 = winw / image->origw; long tmp2 = winh / image->origh; factor = MIN(tmp1, tmp2); rendw = image->origw; xofs = (winw - (factor * rendw)) >> 1; } else if (w == R_TILE_FIT_IMAGE) {
/** * Setup an off-screen pixmap or Ximage to use as the back buffer. * Input: b - the X/Mesa buffer */ static void alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height) { if (b->db_mode == BACK_XIMAGE) { /* Deallocate the old backxrb->ximage, if any */ if (b->backxrb->ximage) { #if defined(USE_XSHM) if (b->shm) { XShmDetach(b->xm_visual->display, &b->shminfo); XDestroyImage(b->backxrb->ximage); shmdt(b->shminfo.shmaddr); } else #endif XMesaDestroyImage(b->backxrb->ximage); b->backxrb->ximage = NULL; } if (width == 0 || height == 0) return; /* Allocate new back buffer */ if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) { /* Allocate a regular XImage for the back buffer. */ b->backxrb->ximage = XCreateImage(b->xm_visual->display, b->xm_visual->visinfo->visual, GET_VISUAL_DEPTH(b->xm_visual), ZPixmap, 0, /* format, offset */ NULL, width, height, 8, 0); /* pad, bytes_per_line */ if (!b->backxrb->ximage) { _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n"); return; } b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height * b->backxrb->ximage->bytes_per_line); if (!b->backxrb->ximage->data) { _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n"); XMesaDestroyImage(b->backxrb->ximage); b->backxrb->ximage = NULL; } } b->backxrb->pixmap = None; } else if (b->db_mode == BACK_PIXMAP) { /* Free the old back pixmap */ if (b->backxrb->pixmap) { XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap); b->backxrb->pixmap = 0; } if (width > 0 && height > 0) { /* Allocate new back pixmap */ b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display, b->frontxrb->drawable, width, height, GET_VISUAL_DEPTH(b->xm_visual)); } b->backxrb->ximage = NULL; b->backxrb->drawable = b->backxrb->pixmap; } }
static void gst_ximage_memory_free (GstAllocator * allocator, GstMemory * gmem) { GstXImageMemory *mem = (GstXImageMemory *) gmem; GstXImageSink *ximagesink; if (gmem->parent) goto sub_mem; ximagesink = mem->sink; GST_DEBUG_OBJECT (ximagesink, "free memory %p", mem); /* Hold the object lock to ensure the XContext doesn't disappear */ GST_OBJECT_LOCK (ximagesink); /* We might have some buffers destroyed after changing state to NULL */ if (ximagesink->xcontext == NULL) { GST_DEBUG_OBJECT (ximagesink, "Destroying XImage after XContext"); #ifdef HAVE_XSHM /* Need to free the shared memory segment even if the x context * was already cleaned up */ if (mem->SHMInfo.shmaddr != ((void *) -1)) { shmdt (mem->SHMInfo.shmaddr); } #endif goto beach; } g_mutex_lock (&ximagesink->x_lock); #ifdef HAVE_XSHM if (ximagesink->xcontext->use_xshm) { if (mem->SHMInfo.shmaddr != ((void *) -1)) { GST_DEBUG_OBJECT (ximagesink, "XServer ShmDetaching from 0x%x id 0x%lx", mem->SHMInfo.shmid, mem->SHMInfo.shmseg); XShmDetach (ximagesink->xcontext->disp, &mem->SHMInfo); XSync (ximagesink->xcontext->disp, FALSE); shmdt (mem->SHMInfo.shmaddr); mem->SHMInfo.shmaddr = (void *) -1; } if (mem->ximage) XDestroyImage (mem->ximage); } else #endif /* HAVE_XSHM */ { if (mem->ximage) { XDestroyImage (mem->ximage); } } XSync (ximagesink->xcontext->disp, FALSE); g_mutex_unlock (&ximagesink->x_lock); beach: GST_OBJECT_UNLOCK (ximagesink); gst_object_unref (mem->sink); sub_mem: g_slice_free (GstXImageMemory, mem); }
/* * create or update the XImage using X shared memory * so that it has the given width and height and return TCL_OK if all * is TCL_OK. */ int ImageDisplay::updateShm(int width, int height) { // use this to catch X errors ErrorHandler errorHandler(display_, verbose_); // create an XImage in shared memory xImage_ = XShmCreateImage(display_, visual_, depth_, ZPixmap, NULL, &shmInfo_, width, height); if (!xImage_) { #ifdef DEBUG if (verbose_) cout << "XShmCreateImage failed\n"; #endif return TCL_ERROR; } // allocate enough shared memory to hold the image // (plus a fudge factor to keep the X server on HP happy) shmInfo_.shmid = shmget(IPC_PRIVATE, (xImage_->bytes_per_line * (height+1)), IPC_CREAT | 0777); if (shmInfo_.shmid < 0) { XDestroyImage(xImage_); xImage_ = NULL; #ifdef DEBUG if (verbose_) { perror("shmget failed for X shared memory"); } #endif return TCL_ERROR; } shmInfo_.shmaddr = (char *) shmat(shmInfo_.shmid, 0, 0); if (shmInfo_.shmaddr == ((char *) -1)) { XDestroyImage(xImage_); shmctl(shmInfo_.shmid, IPC_RMID, 0); shmdt(shmInfo_.shmaddr); xImage_ = NULL; #ifdef DEBUG if (verbose_) perror("shmat failed for X shared memory"); #endif return TCL_ERROR; } xImage_->data = shmInfo_.shmaddr; shmInfo_.readOnly = False; XShmAttach(display_, &shmInfo_); // check for X errors if (errorHandler.errors()) { XShmDetach(display_, &shmInfo_); XDestroyImage(xImage_); shmctl(shmInfo_.shmid, IPC_RMID, 0); shmdt(shmInfo_.shmaddr); xImage_ = NULL; #ifdef DEBUG if (verbose_) cout << "X shared memory error\n"; #endif return TCL_ERROR; } // this will cause the shared memory to be automatically deleted shmctl(shmInfo_.shmid, IPC_RMID, 0); #ifdef XXXDEBUG if (verbose_) cout << "Sharing memory\n"; #endif return TCL_OK; }
static int X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; SDL_VideoDisplay *display = window->display; X11_TextureData *data; int pitch_alignmask = ((renderdata->scanline_pad / 8) - 1); data = (X11_TextureData *) SDL_calloc(1, sizeof(*data)); if (!data) { SDL_OutOfMemory(); return -1; } texture->driverdata = data; if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { data->yuv = SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); if (!data->yuv) { return -1; } data->format = display->current_mode.format; } else { /* The image/pixmap depth must be the same as the window or you get a BadMatch error when trying to putimage or copyarea. */ if (texture->format != display->current_mode.format) { SDL_SetError("Texture format doesn't match window format"); return -1; } data->format = texture->format; } data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format); data->pitch = (data->pitch + pitch_alignmask) & ~pitch_alignmask; if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { #ifndef NO_SHARED_MEMORY XShmSegmentInfo *shminfo = &data->shminfo; shm_error = True; if (SDL_X11_HAVE_SHM) { shminfo->shmid = shmget(IPC_PRIVATE, texture->h * data->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(renderdata->display, shminfo); XSync(renderdata->display, False); XSetErrorHandler(X_handler); if (shm_error) { shmdt(shminfo->shmaddr); } } shmctl(shminfo->shmid, IPC_RMID, NULL); } } if (!shm_error) { data->pixels = shminfo->shmaddr; data->image = XShmCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, shminfo->shmaddr, shminfo, texture->w, texture->h); if (!data->image) { XShmDetach(renderdata->display, shminfo); XSync(renderdata->display, False); shmdt(shminfo->shmaddr); shm_error = True; } } if (shm_error) { shminfo->shmaddr = NULL; } if (!data->image) #endif /* not NO_SHARED_MEMORY */ { data->pixels = SDL_malloc(texture->h * data->pitch); if (!data->pixels) { X11_DestroyTexture(renderer, texture); SDL_OutOfMemory(); return -1; } data->image = XCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, 0, data->pixels, texture->w, texture->h, SDL_BYTESPERPIXEL(data->format) * 8, data->pitch); if (!data->image) { X11_DestroyTexture(renderer, texture); SDL_SetError("XCreateImage() failed"); return -1; } } } else { data->pixmap = XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, texture->h, renderdata->depth); if (data->pixmap == None) { X11_DestroyTexture(renderer, texture); SDL_SetError("XCreatePixmap() failed"); return -1; } data->image = XCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, 0, NULL, texture->w, texture->h, SDL_BYTESPERPIXEL(data->format) * 8, data->pitch); if (!data->image) { X11_DestroyTexture(renderer, texture); SDL_SetError("XCreateImage() failed"); return -1; } } return 0; }
static int _ggi_xshm_create_ximage(struct ggi_visual *vis) { char target[GGI_MAX_APILEN]; ggi_mode tm; ggi_x_priv *priv; int err, i; XShmSegmentInfo *myshminfo; size_t shmsize; err = GGI_OK; priv = GGIX_PRIV(vis); DPRINT_MODE("X: MIT-SHM: Creating shared MIT-SHM buffer\n"); _ggi_xshm_free_ximage(vis); priv->priv = calloc(1, sizeof(XShmSegmentInfo)); if (!priv->priv) return GGI_ENOMEM; myshminfo = priv->priv; priv->ximage = XShmCreateImage(priv->disp, priv->vilist[priv->viidx].vi->visual, (unsigned)priv->vilist[priv->viidx].vi->depth, ZPixmap, /* format */ NULL, /* data */ myshminfo, /* shm object */ (unsigned)LIBGGI_VIRTX(vis), (unsigned)(LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames)); if (priv->ximage == NULL) { DPRINT("XShmCreateImage() failed."); err = GGI_ENOMEM; goto err0; } shmsize = priv->ximage->bytes_per_line * LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames; DPRINT_MODE("X: MIT-SHM: Try to shmget() a buffer of %lu (0x%lx) size bytes\n", shmsize, shmsize); myshminfo->shmid = shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0777); if (myshminfo->shmid == -1) { DPRINT("shmget() failed.\n"); priv->fb = NULL; err = GGI_ENOMEM; goto err1; } priv->fb = shmat(myshminfo->shmid,0,0); if (priv->fb == (void *)-1) { DPRINT("shmat() failed.\n"); priv->fb = NULL; err = GGI_ENOMEM; goto err1; } myshminfo->shmaddr = priv->ximage->data = (char *)priv->fb; DPRINT_MODE("X: MIT-SHM: shmat success at %p.\n", priv->fb); myshminfo->readOnly = False; ggLock(_ggi_global_lock); /* Entering protected section */ shmerror = 0; DPRINT_MODE("X: MIT-SHM: install error handler\n"); oldshmerrorhandler = XSetErrorHandler(shmerrorhandler); DPRINT_MODE("X: MIT-SHM: Attach shm to display\n"); XShmAttach(priv->disp, myshminfo); XSync(priv->disp, 0); DPRINT_MODE("X: MIT-SHM: restore error handler\n"); XSetErrorHandler(oldshmerrorhandler); if (shmerror) { ggUnlock(_ggi_global_lock); /* Exiting protected section */ DPRINT("can not access XSHM.\n"); err = GGI_ENOMEM; goto err2; } else { /* Take the shmid away so noone else can get it. */ shmctl(myshminfo->shmid, IPC_RMID, 0); DPRINT_MODE("X: MIT-SHM: ShmImage allocated\n"); } ggUnlock(_ggi_global_lock); /* Exiting protected section */ err = _ggi_create_dbs(vis); if (err) goto err3; /* We assume LIBGGI_MODE(vis) structure has already been filled out */ memcpy(&tm, LIBGGI_MODE(vis), sizeof(ggi_mode)); /* Make sure we do not fail due to physical size constraints, * which are meaningless on a memory visual. */ tm.size.x = tm.size.y = GGI_AUTO; i = 0; memset(target, '\0', sizeof(target)); i += snprintf(target, sizeof(target), "display-memory:-pixfmt="); _ggi_build_pixfmtstr(vis, target + i, sizeof(target) - i, 1); i = strlen(target); snprintf(target + i, sizeof(target) - i, ":-layout=%iplb%i:-physz=%i,%i:pointer", priv->ximage->bytes_per_line * LIBGGI_VIRTY(vis), priv->ximage->bytes_per_line, LIBGGI_MODE(vis)->size.x, LIBGGI_MODE(vis)->size.y); err = _ggi_openslave(vis, target, &tm); if (err) goto err3; priv->ximage->byte_order = ImageByteOrder(priv->disp); priv->ximage->bitmap_bit_order = BitmapBitOrder(priv->disp); vis->opdisplay->flush = GGI_XSHM_flush_ximage_child; DPRINT_MODE("X: MIT-SHM: XSHMImage and slave visual %p share buffer at %p\n", priv->slave, priv->fb); return GGI_OK; err3: fprintf(stderr, "XSHM extension failed to initialize. Retry with -noshm\n"); _ggi_xshm_free_ximage(vis); return err; err2: XShmDetach(priv->disp, myshminfo); shmdt(priv->fb); priv->fb = NULL; err1: XDestroyImage(priv->ximage); priv->ximage = NULL; err0: fprintf(stderr, "XSHM extension failed to initialize. Retry with -noshm\n"); return err; }
static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT* vevent) { int i; BYTE* data1; BYTE* data2; UINT32 pixfmt; UINT32 xvpixfmt; BOOL converti420yv12 = FALSE; XvImage * image; int colorkey = 0; XShmSegmentInfo shminfo; xfXvContext* xv = (xfXvContext*) xfi->xv_context; if (xv->xv_port == 0) return; /* In case the player is minimized */ if (vevent->x < -2048 || vevent->y < -2048 || vevent->num_visible_rects <= 0) return; if (xv->xv_colorkey_atom != None) { XvGetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, &colorkey); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, colorkey); for (i = 0; i < vevent->num_visible_rects; i++) { XFillRectangle(xfi->display, xfi->window->handle, xfi->gc, vevent->x + vevent->visible_rects[i].x, vevent->y + vevent->visible_rects[i].y, vevent->visible_rects[i].width, vevent->visible_rects[i].height); } } else { XSetClipRectangles(xfi->display, xfi->gc, vevent->x, vevent->y, (XRectangle*) vevent->visible_rects, vevent->num_visible_rects, YXBanded); } pixfmt = vevent->frame_pixfmt; if (xf_tsmf_is_format_supported(xv, pixfmt)) { xvpixfmt = pixfmt; } else if (pixfmt == RDP_PIXFMT_I420 && xf_tsmf_is_format_supported(xv, RDP_PIXFMT_YV12)) { xvpixfmt = RDP_PIXFMT_YV12; converti420yv12 = TRUE; } else if (pixfmt == RDP_PIXFMT_YV12 && xf_tsmf_is_format_supported(xv, RDP_PIXFMT_I420)) { xvpixfmt = RDP_PIXFMT_I420; converti420yv12 = TRUE; } else { DEBUG_XV("pixel format 0x%X not supported by hardware.", pixfmt); return; } image = XvShmCreateImage(xfi->display, xv->xv_port, xvpixfmt, 0, vevent->frame_width, vevent->frame_height, &shminfo); if (xv->xv_image_size != image->data_size) { if (xv->xv_image_size > 0) { shmdt(xv->xv_shmaddr); shmctl(xv->xv_shmid, IPC_RMID, NULL); } xv->xv_image_size = image->data_size; xv->xv_shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); xv->xv_shmaddr = shmat(xv->xv_shmid, 0, 0); } shminfo.shmid = xv->xv_shmid; shminfo.shmaddr = image->data = xv->xv_shmaddr; shminfo.readOnly = FALSE; if (!XShmAttach(xfi->display, &shminfo)) { XFree(image); DEBUG_XV("XShmAttach failed."); return; } /* The video driver may align each line to a different size and we need to convert our original image data. */ switch (pixfmt) { case RDP_PIXFMT_I420: case RDP_PIXFMT_YV12: /* Y */ if (image->pitches[0] == vevent->frame_width) { memcpy(image->data + image->offsets[0], vevent->frame_data, vevent->frame_width * vevent->frame_height); } else { for (i = 0; i < vevent->frame_height; i++) { memcpy(image->data + image->offsets[0] + i * image->pitches[0], vevent->frame_data + i * vevent->frame_width, vevent->frame_width); } } /* UV */ /* Conversion between I420 and YV12 is to simply swap U and V */ if (converti420yv12 == FALSE) { data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; } else { data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; image->id = pixfmt == RDP_PIXFMT_I420 ? RDP_PIXFMT_YV12 : RDP_PIXFMT_I420; } if (image->pitches[1] * 2 == vevent->frame_width) { memcpy(image->data + image->offsets[1], data1, vevent->frame_width * vevent->frame_height / 4); memcpy(image->data + image->offsets[2], data2, vevent->frame_width * vevent->frame_height / 4); } else { for (i = 0; i < vevent->frame_height / 2; i++) { memcpy(image->data + image->offsets[1] + i * image->pitches[1], data1 + i * vevent->frame_width / 2, vevent->frame_width / 2); memcpy(image->data + image->offsets[2] + i * image->pitches[2], data2 + i * vevent->frame_width / 2, vevent->frame_width / 2); } } break; default: memcpy(image->data, vevent->frame_data, image->data_size <= vevent->frame_size ? image->data_size : vevent->frame_size); break; } XvShmPutImage(xfi->display, xv->xv_port, xfi->window->handle, xfi->gc, image, 0, 0, image->width, image->height, vevent->x, vevent->y, vevent->width, vevent->height, FALSE); if (xv->xv_colorkey_atom == None) XSetClipMask(xfi->display, xfi->gc, None); XSync(xfi->display, FALSE); XShmDetach(xfi->display, &shminfo); XFree(image); }
int svlWindowManagerX11::DoModal(bool show, bool fullscreen) { Destroy(); DestroyFlag = false; unsigned int i, atom_count; int x, y, prevright, prevbottom; unsigned int lastimage = 0; unsigned long black, white; XSizeHints wsh; #if CISST_SVL_HAS_XV Atom atoms[3]; unsigned int xvadaptorcount; XvAdaptorInfo *xvai; XVisualInfo xvvinfo; bool xvupdateimage = true; #else // CISST_SVL_HAS_XV Atom atoms[2]; #endif // CISST_SVL_HAS_XV // setting decoration hints for borderless mode struct { unsigned long flags; unsigned long functions; unsigned long decorations; signed long input_mode; unsigned long status; } mwm; mwm.flags = MWM_HINTS_DECORATIONS; mwm.decorations = 0; mwm.functions = 0; mwm.input_mode = 0; mwm.status = 0; // resetting DestroyedSignal event if (DestroyedSignal) delete(DestroyedSignal); DestroyedSignal = new osaThreadSignal(); if (DestroyedSignal == 0) goto labError; // initialize display and pick default screen xDisplay = XOpenDisplay(reinterpret_cast<char*>(0)); xScreen = DefaultScreen(xDisplay); #if CISST_SVL_HAS_XV // check if 24bpp is suppoted by the display if (XMatchVisualInfo(xDisplay, xScreen, 24, TrueColor, &xvvinfo) == 0) goto labError; #endif // CISST_SVL_HAS_XV // pick colors black = BlackPixel(xDisplay, xScreen); white = WhitePixel(xDisplay, xScreen); // create windows xWindows = new Window[NumOfWins]; memset(xWindows, 0, NumOfWins * sizeof(Window)); xGCs = new GC[NumOfWins]; memset(xGCs, 0, NumOfWins * sizeof(GC)); // create atoms for overriding default window behaviours atoms[0] = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False); atoms[1] = XInternAtom(xDisplay, "_MOTIF_WM_HINTS", False); #if CISST_SVL_HAS_XV atoms[2] = XInternAtom(xDisplay, "XV_SYNC_TO_VBLANK", False); #endif // CISST_SVL_HAS_XV // create title strings Titles = new std::string[NumOfWins]; CustomTitles = new std::string[NumOfWins]; CustomTitleEnabled = new int[NumOfWins]; #if CISST_SVL_HAS_XV xvImg = new XvImage*[NumOfWins]; xvShmInfo = new XShmSegmentInfo[NumOfWins]; xvPort = new XvPortID[NumOfWins]; if (xvImg == 0 || xvShmInfo == 0 || xvPort == 0) goto labError; memset(xvImg, 0, NumOfWins * sizeof(XvImage*)); memset(xvShmInfo, 0, NumOfWins * sizeof(XShmSegmentInfo)); memset(xvPort, 0, NumOfWins * sizeof(XvPortID)); #else // CISST_SVL_HAS_XV // create images xImageBuffers = new unsigned char*[NumOfWins]; for (i = 0; i < NumOfWins; i ++) { xImageBuffers[i] = new unsigned char[Width[i] * Height[i] * 4]; } xImg = new XImage*[NumOfWins]; memset(xImg, 0, NumOfWins * sizeof(XImage*)); if (xImg == 0) goto labError; for (i = 0; i < NumOfWins; i ++) { xImg[i] = XCreateImage(xDisplay, DefaultVisual(xDisplay, xScreen), 24, ZPixmap, 0, reinterpret_cast<char*>(xImageBuffers[i]), Width[i], Height[i], 32, 0); } #endif // CISST_SVL_HAS_XV prevright = prevbottom = 0; for (i = 0; i < NumOfWins; i ++) { if (PosX == 0 || PosY == 0) { if (fullscreen) { x = prevright; y = 0; prevright += Width[i]; } else { x = prevright; y = prevbottom; prevright += 50; prevbottom += 50; } } else { x = PosX[i]; y = PosY[i]; } xWindows[i] = XCreateSimpleWindow(xDisplay, DefaultRootWindow(xDisplay), x, y, Width[i], Height[i], 0, black, white); if (xWindows[i] == 0) goto labError; // overriding default behaviours: // - borderless mode // - closing window if (fullscreen) { XChangeProperty(xDisplay, xWindows[i], atoms[1], atoms[1], 32, PropModeReplace, reinterpret_cast<unsigned char*>(&mwm), 5); atom_count = 2; } else { atom_count = 1; } XSetWMProtocols(xDisplay, xWindows[i], atoms, atom_count); wsh.flags = PPosition|PSize; wsh.x = x; wsh.y = y; wsh.width = Width[i]; wsh.height = Height[i]; XSetNormalHints(xDisplay, xWindows[i], &wsh); // set window title CustomTitleEnabled[i] = 0; std::ostringstream ostring; if (Title.length() > 0) { if (NumOfWins > 0) ostring << Title << " #" << i; else ostring << Title; } else { if (NumOfWins > 0) ostring << Title << "svlImageWindow #" << i; else ostring << "svlImageWindow"; } Titles[i] = ostring.str(); XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); // set even mask XSelectInput(xDisplay, xWindows[i], ExposureMask|PointerMotionMask|ButtonPressMask|KeyPressMask); // set window colormap XSetWindowColormap(xDisplay, xWindows[i], DefaultColormapOfScreen(DefaultScreenOfDisplay(xDisplay))); #if CISST_SVL_HAS_XV // query shared memory extension if (!XShmQueryExtension(xDisplay)) goto labError; // query video adaptors if (XvQueryAdaptors(xDisplay, DefaultRootWindow(xDisplay), &xvadaptorcount, &xvai) != Success) goto labError; xvPort[i] = xvai->base_id + i; XvFreeAdaptorInfo(xvai); // overriding default Xvideo vertical sync behavior XvSetPortAttribute (xDisplay, xvPort[i], atoms[2], 1); #endif // CISST_SVL_HAS_XV // create graphics context xGCs[i] = XCreateGC(xDisplay, xWindows[i], 0, 0); // set default colors XSetBackground(xDisplay, xGCs[i], white); XSetForeground(xDisplay, xGCs[i], black); #if CISST_SVL_HAS_XV // create image in shared memory xvImg[i] = XvShmCreateImage(xDisplay, xvPort[i], 0x32595559/*YUV2*/, 0, Width[i], Height[i], &(xvShmInfo[i])); if (xvImg[i]->width < static_cast<int>(Width[i]) || xvImg[i]->height < static_cast<int>(Height[i])) { CMN_LOG_INIT_ERROR << "DoModal - image too large for XV to display (requested=" << Width[i] << "x" << Height[i] << "; allowed=" << xvImg[i]->width << "x" << xvImg[i]->height << ")" << std::endl; goto labError; } xvShmInfo[i].shmid = shmget(IPC_PRIVATE, xvImg[i]->data_size, IPC_CREAT | 0777); xvShmInfo[i].shmaddr = xvImg[i]->data = reinterpret_cast<char*>(shmat(xvShmInfo[i].shmid, 0, 0)); xvShmInfo[i].readOnly = False; if (!XShmAttach(xDisplay, &(xvShmInfo[i]))) goto labError; #endif // CISST_SVL_HAS_XV // clear window XClearWindow(xDisplay, xWindows[i]); // show window if requested if (show) XMapRaised(xDisplay, xWindows[i]); } // signal that initialization is done if (InitReadySignal) InitReadySignal->Raise(); // main message loop XEvent event; KeySym code; unsigned int winid; while (1) { osaSleep(0.001); #if CISST_SVL_HAS_XV if (!xvupdateimage) { for (int events = XPending(xDisplay); events > 0; events --) { #else // CISST_SVL_HAS_XV if (XPending(xDisplay)) { #endif // CISST_SVL_HAS_XV XNextEvent(xDisplay, &event); // find recipient for (winid = 0; winid < NumOfWins; winid ++) { if (event.xany.window == xWindows[winid]) break; } if (winid == NumOfWins) continue; // override default window behaviour if (event.type == ClientMessage) { if (static_cast<unsigned long>(event.xclient.data.l[0]) == atoms[0]) { // X11 server wants to close window // Do nothing.... we will destroy it ourselves later } continue; } // window should be closed if (event.type == UnmapNotify) { printf("destroy\n"); if (xGCs[winid]) { XFreeGC(xDisplay, xGCs[winid]); xGCs[winid] = 0; } xWindows[winid] = 0; continue; } // window should be updated if (event.type == Expose && event.xexpose.count == 0) { XClearWindow(xDisplay, xWindows[winid]); continue; } if (event.type == KeyPress) { code = XLookupKeysym(&event.xkey, 0); if (code >= 48 && code <= 57) { // ascii numbers OnUserEvent(winid, true, code); continue; } if (code >= 97 && code <= 122) { // ascii letters OnUserEvent(winid, true, code); continue; } if (code == 13 || code == 32) { // special characters with correct ascii code OnUserEvent(winid, true, code); continue; } if (code >= 0xffbe && code <= 0xffc9) { // F1-F12 OnUserEvent(winid, false, winInput_KEY_F1 + (code - 0xffbe)); continue; } switch (code) { case 0xFF55: OnUserEvent(winid, false, winInput_KEY_PAGEUP); break; case 0xFF56: OnUserEvent(winid, false, winInput_KEY_PAGEDOWN); break; case 0xFF50: OnUserEvent(winid, false, winInput_KEY_HOME); break; case 0xFF57: OnUserEvent(winid, false, winInput_KEY_END); break; case 0xFF63: OnUserEvent(winid, false, winInput_KEY_INSERT); break; case 0xFFFF: OnUserEvent(winid, false, winInput_KEY_DELETE); break; case 0xFF51: OnUserEvent(winid, false, winInput_KEY_LEFT); break; case 0xFF53: OnUserEvent(winid, false, winInput_KEY_RIGHT); break; case 0xFF52: OnUserEvent(winid, false, winInput_KEY_UP); break; case 0xFF54: OnUserEvent(winid, false, winInput_KEY_DOWN); break; } continue; } if (event.type == ButtonPress) { if (event.xbutton.button == Button1) { if (!LButtonDown && !RButtonDown) { LButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_LBUTTONDOWN); } else if (event.xbutton.button == Button3) { if (!LButtonDown && !RButtonDown) { RButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_RBUTTONDOWN); } } if (event.type == ButtonRelease) { if (event.xbutton.button == Button1) { OnUserEvent(winid, false, winInput_LBUTTONUP); if (LButtonDown && !RButtonDown) { LButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } else if (event.xbutton.button == Button3) { OnUserEvent(winid, false, winInput_RBUTTONUP); if (!LButtonDown && RButtonDown) { RButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } } if (event.type == MotionNotify) { SetMousePos(static_cast<short>(event.xmotion.x), static_cast<short>(event.xmotion.y)); OnUserEvent(winid, false, winInput_MOUSEMOVE); } #if CISST_SVL_HAS_XV // image update complete if (event.type == XShmGetEventBase(xDisplay) + ShmCompletion) { xvupdateimage = true; continue; } } if (!xvupdateimage) signalImage.Wait(0.01); #endif // CISST_SVL_HAS_XV } else { if (DestroyFlag) break; if (ImageCounter > lastimage) { csImage.Enter(); lastimage = ImageCounter; #if CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { XvShmPutImage(xDisplay, xvPort[i], xWindows[i], xGCs[i], xvImg[i], 0, 0, Width[i], Height[i], 0, 0, Width[i], Height[i], True); } xvupdateimage = false; #else // CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { xImg[i]->data = reinterpret_cast<char*>(xImageBuffers[i]); XPutImage(xDisplay, xWindows[i], xGCs[i], xImg[i], 0, 0, 0, 0, Width[i], Height[i]); } #endif // CISST_SVL_HAS_XV /* for (i = 0; i < NumOfWins; i ++) { if (CustomTitleEnabled[i] < 0) { // Restore original timestamp XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); } else if (CustomTitleEnabled[i] > 0) { // Set custom timestamp XSetStandardProperties(xDisplay, xWindows[i], CustomTitles[i].c_str(), CustomTitles[i].c_str(), None, NULL, 0, NULL); } } */ csImage.Leave(); } } } labError: #if CISST_SVL_HAS_XV if (xvShmInfo) { for (i = 0; i < NumOfWins; i ++) { XShmDetach(xDisplay, &(xvShmInfo[i])); shmdt(xvShmInfo[i].shmaddr); } delete [] xvShmInfo; xvShmInfo = 0; } #endif // CISST_SVL_HAS_XV XSync(xDisplay, 0); for (i = 0; i < NumOfWins; i ++) { if (xGCs[i]) XFreeGC(xDisplay, xGCs[i]); if (xWindows[i]) XDestroyWindow(xDisplay, xWindows[i]); } XCloseDisplay(xDisplay); #if CISST_SVL_HAS_XV if (xvImg) { for (i = 0; i < NumOfWins; i ++) { if (xvImg[i]) XFree(xvImg[i]); } delete [] xvImg; xvImg = 0; } if (xvPort) { delete [] xvPort; xvPort = 0; } #else // CISST_SVL_HAS_XV if (xImg) { for (i = 0; i < NumOfWins; i ++) { if (xImg[i]) XDestroyImage(xImg[i]); } delete [] xImg; xImg = 0; } if (xImageBuffers) { delete [] xImageBuffers; xImageBuffers = 0; } #endif // CISST_SVL_HAS_XV if (xGCs) { delete [] xGCs; xGCs = 0; } if (xWindows) { delete [] xWindows; xWindows = 0; } if (Titles) { delete [] Titles; Titles = 0; } if (CustomTitles) { delete [] CustomTitles; CustomTitles = 0; } if (CustomTitleEnabled) { delete [] CustomTitleEnabled; CustomTitleEnabled = 0; } xScreen = 0; xDisplay = 0; if (DestroyedSignal) DestroyedSignal->Raise(); return 0; }
int X11_SetupImage(_THIS, SDL_Surface *screen) { #ifdef NO_SHARED_MEMORY screen->pixels = malloc(screen->h*screen->pitch); #else /* Allocate shared memory if possible */ if ( use_mitshm ) { 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 == True ) shmdt(shminfo.shmaddr); } else { shm_error = True; } shmctl(shminfo.shmid, IPC_RMID, NULL); } else { shm_error = True; } if ( shm_error == True ) use_mitshm = 0; } if ( use_mitshm ) { screen->pixels = shminfo.shmaddr; } else { screen->pixels = malloc(screen->h*screen->pitch); } #endif /* NO_SHARED_MEMORY */ if ( screen->pixels == NULL ) { SDL_OutOfMemory(); return(-1); } #ifdef NO_SHARED_MEMORY { int bpp = screen->format->BytesPerPixel; SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, this->hidden->depth, ZPixmap, 0, (char *)screen->pixels, screen->w, screen->h, (bpp == 3) ? 32 : bpp * 8, 0); } #else if ( use_mitshm ) { SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, this->hidden->depth, ZPixmap, shminfo.shmaddr, &shminfo, screen->w, screen->h); } else { int bpp = screen->format->BytesPerPixel; SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, this->hidden->depth, ZPixmap, 0, (char *)screen->pixels, screen->w, screen->h, (bpp == 3) ? 32 : bpp * 8, 0); } #endif /* NO_SHARED_MEMORY */ if ( SDL_Ximage == NULL ) { SDL_SetError("Couldn't create XImage"); #ifndef NO_SHARED_MEMORY if ( use_mitshm ) { XShmDetach(SDL_Display, &shminfo); XSync(SDL_Display, False); shmdt(shminfo.shmaddr); screen->pixels = NULL; } #endif /* ! NO_SHARED_MEMORY */ return(-1); } screen->pitch = SDL_Ximage->bytes_per_line; /* Determine what blit function to use */ #ifdef NO_SHARED_MEMORY this->UpdateRects = X11_NormalUpdate; #else if ( use_mitshm ) { this->UpdateRects = X11_MITSHMUpdate; } else { this->UpdateRects = X11_NormalUpdate; } #endif return(0); }
*/ REBOOL rebcmp_resize_buffer(REBCMP_CTX* ctx, REBGOB* winGob) /* ** Resize the window compositing buffer. ** ** Returns TRUE if buffer size was really changed, otherwise FALSE. ** ***********************************************************************/ { //check if window size really changed if ((GOB_LOG_W(winGob) != GOB_WO(winGob)) || (GOB_LOG_H(winGob) != GOB_HO(winGob)) || ctx->pixbuf == NULL) {//ctx might haven't been initialized yet REBINT w = GOB_LOG_W_INT(winGob); REBINT h = GOB_LOG_H_INT(winGob); if (ctx->x_image) { XDestroyImage(ctx->x_image); //frees ctx->pixbuf as well } #ifdef USE_XSHM if (ctx->x_image_back) { XDestroyImage(ctx->x_image_back); //frees ctx->pixbuf as well } if (global_x_info->has_xshm && global_x_info->sys_pixmap_format == pix_format_bgra32) { if (ctx->x_shminfo.shmaddr != NULL) { XShmDetach(global_x_info->display, &ctx->x_shminfo); shmdt(ctx->x_shminfo.shmaddr); //RL_Print("Removing SHM %x\n", ctx->x_shminfo.shmid); shmctl(ctx->x_shminfo.shmid, IPC_RMID, NULL); } ctx->x_image = XShmCreateImage(global_x_info->display, global_x_info->default_visual, global_x_info->default_depth, ZPixmap, 0, &ctx->x_shminfo, w, h); if (ctx->x_image == NULL) { global_x_info->has_xshm = 0; } else { ctx->pixbuf_len = ctx->x_image->bytes_per_line * ctx->x_image->height; ctx->x_shminfo.shmid = shmget(IPC_PRIVATE, ctx->pixbuf_len, IPC_CREAT | 0644 ); //RL_Print("Allocated SHM %x\n", ctx->x_shminfo.shmid); if (ctx->x_shminfo.shmid < 0) { //RL_Print("shmget failed, fallback to non-shm\n"); global_x_info->has_xshm = 0; } else { ctx->pixbuf = ctx->x_shminfo.shmaddr = ctx->x_image->data = (char *)shmat(ctx->x_shminfo.shmid, 0, 0); } if (ctx->pixbuf == NULL) { //RL_Print("shmat failed, fallback to non-shm\n"); global_x_info->has_xshm = 0; //RL_Print("Removing SHM %x\n", ctx->x_shminfo.shmid); shmctl(ctx->x_shminfo.shmid, IPC_RMID, NULL); } else { memset(ctx->pixbuf, 0, ctx->pixbuf_len); ctx->x_shminfo.readOnly = False; XSync(global_x_info->display, False); orig_error_handler = XSetErrorHandler(shm_error_handler); XShmAttach(global_x_info->display, &ctx->x_shminfo); //Bad Access error when talking to a remote X server XSync(global_x_info->display, False); XSetErrorHandler(orig_error_handler); if (!global_x_info->has_xshm) { //RL_Print("XShmAttach failed, fallback to non-shm\n"); XDestroyImage(ctx->x_image); shmdt(ctx->x_shminfo.shmaddr); //RL_Print("Removing SHM %x\n", ctx->x_shminfo.shmid); shmctl(ctx->x_shminfo.shmid, IPC_RMID, NULL); }; } } if (global_x_info->has_xshm) { if (ctx->x_shminfo_back.shmaddr != NULL) { XShmDetach(global_x_info->display, &ctx->x_shminfo_back); shmdt(ctx->x_shminfo_back.shmaddr); //RL_Print("Removing SHM %x\n", ctx->x_shminfo_back.shmid); shmctl(ctx->x_shminfo_back.shmid, IPC_RMID, NULL); } ctx->x_image_back = XShmCreateImage(global_x_info->display, global_x_info->default_visual, global_x_info->default_depth, ZPixmap, 0, &ctx->x_shminfo_back, w, h); assert(ctx->x_image_back != NULL); ctx->x_shminfo_back.shmid = shmget(IPC_PRIVATE, ctx->x_image_back->bytes_per_line * ctx->x_image->height, IPC_CREAT | 0644 ); ctx->x_shminfo_back.shmaddr = ctx->x_image_back->data = (char *)shmat(ctx->x_shminfo_back.shmid, 0, 0); XShmAttach(global_x_info->display, &ctx->x_shminfo_back); //Bad Access error when talking to a remote X server XSync(global_x_info->display, False); } } if (!global_x_info->has_xshm || global_x_info->sys_pixmap_format != pix_format_bgra32) {//fall back to non-xshm version global_x_info->has_xshm = 0; #endif //RL_Print("Non-shm version\n"); ctx->pixbuf_len = w * h * BYTE_PER_PIXEL; //BGRA32; ctx->pixbuf = OS_Make(ctx->pixbuf_len); if (ctx->pixbuf == NULL){ //RL_Print("Allocation of %d bytes memory failed\n", ctx->pixbuf_len); Host_Crash("Not enough memory\n"); } memset(ctx->pixbuf, 0, ctx->pixbuf_len); if (global_x_info->display != NULL) { ctx->x_image = XCreateImage(global_x_info->display, global_x_info->default_visual, global_x_info->default_depth, ZPixmap, 0, ctx->pixbuf, w, h, global_x_info->bpp, w * global_x_info->bpp / 8); } #ifdef USE_XSHM } #endif if (ctx->x_image != NULL) { #ifdef ENDIAN_BIG ctx->x_image->byte_order = MSBFirst; #else ctx->x_image->byte_order = LSBFirst; #endif } //update the buffer size values ctx->winBufSize.x = w; ctx->winBufSize.y = h; //update old gob area GOB_XO(winGob) = GOB_LOG_X(winGob); GOB_YO(winGob) = GOB_LOG_Y(winGob); GOB_WO(winGob) = GOB_LOG_W(winGob); GOB_HO(winGob) = GOB_LOG_H(winGob); return TRUE; } return FALSE; }
/** * Called via gl_framebuffer::Delete() method when this buffer * is _really_ being deleted. */ void xmesa_delete_framebuffer(struct gl_framebuffer *fb) { XMesaBuffer b = XMESA_BUFFER(fb); if (b->num_alloced > 0) { /* If no other buffer uses this X colormap then free the colors. */ if (!xmesa_find_buffer(b->display, b->cmap, b)) { #ifdef XFree86Server int client = 0; if (b->frontxrb->drawable) client = CLIENT_ID(b->frontxrb->drawable->id); (void)FreeColors(b->cmap, client, b->num_alloced, b->alloced_colors, 0); #else XFreeColors(b->display, b->cmap, b->alloced_colors, b->num_alloced, 0); #endif } } if (b->gc) XMesaFreeGC(b->display, b->gc); if (b->cleargc) XMesaFreeGC(b->display, b->cleargc); if (b->swapgc) XMesaFreeGC(b->display, b->swapgc); if (fb->Visual.doubleBufferMode) { /* free back ximage/pixmap/shmregion */ if (b->backxrb->ximage) { #if defined(USE_XSHM) && !defined(XFree86Server) if (b->shm) { XShmDetach( b->display, &b->shminfo ); XDestroyImage( b->backxrb->ximage ); shmdt( b->shminfo.shmaddr ); } else #endif XMesaDestroyImage( b->backxrb->ximage ); b->backxrb->ximage = NULL; } if (b->backxrb->pixmap) { XMesaFreePixmap( b->display, b->backxrb->pixmap ); if (b->xm_visual->hpcr_clear_flag) { XMesaFreePixmap( b->display, b->xm_visual->hpcr_clear_pixmap ); XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); } } } if (b->rowimage) { _mesa_free( b->rowimage->data ); b->rowimage->data = NULL; XMesaDestroyImage( b->rowimage ); } _mesa_free_framebuffer_data(fb); _mesa_free(fb); }
int xf_video_process_frame(xfInfo * xfi, RD_VIDEO_FRAME_EVENT * vevent) { XShmSegmentInfo shminfo; XvImage * image; int colorkey = 0; int i; uint32 pixfmt; uint8 * data1; uint8 * data2; if (xfi->xv_port == -1) return 1; /* In case the player is minimized */ if (vevent->x < -2048 || vevent->y < -2048 || vevent->num_visible_rects <= 0) return 0; if (xfi->xv_colorkey_atom != None) { XvGetPortAttribute(xfi->display, xfi->xv_port, xfi->xv_colorkey_atom, &colorkey); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, colorkey); for (i = 0; i < vevent->num_visible_rects; i++) { XFillRectangle(xfi->display, xfi->wnd, xfi->gc, vevent->x + vevent->visible_rects[i].x, vevent->y + vevent->visible_rects[i].y, vevent->visible_rects[i].width, vevent->visible_rects[i].height); } } pixfmt = vevent->frame_pixfmt; image = XvShmCreateImage(xfi->display, xfi->xv_port, pixfmt, 0, vevent->frame_width, vevent->frame_height, &shminfo); if (xfi->xv_image_size != image->data_size) { if (xfi->xv_image_size > 0) { shmdt(xfi->xv_shmaddr); shmctl(xfi->xv_shmid, IPC_RMID, NULL); } xfi->xv_image_size = image->data_size; xfi->xv_shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); xfi->xv_shmaddr = shmat(xfi->xv_shmid, 0, 0); } shminfo.shmid = xfi->xv_shmid; shminfo.shmaddr = image->data = xfi->xv_shmaddr; shminfo.readOnly = False; if (!XShmAttach(xfi->display, &shminfo)) { XFree(image); printf("xf_video_process_frame: XShmAttach failed.\n"); return 1; } /* The video driver may align each line to a different size and we need to convert our original image data. */ switch (pixfmt) { case RD_PIXFMT_I420: case RD_PIXFMT_YV12: if (!xf_video_is_format_supported(xfi, RD_PIXFMT_I420) && !xf_video_is_format_supported(xfi, RD_PIXFMT_YV12)) { printf("xf_video_process_frame: pixel format 0x%X not supported by hardware.\n", pixfmt); break; } /* Y */ if (image->pitches[0] == vevent->frame_width) { memcpy(image->data + image->offsets[0], vevent->frame_data, vevent->frame_width * vevent->frame_height); } else { for (i = 0; i < vevent->frame_height; i++) { memcpy(image->data + image->offsets[0] + i * image->pitches[0], vevent->frame_data + i * vevent->frame_width, vevent->frame_width); } } /* UV */ /* Conversion between I420 and YV12 is to simply swap U and V */ if (xf_video_is_format_supported(xfi, pixfmt)) { data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; } else { data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; image->id = pixfmt == RD_PIXFMT_I420 ? RD_PIXFMT_YV12 : RD_PIXFMT_I420; } if (image->pitches[1] * 2 == vevent->frame_width) { memcpy(image->data + image->offsets[1], data1, vevent->frame_width * vevent->frame_height / 4); memcpy(image->data + image->offsets[2], data2, vevent->frame_width * vevent->frame_height / 4); } else { for (i = 0; i < vevent->frame_height / 2; i++) { memcpy(image->data + image->offsets[1] + i * image->pitches[1], data1 + i * vevent->frame_width / 2, vevent->frame_width / 2); memcpy(image->data + image->offsets[2] + i * image->pitches[2], data2 + i * vevent->frame_width / 2, vevent->frame_width / 2); } } break; default: memcpy(image->data, vevent->frame_data, image->data_size <= vevent->frame_size ? image->data_size : vevent->frame_size); break; } XvShmPutImage(xfi->display, xfi->xv_port, xfi->wnd, xfi->gc_default, image, 0, 0, image->width, image->height, vevent->x, vevent->y, vevent->width, vevent->height, False); XSync(xfi->display, False); XShmDetach(xfi->display, &shminfo); XFree(image); return 0; }
int main(int argc, char **argv) { int num_queued; time_t start_time; double t; long num_frames, fast_skip = 200, fast_rewind = 200; unsigned int width, height; XEvent xevent; const char *prgname = argv[0]; const char *classname = "XLndmovie"; char *pixel_file_name = NULL; FILE *pixel_file; unsigned char *buffer = NULL, *huff = NULL; XImage *shm_image; XShmSegmentInfo shminfo; int shm_major, shm_minor; Bool shm_pixmaps; int ShmCompletionType; int shmtransfer_completed; int i, count, step_key = 0; char xkey[32]; KeySym keysym; XComposeStatus compose; int oc; extern int optind; extern char *optarg; init_signal_handling(); display = xwin_init(NULL, prgname, classname, argc, argv, &screen_no, &width, &height); fixed_font = XLoadQueryFont(display, "fixed"); mit_shm = XShmQueryVersion(display, &shm_major, &shm_minor, &shm_pixmaps); mit_shm = XShmQueryExtension(display); if (mit_shm == True) { /* printf("Shared memory extension used (found V %d.%d)\n", shm_major, shm_minor); */ ShmCompletionType = XShmGetEventBase(display) + ShmCompletion; } /* else printf("Standard Xlib used, no shared memory\n"); */ while ((oc = getopt(argc, argv, "c:f:r:h")) != -1) { switch (oc) { case 'c': cell_boxsize = strtol(optarg, NULL, 10); break; case 'f': fast_skip = strtol(optarg, NULL, 10); if (fast_skip < 1) fast_skip = 200; break; case 'r': fast_rewind = strtol(optarg, NULL, 10); if (fast_rewind < 1) fast_rewind = 200; break; default: fprintf(stderr, "Unknown option \'-%c\' -- ignored\n", oc); break; } } if (optind < argc) pixel_file_name = argv[optind++]; else { fprintf(stderr, "No pixel file specified -- exit\n"); exit (EXIT_FAILURE); } pixel_file = fopen(pixel_file_name, "rb"); if (pixel_file == NULL) { fprintf(stderr, "Failed to open pixel file \"%s\" -- exit\n", pixel_file_name); exit (EXIT_FAILURE); } read_pixheader(pixel_file); if ((cell_boxsize <= 0) || ((width / world_width) < cell_boxsize)) cell_boxsize = width / world_width; if ((height / world_height) < cell_boxsize) cell_boxsize = height / world_height; if (cell_boxsize <= 0) cell_boxsize = 1; if ((height / world_height) < cell_boxsize) cell_boxsize = height / world_height; window_width = world_width * cell_boxsize; pixmap_height = world_height * cell_boxsize; if (fixed_font) window_height = pixmap_height + fixed_font->ascent + fixed_font->descent + 5; else window_height = pixmap_height; buffer = (unsigned char *) malloc(world_width * world_height * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "Failed to allocate internal buffer\n"); exit (EXIT_FAILURE); } huff = (unsigned char *) malloc(world_width * world_height * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "Failed to allocate internal buffer\n"); free(buffer); exit (EXIT_FAILURE); } window = create_window(MOVER | FULLER | CLOSER | RTARROW | LFARROW | UPARROW | DNARROW, window_width, window_height, redraw_pixworld, close_pixwindow, 100, 100, window_width, window_height); XSelectInput(display, window, WH_EVENTMASK | WH_SELECTMASK); map_window(window); if (create_lndgcs(lnd_gc, lndx_gc, background_gc, &text_gc)) { fprintf(stderr, "Failed to create necessary GCs (insufficient colors?)\n"); free(buffer); free(huff); exit (EXIT_FAILURE); } if (mit_shm) { shm_image = XShmCreateImage(display, DefaultVisual(display, screen_no), DefaultDepth(display, screen_no), ZPixmap, NULL, &shminfo, window_width, pixmap_height); /* printf("XImage Structure:\n"); printf("width = %d, height = %d, depth = %d\n", shm_image->width, shm_image->height, shm_image->depth); printf("format: "); switch (shm_image->format) { case XYBitmap: printf("XYBitmap\n"); break; case XYPixmap: printf("XYPixmap\n"); break; case ZPixmap: printf("ZPixmap\n"); break; default: printf("UNKNOWN (%d)\n", shm_image->format); break; } printf("%d bytes per line, %d bits per pixel\n", shm_image->bytes_per_line, shm_image->bits_per_pixel); switch (shm_image->byte_order) { case MSBFirst: printf("byte order: MSBFirst\n"); break; case LSBFirst: printf("byte order: LSBFirst\n"); break; default: printf("byte order UNKNOWN (%d)\n", shm_image->byte_order); break; } switch (shm_image->bitmap_bit_order) { case MSBFirst: printf("bitmap bit order: MSBFirst\n"); break; case LSBFirst: printf("bitmap bit order: LSBFirst\n"); break; default: printf("bitmap bit order UNKNOWN (%d)\n", shm_image->bitmap_bit_order); break; } */ shminfo.shmid = shmget(IPC_PRIVATE, shm_image->bytes_per_line * shm_image->height, IPC_CREAT | 0777); if (shminfo.shmid == -1) { fprintf(stderr, "Failed to get shared memory segment, falling back to standard Xlib\n"); mit_shm = 0; } else { shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); shm_image->data = shminfo.shmaddr; shminfo.readOnly = False; if (XShmAttach(display, &shminfo)) ; /* printf("Shared mem successfully attached to server\n"); */ else { mit_shm = 0; XDestroyImage(shm_image); shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); printf("Shared memory released\n"); } } } if (!mit_shm) { paint_pixmap = XCreatePixmap(display, window, window_width, pixmap_height, DefaultDepth(display, screen_no)); XFillRectangle(display, paint_pixmap, background_gc[15], 0, 0, window_width, pixmap_height); } redraw_pixmap = XCreatePixmap(display, window, window_width, pixmap_height, DefaultDepth(display, screen_no)); XFillRectangle(display, redraw_pixmap, background_gc[15], 0, 0, window_width, pixmap_height); /* for (i = 0; i < 6; i++) { XPutPixel(shm_image, 0, 0, lnd_pixel[i]); printf("lnd_pixel[%d]=%08lx -> data=%02x\n", i, lnd_pixel[i], shm_image->data[0]); XPutPixel(shm_image, 0, 0, lndx_pixel[i]); printf("lndx_pixel[%d]=%08lx -> data=%02x\n", i, lndx_pixel[i], shm_image->data[0]); } XPutPixel(shm_image, 0, 0, back_pixel); printf("back_pixel=%08lx -> data=%02x\n", back_pixel, shm_image->data[0]); */ do { XNextEvent(display, &xevent); num_queued = XEventsQueued(display, QueuedAfterFlush); process_xevent(&xevent); } while (!((xevent.type == Expose) && (xevent.xexpose.window == window))); shmtransfer_completed = 1; start_time = time(NULL); num_frames = 0; while (!game_over) { if(feof(pixel_file) || ferror(pixel_file)) { if (resume_fpos != -1) { mode = SINGLE_STEP; /* printf("switched to single step due to feof / ferror\n"); */ step_key = 0; /* printf("rewinding to resume pos %ld\n", resume_fpos); fseek(pixel_file, resume_fpos, SEEK_SET); */ } else { fprintf(stderr, "Encountered EOF without finding any entry point -- quitting\n"); game_over = 1; } } num_queued = XEventsQueued(display, QueuedAfterFlush); while ((num_queued) || ((mode == SINGLE_STEP) && !step_key)) { XNextEvent(display, &xevent); num_queued = XEventsQueued(display, QueuedAfterFlush); /* printf("received event: %s, window: %d\n", event_name[xevent.type], (int) xevent.xany.window); */ if (process_xevent(&xevent)) continue; if (xevent.type == ShmCompletionType) { /* printf("shm transfer completed\n"); */ shmtransfer_completed = 1; } if (xevent.type == KeyPress) { count = XLookupString(&(xevent.xkey), xkey, 32, &keysym, &compose); if (count) { switch(xkey[0]) { case 'f': /* printf("fast forward\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = FAST_FORWARD; break; case 'r': /* printf("fast rewind\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = FAST_REWIND; break; case 'b': /* printf("backward play\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = BACKWARD_PLAY; rewind_generation(pixel_file); break; case 's': /* printf("single step\n"); */ mode = SINGLE_STEP; step_key = 0; break; case 'n': /* printf("normal play\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = NORMAL_PLAY; break; case 'q': case 'Q': /* printf("game over, bye bye\n"); */ mode = NORMAL_PLAY; step_key = 1; game_over = 1; break; default: step_key = 1; break; } } } } if ((mode == NORMAL_PLAY) || (mode == BACKWARD_PLAY) || ((mode == SINGLE_STEP) && step_key) || ((mode == FAST_FORWARD) && ((generation % fast_skip) == (fast_skip - 1))) || ((mode == FAST_REWIND) && ((generation % fast_rewind) == 1))) { if (mit_shm && shmtransfer_completed) { if (shm_draw_generation(pixel_file, shm_image, buffer, huff)) { mode = SINGLE_STEP; /* printf("switched to single step after shm_draw_generation\n"); */ step_key = 0; } else { if (window != BadValue) XShmPutImage(display, window, background_gc[15], shm_image, 0, 0, 0, window_height - pixmap_height, window_width, pixmap_height, True); if (redraw_pixmap != BadValue) XShmPutImage(display, redraw_pixmap, background_gc[15], shm_image, 0, 0, 0, 0, window_width, pixmap_height, True); shmtransfer_completed = 0; num_frames++; } } else { if (draw_generation(pixel_file, paint_pixmap, buffer, huff)) { mode = SINGLE_STEP; /* printf("switched to single step after draw_generation\n"); */ step_key = 0; } else { if (window != BadValue) XCopyArea(display, paint_pixmap, window, background_gc[15], 0, 0, window_width, pixmap_height, 0, window_height - pixmap_height); if (redraw_pixmap != BadValue) XCopyArea(display, paint_pixmap, redraw_pixmap, background_gc[15], 0, 0, window_width, pixmap_height, 0, 0); num_frames++; } } redraw_text(); if (mode == FAST_REWIND) { if (rewind_generation(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after rewind_generation\n"); */ step_key = 0; } } step_key = 0; } switch (mode) { case BACKWARD_PLAY: if (rewind_generation(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after rewind_generation\n"); */ step_key = 0; } /* fall through */ case FAST_REWIND: if (rewind_generation(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after rewind_generation\n"); */ step_key = 0; } redraw_text(); break; case FAST_FORWARD: if (skip_frame(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after skip_frame\n"); */ step_key = 0; } redraw_text(); break; } } t = difftime(time(NULL), start_time); /* printf("%ld frames in %f seconds (%f frames/sec)\n", num_frames, t, num_frames / t); */ if (mit_shm) { XShmDetach(display, &shminfo); XDestroyImage(shm_image); shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); printf("Shared memory released\n"); } free_lndgcs(); if (window != BadValue) remove_window(window); if (redraw_pixmap != BadValue) XFreePixmap(display, redraw_pixmap); if (paint_pixmap != BadValue) XFreePixmap(display, paint_pixmap); free(buffer); free(huff); return (EXIT_SUCCESS); }
/* This function checks that it is actually really possible to create an image using XShm */ gboolean ximageutil_check_xshm_calls (GstXContext * xcontext) { XImage *ximage; XShmSegmentInfo SHMInfo; size_t size; int (*handler) (Display *, XErrorEvent *); gboolean result = FALSE; gboolean did_attach = FALSE; g_return_val_if_fail (xcontext != NULL, FALSE); /* Sync to ensure any older errors are already processed */ XSync (xcontext->disp, FALSE); /* Set defaults so we don't free these later unnecessarily */ SHMInfo.shmaddr = ((void *) -1); SHMInfo.shmid = -1; /* Setting an error handler to catch failure */ error_caught = FALSE; handler = XSetErrorHandler (ximageutil_handle_xerror); /* Trying to create a 1x1 ximage */ GST_DEBUG ("XShmCreateImage of 1x1"); ximage = XShmCreateImage (xcontext->disp, xcontext->visual, xcontext->depth, ZPixmap, NULL, &SHMInfo, 1, 1); /* Might cause an error, sync to ensure it is noticed */ XSync (xcontext->disp, FALSE); if (!ximage || error_caught) { GST_WARNING ("could not XShmCreateImage a 1x1 image"); goto beach; } size = ximage->height * ximage->bytes_per_line; SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); if (SHMInfo.shmid == -1) { GST_WARNING ("could not get shared memory of %" G_GSIZE_FORMAT " bytes", size); goto beach; } SHMInfo.shmaddr = shmat (SHMInfo.shmid, 0, 0); if (SHMInfo.shmaddr == ((void *) -1)) { GST_WARNING ("Failed to shmat: %s", g_strerror (errno)); goto beach; } /* Delete the SHM segment. It will actually go away automatically * when we detach now */ shmctl (SHMInfo.shmid, IPC_RMID, 0); ximage->data = SHMInfo.shmaddr; SHMInfo.readOnly = FALSE; if (XShmAttach (xcontext->disp, &SHMInfo) == 0) { GST_WARNING ("Failed to XShmAttach"); goto beach; } /* Sync to ensure we see any errors we caused */ XSync (xcontext->disp, FALSE); if (!error_caught) { did_attach = TRUE; /* store whether we succeeded in result */ result = TRUE; } beach: /* Sync to ensure we swallow any errors we caused and reset error_caught */ XSync (xcontext->disp, FALSE); error_caught = FALSE; XSetErrorHandler (handler); if (did_attach) { XShmDetach (xcontext->disp, &SHMInfo); XSync (xcontext->disp, FALSE); } if (SHMInfo.shmaddr != ((void *) -1)) shmdt (SHMInfo.shmaddr); if (ximage) XDestroyImage (ximage); return result; }
int main (void) { int i; int allocateOK; ximg = NULL; d = XOpenDisplay (NULL); if (!d) fputs ("Couldn't open display\n", stderr), exit (1); screen = DefaultScreen (d); gc = DefaultGC (d, screen); /* Find a visual */ vis.screen = screen; vlist = XGetVisualInfo (d, VisualScreenMask, &vis, &match); if (!vlist) fputs ("No matched visuals\n", stderr), exit (1); vis = vlist[0]; XFree (vlist); // That's not a fair comparison colormap_size is depth in bits! // if (vis.colormap_size < COLORS) // printf("Colormap is too small: %i.\n",vis.colormap_size); // , exit (1); printf("Colour depth: %i\n",vis.colormap_size); win = XCreateSimpleWindow (d, DefaultRootWindow (d), 0, 0, WIN_W, WIN_H, 0, WhitePixel (d, screen), BlackPixel (d, screen)); int xclass=get_xvisinfo_class(vis); // printf("class = %i\n",xclass); stylee = ( vis.depth > 8 ? styleeTrueColor : styleePrivate ); // printf("stylee=%i\n",stylee); if ( get_xvisinfo_class(vis) % 2 == 1) { /* The odd numbers can redefine colors */ // printf("%i\n",get_xvisinfo_class(vis)); colormap = DefaultColormap (d, screen); Visual *defaultVisual=DefaultVisual(d,screen); /* Allocate cells */ allocateOK = (XAllocColorCells (d, colormap, 1, NULL, 0, color, COLORS) != 0); // printf("Allocated OK? %i\n",allocateOK); if (allocateOK) { // printf("Allocated OK\n"); // This doesn't work for installed colormap! /* Modify the colorcells */ for (i = 0; i < COLORS; i++) xrgb[i].pixel = color[i]; XStoreColors (d, colormap, xrgb, COLORS); } else { colormap = XCreateColormap(d,win,defaultVisual,AllocNone); // redocolors(); } // black = XBlackPixel(d,screen); // white = XWhitePixel(d,screen); } else if ( get_xvisinfo_class(vis) == TrueColor) { colormap = DefaultColormap (d, screen); // printf("TrueColor %i = %i\n",xclass,TrueColor); /* This will lookup the color and sets the xrgb[i].pixel value */ // for (i = 0; i < COLORS; i++) // XAllocColor (d, colormap, &xrgb[i]); } else fprintf (stderr, "Not content with visual class %d.\n", get_xvisinfo_class(vis) ), exit (1); /* Find out if MITSHM is supported and useable */ printf ("MITSHM: "); if (XShmQueryVersion (d, &mitshm_major_code, &mitshm_minor_code, &shared_pixmaps)) { int (*handler) (Display *, XErrorEvent *); ximg = XShmCreateImage (d, vis.visual, vis.depth, XShmPixmapFormat (d), NULL, &shminfo, WIN_W, WIN_H); shminfo.shmid = shmget (IPC_PRIVATE, ximg->bytes_per_line * ximg->height, IPC_CREAT | 0777); shminfo.shmaddr = (char *)shmat (shminfo.shmid, 0, 0); ximg->data = (char *)shminfo.shmaddr; handler = XSetErrorHandler (mitshm_handler); XShmAttach (d, &shminfo); /* Tell the server to attach */ XSync (d, 0); XSetErrorHandler (handler); shmctl (shminfo.shmid, IPC_RMID, 0); /* Mark this shm segment for deletion at once. The segment will * automatically become released when both the server and this * client have detached from it. * (Process termination automagically detach shm segments) */ if (!can_use_mitshm) { shmdt (shminfo.shmaddr); ximg = NULL; } } if (ximg == NULL) { can_use_mitshm = 0; /* XInitImage(ximg); */ ximg = XCreateImage (d, vis.visual, vis.depth, ZPixmap, 0, (char *)malloc (WIN_W * WIN_H), WIN_W, WIN_H, 8, 0); } if (can_use_mitshm) printf ("YES!\n"); else printf ("NO, using fallback instead.\n"); // DrawFractal (ximg,xrgb); XSelectInput (d, win, ButtonPressMask | ExposureMask); XMapWindow (d, win); real_main(); // XNextEvent (d, &ev); // switch (ev.type) { // case ButtonPress: // should_quit = 1; // break; // case Expose: // if (can_use_mitshm) // XShmPutImage (d, win, gc, img, 0, 0, 0, 0, WIN_W, WIN_H, True); // else // XPutImage (d, win, gc, img, 0, 0, 0, 0, WIN_W, WIN_H); // break; // default: // break; // } if (get_xvisinfo_class(vis) % 2 == 1 || get_xvisinfo_class(vis) == TrueColor) { unsigned long color[COLORS]; if (allocateOK) { for (i = 0; i < COLORS; i++) color[i] = xrgb[i].pixel; XFreeColors (d, colormap, color, COLORS, 0); } /* Allocated colors freed */ } else { XUninstallColormap (d, colormap); } if (can_use_mitshm) { XShmDetach (d, &shminfo); /* Server detached */ XDestroyImage (ximg); /* Image struct freed */ shmdt (shminfo.shmaddr); /* We're detached */ } else XDestroyImage (ximg); /* Image struct freed */ XDestroyWindow (d, win); /* Window removed */ XCloseDisplay (d); /* Display disconnected */ /* So you can see how your computer compares to your friend's */ getrusage (RUSAGE_SELF, &resource_utilization); float seconds=(float)resource_utilization.ru_utime.tv_sec +(float)resource_utilization.ru_utime.tv_usec*0.000000001; printf("CPU seconds per frame: %f\n",seconds/(float)frameno); // printf ("CPU seconds consumed: %ds and %dµs\n", // (int) resource_utilization.ru_utime.tv_sec, // (int) resource_utilization.ru_utime.tv_usec); return 0; }
int X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; XGCValues gcv; XVisualInfo vinfo; /* Free the old framebuffer surface */ X11_DestroyWindowFramebuffer(_this, window); /* Create the graphics context for drawing */ gcv.graphics_exposures = False; data->gc = XCreateGC(display, data->xwindow, GCGraphicsExposures, &gcv); if (!data->gc) { SDL_SetError("Couldn't create graphics context"); return -1; } /* Find out the pixel format and depth */ if (X11_GetVisualInfoFromVisual(display, data->visual, &vinfo) < 0) { SDL_SetError("Couldn't get window visual information"); return -1; } *format = X11_GetPixelFormatFromVisualInfo(display, &vinfo); if (*format == SDL_PIXELFORMAT_UNKNOWN) { SDL_SetError("Unknown window pixel format"); return -1; } /* Calculate pitch */ *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); /* Create the actual image */ #ifndef NO_SHARED_MEMORY if (have_mitshm()) { XShmSegmentInfo *shminfo = &data->shminfo; shminfo->shmid = shmget(IPC_PRIVATE, window->h*(*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(display, shminfo); XSync(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) { data->ximage = XShmCreateImage(display, data->visual, vinfo.depth, ZPixmap, shminfo->shmaddr, shminfo, window->w, window->h); if (!data->ximage) { XShmDetach(display, shminfo); XSync(display, False); shmdt(shminfo->shmaddr); } else { /* Done! */ data->use_mitshm = SDL_TRUE; *pixels = shminfo->shmaddr; return 0; } } } #endif /* not NO_SHARED_MEMORY */ *pixels = SDL_malloc(window->h*(*pitch)); if (*pixels == NULL) { SDL_OutOfMemory(); return -1; } data->ximage = XCreateImage(display, data->visual, vinfo.depth, ZPixmap, 0, (char *)(*pixels), window->w, window->h, 32, 0); if (!data->ximage) { SDL_free(*pixels); SDL_SetError("Couldn't create XImage"); return -1; } return 0; }
/* This function checks that it is actually really possible to create an image using XShm */ gboolean gst_xvimagesink_check_xshm_calls (GstXvImageSink * xvimagesink, GstXContext * xcontext) { XvImage *xvimage; XShmSegmentInfo SHMInfo; size_t size; int (*handler) (Display *, XErrorEvent *); gboolean result = FALSE; gboolean did_attach = FALSE; g_return_val_if_fail (xcontext != NULL, FALSE); /* Sync to ensure any older errors are already processed */ XSync (xcontext->disp, FALSE); /* Set defaults so we don't free these later unnecessarily */ SHMInfo.shmaddr = ((void *) -1); SHMInfo.shmid = -1; /* Setting an error handler to catch failure */ error_caught = FALSE; handler = XSetErrorHandler (gst_xvimagesink_handle_xerror); /* Trying to create a 1x1 picture */ GST_DEBUG ("XvShmCreateImage of 1x1"); xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id, xcontext->im_format, NULL, 1, 1, &SHMInfo); /* Might cause an error, sync to ensure it is noticed */ XSync (xcontext->disp, FALSE); if (!xvimage || error_caught) { GST_WARNING ("could not XvShmCreateImage a 1x1 image"); goto beach; } size = xvimage->data_size; SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); if (SHMInfo.shmid == -1) { GST_WARNING ("could not get shared memory of %" G_GSIZE_FORMAT " bytes", size); goto beach; } SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0); if (SHMInfo.shmaddr == ((void *) -1)) { GST_WARNING ("Failed to shmat: %s", g_strerror (errno)); /* Clean up the shared memory segment */ shmctl (SHMInfo.shmid, IPC_RMID, NULL); goto beach; } xvimage->data = SHMInfo.shmaddr; SHMInfo.readOnly = FALSE; if (XShmAttach (xcontext->disp, &SHMInfo) == 0) { GST_WARNING ("Failed to XShmAttach"); /* Clean up the shared memory segment */ shmctl (SHMInfo.shmid, IPC_RMID, NULL); goto beach; } /* Sync to ensure we see any errors we caused */ XSync (xcontext->disp, FALSE); /* Delete the shared memory segment as soon as everyone is attached. * This way, it will be deleted as soon as we detach later, and not * leaked if we crash. */ shmctl (SHMInfo.shmid, IPC_RMID, NULL); if (!error_caught) { GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid, SHMInfo.shmseg); did_attach = TRUE; /* store whether we succeeded in result */ result = TRUE; } else { GST_WARNING ("MIT-SHM extension check failed at XShmAttach. " "Not using shared memory."); } beach: /* Sync to ensure we swallow any errors we caused and reset error_caught */ XSync (xcontext->disp, FALSE); error_caught = FALSE; XSetErrorHandler (handler); if (did_attach) { GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx", SHMInfo.shmid, SHMInfo.shmseg); XShmDetach (xcontext->disp, &SHMInfo); XSync (xcontext->disp, FALSE); } if (SHMInfo.shmaddr != ((void *) -1)) shmdt (SHMInfo.shmaddr); if (xvimage) XFree (xvimage); return result; }