int VoutManager::controlWindow( struct vout_window_t *pWnd, int query, va_list args ) { intf_thread_t *pIntf = (intf_thread_t *)pWnd->p_private; VoutManager *pThis = pIntf->p_sys->p_voutManager; vout_thread_t* pVout = pWnd->vout; switch( query ) { case VOUT_SET_SIZE: { unsigned int i_width = va_arg( args, unsigned int ); unsigned int i_height = va_arg( args, unsigned int ); if( i_width && i_height ) { pThis->lockVout(); vector<SavedVout>::iterator it; for( it = pThis->m_SavedVoutVec.begin(); it != pThis->m_SavedVoutVec.end(); it++ ) { if( (*it).pVout == pVout ) { // Post a vout resize command CmdResizeVout *pCmd = new CmdResizeVout( pThis->getIntf(), (*it).pVoutWindow, (int)i_width, (int)i_height ); AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); break; } } pThis->unlockVout(); } } default: msg_Dbg( pWnd, "control query not supported" ); break; } return VLC_SUCCESS; }
void VlcProc::on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal ) { (void)p_obj; (void)newVal; bool b_fullscreen = getFullscreenVar().get(); if( !b_fullscreen ) { if( newVal.b_bool ) { // Create a raise all command CmdRaiseAll *pCmd = new CmdRaiseAll( getIntf(), getIntf()->p_sys->p_theme->getWindowManager() ); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); } } else { VoutManager* pVoutManager = VoutManager::instance( getIntf() ); FscWindow *pWin = pVoutManager->getFscWindow(); if( pWin ) { bool b_visible = pWin->getVisibleVar().get(); AsyncQueue *pQueue = AsyncQueue::instance( getIntf() ); if( !b_visible ) { CmdShowWindow* pCmd = new CmdShowWindow( getIntf(), getIntf()->p_sys->p_theme->getWindowManager(), *pWin ); pQueue->push( CmdGenericPtr( pCmd ) ); } else { CmdHideWindow* pCmd = new CmdHideWindow( getIntf(), getIntf()->p_sys->p_theme->getWindowManager(), *pWin ); pQueue->push( CmdGenericPtr( pCmd ) ); } } } }
void *VoutManager::getWindow( intf_thread_t *pIntf, vout_window_t *pWnd ) { // Theme may have been destroyed if( !pIntf->p_sys->p_theme ) return NULL; VoutManager *pThis = pIntf->p_sys->p_voutManager; vout_thread_t* pVout = pWnd->vout; int width = (int)pWnd->width; int height = (int)pWnd->height; pThis->lockVout(); void* handle = pThis->acceptVout( pVout, width, height ); pThis->unlockVout(); return handle; }
void VoutManager::releaseWindow( intf_thread_t *pIntf, vout_window_t *pWnd ) { VoutManager *pThis = pIntf->p_sys->p_voutManager; // Theme may have been destroyed if( !pIntf->p_sys->p_theme ) return; vout_thread_t* pVout = pWnd->vout; pThis->lockVout(); // remove vout thread from savedVec vector<SavedVout>::iterator it; for( it = pThis->m_SavedVoutVec.begin(); it != pThis->m_SavedVoutVec.end(); it++ ) { if( (*it).pVout == pVout ) { msg_Dbg( pIntf, "vout released vout=0x%p, VideoCtrl=0x%p", pVout, (*it).pCtrlVideo ); // if a video control was being used, detach from it if( (*it).pCtrlVideo ) { (*it).pCtrlVideo->detachVoutWindow( ); } // remove resources delete (*it).pVoutWindow; pThis->m_SavedVoutVec.erase( it ); break; } } pThis->unlockVout(); }
X11Window::X11Window( intf_thread_t *pIntf, GenericWindow &rWindow, X11Display &rDisplay, bool dragDrop, bool playOnDrop, X11Window *pParentWindow, GenericWindow::WindowType_t type ): OSWindow( pIntf ), m_rDisplay( rDisplay ), m_pParent( pParentWindow ), m_dragDrop( dragDrop ), m_pDropTarget( NULL ), m_type ( type ) { XSetWindowAttributes attr; unsigned long valuemask; std::string name_type; if( type == GenericWindow::FullscreenWindow ) { m_wnd_parent = DefaultRootWindow( XDISPLAY ); int i_screen = DefaultScreen( XDISPLAY ); attr.event_mask = ExposureMask | StructureNotifyMask; attr.background_pixel = BlackPixel( XDISPLAY, i_screen ); attr.backing_store = Always; valuemask = CWBackingStore | CWBackPixel | CWEventMask; if( NET_WM_STATE_FULLSCREEN == None ) { attr.override_redirect = True; valuemask = valuemask | CWOverrideRedirect; } name_type = "Fullscreen"; } else if( type == GenericWindow::VoutWindow ) { m_wnd_parent = pParentWindow->m_wnd; int i_screen = DefaultScreen( XDISPLAY ); attr.event_mask = ExposureMask | StructureNotifyMask; attr.backing_store = Always; attr.background_pixel = BlackPixel( XDISPLAY, i_screen ); valuemask = CWBackingStore | CWBackPixel | CWEventMask; name_type = "VoutWindow"; } else if( type == GenericWindow::FscWindow ) { m_wnd_parent = DefaultRootWindow( XDISPLAY ); attr.event_mask = ExposureMask | StructureNotifyMask; valuemask = CWEventMask; name_type = "FscWindow"; } else { m_wnd_parent = DefaultRootWindow( XDISPLAY ); attr.event_mask = ExposureMask | StructureNotifyMask; valuemask = CWEventMask; name_type = "TopWindow"; } // Create the window m_wnd = XCreateWindow( XDISPLAY, m_wnd_parent, -10, 0, 10, 10, 0, 0, InputOutput, CopyFromParent, valuemask, &attr ); // wait for X server to process the previous commands XSync( XDISPLAY, false ); // Set the colormap for 8bpp mode if( XPIXELSIZE == 1 ) { XSetWindowColormap( XDISPLAY, m_wnd, m_rDisplay.getColormap() ); } // Select events received by the window long event_mask; if( type == GenericWindow::VoutWindow ) { event_mask = ExposureMask|KeyPressMask| LeaveWindowMask|FocusChangeMask; } else { event_mask = ExposureMask|KeyPressMask| PointerMotionMask|ButtonPressMask|ButtonReleaseMask| LeaveWindowMask|FocusChangeMask; } XSelectInput( XDISPLAY, m_wnd, event_mask ); // Store a pointer on the generic window in a map X11Factory *pFactory = (X11Factory*)X11Factory::instance( getIntf() ); pFactory->m_windowMap[m_wnd] = &rWindow; // Changing decorations struct { unsigned long flags; unsigned long functions; unsigned long decorations; signed long input_mode; unsigned long status; } motifWmHints; Atom hints_atom = XInternAtom( XDISPLAY, "_MOTIF_WM_HINTS", False ); motifWmHints.flags = 2; // MWM_HINTS_DECORATIONS; motifWmHints.decorations = 0; XChangeProperty( XDISPLAY, m_wnd, hints_atom, hints_atom, 32, PropModeReplace, (unsigned char *)&motifWmHints, sizeof( motifWmHints ) / sizeof( uint32_t ) ); // Drag & drop if( m_dragDrop ) { // Create a Dnd object for this window m_pDropTarget = new X11DragDrop( getIntf(), m_rDisplay, m_wnd, playOnDrop, &rWindow ); // Register the window as a drop target Atom xdndAtom = XInternAtom( XDISPLAY, "XdndAware", False ); char xdndVersion = 4; XChangeProperty( XDISPLAY, m_wnd, xdndAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&xdndVersion, 1 ); // Store a pointer to be used in X11Loop pFactory->m_dndMap[m_wnd] = m_pDropTarget; } // Change the window title std::string name_window = "VLC (" + name_type + ")"; XStoreName( XDISPLAY, m_wnd, name_window.c_str() ); // Set the WM_TRANSIENT_FOR property if( type == GenericWindow::FscWindow ) { // Associate the fsc window to the fullscreen window VoutManager* pVoutManager = VoutManager::instance( getIntf() ); GenericWindow* pWin = pVoutManager->getVoutMainWindow(); Window wnd = (Window) pWin->getOSHandle(); XSetTransientForHint( XDISPLAY, m_wnd, wnd ); } else { // Associate the regular top-level window to the offscren main window XSetTransientForHint( XDISPLAY, m_wnd, m_rDisplay.getMainWindow() ); } // initialize Class Hint XClassHint classhint; classhint.res_name = (char*) "vlc"; classhint.res_class = (char*) "Vlc"; XSetClassHint( XDISPLAY, m_wnd, &classhint ); // copies WM_HINTS from the main window XWMHints *wm = XGetWMHints( XDISPLAY, m_rDisplay.getMainWindow() ); if( wm ) { XSetWMHints( XDISPLAY, m_wnd, wm ); XFree( wm ); } // initialize WM_CLIENT_MACHINE char* hostname = NULL; long host_name_max = sysconf( _SC_HOST_NAME_MAX ); if( host_name_max <= 0 ) host_name_max = _POSIX_HOST_NAME_MAX; hostname = new char[host_name_max]; if( hostname && gethostname( hostname, host_name_max ) == 0 ) { hostname[host_name_max - 1] = '\0'; XTextProperty textprop; textprop.value = (unsigned char *) hostname; textprop.encoding = XA_STRING; textprop.format = 8; textprop.nitems = strlen( hostname ); XSetWMClientMachine( XDISPLAY, m_wnd, &textprop); } delete[] hostname; // initialize EWMH pid pid_t pid = getpid(); assert( NET_WM_PID != None ); XChangeProperty( XDISPLAY, m_wnd, NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1 ); }
Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow, HINSTANCE hInst, HWND hParentWindow, bool dragDrop, bool playOnDrop, Win32Window *pParentWindow, GenericWindow::WindowType_t type ): OSWindow( pIntf ), m_dragDrop( dragDrop ), m_isLayered( false ), m_pParent( pParentWindow ), m_type ( type ) { (void)hParentWindow; Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() ); const char* vlc_name = "VlC Media Player"; const char* vlc_class = "SkinWindowClass"; // Create the window if( type == GenericWindow::VoutWindow ) { // Child window (for vout) m_hWnd_parent = pParentWindow->getHandle(); m_hWnd = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_NOPARENTNOTIFY, vlc_class, vlc_name, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL ); } else if( type == GenericWindow::FullscreenWindow ) { // top-level window m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, vlc_class, vlc_name, WS_POPUP | WS_CLIPCHILDREN, 0, 0, 0, 0, NULL, 0, hInst, NULL ); // Store with it a pointer to the interface thread SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() ); } else if( type == GenericWindow::FscWindow ) { VoutManager* pVoutManager = VoutManager::instance( getIntf() ); GenericWindow* pParent = (GenericWindow*)pVoutManager->getVoutMainWindow(); m_hWnd_parent = (HWND)pParent->getOSHandle(); // top-level window m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, vlc_class, vlc_name, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL ); // Store with it a pointer to the interface thread SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() ); } else { // top-level window (owned by the root window) HWND hWnd_owner = pFactory->getParentWindow(); m_hWnd = CreateWindowEx( 0, vlc_class, vlc_name, WS_POPUP | WS_CLIPCHILDREN, 0, 0, 0, 0, hWnd_owner, 0, hInst, NULL ); // Store with it a pointer to the interface thread SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() ); } if( !m_hWnd ) { msg_Err( getIntf(), "CreateWindow failed" ); return; } // Store a pointer to the GenericWindow in a map pFactory->m_windowMap[m_hWnd] = &rWindow; // Drag & drop if( m_dragDrop ) { m_pDropTarget = (LPDROPTARGET) new Win32DragDrop( getIntf(), playOnDrop, &rWindow ); // Register the window as a drop target RegisterDragDrop( m_hWnd, m_pDropTarget ); } }