📄 xcommon.c
字号:
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 ); 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 );}/***************************************************************************** * NewPicture: allocate a picture ***************************************************************************** * Returns 0 on success, -1 otherwise *****************************************************************************/static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ){#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, 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, 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->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; } 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; /* fullscreen window size and position */ p_vout->p_sys->p_win->i_width = DisplayWidth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); p_vout->p_sys->p_win->i_height = DisplayHeight( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); CreateWindow( p_vout, p_vout->p_sys->p_win ); /* 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, p_vout->p_sys->p_win->base_window, DefaultRootWindow( p_vout->p_sys->p_display ), 0, 0 ); } if( p_vout->p_sys->b_net_wm_state_fullscreen ) { XClientMessageEvent event; memset( &event, 0, sizeof( XClientMessageEvent ) ); event.type = ClientMessage; event.message_type = p_vout->p_sys->net_wm_state; event.display = p_vout->p_sys->p_display; event.window = p_vout->p_sys->p_win->base_window; event.format = 32; event.data.l[ 0 ] = 1; /* set property */ event.data.l[ 1 ] = p_vout->p_sys->net_wm_state_fullscreen; XSendEvent( p_vout->p_sys->p_display, DefaultRootWindow( p_vout->p_sys->p_display ), False, SubstructureRedirectMask, (XEvent*)&event ); } /* Make sure the change is effective */ XReparentWindow( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window, DefaultRootWindow( p_vout->p_sys->p_display ), 0, 0 ); /* fullscreen window size and position */ p_vout->p_sys->p_win->i_width = DisplayWidth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); p_vout->p_sys->p_win->i_height = DisplayHeight( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); p_vout->p_sys->p_win->i_x = 0; p_vout->p_sys->p_win->i_y = 0;#ifdef HAVE_XINERAMA if( XineramaQueryExtension( p_vout->p_sys->p_display, &i_d1, &i_d2 ) && XineramaIsActive( p_vout->p_sys->p_display ) ) { XineramaScreenInfo *screens; /* infos for xinerama */ int i_num_screens; msg_Dbg( p_vout, "using XFree Xinerama extension");#define SCREEN p_vout->p_sys->p_win->i_screen /* Get Informations about Xinerama (num of screens) */ screens = XineramaQueryScreens( p_vout->p_sys->p_display, &i_num_screens ); if( !SCREEN ) SCREEN = config_GetInt( p_vout, MODULE_STRING "-xineramascreen" ); /* just check that user has entered a good value */ if( SCREEN >= i_num_screens || SCREEN < 0 ) { msg_Dbg( p_vout, "requested screen number invalid" ); SCREEN = 0; } /* Get the X/Y upper left corner coordinate of the above screen */ p_vout->p_sys->p_win->i_x = screens[SCREEN].x_org; p_vout->p_sys->p_win->i_y = screens[SCREEN].y_org; /* Set the Height/width to the screen resolution */ p_vout->p_sys->p_win->i_width = screens[SCREEN].width; p_vout->p_sys->p_win->i_height = screens[SCREEN].height; XFree(screens);#undef SCREEN }#endif XMoveResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window, p_vout->p_sys->p_win->i_x, p_vout->p_sys->p_win->i_y, p_vout->p_sys->p_win->i_width, p_vout->p_sys->p_win->i_height ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -