📄 x11_out.c
字号:
* lock video mem */GF_Err X11_LockBackBuffer(struct _video_out * vout, GF_VideoSurface * vi, u32 do_lock){ X11VID (); if (do_lock) { if (!vi) return GF_BAD_PARAM; vi->width = xWindow->back_buffer->width; vi->height = xWindow->back_buffer->height; vi->pitch = xWindow->back_buffer->pitch; vi->pixel_format = xWindow->pixel_format; vi->video_buffer = xWindow->back_buffer->buffer; vi->is_hardware_memory = (xWindow->videoaccesstype==VIDEO_XI_STANDARD) ? 0 : 1; return GF_OK; } else { return GF_OK; }}static XErrorHandler old_handler = NULL;static int selectinput_err = 0;static int X11_BadAccess_ByPass(Display * display, XErrorEvent * event){ char msg[60]; if (event->error_code == BadAccess) { selectinput_err = 1; return 0; } if (old_handler != NULL) old_handler(display, event); else { XGetErrorText(display, event->error_code, (char *) &msg, 60); GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Error %s\n",msg)); } return 0;}/* * Setup X11 wnd System */voidX11_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;}GF_Err X11_Setup(struct _video_out *vout, void *os_handle, void *os_display, u32 no_proc_override, GF_GLConfig * cfg){ X11VID (); /*assign window if any, NEVER display*/ xWindow->par_wnd = (Window) os_handle; /*OSMOZILLA HACK*/ if (os_display) xWindow->no_select_input = 1; if (cfg) {#ifdef GPAC_HAS_OPENGL xWindow->is_3D_out = 1; xWindow->gl_cfg = *cfg;#else return GF_NOT_SUPPORTED;#endif } else { xWindow->is_3D_out = 0; } /*the rest is done THROUGH THE MAIN RENDERER TRHEAD!!*/ return GF_OK;}/* Shutdown X11 */void X11_Shutdown (struct _video_out *vout){ X11VID (); if (xWindow->is_3D_out) {#ifdef GPAC_HAS_OPENGL X11_ReleaseGL(xWindow);#endif } else { X11_ReleaseBackBuffer (vout); } free(xWindow->back_buffer); XFreeGC (xWindow->display, xWindow->the_gc); XUnmapWindow (xWindow->display, (Window) xWindow->wnd); XDestroyWindow (xWindow->display, (Window) xWindow->wnd); XDestroyWindow (xWindow->display, (Window) xWindow->full_wnd); XCloseDisplay (xWindow->display); free (xWindow);}void *NewX11VideoOutput (){ GF_VideoOutput *driv; XWindow *xWindow; GF_SAFEALLOC(driv, GF_VideoOutput); if (!driv) return NULL; GF_SAFEALLOC(xWindow, XWindow); if (!xWindow) { free(driv); return NULL; } GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "X11 Video Output", "gpac distribution") driv->opaque = xWindow; driv->Flush = X11_Flush; driv->SetFullScreen = X11_SetFullScreen; driv->Setup = X11_Setup; driv->Shutdown = X11_Shutdown; driv->LockBackBuffer = X11_LockBackBuffer; driv->ProcessEvent = X11_ProcessEvent; driv->hw_caps = GF_VIDEO_HW_HAS_OPENGL; return (void *) driv;}voidDeleteX11VideoOutput (GF_VideoOutput * vout){ free (vout);}/* * interface query */BoolQueryInterface (u32 InterfaceType){ if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; return 0;}/* * interface create */GF_BaseInterface *LoadInterface (u32 InterfaceType){ if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) NewX11VideoOutput (); return NULL;}/* * interface destroy */voidShutdownInterface (GF_BaseInterface *ifce){ switch (ifce->InterfaceType) { case GF_VIDEO_OUTPUT_INTERFACE: DeleteX11VideoOutput ((GF_VideoOutput *)ifce); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -