Esempio n. 1
0
bool X11Grabber::Setup()
{
	_x11Display = XOpenDisplay(NULL);
	if (_x11Display == nullptr)
	{
		Error(_log, "Unable to open display");
		if (getenv("DISPLAY"))
		{
			Error(_log, "%s",getenv("DISPLAY"));
		}
		else
		{
			Error(_log, "DISPLAY environment variable not set");
		}
		return false;
	}
	 
	_window = DefaultRootWindow(_x11Display);

	int dummy, pixmaps_supported;
	
	_XRenderAvailable = XRenderQueryExtension(_x11Display, &dummy, &dummy);
	_XShmAvailable = XShmQueryExtension(_x11Display);
	XShmQueryVersion(_x11Display, &dummy, &dummy, &pixmaps_supported);
	_XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_x11Display) == ZPixmap;
	
	// Image scaling is performed by XRender when available, otherwise by ImageResampler
	_imageResampler.setHorizontalPixelDecimation(_XRenderAvailable ? 1 : _horizontalDecimation);
	_imageResampler.setVerticalPixelDecimation(_XRenderAvailable ? 1 : _verticalDecimation);

	return true;
}
Esempio n. 2
0
bool X11Grabber::Setup()
{
	_x11Display = XOpenDisplay(NULL);
	if (_x11Display == nullptr)
	{
		std::cerr << "X11GRABBER ERROR: Unable to open display";
		if (getenv("DISPLAY")) {
			std::cerr <<  " " << std::string(getenv("DISPLAY")) << std::endl;
		} else {
			std::cerr << ". DISPLAY environment variable not set" << std::endl;
		}
		return false;
	}
	 
	_window = DefaultRootWindow(_x11Display);

	int dummy, pixmaps_supported;
	
	_XRenderAvailable = XRenderQueryExtension(_x11Display, &dummy, &dummy);
	_XShmAvailable = XShmQueryExtension(_x11Display);
	XShmQueryVersion(_x11Display, &dummy, &dummy, &pixmaps_supported);
	_XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_x11Display) == ZPixmap;

	return true;
}
Esempio n. 3
0
int	mlx_int_deal_shm(t_xvar *xvar)
{
  int	use_pshm;
  int	bidon;
  char	*dpy;
  char	buff[33];

  xvar->use_xshm = XShmQueryVersion(xvar->display,&bidon,&bidon,&(use_pshm));
  if (xvar->use_xshm && use_pshm)
    xvar->pshm_format = XShmPixmapFormat(xvar->display);
  else
    xvar->pshm_format = -1;
  gethostname(buff,32);
  dpy = getenv(ENV_DISPLAY);
  if (dpy && strlen(dpy) && *dpy!=':' && strncmp(dpy,buff,strlen(buff)) &&
      strncmp(dpy,LOCALHOST,strlen(LOCALHOST)) )
    {
      xvar->pshm_format = -1;
      xvar->use_xshm = 0;
    }
}
Esempio n. 4
0
/*
 * Setup X11 wnd System
 */
void
X11_SetupWindow (GF_VideoOutput * vout)
{
	X11VID ();
	const char *sOpt;
        Bool autorepeat, supported;

	xWindow->display = XOpenDisplay (NULL);
	xWindow->screennum = DefaultScreen (xWindow->display);
	xWindow->screenptr = DefaultScreenOfDisplay (xWindow->display);
	xWindow->visual = DefaultVisualOfScreen (xWindow->screenptr);
	xWindow->depth = DefaultDepth (xWindow->display, xWindow->screennum);

	{
		Float screenWidth = (Float)XWidthOfScreen(xWindow->screenptr);
		Float screenWidthIn = (Float)XWidthMMOfScreen(xWindow->screenptr) / 25.4f;
		Float screenHeight = (Float)XHeightOfScreen(xWindow->screenptr);
		Float screenHeightIn = (Float)XHeightMMOfScreen(xWindow->screenptr) / 25.4f;
		vout->dpi_x = (u32)(screenWidth / screenWidthIn);
		vout->dpi_y = (u32)(screenHeight / screenHeightIn);	
	}

	switch (xWindow->depth) {
	case 8:
		xWindow->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	case 16:
		xWindow->pixel_format = GF_PIXEL_RGB_565;
		break;
	case 24:
		xWindow->pixel_format = GF_PIXEL_RGB_32;
		break;
	default:
		xWindow->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	}
	xWindow->bpp = xWindow->depth / 8;
	xWindow->bpp = xWindow->bpp == 3 ? 4 : xWindow->bpp;

xWindow->screennum=0;
	vout->max_screen_width = DisplayWidth(xWindow->display, xWindow->screennum);
	vout->max_screen_height = DisplayHeight(xWindow->display, xWindow->screennum);
	/*
	 * Full screen wnd
	 */
	xWindow->full_wnd = XCreateWindow (xWindow->display,
								   RootWindowOfScreen (xWindow->screenptr),
								   0, 0,
								   vout->max_screen_width,
								   vout->max_screen_height, 0,
								   xWindow->depth, InputOutput,
								   xWindow->visual, 0, NULL);

	XSelectInput(xWindow->display, xWindow->full_wnd,
					FocusChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask);

	if (!xWindow->par_wnd) {
		xWindow->w_width = 320;
		xWindow->w_height = 240;
		xWindow->wnd = XCreateWindow (xWindow->display,
					   RootWindowOfScreen(xWindow->screenptr), 0, 0,
					   xWindow->w_width, xWindow->w_height, 0,
					   xWindow->depth, InputOutput,
					   xWindow->visual, 0, NULL);
		XMapWindow (xWindow->display, (Window) xWindow->wnd);
	} else {
		XWindowAttributes pwa;
		XGetWindowAttributes(xWindow->display, xWindow->par_wnd, &pwa);
		xWindow->w_width = pwa.width;
		xWindow->w_height = pwa.height;
		xWindow->wnd = XCreateWindow (xWindow->display, xWindow->par_wnd, pwa.x, pwa.y,
					xWindow->w_width, xWindow->w_height, 0,
					   xWindow->depth, InputOutput,
					   xWindow->visual, 0, NULL);
		XMapWindow (xWindow->display, (Window) xWindow->wnd);
	}

	XSync(xWindow->display, False);
	XUnmapWindow (xWindow->display, (Window) xWindow->wnd);
	XSync(xWindow->display, False);
	old_handler = XSetErrorHandler(X11_BadAccess_ByPass);
	selectinput_err = 0;
	XSelectInput(xWindow->display, xWindow->wnd,
		FocusChangeMask | StructureNotifyMask | PropertyChangeMask | ExposureMask |
		PointerMotionMask | ButtonReleaseMask | ButtonPressMask |
		KeyPressMask | KeyReleaseMask);
	XSync(xWindow->display, False);
	XSetErrorHandler(old_handler);
	if (selectinput_err) {
	       	XSelectInput(xWindow->display, xWindow->wnd,
			StructureNotifyMask | PropertyChangeMask | ExposureMask |
			KeyPressMask | KeyReleaseMask);

		GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Cannot select input focus\n"));
	}
	XSync(xWindow->display, False);
	XMapWindow (xWindow->display, (Window) xWindow->wnd);

	XSizeHints *Hints = XAllocSizeHints ();
	Hints->flags = PSize | PMinSize;
	Hints->min_width = 64;
	Hints->min_height = 64;
	Hints->max_height = 4096;
	Hints->max_width = 4096;
	if (!xWindow->par_wnd) {
		XSetWMNormalHints (xWindow->display, xWindow->wnd, Hints);
		XStoreName (xWindow->display, xWindow->wnd, "GPAC X11 Output");
	}
	Hints->x = 0;
	Hints->y = 0;
	Hints->flags |= USPosition;
	XSetWMNormalHints (xWindow->display, xWindow->full_wnd, Hints);

	autorepeat = 1;
	XkbSetDetectableAutoRepeat(xWindow->display, autorepeat, &supported);


	if (xWindow->init_flags & GF_TERM_WINDOW_NO_DECORATION) {
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
#define MWM_HINTS_DECORATIONS (1L << 1)
	  struct {
	    unsigned long flags;
	    unsigned long functions;
	    unsigned long decorations;
	    long inputMode;
	    unsigned long status;
	  } hints = {2, 0, 0, 0, 0};

	  hints.flags = MWM_HINTS_DECORATIONS;
	  hints.decorations = 0;

	  XChangeProperty(xWindow->display, xWindow->wnd, XInternAtom(xWindow->display,"_MOTIF_WM_HINTS", False), XInternAtom(xWindow->display, "_MOTIF_WM_HINTS", False), 32, PropModeReplace, (unsigned char *)&hints, PROP_MOTIF_WM_HINTS_ELEMENTS);

	}

	xWindow->the_gc = XCreateGC (xWindow->display, xWindow->wnd, 0, NULL);
	xWindow->use_shared_memory = 0;

#ifdef GPAC_HAS_X11_SHM
	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseHardwareMemory");
        if (sOpt && !strcmp(sOpt, "yes")) {
	  int XShmMajor, XShmMinor;
	  Bool XShmPixmaps;
	  if (XShmQueryVersion(xWindow->display, &XShmMajor, &XShmMinor, &XShmPixmaps)) {
		xWindow->use_shared_memory = 1;
		GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using X11 Shared Memory\n"));
		if ((XShmPixmaps==True) && (XShmPixmapFormat(xWindow->display)==ZPixmap)) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] X11 Shared Memory Pixmaps available\n"));
		}
	  }
	}

#endif

#ifdef GPAC_HAS_X11_XV
	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "DisableColorKeying");
	if (sOpt && !strcmp(sOpt, "yes")) {
		xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0);
	} else {
		xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 1);
		if (xWindow->xvport<0) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware has no color keying\n"));
			vout->overlay_color_key = 0;
			xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0);
		} else {
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware uses color key %08x\n", vout->overlay_color_key));
		}
	}
	if (xWindow->xvport>=0) {
		XvUngrabPort(xWindow->display, xWindow->xvport, CurrentTime );
		xWindow->xvport = -1;
		vout->yuv_pixel_format = X11_GetPixelFormat(xWindow->xv_pf_format);
		vout->Blit = X11_Blit;
		vout->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY;
		GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV YUV Overlays\n"));

#ifdef GPAC_HAS_X11_SHM
		/*if user asked for YUV->RGB on offscreen, do it (it may crash the system)*/
		sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "EnableOffscreenYUV");
		if (sOpt && !strcmp(sOpt, "yes")) {
			vout->hw_caps |= GF_VIDEO_HW_HAS_YUV;
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV Offscreen YUV2RGB acceleration\n"));
		}
#endif
	} 
#endif

	XSetWindowAttributes xsw;
	xsw.border_pixel = WhitePixel (xWindow->display, xWindow->screennum);
	xsw.background_pixel = BlackPixel (xWindow->display, xWindow->screennum);
	xsw.win_gravity = NorthWestGravity;
	XChangeWindowAttributes (xWindow->display, xWindow->wnd, CWBackPixel | CWWinGravity, &xsw);

	xsw.override_redirect = True;
	XChangeWindowAttributes(xWindow->display, xWindow->full_wnd,
				CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWWinGravity, &xsw);

	if (!xWindow->par_wnd) {
		xWindow->WM_DELETE_WINDOW = XInternAtom (xWindow->display, "WM_DELETE_WINDOW", False);
		XSetWMProtocols(xWindow->display, xWindow->wnd, &xWindow->WM_DELETE_WINDOW, 1);
	}


	{
		XEvent ev;
		long mask;

		memset (&ev, 0, sizeof (ev));
		ev.xclient.type = ClientMessage;
		ev.xclient.window = RootWindowOfScreen (xWindow->screenptr);
		ev.xclient.message_type = XInternAtom (xWindow->display, "KWM_KEEP_ON_TOP", False);
		ev.xclient.format = 32;
		ev.xclient.data.l[0] = xWindow->full_wnd;
		ev.xclient.data.l[1] = CurrentTime;
		mask = SubstructureRedirectMask;
		XSendEvent (xWindow->display,RootWindowOfScreen (xWindow->screenptr), False,
			    mask, &ev);
	}

	/*openGL setup*/
#ifdef GPAC_HAS_OPENGL
	{
	  int attribs[64];
	  int i, nb_bits;

	  sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent");
	  /* Most outputs are 24/32 bits these days, use 8 bits per channel instead of 5, works better on MacOS X */
	  nb_bits = sOpt ? atoi(sOpt) : 8;
          if (!sOpt){
             gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent", "8");
          }
	  i=0;
	  attribs[i++] = GLX_RGBA;
	  attribs[i++] = GLX_RED_SIZE;
	  attribs[i++] = nb_bits;
	  attribs[i++] = GLX_GREEN_SIZE;
	  attribs[i++] = nb_bits;
	  attribs[i++] = GLX_BLUE_SIZE;
	  attribs[i++] = nb_bits;
	  sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth");
	  nb_bits = sOpt ? atoi(sOpt) : 16;
          if (!sOpt){
             gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth", "16");
          }
	  if (nb_bits) {
		  attribs[i++] = GLX_DEPTH_SIZE;
		  attribs[i++] = nb_bits;
	  }
	  sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering");
          if (!sOpt){
             gf_modules_set_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering", "yes");
          }
	  if (!sOpt || !strcmp(sOpt, "yes")) attribs[i++] = GLX_DOUBLEBUFFER;
	  attribs[i++] = None;
	  xWindow->glx_visualinfo = glXChooseVisual(xWindow->display, xWindow->screennum, attribs);
	  if (!xWindow->glx_visualinfo) {
		  GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Error selecting GL display\n"));
	  }
	}

	xWindow->gl_wnd = XCreateWindow (xWindow->display, RootWindowOfScreen (xWindow->screenptr),
								   0,
								   0,
								   200,
								   200, 0,
								   xWindow->depth, InputOutput,
								   xWindow->visual, 0, NULL);

	XSync(xWindow->display, False);
	XUnmapWindow(xWindow->display, (Window) xWindow->gl_wnd);
	XSync(xWindow->display, False);

	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode");
	if (!sOpt)
		gf_modules_set_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode", "Pixmap");
        if (sOpt && !strcmp(sOpt, "Window")) {
		xWindow->offscreen_type = 1;
        } else if (sOpt && !strcmp(sOpt, "VisibleWindow")) {
		xWindow->offscreen_type = 2;
		XSetWMNormalHints (xWindow->display, xWindow->gl_wnd, Hints);
       } else if (sOpt && !strcmp(sOpt, "Pixmap")) {
		xWindow->offscreen_type = 0;
	} else {
		xWindow->offscreen_type = 0;
	}
#endif


	/*turn off xscreensaver*/
	X11_XScreenSaverState(xWindow, 0);

	xWindow->setup_done = 1;
	XFree (Hints);
}
Esempio n. 5
0
bool video::init_window(int xsize, int ysize)
{
    { //enclose local variables before fail label
    g_sizex = xsize; g_sizey = ysize;

    // Open the display
    if (!dpy) {
        dpy = XOpenDisplay(display_name);
        if (!dpy) {
            fprintf(stderr, "Can't open X11 display %s\n", XDisplayName(display_name));
            goto fail;
        }
    }
    int theScreen = DefaultScreen(dpy);
    scrn = ScreenOfDisplay(dpy, theScreen);
    dispdepth = DefaultDepth(dpy, theScreen);
    XVisualInfo vinfo;
    if (!( (dispdepth >= 15 && dispdepth <= 32 && XMatchVisualInfo(dpy, theScreen, dispdepth, TrueColor, &vinfo) )
        || XMatchVisualInfo(dpy, theScreen, 24, TrueColor, &vinfo)
        || XMatchVisualInfo(dpy, theScreen, 32, TrueColor, &vinfo)
        || XMatchVisualInfo(dpy, theScreen, 16, TrueColor, &vinfo)
        || XMatchVisualInfo(dpy, theScreen, 15, TrueColor, &vinfo)
        )) {
        fprintf(stderr, "Display has no appropriate True Color visual\n");
        goto fail;
    }
    vis = vinfo.visual;
    depth = dispdepth = vinfo.depth;
    mask2bits(vinfo.red_mask, red_mask, red_shift);
    mask2bits(vinfo.green_mask, green_mask, green_shift);
    mask2bits(vinfo.blue_mask, blue_mask, blue_shift);
    rootW = RootWindow(dpy, theScreen);
    cmap = XCreateColormap(dpy, rootW, vis, AllocNone);
    XSetWindowAttributes attrs;
    attrs.backing_store = Always;
    attrs.colormap = cmap;
    attrs.event_mask = StructureNotifyMask|KeyPressMask|ButtonPressMask|ButtonReleaseMask;
    attrs.background_pixel = BlackPixelOfScreen(scrn);
    attrs.border_pixel = WhitePixelOfScreen(scrn);
    win = XCreateWindow(dpy, rootW,
        0, 0, xsize, ysize, 2,
        dispdepth, InputOutput, vis,
        CWBackingStore | CWColormap | CWEventMask |
        CWBackPixel | CWBorderPixel,
        &attrs);
    if(!win) {
        fprintf(stderr, "Can't create the window\n");
        goto fail;
    }
    XSizeHints sh;
    sh.flags = PSize | PMinSize | PMaxSize;
    sh.width = sh.min_width = sh.max_width = xsize;
    sh.height = sh.min_height = sh.max_height = ysize;
    XSetStandardProperties( dpy, win, g_video->title, g_video->title, None, NULL, 0, &sh );
    _XA_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", false);
    XSetWMProtocols(dpy, win, &_XA_WM_DELETE_WINDOW, 1);
    gc = XCreateGC(dpy, win, 0L, &xgcv);
    XMapRaised(dpy, win);
    XFlush(dpy);
#ifdef X_FULLSYNC
	XSynchronize(dpy, true);
#endif
    XSetErrorHandler(xerr_handler);

    int imgbytes = xsize*ysize*(dispdepth<=16?2:4);
    const char *vidstr;
#ifndef X_NOSHMEM
    int major, minor, pixmaps;
    if(XShmQueryExtension(dpy) &&
       XShmQueryVersion(dpy, &major, &minor, &pixmaps))
    { // Shared memory
        if(NULL!=getenv(NOSHMEM_env_var_name) && 0!=strcmp("0",getenv(NOSHMEM_env_var_name))) {
            goto generic;
        }
        shmseginfo.shmid = shmget(IPC_PRIVATE, imgbytes, IPC_CREAT|0777);
        if(shmseginfo.shmid < 0) {
            fprintf(stderr, "Warning: Can't get shared memory: %s\n", strerror(errno));
            goto generic;
        }
        g_pImg = (unsigned int*)(shmseginfo.shmaddr = (char*)shmat(shmseginfo.shmid, 0, 0));
        if(g_pImg == (unsigned int*)-1) {
            fprintf(stderr, "Warning: Can't attach to shared memory: %s\n", strerror(errno));
            shmctl(shmseginfo.shmid, IPC_RMID, NULL);
            goto generic;
        }
        shmseginfo.readOnly = false;
        if(!XShmAttach(dpy, &shmseginfo) || x_error) {
            char err[256]; XGetErrorText(dpy, x_error, err, 255);
            fprintf(stderr, "Warning: Can't attach shared memory to display: %s (%d)\n", err, x_error);
            shmdt(shmseginfo.shmaddr); shmctl(shmseginfo.shmid, IPC_RMID, NULL);
            goto generic;
        }
        already_called_X_ShmAttach = true;

#ifndef X_NOSHMPIX
        if(pixmaps && XShmPixmapFormat(dpy) == ZPixmap)
        { // Pixmaps
            vidtype = 2; vidstr = "X11 shared memory pixmap";
            pixmap = XShmCreatePixmap(dpy, win, (char*)g_pImg, &shmseginfo, xsize, ysize, dispdepth);
            XSetWindowBackgroundPixmap(dpy, win, pixmap);
        } else
#endif//!X_NOSHMPIX
        { // Standard
            vidtype = 1; vidstr = "X11 shared memory";
            ximage = XShmCreateImage(dpy, vis, dispdepth,
                ZPixmap, 0, &shmseginfo, xsize, ysize);
            if(!ximage) {
                fprintf(stderr, "Can't create the shared image\n");
                goto fail;
            }
            assert(ximage->bytes_per_line == xsize*(dispdepth<=16?2:4));
            ximage->data = shmseginfo.shmaddr;
        }
    } else
#endif
    {
#ifndef X_NOSHMEM
generic:
#endif
        vidtype = 0; vidstr = "generic X11";
        g_pImg = new unsigned int[imgbytes/sizeof(int)];
        ximage = XCreateImage(dpy, vis, dispdepth, ZPixmap, 0, (char*)g_pImg, xsize, ysize, 32, imgbytes/ysize);
        if(!ximage) {
            fprintf(stderr, "Can't create the image\n");
            goto fail;
        }
    }
    // Note: It may be more efficient to adopt the server's byte order
    //       and swap once per get_color() call instead of once per pixel.
    const uint32_t probe = 0x03020100;
    const bool big_endian = (((const char*)(&probe))[0]==0x03);
    ximage->byte_order = big_endian ? MSBFirst : LSBFirst;

    printf("Note: using %s with %s visual for %d-bit color depth\n", vidstr, vis==DefaultVisual(dpy, theScreen)?"default":"non-default", dispdepth);
    running = true;
    return true;
    } // end of enclosing local variables
fail:
    terminate(); init_console();
    return false;
}
Esempio n. 6
0
void Xinitialize (int width, int height)
{
	XVisualInfo vinfo_return;
	XSetWindowAttributes wa;
	Pixmap mask, cur;
	XColor black, white;

	black.red = black.green = black.blue = 0;
	/* buggered if I care, its just for an invisible cursor :] */
	white.red = white.green = white.blue = 0;

	xWidth = width;
	xHeight = height;

#ifdef __DEBUG__
	printf ("xshm: connecting to X server\n");
#endif

	if ((dp = XOpenDisplay (0)) == 0) {
		printf ("xshm: could not open X display\n");
		exit (0);
		}

	XSetCloseDownMode (dp, DestroyAll);
	screen = DefaultScreen (dp);

	if (XMatchVisualInfo (dp, DefaultScreen (dp),
		8, PseudoColor, &vinfo_return) == False) {
		printf ("X: Screen doesn't support PseudoColor!\n");
		exit(666);
		}

	/* Make sure all is destroyed if killed off */
	/* Make sure we can do PsuedoColor colormap stuff */

	if (!XShmQueryExtension (dp)) {
		/* Check to see if the extensions are supported */
		fprintf (stderr, "X server doesn't support MITSHM extension.\n");
		exit(666);
	} else if (!XShmPixmapFormat (dp)) {
		fprintf (stderr, "X server doesn't do shared memory pixmaps.\n");
		exit(666);
	} 
#ifdef __DEBUG__
	else printf ("xshm: MITSHM present\n");
#endif


	wi = XCreateSimpleWindow (dp, RootWindow (dp, screen), 50, 50, xWidth, xHeight, 0, 0, 0);
        colours = XCreateColormap (dp, wi, DefaultVisual (dp, XDefaultScreen (dp)),
                                      AllocAll);
        XSetWindowColormap (dp, wi, colours);

        cur = XCreatePixmapFromBitmapData (dp, wi, (char *) nocursorm_bits,
                nocursorm_width, nocursorm_height, (unsigned long) 1,
                (unsigned long) 0, (unsigned int) 1);
        mask = XCreatePixmapFromBitmapData (dp, wi, (char *) nocursorm_bits,
                nocursorm_width, nocursorm_height, (unsigned long) 1,
                (unsigned long) 0, (unsigned int) 1);
	cursor = XCreatePixmapCursor (dp, cur, mask, &black, &white, 0, 0);

	XFreePixmap (dp, cur);
	XFreePixmap (dp, mask);

	XDefineCursor (dp, wi, cursor);

	XMapWindow(dp, wi);

	GetShmPixmap();
	XSetWindowBackgroundPixmap (dp, wi, pixmap);

	XSelectInput(dp, wi, KeyPressMask|KeyReleaseMask|ButtonPressMask|
		ButtonReleaseMask|PointerMotionMask|LeaveWindowMask|ExposureMask);
	atexit( Xuninitialize );
}
Esempio n. 7
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;
  }
Esempio n. 8
0
/*
 * Setup X11 wnd System
 */
void
X11_SetupWindow (GF_VideoOutput * vout)
{
	X11VID ();
	const char *sOpt;

	xWindow->display = XOpenDisplay (NULL);
	xWindow->screennum = DefaultScreen (xWindow->display);
	xWindow->screenptr = DefaultScreenOfDisplay (xWindow->display);
	xWindow->visual = DefaultVisualOfScreen (xWindow->screenptr);
	xWindow->depth = DefaultDepth (xWindow->display, xWindow->screennum);

	switch (xWindow->depth) {
	case 8:
		xWindow->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	case 16:
		xWindow->pixel_format = GF_PIXEL_RGB_565;
		break;
	case 24:
		xWindow->pixel_format = GF_PIXEL_RGB_32;
		break;
	default:
		xWindow->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	}
	xWindow->bpp = xWindow->depth / 8;
	xWindow->bpp = xWindow->bpp == 3 ? 4 : xWindow->bpp;

	vout->max_screen_width = DisplayWidth(xWindow->display, xWindow->screennum);
	vout->max_screen_height = DisplayHeight(xWindow->display, xWindow->screennum);

	/*
	 * Full screen wnd
	 */
	xWindow->full_wnd = XCreateWindow (xWindow->display,
								   RootWindowOfScreen (xWindow->screenptr),
								   0, 0,
								   vout->max_screen_width,
								   vout->max_screen_height, 0,
								   xWindow->depth, InputOutput,
								   xWindow->visual, 0, NULL);

	XSelectInput(xWindow->display, xWindow->full_wnd,
					FocusChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask);

	if (!xWindow->par_wnd) {
		xWindow->w_width = 320;
		xWindow->w_height = 20;
		xWindow->wnd = XCreateWindow (xWindow->display,
					   RootWindowOfScreen(xWindow->screenptr), 0, 0,
					   xWindow->w_width, xWindow->w_height, 0,
					   xWindow->depth, InputOutput,
					   xWindow->visual, 0, NULL);
		XMapWindow (xWindow->display, (Window) xWindow->wnd);
	} else {
		XWindowAttributes pwa;
		XGetWindowAttributes(xWindow->display, xWindow->par_wnd, &pwa);
		xWindow->w_width = pwa.width;
		xWindow->w_height = pwa.height;
		xWindow->wnd = XCreateWindow (xWindow->display, xWindow->par_wnd, pwa.x, pwa.y,
					xWindow->w_width, xWindow->w_height, 0,
					   xWindow->depth, InputOutput,
					   xWindow->visual, 0, NULL);
		XMapWindow (xWindow->display, (Window) xWindow->wnd);
	}

	XSync(xWindow->display, False);
	XUnmapWindow (xWindow->display, (Window) xWindow->wnd);
	XSync(xWindow->display, False);
	old_handler = XSetErrorHandler(X11_BadAccess_ByPass);
	selectinput_err = 0;
	XSelectInput(xWindow->display, xWindow->wnd,
		FocusChangeMask | StructureNotifyMask | PropertyChangeMask | ExposureMask |
		PointerMotionMask | ButtonReleaseMask | ButtonPressMask |
		KeyPressMask | KeyReleaseMask);
	XSync(xWindow->display, False);
	XSetErrorHandler(old_handler);
	if (selectinput_err) {
       	XSelectInput(xWindow->display, xWindow->wnd,
			StructureNotifyMask | PropertyChangeMask | ExposureMask |
			KeyPressMask | KeyReleaseMask);

		GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Cannot select input focus\n"));
	}
	XSync(xWindow->display, False);
	XMapWindow (xWindow->display, (Window) xWindow->wnd);

	XSizeHints *Hints = XAllocSizeHints ();
	Hints->flags = PSize | PMinSize;
	Hints->min_width = 32;
	Hints->min_height = 32;
	Hints->max_height = 4096;
	Hints->max_width = 4096;
	if (!xWindow->par_wnd) {
		XSetWMNormalHints (xWindow->display, xWindow->wnd, Hints);
		XStoreName (xWindow->display, xWindow->wnd, "GPAC X11 Output");
	}
	Hints->x = 0;
	Hints->y = 0;
	Hints->flags |= USPosition;
	XSetWMNormalHints (xWindow->display, xWindow->full_wnd, Hints);
	XFree (Hints);


	xWindow->the_gc = XCreateGC (xWindow->display, xWindow->wnd, 0, NULL);
	xWindow->videoaccesstype = VIDEO_XI_STANDARD;

#ifdef GPAC_HAS_X11_SHM
	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseHardwareMemory");
        if (sOpt && !strcmp(sOpt, "yes")) {
	  int XShmMajor, XShmMinor;
	  Bool XShmPixmaps;
	  if (XShmQueryVersion(xWindow->display, &XShmMajor, &XShmMinor, &XShmPixmaps)) {
	    /*this is disabled due to flip pb (we cannot reposition backbuffer)*/
	    if (0 && XShmPixmaps && (XShmPixmapFormat(xWindow->display) == ZPixmap)) {
		xWindow->videoaccesstype = VIDEO_XI_SHMPIXMAP;
	    } else {
	      xWindow->videoaccesstype = VIDEO_XI_SHMSTD;
	      GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using X11 Hardware Blit\n"));
	    }
	  }
	}
#endif

	GF_SAFEALLOC(xWindow->back_buffer, X11WrapSurface);
	xWindow->back_buffer->id = -1;


	XSetWindowAttributes xsw;
	xsw.border_pixel = WhitePixel (xWindow->display, xWindow->screennum);
	xsw.background_pixel = BlackPixel (xWindow->display, xWindow->screennum);
	xsw.win_gravity = NorthWestGravity;
	XChangeWindowAttributes (xWindow->display, xWindow->wnd, CWBackPixel | CWWinGravity, &xsw);

	xsw.override_redirect = True;
	XChangeWindowAttributes(xWindow->display, xWindow->full_wnd,
				CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWWinGravity, &xsw);

	if (!xWindow->par_wnd) {
		xWindow->WM_DELETE_WINDOW = XInternAtom (xWindow->display, "WM_DELETE_WINDOW", False);
		XSetWMProtocols(xWindow->display, xWindow->wnd, &xWindow->WM_DELETE_WINDOW, 1);
	}

	{
		XEvent ev;
		long mask;

		memset (&ev, 0, sizeof (ev));
		ev.xclient.type = ClientMessage;
		ev.xclient.window = RootWindowOfScreen (xWindow->screenptr);
		ev.xclient.message_type = XInternAtom (xWindow->display, "KWM_KEEP_ON_TOP", False);
		ev.xclient.format = 32;
		ev.xclient.data.l[0] = xWindow->full_wnd;
		ev.xclient.data.l[1] = CurrentTime;
		mask = SubstructureRedirectMask;
		XSendEvent (xWindow->display,RootWindowOfScreen (xWindow->screenptr), False,
			    mask, &ev);
	}
#ifdef GPAC_HAS_OPENGL
	if (xWindow->is_3D_out) {
	  int attribs[64];
	  int i;

	  i=0;
	  attribs[i++] = GLX_RGBA;
	  attribs[i++] = GLX_RED_SIZE;
	  attribs[i++] = 5;
	  attribs[i++] = GLX_GREEN_SIZE;
	  attribs[i++] = 5;
	  attribs[i++] = GLX_BLUE_SIZE;
	  attribs[i++] = 5;
	  attribs[i++] = GLX_DEPTH_SIZE;
	  attribs[i++] = 16;
	  if (xWindow->gl_cfg.double_buffered) attribs[i++] = GLX_DOUBLEBUFFER;
	  attribs[i++] = None;
	  xWindow->glx_visualinfo = glXChooseVisual(xWindow->display, xWindow->screennum, attribs);
	  if (!xWindow->glx_visualinfo) {
		  GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Error selecting GL display\n"));
	  }
	}
#endif
	xWindow->setup_done = 1;
}