📄 xcommon.c
字号:
var_Get( p_vout, "mouse-button-down", &val ); val.i_int &= ~4; var_Set( p_vout, "mouse-button-down", val ); p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF, FIND_ANYWHERE ); if( p_intf ) { p_intf->b_menu_change = 1; vlc_object_release( p_intf ); } p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist != NULL ) { vlc_value_t val; val.b_bool = VLC_TRUE; var_Set( p_playlist, "intf-popupmenu", val ); vlc_object_release( p_playlist ); } } break; case Button4: var_Get( p_vout, "mouse-button-down", &val ); val.i_int &= ~8; var_Set( p_vout, "mouse-button-down", val ); break; case Button5: var_Get( p_vout, "mouse-button-down", &val ); val.i_int &= ~16; var_Set( p_vout, "mouse-button-down", val ); break; } } /* Mouse move */ else if( xevent.type == MotionNotify ) { int i_width, i_height, i_x, i_y; vlc_value_t val; /* somewhat different use for vout_PlacePicture: * here the values are needed to give to mouse coordinates * in the original picture space */ vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width, p_vout->p_sys->p_win->i_height, &i_x, &i_y, &i_width, &i_height ); val.i_int = ( xevent.xmotion.x - i_x ) * p_vout->render.i_width / i_width; var_Set( p_vout, "mouse-x", val ); val.i_int = ( xevent.xmotion.y - i_y ) * p_vout->render.i_height / i_height; var_Set( p_vout, "mouse-y", val ); val.b_bool = VLC_TRUE; var_Set( p_vout, "mouse-moved", val ); p_vout->p_sys->i_time_mouse_last_moved = mdate(); if( ! p_vout->p_sys->b_mouse_pointer_visible ) { ToggleCursor( p_vout ); } } else if( xevent.type == ReparentNotify /* XXX: why do we get this? */ || xevent.type == MapNotify || xevent.type == UnmapNotify ) { /* Ignore these events */ } else /* Other events */ { msg_Warn( p_vout, "unhandled event %d received", xevent.type ); } } /* Handle events for video output sub-window */ while( XCheckWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->p_win->video_window, ExposureMask, &xevent ) == True ) { /* Window exposed (only handled if stream playback is paused) */ if( xevent.type == Expose ) { if( ((XExposeEvent *)&xevent)->count == 0 ) { /* (if this is the last a collection of expose events...) */#if 0 if( p_vout->p_vlc->p_input_bank->pp_input[0] != NULL ) { if( PAUSE_S == p_vout->p_vlc->p_input_bank->pp_input[0] ->stream.control.i_status ) { /* XVideoDisplay( p_vout )*/; } }#endif } } } /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data * are handled - according to the man pages, the format is always 32 * in this case */ while( XCheckTypedEvent( p_vout->p_sys->p_display, ClientMessage, &xevent ) ) { if( (xevent.xclient.message_type == p_vout->p_sys->p_win->wm_protocols) && ((Atom)xevent.xclient.data.l[0] == p_vout->p_sys->p_win->wm_delete_window ) ) { /* the user wants to close the window */ playlist_t * p_playlist = (playlist_t *)vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist != NULL ) { playlist_Stop( p_playlist ); vlc_object_release( p_playlist ); } } } /* * Fullscreen Change */ if ( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE ) { vlc_value_t val; /* Update the object variable and trigger callback */ val.b_bool = !p_vout->b_fullscreen; var_Set( p_vout, "fullscreen", val ); ToggleFullScreen( p_vout ); p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; } /* * Size change * * (Needs to be placed after VOUT_FULLSREEN_CHANGE because we can activate * the size flag inside the fullscreen routine) */ if( p_vout->i_changes & VOUT_SIZE_CHANGE ) { int i_width, i_height, i_x, i_y; p_vout->i_changes &= ~VOUT_SIZE_CHANGE;#ifdef MODULE_NAME_IS_x11 /* We need to signal the vout thread about the size change because it * is doing the rescaling */ p_vout->i_changes |= VOUT_SIZE_CHANGE;#endif vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width, p_vout->p_sys->p_win->i_height, &i_x, &i_y, &i_width, &i_height ); XMoveResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->p_win->video_window, i_x, i_y, i_width, i_height ); } /* Autohide Cursour */ if( mdate() - p_vout->p_sys->i_time_mouse_last_moved > 2000000 ) { /* Hide the mouse automatically */ if( p_vout->p_sys->b_mouse_pointer_visible ) { ToggleCursor( p_vout ); } } vlc_mutex_unlock( &p_vout->p_sys->lock ); return 0;}/***************************************************************************** * EndVideo: terminate X11 video thread output method ***************************************************************************** * Destroy the X11 XImages created by Init. It is called at the end of * the thread, but also each time the window is resized. *****************************************************************************/static void EndVideo( vout_thread_t *p_vout ){ int i_index; /* Free the direct buffers we allocated */ for( i_index = I_OUTPUTPICTURES ; i_index ; ) { i_index--; FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] ); }}/* following functions are local *//***************************************************************************** * CreateWindow: open and set-up X11 main window *****************************************************************************/static int CreateWindow( vout_thread_t *p_vout, x11_window_t *p_win ){ XSizeHints xsize_hints; XSetWindowAttributes xwindow_attributes; XGCValues xgcvalues; XEvent xevent; vlc_bool_t b_expose = VLC_FALSE; vlc_bool_t b_configure_notify = VLC_FALSE; vlc_bool_t b_map_notify = VLC_FALSE; /* Prepare window manager hints and properties */ p_win->wm_protocols = XInternAtom( p_vout->p_sys->p_display, "WM_PROTOCOLS", True ); p_win->wm_delete_window = XInternAtom( p_vout->p_sys->p_display, "WM_DELETE_WINDOW", True ); /* Never have a 0-pixel-wide window */ xsize_hints.min_width = 2; xsize_hints.min_height = 1; /* Prepare window attributes */ xwindow_attributes.backing_store = Always; /* save the hidden part */ xwindow_attributes.background_pixel = BlackPixel(p_vout->p_sys->p_display, p_vout->p_sys->i_screen); xwindow_attributes.event_mask = ExposureMask | StructureNotifyMask; if( !p_vout->b_fullscreen ) { p_win->owner_window = (Window)vout_RequestWindow( p_vout, &p_win->i_x, &p_win->i_y, &p_win->i_width, &p_win->i_height ); xsize_hints.base_width = xsize_hints.width = p_win->i_width; xsize_hints.base_height = xsize_hints.height = p_win->i_height; xsize_hints.flags = PSize | PMinSize; if( p_win->i_x >=0 || p_win->i_y >= 0 ) { xsize_hints.x = p_win->i_x; xsize_hints.y = p_win->i_y; xsize_hints.flags |= PPosition; } } else { /* Fullscreen window size and position */ p_win->owner_window = 0; p_win->i_x = p_win->i_y = 0; p_win->i_width = DisplayWidth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); p_win->i_height = DisplayHeight( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); } if( !p_win->owner_window ) { /* Create the window and set hints - the window must receive * ConfigureNotify events, and until it is displayed, Expose and * MapNotify events. */ p_win->base_window = XCreateWindow( p_vout->p_sys->p_display, DefaultRootWindow( p_vout->p_sys->p_display ), p_win->i_x, p_win->i_y, p_win->i_width, p_win->i_height, 0, 0, InputOutput, 0, CWBackingStore | CWBackPixel | CWEventMask, &xwindow_attributes ); if( !p_vout->b_fullscreen ) { /* Set window manager hints and properties: size hints, command, * window's name, and accepted protocols */ XSetWMNormalHints( p_vout->p_sys->p_display, p_win->base_window, &xsize_hints ); XSetCommand( p_vout->p_sys->p_display, p_win->base_window, p_vout->p_vlc->ppsz_argv, p_vout->p_vlc->i_argc ); XStoreName( p_vout->p_sys->p_display, p_win->base_window,#ifdef MODULE_NAME_IS_x11 VOUT_TITLE " (X11 output)"#elif defined(MODULE_NAME_IS_glx) VOUT_TITLE " (GLX output)"#else VOUT_TITLE " (XVideo output)"#endif ); } } else { Window dummy1; unsigned int dummy2, dummy3; /* Select events we are interested in. */ XSelectInput( p_vout->p_sys->p_display, p_win->owner_window, StructureNotifyMask ); /* Get the parent window's geometry information */ XGetGeometry( p_vout->p_sys->p_display, p_win->owner_window, &dummy1, &dummy2, &dummy3, &p_win->i_width, &p_win->i_height, &dummy2, &dummy3 ); /* We are already configured */ b_configure_notify = VLC_TRUE; /* From man XSelectInput: only one client at a time can select a * ButtonPress event, so we need to open a new window anyway. */ p_win->base_window = XCreateWindow( p_vout->p_sys->p_display, p_win->owner_window, 0, 0, p_win->i_width, p_win->i_height, 0, 0, CopyFromParent, 0, CWBackingStore | CWBackPixel | CWEventMask, &xwindow_attributes ); } if( (p_win->wm_protocols == None) /* use WM_DELETE_WINDOW */ || (p_win->wm_delete_window == None) || !XSetWMProtocols( p_vout->p_sys->p_display, p_win->base_window, &p_win->wm_delete_window, 1 ) ) { /* WM_DELETE_WINDOW is not supported by window manager */ msg_Warn( p_vout, "missing or bad window manager" ); } /* Creation of a graphic context that doesn't generate a GraphicsExpose * event when using functions like XCopyArea */ xgcvalues.graphics_exposures = False; p_win->gc = XCreateGC( p_vout->p_sys->p_display, p_win->base_window, GCGraphicsExposures, &xgcvalues ); /* Send orders to server, and wait until window is displayed - three * events must be received: a MapNotify event, an Expose event allowing * drawing in the window, and a ConfigureNotify to get the window * dimensions. Once those events have been received, only * ConfigureNotify events need to be received. */ XMapWindow( p_vout->p_sys->p_display, p_win->base_window );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -