📄 xcommon.c
字号:
/***************************************************************************** * xcommon.c: Functions common to the X11 and XVideo plugins ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN * $Id: xcommon.c 10831 2005-04-26 14:27:47Z gbazin $ * * Authors: Vincent Seguin <seguin@via.ecp.fr> * Sam Hocevar <sam@zoy.org> * David Kennedy <dkennedy@tinytoad.com> * Gildas Bazin <gbazin@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <errno.h> /* ENOMEM */#include <stdlib.h> /* free() */#include <string.h> /* strerror() */#include <vlc/vlc.h>#include <vlc/intf.h>#include <vlc/vout.h>#include <vlc_keys.h>#ifdef HAVE_MACHINE_PARAM_H /* BSD */# include <machine/param.h># include <sys/types.h> /* typedef ushort */# include <sys/ipc.h>#endif#ifndef WIN32# include <netinet/in.h> /* BSD: struct in_addr */#endif#ifdef HAVE_SYS_SHM_H# include <sys/shm.h> /* shmget(), shmctl() */#endif#include <X11/Xlib.h>#include <X11/Xproto.h>#include <X11/Xmd.h>#include <X11/Xutil.h>#include <X11/keysym.h>#ifdef HAVE_SYS_SHM_H# include <X11/extensions/XShm.h>#endif#ifdef DPMSINFO_IN_DPMS_H# include <X11/extensions/dpms.h>#endif#ifdef MODULE_NAME_IS_xvideo# include <X11/extensions/Xv.h># include <X11/extensions/Xvlib.h>#endif#ifdef MODULE_NAME_IS_glx# include <GL/glx.h>#endif#ifdef HAVE_XINERAMA# include <X11/extensions/Xinerama.h>#endif#include "xcommon.h"/***************************************************************************** * Local prototypes *****************************************************************************/int E_(Activate) ( vlc_object_t * );void E_(Deactivate) ( vlc_object_t * );static int InitVideo ( vout_thread_t * );static void EndVideo ( vout_thread_t * );static void DisplayVideo ( vout_thread_t *, picture_t * );static int ManageVideo ( vout_thread_t * );static int Control ( vout_thread_t *, int, va_list );static int InitDisplay ( vout_thread_t * );static int CreateWindow ( vout_thread_t *, x11_window_t * );static void DestroyWindow ( vout_thread_t *, x11_window_t * );static int NewPicture ( vout_thread_t *, picture_t * );static void FreePicture ( vout_thread_t *, picture_t * );static IMAGE_TYPE *CreateImage ( vout_thread_t *, Display *, EXTRA_ARGS, int, int );#ifdef HAVE_SYS_SHM_Hstatic IMAGE_TYPE *CreateShmImage ( vout_thread_t *, Display *, EXTRA_ARGS_SHM, int, int );#endifstatic void ToggleFullScreen ( vout_thread_t * );static void EnableXScreenSaver ( vout_thread_t * );static void DisableXScreenSaver ( vout_thread_t * );static void CreateCursor ( vout_thread_t * );static void DestroyCursor ( vout_thread_t * );static void ToggleCursor ( vout_thread_t * );#ifdef MODULE_NAME_IS_xvideostatic int XVideoGetPort ( vout_thread_t *, vlc_fourcc_t, vlc_fourcc_t * );static void XVideoReleasePort( vout_thread_t *, int );#endif#ifdef MODULE_NAME_IS_x11static void SetPalette ( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );#endifstatic void TestNetWMSupport( vout_thread_t * );static int ConvertKey( int );static int WindowOnTop( vout_thread_t *, vlc_bool_t );static int X11ErrorHandler( Display *, XErrorEvent * );/***************************************************************************** * Activate: allocate X11 video thread output method ***************************************************************************** * This function allocate and initialize a X11 vout method. It uses some of the * vout properties to choose the window size, and change them according to the * actual properties of the display. *****************************************************************************/int E_(Activate) ( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; char * psz_display; vlc_value_t val;#ifdef MODULE_NAME_IS_xvideo char * psz_chroma; vlc_fourcc_t i_chroma = 0; vlc_bool_t b_chroma = 0;#endif p_vout->pf_init = InitVideo; p_vout->pf_end = EndVideo; p_vout->pf_manage = ManageVideo; p_vout->pf_render = NULL; p_vout->pf_display = DisplayVideo; p_vout->pf_control = Control; /* Allocate structure */ p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); if( p_vout->p_sys == NULL ) { msg_Err( p_vout, "out of memory" ); return VLC_ENOMEM; } vlc_mutex_init( p_vout, &p_vout->p_sys->lock ); /* Open display, using the "display" config variable or the DISPLAY * environment variable */ psz_display = config_GetPsz( p_vout, MODULE_STRING "-display" ); p_vout->p_sys->p_display = XOpenDisplay( psz_display ); if( p_vout->p_sys->p_display == NULL ) /* error */ { msg_Err( p_vout, "cannot open display %s", XDisplayName( psz_display ) ); free( p_vout->p_sys ); if( psz_display ) free( psz_display ); return VLC_EGENERIC; } if( psz_display ) free( psz_display ); /* Replace error handler so we can intercept some non-fatal errors */ XSetErrorHandler( X11ErrorHandler ); /* Get a screen ID matching the XOpenDisplay return value */ p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display );#ifdef MODULE_NAME_IS_xvideo psz_chroma = config_GetPsz( p_vout, "xvideo-chroma" ); if( psz_chroma ) { if( strlen( psz_chroma ) >= 4 ) { /* Do not use direct assignment because we are not sure of the * alignment. */ memcpy(&i_chroma, psz_chroma, 4); b_chroma = 1; } free( psz_chroma ); } if( b_chroma ) { msg_Dbg( p_vout, "forcing chroma 0x%.8x (%4.4s)", i_chroma, (char*)&i_chroma ); } else { i_chroma = p_vout->render.i_chroma; } /* Check that we have access to an XVideo port providing this chroma */ p_vout->p_sys->i_xvport = XVideoGetPort( p_vout, VLC2X11_FOURCC(i_chroma), &p_vout->output.i_chroma ); if( p_vout->p_sys->i_xvport < 0 ) { /* If a specific chroma format was requested, then we don't try to * be cleverer than the user. He knew pretty well what he wanted. */ if( b_chroma ) { XCloseDisplay( p_vout->p_sys->p_display ); free( p_vout->p_sys ); return VLC_EGENERIC; } /* It failed, but it's not completely lost ! We try to open an * XVideo port for an YUY2 picture. We'll need to do an YUV * conversion, but at least it has got scaling. */ p_vout->p_sys->i_xvport = XVideoGetPort( p_vout, X11_FOURCC('Y','U','Y','2'), &p_vout->output.i_chroma ); if( p_vout->p_sys->i_xvport < 0 ) { /* It failed, but it's not completely lost ! We try to open an * XVideo port for a simple 16bpp RGB picture. We'll need to do * an YUV conversion, but at least it has got scaling. */ p_vout->p_sys->i_xvport = XVideoGetPort( p_vout, X11_FOURCC('R','V','1','6'), &p_vout->output.i_chroma ); if( p_vout->p_sys->i_xvport < 0 ) { XCloseDisplay( p_vout->p_sys->p_display ); free( p_vout->p_sys ); return VLC_EGENERIC; } } } p_vout->output.i_chroma = X112VLC_FOURCC(p_vout->output.i_chroma);#endif /* Create blank cursor (for mouse cursor autohiding) */ p_vout->p_sys->i_time_mouse_last_moved = mdate(); p_vout->p_sys->b_mouse_pointer_visible = 1; CreateCursor( p_vout ); /* Set main window's size */ p_vout->p_sys->original_window.i_width = p_vout->i_window_width; p_vout->p_sys->original_window.i_height = p_vout->i_window_height; /* Spawn base window - this window will include the video output window, * but also command buttons, subtitles and other indicators */ if( CreateWindow( p_vout, &p_vout->p_sys->original_window ) ) { msg_Err( p_vout, "cannot create X11 window" ); DestroyCursor( p_vout ); XCloseDisplay( p_vout->p_sys->p_display ); free( p_vout->p_sys ); return VLC_EGENERIC; } /* Open and initialize device. */ if( InitDisplay( p_vout ) ) { msg_Err( p_vout, "cannot initialize X11 display" ); DestroyCursor( p_vout ); DestroyWindow( p_vout, &p_vout->p_sys->original_window ); XCloseDisplay( p_vout->p_sys->p_display ); free( p_vout->p_sys ); return VLC_EGENERIC; } /* Disable screen saver */ DisableXScreenSaver( p_vout ); /* Misc init */ p_vout->p_sys->b_altfullscreen = 0; p_vout->p_sys->i_time_button_last_pressed = 0; TestNetWMSupport( p_vout ); /* Variable to indicate if the window should be on top of others */ /* Trigger a callback right now */ var_Get( p_vout, "video-on-top", &val ); var_Set( p_vout, "video-on-top", val ); return VLC_SUCCESS;}/***************************************************************************** * Deactivate: destroy X11 video thread output method ***************************************************************************** * Terminate an output method created by Open *****************************************************************************/void E_(Deactivate) ( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; /* If the fullscreen window is still open, close it */ if( p_vout->b_fullscreen ) { ToggleFullScreen( p_vout ); } /* Restore cursor if it was blanked */ if( !p_vout->p_sys->b_mouse_pointer_visible ) { ToggleCursor( p_vout ); }#ifdef MODULE_NAME_IS_x11 /* Destroy colormap */ if( XDefaultDepth(p_vout->p_sys->p_display, p_vout->p_sys->i_screen) == 8 ) { XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap ); }#elif defined(MODULE_NAME_IS_xvideo) XVideoReleasePort( p_vout, p_vout->p_sys->i_xvport );#endif DestroyCursor( p_vout ); EnableXScreenSaver( p_vout ); DestroyWindow( p_vout, &p_vout->p_sys->original_window ); XCloseDisplay( p_vout->p_sys->p_display ); /* Destroy structure */ vlc_mutex_destroy( &p_vout->p_sys->lock ); free( p_vout->p_sys );}/***************************************************************************** * InitVideo: initialize X11 video thread output method ***************************************************************************** * This function create the XImages needed by the output thread. It is called * at the beginning of the thread, but also each time the window is resized.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -