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; }
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; }
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; } }
/* * 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); }
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; }
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 ); }
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; }
/* * 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; }