📄 xcommon.c
字号:
do { XWindowEvent( p_vout->p_sys->p_display, p_win->base_window, SubstructureNotifyMask | StructureNotifyMask | ExposureMask, &xevent); if( (xevent.type == Expose) && (xevent.xexpose.window == p_win->base_window) ) { b_expose = VLC_TRUE; /* ConfigureNotify isn't sent if there isn't a window manager. * Expose should be the last event to be received so it should * be fine to assume we won't receive it anymore. */ b_configure_notify = VLC_TRUE; } else if( (xevent.type == MapNotify) && (xevent.xmap.window == p_win->base_window) ) { b_map_notify = VLC_TRUE; } else if( (xevent.type == ConfigureNotify) && (xevent.xconfigure.window == p_win->base_window) ) { b_configure_notify = VLC_TRUE; p_win->i_width = xevent.xconfigure.width; p_win->i_height = xevent.xconfigure.height; } } while( !( b_expose && b_configure_notify && b_map_notify ) ); XSelectInput( p_vout->p_sys->p_display, p_win->base_window, StructureNotifyMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask );#ifdef MODULE_NAME_IS_x11 if( XDefaultDepth(p_vout->p_sys->p_display, p_vout->p_sys->i_screen) == 8 ) { /* Allocate a new palette */ p_vout->p_sys->colormap = XCreateColormap( p_vout->p_sys->p_display, DefaultRootWindow( p_vout->p_sys->p_display ), DefaultVisual( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ), AllocAll ); xwindow_attributes.colormap = p_vout->p_sys->colormap; XChangeWindowAttributes( p_vout->p_sys->p_display, p_win->base_window, CWColormap, &xwindow_attributes ); }#endif /* Create video output sub-window. */ p_win->video_window = XCreateSimpleWindow( p_vout->p_sys->p_display, p_win->base_window, 0, 0, p_win->i_width, p_win->i_height, 0, BlackPixel( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ), WhitePixel( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ) ); XSetWindowBackground( p_vout->p_sys->p_display, p_win->video_window, BlackPixel( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ) ); XMapWindow( p_vout->p_sys->p_display, p_win->video_window ); XSelectInput( p_vout->p_sys->p_display, p_win->video_window, ExposureMask ); /* make sure the video window will be centered in the next ManageVideo() */ p_vout->i_changes |= VOUT_SIZE_CHANGE; /* If the cursor was formerly blank than blank it again */ if( !p_vout->p_sys->b_mouse_pointer_visible ) { ToggleCursor( p_vout ); ToggleCursor( p_vout ); } /* Do NOT use XFlush here ! */ XSync( p_vout->p_sys->p_display, False ); /* At this stage, the window is open, displayed, and ready to * receive data */ p_vout->p_sys->p_win = p_win; return VLC_SUCCESS;}/***************************************************************************** * DestroyWindow: destroy the window ***************************************************************************** * *****************************************************************************/static void DestroyWindow( vout_thread_t *p_vout, x11_window_t *p_win ){ /* Do NOT use XFlush here ! */ XSync( p_vout->p_sys->p_display, False ); if( p_win->video_window != None ) XDestroyWindow( p_vout->p_sys->p_display, p_win->video_window ); XFreeGC( p_vout->p_sys->p_display, p_win->gc ); XUnmapWindow( p_vout->p_sys->p_display, p_win->base_window ); XDestroyWindow( p_vout->p_sys->p_display, p_win->base_window ); if( p_win->owner_window ) vout_ReleaseWindow( p_vout, (void *)p_win->owner_window );}/***************************************************************************** * NewPicture: allocate a picture ***************************************************************************** * Returns 0 on success, -1 otherwise *****************************************************************************/static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ){#ifndef MODULE_NAME_IS_glx#ifdef MODULE_NAME_IS_xvideo int i_plane;#endif /* We know the chroma, allocate a buffer which will be used * directly by the decoder */ p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); if( p_pic->p_sys == NULL ) { return -1; } /* Fill in picture_t fields */ vout_InitPicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma, p_vout->output.i_width, p_vout->output.i_height, p_vout->output.i_aspect );#ifdef HAVE_SYS_SHM_H if( p_vout->p_sys->b_shm ) { /* Create image using XShm extension */ p_pic->p_sys->p_image = CreateShmImage( p_vout, p_vout->p_sys->p_display,# ifdef MODULE_NAME_IS_xvideo p_vout->p_sys->i_xvport, VLC2X11_FOURCC(p_vout->output.i_chroma),# else p_vout->p_sys->p_visual, p_vout->p_sys->i_screen_depth,# endif &p_pic->p_sys->shminfo, p_vout->output.i_width, p_vout->output.i_height ); } else#endif /* HAVE_SYS_SHM_H */ { /* Create image without XShm extension */ p_pic->p_sys->p_image = CreateImage( p_vout, p_vout->p_sys->p_display,#ifdef MODULE_NAME_IS_xvideo p_vout->p_sys->i_xvport, VLC2X11_FOURCC(p_vout->output.i_chroma), p_pic->format.i_bits_per_pixel,#else p_vout->p_sys->p_visual, p_vout->p_sys->i_screen_depth, p_vout->p_sys->i_bytes_per_pixel,#endif p_vout->output.i_width, p_vout->output.i_height ); } if( p_pic->p_sys->p_image == NULL ) { free( p_pic->p_sys ); return -1; } switch( p_vout->output.i_chroma ) {#ifdef MODULE_NAME_IS_xvideo case VLC_FOURCC('I','4','2','0'): case VLC_FOURCC('Y','V','1','2'): case VLC_FOURCC('Y','2','1','1'): case VLC_FOURCC('Y','U','Y','2'): case VLC_FOURCC('U','Y','V','Y'): case VLC_FOURCC('R','V','1','5'): case VLC_FOURCC('R','V','1','6'): case VLC_FOURCC('R','V','2','4'): /* Fixme: pixel pitch == 4 ? */ case VLC_FOURCC('R','V','3','2'): for( i_plane = 0; i_plane < p_pic->p_sys->p_image->num_planes; i_plane++ ) { p_pic->p[i_plane].p_pixels = p_pic->p_sys->p_image->data + p_pic->p_sys->p_image->offsets[i_plane]; p_pic->p[i_plane].i_pitch = p_pic->p_sys->p_image->pitches[i_plane]; } if( p_vout->output.i_chroma == VLC_FOURCC('Y','V','1','2') ) { /* U and V inverted compared to I420 * Fixme: this should be handled by the vout core */ p_pic->U_PIXELS = p_pic->p_sys->p_image->data + p_pic->p_sys->p_image->offsets[2]; p_pic->V_PIXELS = p_pic->p_sys->p_image->data + p_pic->p_sys->p_image->offsets[1]; } break;#else case VLC_FOURCC('R','G','B','2'): case VLC_FOURCC('R','V','1','6'): case VLC_FOURCC('R','V','1','5'): case VLC_FOURCC('R','V','2','4'): case VLC_FOURCC('R','V','3','2'): p_pic->p->i_lines = p_pic->p_sys->p_image->height; p_pic->p->i_visible_lines = p_pic->p_sys->p_image->height; p_pic->p->p_pixels = p_pic->p_sys->p_image->data + p_pic->p_sys->p_image->xoffset; p_pic->p->i_pitch = p_pic->p_sys->p_image->bytes_per_line; /* p_pic->p->i_pixel_pitch = 4 for RV24 but this should be set * properly by vout_InitPicture() */ p_pic->p->i_visible_pitch = p_pic->p->i_pixel_pitch * p_pic->p_sys->p_image->width; break;#endif default: /* Unknown chroma, tell the guy to get lost */ IMAGE_FREE( p_pic->p_sys->p_image ); free( p_pic->p_sys ); msg_Err( p_vout, "never heard of chroma 0x%.8x (%4.4s)", p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma ); p_pic->i_planes = 0; return -1; }#endif /* !MODULE_NAME_IS_glx */ return 0;}/***************************************************************************** * FreePicture: destroy a picture allocated with NewPicture ***************************************************************************** * Destroy XImage AND associated data. If using Shm, detach shared memory * segment from server and process, then free it. The XDestroyImage manpage * says that both the image structure _and_ the data pointed to by the * image structure are freed, so no need to free p_image->data. *****************************************************************************/static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic ){ /* The order of operations is correct */#ifdef HAVE_SYS_SHM_H if( p_vout->p_sys->b_shm ) { XShmDetach( p_vout->p_sys->p_display, &p_pic->p_sys->shminfo ); IMAGE_FREE( p_pic->p_sys->p_image ); shmctl( p_pic->p_sys->shminfo.shmid, IPC_RMID, 0 ); if( shmdt( p_pic->p_sys->shminfo.shmaddr ) ) { msg_Err( p_vout, "cannot detach shared memory (%s)", strerror(errno) ); } } else#endif { IMAGE_FREE( p_pic->p_sys->p_image ); } /* Do NOT use XFlush here ! */ XSync( p_vout->p_sys->p_display, False ); free( p_pic->p_sys );}/***************************************************************************** * ToggleFullScreen: Enable or disable full screen mode ***************************************************************************** * This function will switch between fullscreen and window mode. *****************************************************************************/static void ToggleFullScreen ( vout_thread_t *p_vout ){ Atom prop; XEvent xevent; mwmhints_t mwmhints; XSetWindowAttributes attributes;#ifdef HAVE_XINERAMA int i_d1, i_d2;#endif p_vout->b_fullscreen = !p_vout->b_fullscreen; if( p_vout->b_fullscreen ) { msg_Dbg( p_vout, "entering fullscreen mode" ); p_vout->p_sys->b_altfullscreen = config_GetInt( p_vout, MODULE_STRING "-altfullscreen" ); XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window ); p_vout->p_sys->p_win = &p_vout->p_sys->fullscreen_window; CreateWindow( p_vout, p_vout->p_sys->p_win ); XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->fullscreen_window.video_window ); XReparentWindow( p_vout->p_sys->p_display, p_vout->p_sys->original_window.video_window, p_vout->p_sys->fullscreen_window.base_window, 0, 0 ); p_vout->p_sys->fullscreen_window.video_window = p_vout->p_sys->original_window.video_window; /* To my knowledge there are two ways to create a borderless window. * There's the generic way which is to tell x to bypass the window * manager, but this creates problems with the focus of other * applications. * The other way is to use the motif property "_MOTIF_WM_HINTS" which * luckily seems to be supported by most window managers. */ if( !p_vout->p_sys->b_altfullscreen ) { mwmhints.flags = MWM_HINTS_DECORATIONS; mwmhints.decorations = False; prop = XInternAtom( p_vout->p_sys->p_display, "_MOTIF_WM_HINTS", False ); XChangeProperty( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window, prop, prop, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS ); } else { /* brute force way to remove decorations */ attributes.override_redirect = True; XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window, CWOverrideRedirect, &attributes); /* Make sure the change is effective */ XReparentWindow( p_vout->p_sys->p_display,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -