Example #1
0
File: vo_xv.c Project: hroncok/mpv
static bool allocate_xvimage(struct vo *vo, int foo)
{
    struct xvctx *ctx = vo->priv;
    struct vo_x11_state *x11 = vo->x11;
    // align it for faster OSD rendering (draw_bmp.c swscale usage)
    int aligned_w = FFALIGN(ctx->image_width, 32);
#if HAVE_SHM
    if (x11->display_is_local && XShmQueryExtension(x11->display)) {
        ctx->Shmem_Flag = 1;
        x11->ShmCompletionEvent = XShmGetEventBase(x11->display)
                                + ShmCompletion;
    } else {
        ctx->Shmem_Flag = 0;
        MP_INFO(vo, "Shared memory not supported\nReverting to normal Xv.\n");
    }
    if (ctx->Shmem_Flag) {
        ctx->xvimage[foo] =
            (XvImage *) XvShmCreateImage(x11->display, ctx->xv_port,
                                         ctx->xv_format, NULL,
                                         aligned_w, ctx->image_height,
                                         &ctx->Shminfo[foo]);
        if (!ctx->xvimage[foo])
            return false;

        ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
                                         ctx->xvimage[foo]->data_size,
                                         IPC_CREAT | 0777);
        ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0,
                                                   0);
        if (ctx->Shminfo[foo].shmaddr == (void *)-1)
            return false;
        ctx->Shminfo[foo].readOnly = False;

        ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr;
        XShmAttach(x11->display, &ctx->Shminfo[foo]);
        XSync(x11->display, False);
        shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0);
    } else
#endif
    {
        ctx->xvimage[foo] =
            (XvImage *) XvCreateImage(x11->display, ctx->xv_port,
                                      ctx->xv_format, NULL, aligned_w,
                                      ctx->image_height);
        if (!ctx->xvimage[foo])
            return false;
        ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size);
        if (!ctx->xvimage[foo]->data)
            return false;
        XSync(x11->display, False);
    }
    struct mp_image img = get_xv_buffer(vo, foo);
    img.w = aligned_w;
    mp_image_clear(&img, 0, 0, img.w, img.h);
    return true;
}
Example #2
0
void wsCreateImage( wsTWindow * win,int Width,int Height )
{
 int CompletionType = -1;
 if ( wsUseXShm )
  {
   CompletionType=XShmGetEventBase( wsDisplay ) + ShmCompletion;
   win->xImage=XShmCreateImage( wsDisplay,win->VisualInfo.visual,
                   win->VisualInfo.depth,ZPixmap,NULL,&win->Shminfo,Width,Height );
   if ( win->xImage == NULL )
    {
     mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError );
     exit( 0 );
    }
   win->Shminfo.shmid=shmget( IPC_PRIVATE,win->xImage->bytes_per_line * win->xImage->height,IPC_CREAT|0777 );
   if ( win->Shminfo.shmid < 0 )
    {
     XDestroyImage( win->xImage );
     mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError );
     exit( 0 );
    }
   win->Shminfo.shmaddr=(char *)shmat( win->Shminfo.shmid,0,0 );

   if ( win->Shminfo.shmaddr == ((char *) -1) )
    {
     XDestroyImage( win->xImage );
     if ( win->Shminfo.shmaddr != ((char *) -1) ) shmdt( win->Shminfo.shmaddr );
     mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError );
     exit( 0 );
    }
   win->xImage->data=win->Shminfo.shmaddr;
   win->Shminfo.readOnly=0;
   XShmAttach( wsDisplay,&win->Shminfo );
   XSync(wsDisplay, False);
   shmctl( win->Shminfo.shmid,IPC_RMID,0 );
  }
  else
   {
    win->xImage=XCreateImage( wsDisplay,win->VisualInfo.visual,win->VisualInfo.depth,
                              ZPixmap,0,0,Width,Height,
                              (wsDepthOnScreen == 3) ? 32 : wsDepthOnScreen,
                              0 );
    if ( ( win->xImage->data=malloc( win->xImage->bytes_per_line * win->xImage->height ) ) == NULL )
     {
      mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_NotEnoughMemoryDrawBuffer );
      exit( 0 );
     }
   }
 win->ImageData=(unsigned char *)win->xImage->data;
 win->ImageDataw=(unsigned short int *)win->xImage->data;
 win->ImageDatadw=(unsigned int *)win->xImage->data;
}
Example #3
0
static int init_xshm_stuff(struct DriverInstance* sh, char* error_text,
                           int text_len)
{
  sh->completion_type = XShmGetEventBase(sh->display) + ShmCompletion;
  sh->event_pending = 0;

  /* allocate shared memory */

  // changed flags from 0777 to 0666, see
  // http://lists.apple.com/archives/unix-porting/2004/Apr/msg00081.html
  sh->shminfo.shmid = shmget (IPC_PRIVATE,
                              MAX_RES_X * MAX_RES_Y * 4,
                              0666 | IPC_CREAT);

  if (sh->shminfo.shmid == -1)
    {
      snprintf(error_text, text_len, "shmget() failed, errno=%i!", errno);
      return 0;
    }

  /* attach shared memory to our process */
  sh->shminfo.shmaddr = shmat (sh->shminfo.shmid, 0, 0);
  if (sh->shminfo.shmaddr == (void*) -1) // TODO
    {
      shmctl (sh->shminfo.shmid, IPC_RMID, 0);
      snprintf(error_text, text_len, "shmat() failed!");
      return 0;
    }

  /* the server is not allowed to write to the shared memory */
  sh->shminfo.readOnly = True;

  /* tell the server to attach to the shared memory */
  if (XShmAttach(sh->display, &sh->shminfo) != True)
    {
      shmdt (sh->shminfo.shmaddr);
      shmctl (sh->shminfo.shmid, IPC_RMID, 0);

      snprintf(error_text, text_len,
               "Server would not attach to shared memory!");
      return 0;
    }

  return 1;
}
Example #4
0
int bg_x11_window_check_shm(Display * dpy, int * completion_type)
  {
#if 0
  return 0;
#else
  int major;
  int minor;
  Bool pixmaps;
  int ret;
  if ((XShmQueryVersion (dpy, &major, &minor,
                         &pixmaps) == 0) ||
      (major < 1) || ((major == 1) && (minor < 1)))
    ret = 0;
  else
    ret = 1;
  if(ret)
    *completion_type = XShmGetEventBase(dpy) + ShmCompletion;
  return ret;
#endif
  }
Example #5
0
static void getMyXImage(void)
{
#ifdef HAVE_SHM
    if (mLocalDisplay && XShmQueryExtension(mDisplay))
        Shmem_Flag = 1;
    else
    {
        Shmem_Flag = 0;
        mp_msg(MSGT_VO, MSGL_WARN,
               "Shared memory not supported\nReverting to normal Xlib\n");
    }
    if (Shmem_Flag)
        CompletionType = XShmGetEventBase(mDisplay) + ShmCompletion;

    if (Shmem_Flag)
    {
        myximage =
            XShmCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, NULL,
                            &Shminfo[0], image_width, image_height);
        if (myximage == NULL)
        {
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( Ximage error )\n");
            goto shmemerror;
        }
        Shminfo[0].shmid = shmget(IPC_PRIVATE,
                                  myximage->bytes_per_line *
                                  myximage->height, IPC_CREAT | 0777);
        if (Shminfo[0].shmid < 0)
        {
            XDestroyImage(myximage);
            mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno));
            //perror( strerror( errno ) );
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( seg id error )\n");
            goto shmemerror;
        }
        Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0);

        if (Shminfo[0].shmaddr == ((char *) -1))
        {
            XDestroyImage(myximage);
            if (Shminfo[0].shmaddr != ((char *) -1))
                shmdt(Shminfo[0].shmaddr);
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( address error )\n");
            goto shmemerror;
        }
        myximage->data = Shminfo[0].shmaddr;
        ImageData = (unsigned char *) myximage->data;
        Shminfo[0].readOnly = False;
        XShmAttach(mDisplay, &Shminfo[0]);

        XSync(mDisplay, False);

        if (gXErrorFlag)
        {
            XDestroyImage(myximage);
            shmdt(Shminfo[0].shmaddr);
            mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n");
            gXErrorFlag = 0;
            goto shmemerror;
        } else
            shmctl(Shminfo[0].shmid, IPC_RMID, 0);

        {
            static int firstTime = 1;

            if (firstTime)
            {
                mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n");
                firstTime = 0;
            }
        }
    } else
    {
      shmemerror:
        Shmem_Flag = 0;
#endif
        myximage = XCreateImage(mDisplay, vinfo.visual, depth, ZPixmap,
                             0, NULL, image_width, image_height, 8, 0);
        ImageDataOrig = malloc(myximage->bytes_per_line * image_height + 32);
        myximage->data = ImageDataOrig + 16 - ((long)ImageDataOrig & 15);
        memset(myximage->data, 0, myximage->bytes_per_line * image_height);
        ImageData = myximage->data;
#ifdef HAVE_SHM
    }
#endif
}
Example #6
0
File: vo_x11.c Project: kax4/mpv
static void getMyXImage(struct priv *p)
{
    struct vo *vo = p->vo;
#ifdef HAVE_SHM
    if (vo->x11->display_is_local && XShmQueryExtension(vo->x11->display))
        p->Shmem_Flag = 1;
    else {
        p->Shmem_Flag = 0;
        mp_msg(MSGT_VO, MSGL_WARN,
               "Shared memory not supported\nReverting to normal Xlib\n");
    }
    if (p->Shmem_Flag)
        p->CompletionType = XShmGetEventBase(vo->x11->display) + ShmCompletion;

    if (p->Shmem_Flag) {
        p->myximage =
            XShmCreateImage(vo->x11->display, p->vinfo.visual, p->depth,
                            ZPixmap, NULL, &p->Shminfo[0], p->image_width,
                            p->image_height);
        if (p->myximage == NULL) {
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( Ximage error )\n");
            goto shmemerror;
        }
        p->Shminfo[0].shmid = shmget(IPC_PRIVATE,
                                     p->myximage->bytes_per_line *
                                        p->myximage->height,
                                     IPC_CREAT | 0777);
        if (p->Shminfo[0].shmid < 0) {
            XDestroyImage(p->myximage);
            mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno));
            //perror( strerror( errno ) );
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( seg id error )\n");
            goto shmemerror;
        }
        p->Shminfo[0].shmaddr = (char *) shmat(p->Shminfo[0].shmid, 0, 0);

        if (p->Shminfo[0].shmaddr == ((char *) -1)) {
            XDestroyImage(p->myximage);
            if (p->Shminfo[0].shmaddr != ((char *) -1))
                shmdt(p->Shminfo[0].shmaddr);
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( address error )\n");
            goto shmemerror;
        }
        p->myximage->data = p->Shminfo[0].shmaddr;
        p->ImageData = (unsigned char *) p->myximage->data;
        p->Shminfo[0].readOnly = False;
        XShmAttach(vo->x11->display, &p->Shminfo[0]);

        XSync(vo->x11->display, False);

        if (p->gXErrorFlag) {
            XDestroyImage(p->myximage);
            shmdt(p->Shminfo[0].shmaddr);
            mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n");
            p->gXErrorFlag = 0;
            goto shmemerror;
        } else
            shmctl(p->Shminfo[0].shmid, IPC_RMID, 0);

        if (!p->firstTime) {
            mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n");
            p->firstTime = 1;
        }
    } else {
shmemerror:
        p->Shmem_Flag = 0;
#endif
    p->myximage =
        XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
                     0, NULL, p->image_width, p->image_height, 8, 0);
    p->ImageDataOrig =
        malloc(p->myximage->bytes_per_line * p->image_height + 32);
    p->myximage->data = p->ImageDataOrig + 16 - ((long)p->ImageDataOrig & 15);
    memset(p->myximage->data, 0, p->myximage->bytes_per_line * p->image_height);
    p->ImageData = p->myximage->data;
#ifdef HAVE_SHM
}
#endif
}
Example #7
0
void I_InitGraphics(void)
{
  const char*	displayname = NULL;
  int		n;
  int		pnum;
  int		x=0;
  int		y=0;
  
  {  
    static int		firsttime=1;
    
    if (!firsttime) {
      return;
    }
    firsttime = 0;
  }

  { // Check for screen enlargement
    char str[3] = { '-', 0, 0 };

    for (n=1; n<4; n++) {
      str[1] = n + '0';
      if (M_CheckParm(str)) multiply = n;
    }
  }
  
  X_width = SCREENWIDTH * multiply;
  X_height = SCREENHEIGHT * multiply;
  
  // check for command-line geometry
  if ( (pnum=M_CheckParm("-geom")) ? 1 : (pnum=M_CheckParm("-geometry"))) 
   if (pnum+1 < myargc) { // check parm given
    // warning: char format, different type arg
    char	xsign=' ';
    char	ysign=' ';
    const char* pg = myargv[pnum+1];
    
    pg += strcspn(pg, "+-");
    
    // warning: char format, different type arg 3,5
    n = sscanf(pg, "%c%d%c%d", &xsign, &x, &ysign, &y);
    
    if (n==2)
      x = y = 0;
    else if (n==4) {
      if (xsign == '-')
	x = -x;
      if (ysign == '-')
	y = -y;
    } else
      fprintf(stderr, "I_InitGraphics: bad -geom offsets \"%s\"\n", pg);
  }
  
  // check for command-line display name
  if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment
    displayname = myargv[pnum+1];
  // CPhipps - support more standard -display param
  if ( (pnum=M_CheckParm("-display")) ) // ditto
    displayname = myargv[pnum+1];
  // CPhipps - and -displayname as for xterm
  if ( (pnum=M_CheckParm("-displayname")) ) // ditto
    displayname = myargv[pnum+1];

  // open the display
  if (!(X_display = XOpenDisplay(displayname))) {
    if (displayname)
      I_Error("Could not open display [%s]", displayname);
    else
      I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
  }

  // use the default visual 
  X_screen = DefaultScreen(X_display);

  X_deletewin = XInternAtom(X_display, "WM_DELETE_WINDOW", False);

  // check for the MITSHM extension
  // even if it's available, make sure it's a local connection
  lprintf(LO_INFO,"I_InitGraphics:");

#ifdef HAVE_LIBXXF86DGA
  if ((doDga = (M_CheckParm("-dga") && XF86DGAQueryExtension(X_display, &n, &n)) )) {
    lprintf(LO_INFO,"I_InitGraphics: found DGA extension\n");
    if (M_CheckParm("-noaccel") || (X_opt & 1)) doDga = false;
    else lprintf(LO_INFO, "(using DGA)");
  }
  else 
#endif
#ifdef HAVE_LIBXEXT
  if ((doShm = XShmQueryExtension(X_display))) {

    if (!displayname) displayname = getenv("DISPLAY");
    
    if (displayname) {
      // CPhipps - don't modify the original string, please.
      //         - oops my code here was totally wrong
      // I have no idea exactly what should go here.

      if (M_CheckParm("-noaccel") || (X_opt & 1)) doShm = false;
      else lprintf(LO_INFO, "(using MITShm)");
    }
  }
  else 
#endif 
    if (devparm) 
      fprintf(stderr, "No MITShm extension in server");

  if (devparm)
    fputc('\n', stderr);

  if ((X_visual = I_FindMode(X_screen)) == NULL) 
    I_Error("Unsupported visual");
  
  // create the colormap
  X_cmap = XCreateColormap(X_display, RootWindow(X_display, X_screen), 
			   X_visual, true_color ? AllocNone : AllocAll);

#ifdef HAVE_LIBXXF86DGA
  /* setup for DGA */
  if(doDga) {
     char *fb;
     X_mainWindow=RootWindow(X_display, X_screen);
     XF86DGAGetViewPortSize(X_display, X_screen, &DGA_width, &DGA_height);
     XF86DGAGetVideo(X_display, X_screen, &fb,
		     &DGA_real_width, &DGA_pagelen, &DGA_memlen);

     fprintf(stderr,
	     "I_InitGraphics: DGA reports %dx%d scan=%d page=%d mem=%d\n",
	     DGA_width,DGA_height,DGA_real_width,DGA_pagelen,DGA_memlen);

     out_buffer=(void*)fb;

     XF86DGADirectVideo(X_display, X_screen, XF86DGADirectGraphics);
     XF86DGASetVidPage(X_display, X_screen, 0);
     XF86DGAForkApp(X_screen);
     XSelectInput(X_display, X_mainWindow, KeyPressMask | KeyReleaseMask);
     fprintf(stderr,"DGA framebuffer @%p\n",fb);
     memset(fb,0,102400);
  }
#endif

#ifdef HAVE_LIBXXF86DGA
  if(!doDga)
#endif

  { // setup attributes for main window
    unsigned long	attribmask;
    XSetWindowAttributes attribs;

    attribmask = CWEventMask | CWColormap | CWBorderPixel;
    attribs.event_mask = KeyPressMask | KeyReleaseMask
#ifdef MONITOR_VISIBILITY
      | VisibilityChangeMask
#endif
      | ExposureMask;
    
    attribs.colormap = X_cmap;
    attribs.border_pixel = 0;
    
    // create the main window
    X_mainWindow = XCreateWindow( X_display,
				  RootWindow(X_display, X_screen),
				  x, y,
				  X_width, X_height,
				  0, // borderwidth
				  X_bpp, // depth
				  InputOutput, X_visual,
				  attribmask, &attribs );
  }
  
#ifdef HAVE_LIBXXF86DGA
  if(!doDga)
#endif

  {
    XClassHint c_hint;
    XTextProperty x_name;
    XSizeHints s_hint;
    XWMHints wm_hint;
    char lcase_buf[10], ucase_buf[10];
    char* str;

    strcpy(str = lcase_buf, lcase_lxdoom);
    XStringListToTextProperty(&str, 1, &x_name);

    s_hint.flags = PSize | PMinSize | PMaxSize;
    s_hint.min_width = s_hint.max_width = s_hint.base_width = X_width;
    s_hint.min_height = s_hint.max_height = s_hint.base_height = X_height;

    wm_hint.input = True;
    wm_hint.window_group = X_mainWindow;
    wm_hint.flags = InputHint | WindowGroupHint;

    strcpy(c_hint.res_name = lcase_buf, lcase_lxdoom);
    strcpy(c_hint.res_class = ucase_buf, ucase_lxdoom);
    
    XSetWMProtocols(X_display, X_mainWindow, &X_deletewin, 1);
    
    XSetWMProperties(X_display, X_mainWindow, &x_name, &x_name, 
		     (char**)myargv, myargc, &s_hint, &wm_hint, &c_hint);

    XFlush(X_display);
  }

#ifdef HAVE_LIBXXF86DGA
  if(!doDga)
#endif
  // Hide pointer while over this window
  XDefineCursor(X_display, X_mainWindow,
		I_XCreateNullCursor( X_display, X_mainWindow ) );
  
  { // create the GC
    XGCValues		xgcvalues;
    int		valuemask;
    
    valuemask = GCGraphicsExposures;
    xgcvalues.graphics_exposures = False;
    X_gc = XCreateGC(X_display, X_mainWindow, valuemask, &xgcvalues);
  }
  
#ifdef HAVE_LIBXXF86DGA
  if(!doDga)
#endif
  {
     // name the window
     XStoreName(X_display, X_mainWindow, "lxdoom");
  
     // map the window
     XMapWindow(X_display, X_mainWindow);
  }  

  // wait until it is OK to draw
#ifdef HAVE_LIBXXF86DGA
  if(!doDga)
#endif
  do {
    XNextEvent(X_display, &X_event);
  } while (!(X_event.type == Expose && !X_event.xexpose.count));

#ifdef HAVE_LIBXXF86DGA
  if(doDga) {}
  else
#endif

#ifdef HAVE_LIBXEXT
  if (doShm) {
    
    X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
    
    // create the image
    image = XShmCreateImage( X_display, X_visual,
			     X_bpp, ZPixmap,
			     0, &X_shminfo,
			     X_width, X_height );
    
    I_XShmGrabSharedMemory(image->bytes_per_line * image->height);
    
    if (!(out_buffer = (pval*)image->data)) {
      perror("");
      I_Error("shmat() failed in I_InitGraphics()");
    }
    
    // get the X server to attach to it
    if (!XShmAttach(X_display, &X_shminfo))
      I_Error("XShmAttach() failed in InitGraphics()");
    
    if (!expand_buffer) {
      // Render directly into MitSHM memory
      Z_Free(screens[0]);
      screens[0] = (unsigned char *) (image->data); 
    }
  } else
#endif 
  {
    if (!expand_buffer) {
      // Very efficient, render directly into image
      out_buffer = (pval*)screens[0];
    } else {
      // Will have to enlarge from rendering buffer
      //  into image buffer
      out_buffer = (pval*)malloc (X_width * X_height * BYTESPP);
    }

	{ 
/* hack to enable 15 bpp usage */
		int bpp=X_bpp;
		if(bpp==15)bpp=16;

    	image=XCreateImage( X_display, X_visual,
				X_bpp, ZPixmap,
				0, (char*)out_buffer,
				X_width, X_height,
				bpp, 0);
#ifdef NOT_NOW
    image=XCreateImage( X_display, X_visual,
			X_bpp, ZPixmap,
			0, (char*)out_buffer,
			X_width, X_height,
			X_bpp, 0);
#endif

	}
    if (!image) 
      I_Error("XCreateImage: failed to create image %dx%d %d bpp", 
	      X_width, X_height, X_bpp);
  }
  
  atexit(I_ShutdownGraphics);

  I_XInitInputs();
}
Example #8
0
static PyObject *
tkwin_ShmCompletionEventType(TkWinObject * self, PyObject *args)
{
    return PyInt_FromLong(XShmGetEventBase(Tk_Display(self->tkwin))
			  + ShmCompletion);
}
Example #9
0
int main (int argc, char* argv[]) {
  int		yuv_width = 1024;
  int		yuv_height = 768;
  
  int		xv_port = -1;
  int		adaptor, encodings, attributes, formats;
  int		i, j, ret, p, _d, _w, _h;
  long		secsb, secsa, frames;
  
  XvAdaptorInfo		*ai;
  XvEncodingInfo	*ei;
  XvAttribute		*at;
  XvImageFormatValues	*fo;

  XvImage		*yuv_image;

#define GUID_YUV12_PLANAR 0x32315659

  unsigned int		p_version, p_release,
  			p_request_base, p_event_base, p_error_base;
  int			p_num_adaptors;
   	
  Display		*dpy;
  Window		window, _dw;
  XSizeHints		hint;
  XSetWindowAttributes	xswa;
  XVisualInfo		vinfo;
  int			screen;
  unsigned long		mask;
  XEvent		event;
  GC			gc;

  /** for shm */
  int 			shmem_flag = 0;
  XShmSegmentInfo	yuv_shminfo;
  int			CompletionType;


  printf("starting up video testapp...\n\n");
  
  adaptor = -1;
	
  dpy = XOpenDisplay(NULL);
  if (dpy == NULL) {
    printf("Cannot open Display.\n");
    exit (-1);
  }
  
  screen = DefaultScreen(dpy);
  
  /** find best display */
  if (XMatchVisualInfo(dpy, screen, 24, TrueColor, &vinfo)) {
    printf(" found 24bit TrueColor\n");
  } else
    if (XMatchVisualInfo(dpy, screen, 16, TrueColor, &vinfo)) {
      printf(" found 16bit TrueColor\n");
    } else
      if (XMatchVisualInfo(dpy, screen, 15, TrueColor, &vinfo)) {
	printf(" found 15bit TrueColor\n");
      } else
  	if (XMatchVisualInfo(dpy, screen, 8, PseudoColor, &vinfo)) {
	  printf(" found 8bit PseudoColor\n");
  	} else
	  if (XMatchVisualInfo(dpy, screen, 8, GrayScale, &vinfo)) {
	    printf(" found 8bit GrayScale\n");
	  } else
	    if (XMatchVisualInfo(dpy, screen, 8, StaticGray, &vinfo)) {
	      printf(" found 8bit StaticGray\n");
	    } else
	      if (XMatchVisualInfo(dpy, screen, 1, StaticGray, &vinfo)) {
  		printf(" found 1bit StaticGray\n");
	      } else {
  		printf("requires 16 bit display\n");
  		exit (-1);
	      }
  
  CompletionType = -1;	
  
  hint.x = 1;
  hint.y = 1;
  hint.width = yuv_width;
  hint.height = yuv_height;
  hint.flags = PPosition | PSize;
  
  xswa.colormap =  XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual, AllocNone);
  xswa.event_mask = StructureNotifyMask | ExposureMask;
  xswa.background_pixel = 0;
  xswa.border_pixel = 0;
  
  mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  
  window = XCreateWindow(dpy, DefaultRootWindow(dpy),
			 0, 0,
			 yuv_width,
			 yuv_height,
			 0, vinfo.depth,
			 InputOutput,
			 vinfo.visual,
			 mask, &xswa);
  
  XStoreName(dpy, window, "XV");
  XSetIconName(dpy, window, "XV");
  
  XSelectInput(dpy, window, StructureNotifyMask);
  
  /** Map window */
  XMapWindow(dpy, window);
  
  /** Wait for map. */
  do {
    XNextEvent(dpy, &event);
  }
  while (event.type != MapNotify || event.xmap.event != window);
  
  if (XShmQueryExtension(dpy)) shmem_flag = 1;
  if (!shmem_flag) {
    printf("no shmem available.\n");
    exit (-1);
  }
  
  if (shmem_flag==1) CompletionType = XShmGetEventBase(dpy) + ShmCompletion;
  
  
  /**--------------------------------- XV ------------------------------------*/
  printf("beginning to parse the Xvideo extension...\n\n");
  
  /** query and print Xvideo properties */
  ret = XvQueryExtension(dpy, &p_version, &p_release, &p_request_base,
			 &p_event_base, &p_error_base);
  if (ret != Success) {
    if (ret == XvBadExtension)
      printf("XvBadExtension returned at XvQueryExtension.\n");
    else
      if (ret == XvBadAlloc)
	printf("XvBadAlloc returned at XvQueryExtension.\n");
      else
	printf("other error happened at XvQueryExtension.\n");
  }
  printf("========================================\n");
  printf("XvQueryExtension returned the following:\n");
  printf("p_version      : %u\n", p_version);
  printf("p_release      : %u\n", p_release);
  printf("p_request_base : %u\n", p_request_base);
  printf("p_event_base   : %u\n", p_event_base);
  printf("p_error_base   : %u\n", p_error_base);
  printf("========================================\n");
  
  ret = XvQueryAdaptors(dpy, DefaultRootWindow(dpy),
			&p_num_adaptors, &ai);
  
  if (ret != Success) {
    if (ret == XvBadExtension)
      printf("XvBadExtension returned at XvQueryExtension.\n");
    else
      if (ret == XvBadAlloc)
	printf("XvBadAlloc returned at XvQueryExtension.\n");
      else
	printf("other error happaned at XvQueryAdaptors.\n");
  }
  printf("=======================================\n");
  printf("XvQueryAdaptors returned the following:\n");
  printf("%d adaptors available.\n", p_num_adaptors);
  for (i = 0; i < p_num_adaptors; i++) {
    printf(" name:        %s\n"
	   " type:        %s%s%s%s%s\n"
	   " ports:       %ld\n"
	   " first port:  %ld\n",
	   ai[i].name,
	   (ai[i].type & XvInputMask)	? "input | "	: "",
	   (ai[i].type & XvOutputMask)	? "output | "	: "",
	   (ai[i].type & XvVideoMask)	? "video | "	: "",
	   (ai[i].type & XvStillMask)	? "still | "	: "",
	   (ai[i].type & XvImageMask)	? "image | "	: "",
	   ai[i].num_ports,
	   ai[i].base_id);
    xv_port = ai[i].base_id;
    
    printf("adaptor %d ; format list:\n", i);
    for (j = 0; j < ai[i].num_formats; j++) {
      printf(" depth=%d, visual=%ld\n",
	     ai[i].formats[j].depth,
	     ai[i].formats[j].visual_id);
    }
    for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
      
      printf(" encoding list for port %d\n", p);
      if (XvQueryEncodings(dpy, p, &encodings, &ei) != Success) {
	printf("XvQueryEncodings failed.\n");
	continue;
      }
      for (j = 0; j < encodings; j++) {
	printf("  id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n",
	       ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
	       ei[j].rate.numerator, ei[j].rate.denominator);
      }
      XvFreeEncodingInfo(ei);
      
      printf(" attribute list for port %d\n", p);
      at = XvQueryPortAttributes(dpy, p, &attributes);
      for (j = 0; j < attributes; j++) {
	printf("  name:       %s\n"
	       "  flags:     %s%s\n"
	       "  min_color:  %i\n"
	       "  max_color:  %i\n",
	       at[j].name,
	       (at[j].flags & XvGettable) ? " get" : "",
	       (at[j].flags & XvSettable) ? " set" : "",						
	       at[j].min_value, at[j].max_value);
      }
      if (at)
	XFree(at);
      
      printf(" image format list for port %d\n", p);
      fo = XvListImageFormats(dpy, p, &formats);
      for (j = 0; j < formats; j++) {
	printf("  0x%x (%4.4s) %s\n",
	       fo[j].id,
	       (char *)&fo[j].id,
	       (fo[j].format == XvPacked) ? "packed" : "planar");
      }
      if (fo)
	XFree(fo);
    }
    printf("\n");
  }
  if (p_num_adaptors > 0)
    XvFreeAdaptorInfo(ai);
  if (xv_port == -1)
    exit (0);
  
  gc = XCreateGC(dpy, window, 0, 0);		
  
  yuv_image = XvShmCreateImage(dpy, xv_port, GUID_YUV12_PLANAR, 0, yuv_width, yuv_height, &yuv_shminfo);
  yuv_shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777);
  yuv_shminfo.shmaddr = yuv_image->data = shmat(yuv_shminfo.shmid, 0, 0);
  yuv_shminfo.readOnly = False;
  
  if (!XShmAttach(dpy, &yuv_shminfo)) {
    printf("XShmAttach failed !\n");
    exit (-1);
  }
  
  for (i = 0; i < yuv_image->height; i++) {
    for (j = 0; j < yuv_image->width; j++) {
      yuv_image->data[yuv_image->width*i + j] = i*j;
    }
  }
  
  printf("%d\n", yuv_image->data_size);
  int joe = 0;
  while (1) {
    frames = secsa = secsb = 0;
    time(&secsa);
    while (frames < 200) {	
        XGetGeometry(dpy, window, &_dw, &_d, &_d, &_w, &_h, &_d, &_d);
        for (i = 0; i < yuv_image->height * 1.5; i++) {
            for (j = 0; j < yuv_image->width; j++) {
                yuv_image->data[yuv_image->width*i + j] = (i + j + joe / 5);
            }
        }
   
      XvShmPutImage(dpy, xv_port, window, gc, yuv_image,
		    0, 0, yuv_image->width, yuv_image->height,
		    0, 0, _w, _h, True);
      
      /* XFlush(dpy); */
      joe++;
      frames++;
    }
    time(&secsb);
    printf("%ld frames in %ld seconds; %.4f fps\n", frames, secsb-secsa, (double) frames/(secsb-secsa));
  }
  
  return 0;
}
/** The initialization function
  * This function opens the frame buffer device and allocates memory for display
  * also it finds the frame buffer supported display formats
  */
OMX_ERRORTYPE omx_xvideo_sink_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) {
  omx_xvideo_sink_component_PrivateType* omx_xvideo_sink_component_Private = openmaxStandComp->pComponentPrivate;
  omx_xvideo_sink_component_PortType* pPort = (omx_xvideo_sink_component_PortType *) omx_xvideo_sink_component_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX];
  int yuv_width  = pPort->sPortParam.format.video.nFrameWidth;
  int yuv_height = pPort->sPortParam.format.video.nFrameHeight;
  unsigned int err,i;

  omx_xvideo_sink_component_Private->dpy = XOpenDisplay(NULL);
  omx_xvideo_sink_component_Private->screen = DefaultScreen(omx_xvideo_sink_component_Private->dpy);

  XGetWindowAttributes(omx_xvideo_sink_component_Private->dpy,
    DefaultRootWindow(omx_xvideo_sink_component_Private->dpy),
    &omx_xvideo_sink_component_Private->attribs);

  XMatchVisualInfo(omx_xvideo_sink_component_Private->dpy,
    omx_xvideo_sink_component_Private->screen,
    omx_xvideo_sink_component_Private->attribs.depth, TrueColor, &
    omx_xvideo_sink_component_Private->vinfo);

  omx_xvideo_sink_component_Private->wmDeleteWindow = XInternAtom(omx_xvideo_sink_component_Private->dpy, "WM_DELETE_WINDOW", False);

  omx_xvideo_sink_component_Private->hint.x = 1;
  omx_xvideo_sink_component_Private->hint.y = 1;
  omx_xvideo_sink_component_Private->hint.width = yuv_width;
  omx_xvideo_sink_component_Private->hint.height = yuv_height;
  omx_xvideo_sink_component_Private->hint.flags = PPosition | PSize;

  omx_xvideo_sink_component_Private->xswa.colormap = XCreateColormap(omx_xvideo_sink_component_Private->dpy,
                                                                     DefaultRootWindow(omx_xvideo_sink_component_Private->dpy),
                                                                     omx_xvideo_sink_component_Private->vinfo.visual, AllocNone);
  omx_xvideo_sink_component_Private->xswa.event_mask = StructureNotifyMask | ExposureMask;
  omx_xvideo_sink_component_Private->xswa.background_pixel = 0;
  omx_xvideo_sink_component_Private->xswa.border_pixel = 0;

  omx_xvideo_sink_component_Private->window =
                        XCreateWindow(omx_xvideo_sink_component_Private->dpy,
                                      DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), 0, 0, yuv_width,
                                      yuv_height, 0, omx_xvideo_sink_component_Private->vinfo.depth, InputOutput,
                                      omx_xvideo_sink_component_Private->vinfo.visual,
                                      CWBackPixel | CWBorderPixel | CWColormap |
                                      CWEventMask, &omx_xvideo_sink_component_Private->xswa);

  XSelectInput(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, StructureNotifyMask);
  XSetStandardProperties(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, "xvcam", "xvcam", None, NULL, 0,
                        &omx_xvideo_sink_component_Private->hint);

  XSetWMProtocols(omx_xvideo_sink_component_Private->dpy,
                  omx_xvideo_sink_component_Private->window,
                  &omx_xvideo_sink_component_Private->wmDeleteWindow, 1);
  XMapWindow(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window);

  if (XShmQueryExtension(omx_xvideo_sink_component_Private->dpy))
    omx_xvideo_sink_component_Private->CompletionType = XShmGetEventBase(omx_xvideo_sink_component_Private->dpy) + ShmCompletion;
  else
    return OMX_ErrorUndefined;

  if (Success !=
     XvQueryExtension(omx_xvideo_sink_component_Private->dpy,
                      &omx_xvideo_sink_component_Private->ver,
                      &omx_xvideo_sink_component_Private->rel,
                      &omx_xvideo_sink_component_Private->req,
                      &omx_xvideo_sink_component_Private->ev, &err))
    fprintf(stderr, "Couldn't do Xv stuff\n");

  if (Success !=
     XvQueryAdaptors(omx_xvideo_sink_component_Private->dpy,
                     DefaultRootWindow(omx_xvideo_sink_component_Private->dpy),
                     &omx_xvideo_sink_component_Private->adapt,
                     &omx_xvideo_sink_component_Private->ai))
    fprintf(stderr, "Couldn't do Xv stuff\n");

  for (i = 0; i < (int) omx_xvideo_sink_component_Private->adapt; i++) {
    omx_xvideo_sink_component_Private->xv_port = omx_xvideo_sink_component_Private->ai[i].base_id;
  }

  if (omx_xvideo_sink_component_Private->adapt > 0)
    XvFreeAdaptorInfo(omx_xvideo_sink_component_Private->ai);

  omx_xvideo_sink_component_Private->gc = XCreateGC(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, 0, 0);

  omx_xvideo_sink_component_Private->yuv_image = XvShmCreateImage(omx_xvideo_sink_component_Private->dpy,
                                                                  omx_xvideo_sink_component_Private->xv_port,
                                                                  GUID_I420_PLANAR, 0, yuv_width,
                                                                  yuv_height, &omx_xvideo_sink_component_Private->yuv_shminfo);

  omx_xvideo_sink_component_Private->yuv_shminfo.shmid    = shmget(IPC_PRIVATE, omx_xvideo_sink_component_Private->yuv_image->data_size, IPC_CREAT | 0777);
  omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr  = (char *) shmat(omx_xvideo_sink_component_Private->yuv_shminfo.shmid, 0, 0);
  omx_xvideo_sink_component_Private->yuv_image->data      = omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr;
  omx_xvideo_sink_component_Private->yuv_shminfo.readOnly = False;

  if (!XShmAttach(omx_xvideo_sink_component_Private->dpy, &omx_xvideo_sink_component_Private->yuv_shminfo)) {
    printf("XShmAttach go boom boom!\n");
    return OMX_ErrorUndefined;
  }

  omx_xvideo_sink_component_Private->old_time = 0;
  omx_xvideo_sink_component_Private->new_time = 0;

  omx_xvideo_sink_component_Private->bIsXVideoInit = OMX_TRUE;
  /*Signal XVideo Initialized*/
  tsem_up(omx_xvideo_sink_component_Private->xvideoSyncSem);

  return OMX_ErrorNone;
}
Example #11
0
File: vo_x11.c Project: chyiz/mpv
static bool getMyXImage(struct priv *p, int foo)
{
    struct vo *vo = p->vo;
#if HAVE_SHM && HAVE_XEXT
    if (vo->x11->display_is_local && XShmQueryExtension(vo->x11->display)) {
        p->Shmem_Flag = 1;
        vo->x11->ShmCompletionEvent = XShmGetEventBase(vo->x11->display)
                                    + ShmCompletion;
    } else {
        p->Shmem_Flag = 0;
        MP_WARN(vo, "Shared memory not supported\nReverting to normal Xlib\n");
    }

    if (p->Shmem_Flag) {
        p->myximage[foo] =
            XShmCreateImage(vo->x11->display, p->vinfo.visual, p->depth,
                            ZPixmap, NULL, &p->Shminfo[foo], p->image_width,
                            p->image_height);
        if (p->myximage[foo] == NULL) {
            MP_WARN(vo, "Shared memory error,disabling ( Ximage error )\n");
            goto shmemerror;
        }
        p->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
                                       p->myximage[foo]->bytes_per_line *
                                       p->myximage[foo]->height,
                                       IPC_CREAT | 0777);
        if (p->Shminfo[foo].shmid < 0) {
            XDestroyImage(p->myximage[foo]);
            MP_WARN(vo, "Shared memory error,disabling ( seg id error )\n");
            goto shmemerror;
        }
        p->Shminfo[foo].shmaddr = (char *) shmat(p->Shminfo[foo].shmid, 0, 0);

        if (p->Shminfo[foo].shmaddr == ((char *) -1)) {
            XDestroyImage(p->myximage[foo]);
            MP_WARN(vo, "Shared memory error,disabling ( address error )\n");
            goto shmemerror;
        }
        p->myximage[foo]->data = p->Shminfo[foo].shmaddr;
        p->Shminfo[foo].readOnly = False;
        XShmAttach(vo->x11->display, &p->Shminfo[foo]);

        XSync(vo->x11->display, False);

        shmctl(p->Shminfo[foo].shmid, IPC_RMID, 0);
    } else {
shmemerror:
        p->Shmem_Flag = 0;
#endif
    MP_VERBOSE(vo, "Not using SHM.\n");
    p->myximage[foo] =
        XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
                     0, NULL, p->image_width, p->image_height, 8, 0);
    if (!p->myximage[foo]) {
        MP_WARN(vo, "could not allocate image");
        return false;
    }
    p->myximage[foo]->data =
        calloc(1, p->myximage[foo]->bytes_per_line * p->image_height + 32);
#if HAVE_SHM && HAVE_XEXT
}
#endif
    return true;
}
Example #12
0
static Bool
init_x11( char * error_buf )
{
	/*XXX*/ /* Namely, support for -display host:0.0 etc. */
	XrmQuark common_quarks_list[20];  /*XXX change number of elements if necessary */
	XrmQuarkList ql = common_quarks_list;
	XGCValues gcv;
	char *common_quarks =
		"String."
		"Blinkinvisibletime.blinkinvisibletime."
		"Blinkvisibletime.blinkvisibletime."
		"Clicktimeframe.clicktimeframe."
		"Doubleclicktimeframe.doubleclicktimeframe."
		"Wheeldown.wheeldown."
		"Wheelup.wheelup."
		"Submenudelay.submenudelay."
		"Scrollfirst.scrollfirst."
		"Scrollnext.scrollnext";

	char * atom_names[AI_count] = {
		"RESOLUTION_X",
		"RESOLUTION_Y",
		"PIXEL_SIZE",
		"SPACING",
		"RELATIVE_WEIGHT",
		"FOUNDRY",
		"AVERAGE_WIDTH",
		"CHARSET_REGISTRY",
		"CHARSET_ENCODING",
		"CREATE_EVENT",
		"WM_DELETE_WINDOW",
		"WM_PROTOCOLS",
		"WM_TAKE_FOCUS",
		"_NET_WM_STATE",
		"_NET_WM_STATE_SKIP_TASKBAR",
		"_NET_WM_STATE_MAXIMIZED_VERT",
		"_NET_WM_STATE_MAXIMIZED_HORZ",
		"_NET_WM_NAME",
		"_NET_WM_ICON_NAME",
		"UTF8_STRING",
		"TARGETS",
		"INCR",
		"PIXEL",
		"FOREGROUND",
		"BACKGROUND",
		"_MOTIF_WM_HINTS",
		"_NET_WM_STATE_MODAL",
		"_NET_SUPPORTED",
		"_NET_WM_STATE_MAXIMIZED_HORIZ",
		"text/plain;charset=UTF-8",
		"_NET_WM_STATE_STAYS_ON_TOP",
		"_NET_CURRENT_DESKTOP",
		"_NET_WORKAREA",
		"_NET_WM_STATE_ABOVE"
	};
	char hostname_buf[256], *hostname = hostname_buf;

	guts. click_time_frame = 200;
	guts. double_click_time_frame = 200;
	guts. visible_timeout = 500;
	guts. invisible_timeout = 500;
	guts. insert = true;
	guts. last_time = CurrentTime;

	guts. ri_head = guts. ri_tail = 0;
	DISP = XOpenDisplay( do_display);
	
	if (!DISP) {
		char * disp = getenv("DISPLAY");
		snprintf( error_buf, 256, "Error: Can't open display '%s'", 
					do_display ? do_display : (disp ? disp : ""));
		free( do_display);
		do_display = nil;
		return false;
	}
	free( do_display);
	do_display = nil;
	XSetErrorHandler( x_error_handler);
	guts.main_error_handler = x_error_handler;
	(void)x_io_error_handler;
	XCHECKPOINT;
	guts.connection = ConnectionNumber( DISP);

	{
		struct sockaddr name;
		unsigned int l = sizeof( name);
		guts. local_connection = getsockname( guts.connection, &name, &l) >= 0 && l == 0;
	}
	
#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
	if ( XShapeQueryExtension( DISP, &guts.shape_event, &guts.shape_error)) {
		guts. shape_extension = true;
	} else {
		guts. shape_extension = false;
	}
#else
	guts. shape_extension = false;
#endif
#ifdef USE_MITSHM
	if ( !do_no_shmem && XShmQueryExtension( DISP)) {
		guts. shared_image_extension = true;
		guts. shared_image_completion_event = XShmGetEventBase( DISP) + ShmCompletion;
	} else {
		guts. shared_image_extension = false;
		guts. shared_image_completion_event = -1;
	}
#else
	guts. shared_image_extension = false;
	guts. shared_image_completion_event = -1;
#endif
	guts. randr_extension = false;
#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
	{
		int dummy;
		if ( XRRQueryExtension( DISP, &dummy, &dummy))
			guts. randr_extension = true;
	}	 
#endif
#ifdef HAVE_X11_EXTENSIONS_XRENDER_H
	{
		int dummy;
		if ( XRenderQueryExtension( DISP, &dummy, &dummy))
			guts. render_extension = true;
	}	 
#endif
#ifdef HAVE_X11_EXTENSIONS_XCOMPOSITE_H
	{
		int dummy;
		if (XQueryExtension(DISP, COMPOSITE_NAME, &guts.composite_opcode, &dummy, &dummy))
			guts. composite_extension = true;
	}	 
#endif
	XrmInitialize();
	guts.db = get_database();
	XrmStringToQuarkList( common_quarks, common_quarks_list);
	guts.qString = *ql++;
	guts.qBlinkinvisibletime = *ql++;
	guts.qblinkinvisibletime = *ql++;
	guts.qBlinkvisibletime = *ql++;
	guts.qblinkvisibletime = *ql++;
	guts.qClicktimeframe = *ql++;
	guts.qclicktimeframe = *ql++;
	guts.qDoubleclicktimeframe = *ql++;
	guts.qdoubleclicktimeframe = *ql++;
	guts.qWheeldown = *ql++;
	guts.qwheeldown = *ql++;
	guts.qWheelup = *ql++;
	guts.qwheelup = *ql++;
	guts.qSubmenudelay = *ql++;
	guts.qsubmenudelay = *ql++;
	guts.qScrollfirst = *ql++;
	guts.qscrollfirst = *ql++;
	guts.qScrollnext = *ql++;
	guts.qscrollnext = *ql++;

	guts. mouse_buttons = XGetPointerMapping( DISP, guts. buttons_map, 256);
	XCHECKPOINT;

	guts. limits. request_length = XMaxRequestSize( DISP);
	guts. limits. XDrawLines = guts. limits. request_length - 3;
	guts. limits. XFillPolygon = guts. limits. request_length - 4;
	guts. limits. XDrawSegments = (guts. limits. request_length - 3) / 2;
	guts. limits. XDrawRectangles = (guts. limits. request_length - 3) / 2;
	guts. limits. XFillRectangles = (guts. limits. request_length - 3) / 2;
	guts. limits. XFillArcs =
		guts. limits. XDrawArcs = (guts. limits. request_length - 3) / 3;
	XCHECKPOINT;
	SCREEN = DefaultScreen( DISP);

	/* XXX - return code? */
	guts. root = RootWindow( DISP, SCREEN);
	guts. displaySize. x = DisplayWidth( DISP, SCREEN);
	guts. displaySize. y = DisplayHeight( DISP, SCREEN);
	XQueryBestCursor( DISP, guts. root,
							guts. displaySize. x,     /* :-) */
							guts. displaySize. y,
							&guts. cursor_width,
							&guts. cursor_height);
	XCHECKPOINT;
	
	TAILQ_INIT( &guts.paintq);
	TAILQ_INIT( &guts.peventq);
	TAILQ_INIT( &guts.bitmap_gc_pool);
	TAILQ_INIT( &guts.screen_gc_pool);
	TAILQ_INIT( &guts.argb_gc_pool);

	guts. currentFocusTime = CurrentTime;
	guts. windows = hash_create();
	guts. menu_windows = hash_create();
	guts. ximages = hash_create();
	gcv. graphics_exposures = false;
	guts. menugc = XCreateGC( DISP, guts. root, GCGraphicsExposures, &gcv);
	guts. resolution. x = 25.4 * guts. displaySize. x / DisplayWidthMM( DISP, SCREEN) + .5;
	guts. resolution. y = 25.4 * DisplayHeight( DISP, SCREEN) / DisplayHeightMM( DISP, SCREEN) + .5;
	guts. depth = DefaultDepth( DISP, SCREEN);
	guts. idepth = get_idepth();
	if ( guts.depth == 1) guts. qdepth = 1; else
	if ( guts.depth <= 4) guts. qdepth = 4; else
	if ( guts.depth <= 8) guts. qdepth = 8; else
		guts. qdepth = 24;
	guts. byte_order = ImageByteOrder( DISP);
	guts. bit_order = BitmapBitOrder( DISP);
	if ( BYTEORDER == LSB32 || BYTEORDER == LSB64)
		guts. machine_byte_order = LSBFirst;
	else if ( BYTEORDER == MSB32 || BYTEORDER == MSB64)
		guts. machine_byte_order = MSBFirst;
	else {
		sprintf( error_buf, "UAA_001: weird machine byte order: %08x", BYTEORDER);
		return false;
	}  

	XInternAtoms( DISP, atom_names, AI_count, 0, guts. atoms);

	guts. null_pointer = nilHandle;
	guts. pointer_invisible_count = 0;
	guts. files = plist_create( 16, 16);
	prima_rebuild_watchers();
	guts. wm_event_timeout = 100;
	guts. menu_timeout = 200;
	guts. scroll_first = 200;
	guts. scroll_next = 50;
	apc_timer_create( CURSOR_TIMER);
	apc_timer_set_timeout(CURSOR_TIMER, 2);
	apc_timer_create( MENU_TIMER);
	apc_timer_set_timeout( MENU_TIMER,  guts. menu_timeout);
	apc_timer_create( MENU_UNFOCUS_TIMER);
	apc_timer_set_timeout( MENU_UNFOCUS_TIMER, 50);
	if ( !prima_init_clipboard_subsystem( error_buf)) return false;
	if ( !prima_init_color_subsystem( error_buf)) return false;
	if ( !prima_init_font_subsystem( error_buf)) return false;
#ifdef WITH_GTK2
	if (!prima_gtk_init()) return false;
#endif
	bzero( &guts. cursor_gcv, sizeof( guts. cursor_gcv));
	guts. cursor_gcv. cap_style = CapButt;
	guts. cursor_gcv. function = GXcopy;

	gethostname( hostname, 256);
	hostname[255] = '\0';
	XStringListToTextProperty((char **)&hostname, 1, &guts. hostname);
	
	guts. net_wm_maximization = prima_wm_net_state_read_maximization( guts. root, NET_SUPPORTED);

	if ( do_sync) XSynchronize( DISP, true);
	return true;
}
Example #13
0
File: x11.c Project: aki5/libdraw3
/*
 *	drawevents2 calls flush to display anything that was drawn.
 */
static Input *
drawevents2(int block, int *ninp)
{
	static int flushing;

	if(!flushing){
		if(screen.dirty){
			drawflush(screen.r);
			flushing = 1;
			screen.dirty = 0;
		}
		ninputs = 0;
	}
	while((block && (flushing || ninputs == 0)) || XPending(display)){
		XEvent ev;
		XNextEvent(display, &ev);
		switch(ev.type){
		case MapNotify:
		case ReparentNotify:
			addredraw();
			continue;
		case Expose:
			addredraw();
			continue;
		case KeyPress:
		case KeyRelease:
			{
				XKeyEvent *ep = &ev.xkey;
				if(0)fprintf(
					stderr,
					"key %s %d (%x) '%c' at (%d,%d) state %x\n",
					ev.type == KeyPress ? "pressed" : "released",
					ep->keycode,
					ep->keycode,
					isprint(ep->keycode) ? ep->keycode : '.',
					ep->x, ep->y,
					ep->state
				);

				u64int mod;
				KeySym keysym;
				int code;
				char keystr[8] = {0};

				keysym = XLookupKeysym(ep, ep->state & (ShiftMask|LockMask));
				if((code = keysym2ucs(keysym)) != -1)
					utf8encode(keystr, sizeof keystr-1, code);
				else
					keystr[0] = '\0';

				switch(keysym){
				case XK_Return:
				case XK_KP_Enter:
					strncpy(keystr, "\n", sizeof keystr-1);
					mod = KeyStr;
					break;
				case XK_Tab:
				case XK_KP_Tab:
				case XK_ISO_Left_Tab:
					strncpy(keystr, "\t", sizeof keystr-1);
					mod = KeyStr;
					break;
				case XK_Break:
					mod = KeyBreak;
					break;
				case XK_BackSpace:
					mod = KeyBackSpace;
					break;
				case XK_Down:
					mod = KeyDown;
					break;
				case XK_End:
					mod = KeyEnd;
					break;
				case XK_Home:
					mod = KeyHome;
					break;
				case XK_Left:
					mod = KeyLeft;
					break;
				case XK_Page_Down:
					mod = KeyPageDown;
					break;
				case XK_Page_Up:
					mod = KeyPageUp;
					break;
				case XK_Right:
					mod = KeyRight;
					break;
				case XK_Up:
					mod = KeyUp;
					break;
				case XK_Shift_L:
				case XK_Shift_R:
					mod = KeyShift;
					break;
				case XK_Control_L:
				case XK_Control_R:
					mod = KeyControl;
					break;
				case XK_Meta_L:
				case XK_Meta_R: 
					mod = KeyMeta;	/* mac command key */
					break;
				case XK_Alt_L:
				case XK_Alt_R:
					mod = KeyAlt;
					break;
				case XK_Super_L:
				case XK_Super_R:
fprintf(stderr, "super\n");
					mod = KeySuper;
					break;
				case XK_Hyper_L:
				case XK_Hyper_R:
fprintf(stderr, "hyper\n");
					mod = KeyHyper;
					break;
				case XK_KP_Insert:
				case XK_Insert:
					mod = KeyIns;
					break;
				case XK_KP_Delete:
				case XK_Delete:
					mod = KeyDel;
					break;
				case XK_Caps_Lock:
					mod = KeyCapsLock;
					break;
				default:
					mod = 0;
					break;
				}

				addinput(
					0, 0,
					keystr,
					mod,
					ev.type == KeyPress,
					ev.type == KeyRelease
				);
			}
			continue;
		case ButtonPress:
		case ButtonRelease:
			{
				XButtonEvent *ep = &ev.xbutton;
				u64int mod;
				switch(ep->button){
				case 0:case 1:case 2:case 3:case 4:
				case 5:case 6:case 7:case 9:case 10:
					mod = Mouse0 << ep->button;
					break;
				default:
					fprintf(stderr, "unsupported mouse button %d\n", ep->button);
					mod = 0;
					break;
				}
				if(mod != 0){
					addinput(
						ep->x, ep->y,
						NULL,
						mod,
						ev.type == ButtonPress,
						ev.type == ButtonRelease
					);
				}
			}
			continue;	
		case EnterNotify:
		case LeaveNotify:
			fprintf(stderr, "enter/leave\n");
			continue;
		case MotionNotify:
			if(input_prevmod != 0){
				XMotionEvent *ep = &ev.xmotion;
				u64int m;
				if(0)fprintf(
					stderr,
					"motion at (%d,%d) state %x\n",
					ep->x, ep->y,
					ep->state
				);
				for(m = Mouse0; m <= LastMouse; m <<= 1){
					addinput(
						ep->x, ep->y,
						NULL,
						m,
						0,0
					);
				}
			}
			continue;
		case ConfigureNotify:
			{
				XConfigureEvent *ce = &ev.xconfigure;
				if(ce->width != width || ce->height != height){
					shmfree();
					width = ce->width;
					height = ce->height;
					if(shminit() == -1){
						*ninp = 0;
						return NULL;
					}
					addredraw();
				}
				continue;
			}
		}
		if(ev.type == XShmGetEventBase(display) + ShmCompletion){
			flushing = 0;
			if(animating){
				addredraw();
			}
			continue;
		}
		fprintf(stderr, "unknown xevent %d\n", ev.type);
	}

	if(!flushing && ninputs > 0){
		*ninp = ninputs;
		return inputs;
	}

	*ninp = 0;
	return NULL;
}
Example #14
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;
}
Example #15
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);
}