Commit 9f475faa authored by Erwan Tulou's avatar Erwan Tulou

skins2(x11): implement cursor management

parent 93b9f3a3
......@@ -3750,9 +3750,10 @@ AS_IF([test "${enable_skins2}" != "no"], [
], [
PKG_CHECK_MODULES([XPM], [xpm],, [have_skins_deps="no"])
PKG_CHECK_MODULES([XINERAMA], [xinerama],, [have_skins_deps="no"])
PKG_CHECK_MODULES([XCURSOR], [xcursor],, [have_skins_x11_deps="no"])
PKG_CHECK_MODULES([XEXT], [xext],, [have_skins_deps="no"])
VLC_ADD_CPPFLAGS([skins2],[${X_CFLAGS} ${XEXT_CFLAGS} ${XPM_CFLAGS} -DX11_SKINS])
VLC_ADD_LIBS([skins2],[${X_LIBS} ${X_PRE_LIBS} ${XEXT_LIBS} ${XPM_LIBS} ${XINERAMA_LIBS} -lX11])
VLC_ADD_LIBS([skins2],[${X_LIBS} ${X_PRE_LIBS} ${XEXT_LIBS} ${XPM_LIBS} ${XINERAMA_LIBS} ${XCURSOR_LIBS} -lX11])
])
dnl we need freetype
......
......@@ -32,8 +32,8 @@
GenericWindow::GenericWindow( intf_thread_t *pIntf, int left, int top,
bool dragDrop, bool playOnDrop,
GenericWindow *pParent, WindowType_t type ):
SkinObject( pIntf ), m_left( left ), m_top( top ), m_width( 0 ),
m_height( 0 ), m_pVarVisible( NULL )
SkinObject( pIntf ), m_type( type ), m_left( left ), m_top( top ),
m_width( 0 ), m_height( 0 ), m_pVarVisible( NULL )
{
// Get the OSFactory
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
......
......@@ -114,6 +114,9 @@ public:
/// windows handle
vlc_wnd_type getOSHandle() const;
/// window type
WindowType_t getType() { return m_type; }
/// reparent
void setParent( GenericWindow* pParent,
int x = 0, int y = 0, int w = -1, int h = -1 );
......@@ -157,6 +160,7 @@ protected:
virtual void onUpdate( Subject<VarBool> &rVariable , void*);
private:
WindowType_t m_type;
/// Window position and size
int m_left, m_top, m_width, m_height;
/// OS specific implementation
......
......@@ -45,7 +45,8 @@
#include <vlc_xlib.h>
X11Factory::X11Factory( intf_thread_t *pIntf ): OSFactory( pIntf ),
m_pDisplay( NULL ), m_pTimerLoop( NULL ), m_dirSep( "/" )
m_pDisplay( NULL ), m_pTimerLoop( NULL ), m_dirSep( "/" ),
mPointerWindow( None ), mVoutWindow( None ), mEmptyCursor( None )
{
// see init()
}
......@@ -53,6 +54,8 @@ X11Factory::X11Factory( intf_thread_t *pIntf ): OSFactory( pIntf ),
X11Factory::~X11Factory()
{
if( mEmptyCursor != None )
XFreeCursor( m_pDisplay->getDisplay(), mEmptyCursor );
delete m_pTimerLoop;
delete m_pDisplay;
}
......@@ -107,6 +110,9 @@ bool X11Factory::init()
XFree( info );
}
// init cursors
initCursors();
return true;
}
......@@ -370,4 +376,50 @@ void X11Factory::rmDir( const std::string &rPath )
rmdir( rPath.c_str() );
}
void X11Factory::changeCursor( CursorType_t type ) const
{
Cursor cursor = mCursors[type];
Window win = (type == OSFactory::kNoCursor) ? mVoutWindow : mPointerWindow;
if( win != None )
XDefineCursor( m_pDisplay->getDisplay(), win, cursor );
}
void X11Factory::initCursors( )
{
Display *display = m_pDisplay->getDisplay();
static const struct {
CursorType_t type;
const char *name;
} cursors[] = {
{ kDefaultArrow, "left_ptr" },
{ kResizeNWSE, "bottom_right_corner" },
{ kResizeNS, "bottom_side" },
{ kResizeWE, "right_side" },
{ kResizeNESW, "bottom_left_corner" },
};
// retrieve cursors from default theme
for( unsigned i = 0; i < sizeof(cursors) / sizeof(cursors[0]); i++ )
mCursors[cursors[i].type] =
XcursorLibraryLoadCursor( display, cursors[i].name );
// build an additional empty cursor
XColor color;
const char data[] = { 0 };
Window root = DefaultRootWindow( display );
Pixmap pix = XCreateBitmapFromData( display, root, data, 1, 1 );
mEmptyCursor = XCreatePixmapCursor( display, pix, pix, &color, &color, 0, 0 );
XFreePixmap( display, pix );
mCursors[kNoCursor] = mEmptyCursor;
}
void X11Factory::setPointerWindow( Window win )
{
GenericWindow *pWin = m_windowMap[win];
if( pWin->getType() == GenericWindow::VoutWindow )
mVoutWindow = win;
mPointerWindow = win;
}
#endif
......@@ -26,6 +26,7 @@
#define X11_FACTORY_HPP
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
#include "../src/os_factory.hpp"
#include "../src/generic_window.hpp"
......@@ -144,8 +145,7 @@ public:
virtual void getMousePos( int &rXPos, int &rYPos ) const;
/// Change the cursor
virtual void changeCursor( CursorType_t type ) const
{ /*TODO*/ (void)type; }
virtual void changeCursor( CursorType_t type ) const;
/// Delete a directory recursively
virtual void rmDir( const std::string &rPath );
......@@ -153,6 +153,10 @@ public:
/// Get the timer loop
X11TimerLoop *getTimerLoop() const { return m_pTimerLoop; }
/// retain current window where mouse pointer lies
void setPointerWindow( Window win );
private:
/// X11 display
X11Display *m_pDisplay;
......@@ -164,6 +168,11 @@ private:
std::list<std::string> m_resourcePath;
/// Monitor geometry
int m_screenWidth, m_screenHeight;
/// cursor management variables
mutable std::map<CursorType_t, Cursor> mCursors;
void initCursors();
Window mPointerWindow, mVoutWindow;
Cursor mEmptyCursor;
};
#endif
......@@ -161,7 +161,7 @@ inline int X11Loop::X11ModToMod( unsigned state )
void X11Loop::handleX11Event()
{
XEvent event;
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
X11Factory *pFactory = (X11Factory*)OSFactory::instance( getIntf() );
// Look for the next event in the queue
XNextEvent( XDISPLAY, &event );
......@@ -186,8 +186,7 @@ void X11Loop::handleX11Event()
}
// Find the window to which the event is sent
GenericWindow *pWin =
((X11Factory*)pOsFactory)->m_windowMap[event.xany.window];
GenericWindow *pWin = pFactory->m_windowMap[event.xany.window];
if( !pWin )
{
......@@ -223,7 +222,8 @@ void X11Loop::handleX11Event()
// 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 );
pFactory->getMousePos( x, y );
pFactory->setPointerWindow( event.xany.window );
EvtMotion evt( getIntf(), x, y );
pWin->processEvent( evt );
break;
......@@ -256,7 +256,7 @@ void X11Loop::handleX11Event()
{
mtime_t time = mdate();
int x, y;
pOsFactory->getMousePos( x, y );
pFactory->getMousePos( x, y );
if( time - m_lastClickTime < m_dblClickDelay &&
x == m_lastClickPosX && y == m_lastClickPosY )
{
......@@ -343,8 +343,7 @@ void X11Loop::handleX11Event()
std::string type = XGetAtomName( XDISPLAY, event.xclient.message_type );
// Find the DnD object for this window
X11DragDrop *pDnd =
((X11Factory*)pOsFactory)->m_dndMap[event.xany.window];
X11DragDrop *pDnd = pFactory->m_dndMap[event.xany.window];
if( !pDnd )
{
msg_Err( getIntf(), "no associated D&D object" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment