Пример #1
1
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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
0
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();
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
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 );
}
Пример #13
0
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;
}
Пример #14
0
/* 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) {
Пример #15
0
/**
 * 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;
    }
}
Пример #16
0
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);
}
Пример #17
0
/*
 * 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;
}
Пример #18
0
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;
}
Пример #19
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;
}
Пример #20
0
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);
}
Пример #21
0
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;
}
Пример #22
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);
}
Пример #23
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;
}
Пример #24
0
/**
 * 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);
}
Пример #25
0
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;
}
Пример #26
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);
}
Пример #27
0
/* 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;
}
Пример #28
0
  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;
  }
Пример #29
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;
}
Пример #30
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;
}