📄 xcommon.c
字号:
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, 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 );#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 Information about Xinerama (num of screens) */ screens = XineramaQueryScreens( p_vout->p_sys->p_display, &i_num_screens ); 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 (%d/%d)", SCREEN, i_num_screens ); 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 } else#endif {#ifdef HAVE_XF86VIDMODE XF86VidModeModeLine mode; int i_dummy;#endif /* The window wasn't necessarily created at the requested size */ p_vout->p_sys->p_win->i_x = p_vout->p_sys->p_win->i_y = 0;#ifdef HAVE_XF86VIDMODE if( XF86VidModeGetModeLine( p_vout->p_sys->p_display, p_vout->p_sys->i_screen, &i_dummy, &mode ) ) { p_vout->p_sys->p_win->i_width = mode.hdisplay; p_vout->p_sys->p_win->i_height = mode.vdisplay; /* move cursor to the middle of the window to prevent * unwanted display move if the display is smaller than the * full desktop */ XWarpPointer( p_vout->p_sys->p_display, None, p_vout->p_sys->p_win->base_window, 0, 0, 0, 0, mode.hdisplay / 2 , mode.vdisplay / 2 ); /* force desktop view to upper left corner */ XF86VidModeSetViewPort( p_vout->p_sys->p_display, p_vout->p_sys->i_screen, 0, 0 ); } else#endif { 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 ); } } 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 ); } else { msg_Dbg( p_vout, "leaving fullscreen mode" ); XReparentWindow( p_vout->p_sys->p_display, p_vout->p_sys->original_window.video_window, p_vout->p_sys->original_window.base_window, 0, 0 ); p_vout->p_sys->fullscreen_window.video_window = None; DestroyWindow( p_vout, &p_vout->p_sys->fullscreen_window ); p_vout->p_sys->p_win = &p_vout->p_sys->original_window; XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window ); } /* Unfortunately, using XSync() here is not enough to ensure the * window has already been mapped because the XMapWindow() request * has not necessarily been sent directly to our window (remember, * the call is first redirected to the window manager) */ do { XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window, StructureNotifyMask, &xevent ); } while( xevent.type != MapNotify ); /* Be careful, this can generate a BadMatch error if the window is not * already mapped by the server (see above) */ XSetInputFocus(p_vout->p_sys->p_display, p_vout->p_sys->p_win->base_window, RevertToParent, CurrentTime); /* signal that the size needs to be updated */ p_vout->i_changes |= VOUT_SIZE_CHANGE;}/***************************************************************************** * EnableXScreenSaver: enable screen saver ***************************************************************************** * This function enables the screen saver on a display after it has been * disabled by XDisableScreenSaver. * FIXME: what happens if multiple vlc sessions are running at the same * time ??? *****************************************************************************/static void EnableXScreenSaver( vout_thread_t *p_vout ){#ifdef DPMSINFO_IN_DPMS_H int dummy;#endif if( p_vout->p_sys->i_ss_timeout ) { XSetScreenSaver( p_vout->p_sys->p_display, p_vout->p_sys->i_ss_timeout, p_vout->p_sys->i_ss_interval, p_vout->p_sys->i_ss_blanking,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -