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 ); } }