Пример #1
0
void X11Factory::getMonitorInfo( const GenericWindow &rWindow,
                                 int* p_x, int* p_y,
                                 int* p_width, int* p_height ) const
{
    // initialize to default geometry
    *p_x = 0;
    *p_y = 0;
    *p_width = getScreenWidth();
    *p_height = getScreenHeight();

    // Use Xinerama to determine the monitor where the video
    // mostly resides (biggest surface)
    Display *pDisplay = m_pDisplay->getDisplay();
    Window wnd = (Window)rWindow.getOSHandle();
    Window root = DefaultRootWindow( pDisplay );
    Window child_wnd;

    int x, y;
    unsigned int w, h, border, depth;
    XGetGeometry( pDisplay, wnd, &root, &x, &y, &w, &h, &border, &depth );
    XTranslateCoordinates( pDisplay, wnd, root, 0, 0, &x, &y, &child_wnd );

    int num;
    XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
    if( info )
    {
        Region reg1 = XCreateRegion();
        XRectangle rect1 = { (short)x, (short)y, (unsigned short)w, (unsigned short)h };
        XUnionRectWithRegion( &rect1, reg1, reg1 );

        unsigned int surface = 0;
        for( int i = 0; i < num; i++ )
        {
            Region reg2 = XCreateRegion();
            XRectangle rect2 = { info[i].x_org, info[i].y_org,
                                 (unsigned short)info[i].width, (unsigned short)info[i].height };
            XUnionRectWithRegion( &rect2, reg2, reg2 );

            Region reg = XCreateRegion();
            XIntersectRegion( reg1, reg2, reg );
            XRectangle rect;
            XClipBox( reg, &rect );
            unsigned int surf = rect.width * rect.height;
            if( surf > surface )
            {
               surface = surf;
               *p_x = info[i].x_org;
               *p_y = info[i].y_org;
               *p_width = info[i].width;
               *p_height = info[i].height;
            }
            XDestroyRegion( reg );
            XDestroyRegion( reg2 );
        }
        XDestroyRegion( reg1 );
        XFree( info );
    }
}
static pascal OSStatus WinEventHandler( EventHandlerCallRef handler,
                                        EventRef event, void *data )
{
    GenericWindow *pWin = (GenericWindow*)data;
    intf_thread_t *pIntf = pWin->getIntf();

    //fprintf(stderr, "event\n" );
    UInt32 evclass = GetEventClass( event );
    UInt32 evkind = GetEventKind( event );

    switch( evclass )
    {
    case kEventClassWindow:
        EvtRefresh evt( pIntf, 0, 0, -1, -1);
        pWin->processEvent( evt );
        break;
    }
}
Пример #3
0
// static 
INT_PTR GenericWindow::_dlgProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	GenericWindow *pThis = NULL;

	if (msg == WM_INITDIALOG) {			
		// map dialog window handle to its GenericWindow object
		pThis = (GenericWindow *) lParam;		
		::SetWindowLongPtr ( hWnd, GWLP_USERDATA, (__int3264)(LONG_PTR)pThis);
		pThis->m_hWnd = hWnd;
	}
	else {
		// get window object from window handle
		LONG_PTR ptr = ::GetWindowLongPtr (hWnd, GWLP_USERDATA);
		pThis = (GenericWindow *) ptr;
	}

	if (pThis) {
		return pThis->HandleDialogMessage (msg, wParam, lParam);
	}

	return FALSE;
}
Пример #4
0
// static 
LRESULT CALLBACK GenericWindow::_wndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	GenericWindow *pWnd = NULL;

	if (msg == WM_CREATE) {
		// get GenericWindow object
		CREATESTRUCT *cs = (CREATESTRUCT *) lParam;
		pWnd = (GenericWindow *)cs->lpCreateParams;
		WINGUI_ASSERT (pWnd);

		// bind HWND with the Sim8085IdeWindow object 
		::SetWindowLongPtr ( hWnd, GWLP_USERDATA, (__int3264)(LONG_PTR)pWnd);
	} else {
		// get window object from window handle
		LONG_PTR ptr = ::GetWindowLongPtr (hWnd, GWLP_USERDATA);
		pWnd = (GenericWindow *) ptr;
	}

	if (pWnd) {
		return pWnd->HandleMessage (msg, wParam, lParam);
	}

	return ::DefWindowProc (hWnd, msg, wParam, lParam);
}
void Win32Factory::getMonitorInfo( const GenericWindow &rWindow,
                                   int* p_x, int* p_y,
                                   int* p_width, int* p_height ) const
{
    HWND wnd = (HWND)rWindow.getOSHandle();
    HMONITOR hmon = MonitorFromWindow( wnd, MONITOR_DEFAULTTONEAREST );
    MONITORINFO mi;
    mi.cbSize = sizeof( MONITORINFO );
    if( hmon && GetMonitorInfo( hmon, &mi ) )
    {
        *p_x = mi.rcMonitor.left;
        *p_y = mi.rcMonitor.top;
        *p_width = mi.rcMonitor.right - mi.rcMonitor.left;
        *p_height = mi.rcMonitor.bottom - mi.rcMonitor.top;
    }
    else
    {
        *p_x = 0;
        *p_y = 0;
        *p_width = getScreenWidth();
        *p_height = getScreenHeight();
    }
}
Пример #6
0
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 );

}
Пример #7
0
void X11Loop::handleX11Event()
{
    XEvent event;
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );

    // Look for the next event in the queue
    XNextEvent( XDISPLAY, &event );

    if( event.xany.window == m_rDisplay.getMainWindow() )
    {
        if( event.type == MapNotify )
        {
            // When the "parent" window is mapped, show all the visible
            // windows, as it is not automatic, unfortunately
            Theme *pTheme = getIntf()->p_sys->p_theme;
            if( pTheme )
            {
                // Commented out as it really doesn't seem useful
                // but rather brings visible problems
                // pTheme->getWindowManager().synchVisibility();
            }
        }
        return;
    }

    // Find the window to which the event is sent
    GenericWindow *pWin =
        ((X11Factory*)pOsFactory)->m_windowMap[event.xany.window];

    if( !pWin )
    {
        return;
    }

    // Send the right event object to the window
    switch( event.type )
    {
        case Expose:
        {
            EvtRefresh evt( getIntf(), event.xexpose.x,
                            event.xexpose.y, event.xexpose.width,
                            event.xexpose.height );
            pWin->processEvent( evt );
            break;
        }
        case FocusIn:
        {
            EvtFocus evt( getIntf(), true );
            pWin->processEvent( evt );
            break;
        }
        case FocusOut:
        {
            EvtFocus evt( getIntf(), false );
            pWin->processEvent( evt );
            break;
        }

        case MotionNotify:
        {
            // Don't trust the position in the event, it is
            // out of date. Get the actual current position instead
            int x, y;
            pOsFactory->getMousePos( x, y );
            EvtMotion evt( getIntf(), x, y );
            pWin->processEvent( evt );
            break;
        }
        case LeaveNotify:
        {
            EvtLeave evt( getIntf() );
            pWin->processEvent( evt );
            break;
        }
        case ButtonPress:
        case ButtonRelease:
        {
            EvtMouse::ActionType_t action = EvtMouse::kDown;
            switch( event.type )
            {
                case ButtonPress:
                    action = EvtMouse::kDown;
                    break;
                case ButtonRelease:
                    action = EvtMouse::kUp;
                    break;
            }

            // Get the modifiers
            int mod = EvtInput::kModNone;
            if( event.xbutton.state & Mod1Mask )
            {
                mod |= EvtInput::kModAlt;
            }
            if( event.xbutton.state & ControlMask )
            {
                mod |= EvtInput::kModCtrl;
            }
            if( event.xbutton.state & ShiftMask )
            {
                mod |= EvtInput::kModShift;
            }

            // Check for double clicks
            if( event.type == ButtonPress &&
                event.xbutton.button == 1 )
            {
                mtime_t time = mdate();
                int x, y;
                pOsFactory->getMousePos( x, y );
                if( time - m_lastClickTime < m_dblClickDelay &&
                    x == m_lastClickPosX && y == m_lastClickPosY )
                {
                    m_lastClickTime = 0;
                    action = EvtMouse::kDblClick;
                }
                else
                {
                    m_lastClickTime = time;
                    m_lastClickPosX = x;
                    m_lastClickPosY = y;
                }
            }

            switch( event.xbutton.button )
            {
                case 1:
                {
                    EvtMouse evt( getIntf(), event.xbutton.x,
                                  event.xbutton.y, EvtMouse::kLeft,
                                  action, mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 2:
                {
                    EvtMouse evt( getIntf(), event.xbutton.x,
                                  event.xbutton.y, EvtMouse::kMiddle,
                                  action, mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 3:
                {
                    EvtMouse evt( getIntf(), event.xbutton.x,
                                  event.xbutton.y, EvtMouse::kRight,
                                  action, mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 4:
                {
                    // Scroll up
                    EvtScroll evt( getIntf(), event.xbutton.x,
                                   event.xbutton.y, EvtScroll::kUp,
                                   mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 5:
                {
                    // Scroll down
                    EvtScroll evt( getIntf(), event.xbutton.x,
                                   event.xbutton.y, EvtScroll::kDown,
                                   mod );
                    pWin->processEvent( evt );
                    break;
                }
            }
            break;
        }
        case KeyPress:
        case KeyRelease:
        {
            EvtKey::ActionType_t action = EvtKey::kDown;
            int mod = EvtInput::kModNone;
            // Get the modifiers
            if( event.xkey.state & Mod1Mask )
            {
                mod |= EvtInput::kModAlt;
            }
            if( event.xkey.state & ControlMask )
            {
                mod |= EvtInput::kModCtrl;
            }
            if( event.xkey.state & ShiftMask )
            {
                mod |= EvtInput::kModShift;
            }

            // Take the first keysym = lower case character
            KeySym keysym = XLookupKeysym( &event.xkey, 0 );

            // Get VLC key code from the keysym
            int key = keysymToVlcKey[keysym];
            if( !key )
            {
                // Normal key
                key = keysym;
            }

            switch( event.type )
            {
                case KeyPress:
                    action = EvtKey::kDown;
                    break;
                case KeyRelease:
                    action = EvtKey::kUp;
                    break;
            }
            EvtKey evt( getIntf(), key, action, mod );
            pWin->processEvent( evt );
            break;
        }

        case ClientMessage:
        {
            // Get the message type
            string type = XGetAtomName( XDISPLAY, event.xclient.message_type );

            // Find the DnD object for this window
            X11DragDrop *pDnd =
                ((X11Factory*)pOsFactory)->m_dndMap[event.xany.window];
            if( !pDnd )
            {
                msg_Err( getIntf(), "no associated D&D object" );
                return;
            }

            if( type == "XdndEnter" )
            {
                pDnd->dndEnter( event.xclient.data.l );
            }
            else if( type == "XdndPosition" )
            {
                pDnd->dndPosition( event.xclient.data.l );
            }
            else if( type == "XdndLeave" )
            {
                pDnd->dndLeave( event.xclient.data.l );
            }
            else if( type == "XdndDrop" )
            {
                pDnd->dndDrop( event.xclient.data.l );
            }
            break;
        }
    }
}
Пример #8
0
void X11Loop::handleX11Event()
{
    XEvent event;
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );

    // Look for the next event in the queue
    XNextEvent( XDISPLAY, &event );

    if( event.xany.window == m_rDisplay.getMainWindow() )
    {
        if( event.type == ClientMessage )
        {
            Atom wm_protocols =
                XInternAtom( XDISPLAY, "WM_PROTOCOLS", False);
            Atom wm_delete =
                XInternAtom( XDISPLAY, "WM_DELETE_WINDOW", False);

            if( event.xclient.message_type == wm_protocols &&
                event.xclient.data.l[0] == wm_delete )
            {
                msg_Dbg( getIntf(), "Received WM_DELETE_WINDOW message" );
                libvlc_Quit( getIntf()->p_libvlc );
            }
        }
        return;
    }

    // Find the window to which the event is sent
    GenericWindow *pWin =
        ((X11Factory*)pOsFactory)->m_windowMap[event.xany.window];

    if( !pWin )
    {
        return;
    }

    // Send the right event object to the window
    switch( event.type )
    {
        case Expose:
        {
            EvtRefresh evt( getIntf(), event.xexpose.x,
                            event.xexpose.y, event.xexpose.width,
                            event.xexpose.height );
            pWin->processEvent( evt );
            break;
        }
        case FocusIn:
        {
            EvtFocus evt( getIntf(), true );
            pWin->processEvent( evt );
            break;
        }
        case FocusOut:
        {
            EvtFocus evt( getIntf(), false );
            pWin->processEvent( evt );
            break;
        }

        case MotionNotify:
        {
            // Don't trust the position in the event, it is
            // out of date. Get the actual current position instead
            int x, y;
            pOsFactory->getMousePos( x, y );
            EvtMotion evt( getIntf(), x, y );
            pWin->processEvent( evt );
            break;
        }
        case LeaveNotify:
        {
            EvtLeave evt( getIntf() );
            pWin->processEvent( evt );
            break;
        }
        case ButtonPress:
        case ButtonRelease:
        {
            EvtMouse::ActionType_t action = EvtMouse::kDown;
            switch( event.type )
            {
            case ButtonPress:
                action = EvtMouse::kDown;
                break;
            case ButtonRelease:
                action = EvtMouse::kUp;
                break;
            }

            int mod = X11ModToMod( event.xbutton.state );

            // Check for double clicks
            if( event.type == ButtonPress &&
                event.xbutton.button == 1 )
            {
                mtime_t time = mdate();
                int x, y;
                pOsFactory->getMousePos( x, y );
                if( time - m_lastClickTime < m_dblClickDelay &&
                    x == m_lastClickPosX && y == m_lastClickPosY )
                {
                    m_lastClickTime = 0;
                    action = EvtMouse::kDblClick;
                }
                else
                {
                    m_lastClickTime = time;
                    m_lastClickPosX = x;
                    m_lastClickPosY = y;
                }
            }

            switch( event.xbutton.button )
            {
                case 1:
                {
                    EvtMouse evt( getIntf(), event.xbutton.x,
                                  event.xbutton.y, EvtMouse::kLeft,
                                  action, mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 2:
                {
                    EvtMouse evt( getIntf(), event.xbutton.x,
                                  event.xbutton.y, EvtMouse::kMiddle,
                                  action, mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 3:
                {
                    EvtMouse evt( getIntf(), event.xbutton.x,
                                  event.xbutton.y, EvtMouse::kRight,
                                  action, mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 4:
                {
                    // Scroll up
                    EvtScroll evt( getIntf(), event.xbutton.x,
                                   event.xbutton.y, EvtScroll::kUp,
                                   mod );
                    pWin->processEvent( evt );
                    break;
                }
                case 5:
                {
                    // Scroll down
                    EvtScroll evt( getIntf(), event.xbutton.x,
                                   event.xbutton.y, EvtScroll::kDown,
                                   mod );
                    pWin->processEvent( evt );
                    break;
                }
            }
            break;
        }
        case KeyPress:
        case KeyRelease:
        {
            // Take the first keysym = lower case character, and translate.
            int key = keysymToVlcKey( XLookupKeysym( &event.xkey, 0 ) );

            EvtKey evt( getIntf(), key,
                        event.type==KeyRelease ? EvtKey::kUp : EvtKey::kDown,
                        X11ModToMod( event.xkey.state ) );
            pWin->processEvent( evt );
            break;
        }

        case ClientMessage:
        {
            // Get the message type
            string type = XGetAtomName( XDISPLAY, event.xclient.message_type );

            // Find the DnD object for this window
            X11DragDrop *pDnd =
                ((X11Factory*)pOsFactory)->m_dndMap[event.xany.window];
            if( !pDnd )
            {
                msg_Err( getIntf(), "no associated D&D object" );
                return;
            }

            if( type == "XdndEnter" )
                pDnd->dndEnter( event.xclient.data.l );
            else if( type == "XdndPosition" )
                pDnd->dndPosition( event.xclient.data.l );
            else if( type == "XdndLeave" )
                pDnd->dndLeave( event.xclient.data.l );
            else if( type == "XdndDrop" )
                pDnd->dndDrop( event.xclient.data.l );
            break;
        }
    }
}
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 );
    }
}