diff --git a/Doxyfile b/Doxyfile
index 682af9699..4687055f6 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -148,11 +148,17 @@ FILE_PATTERNS = *.c \
*.dox
RECURSIVE = YES
EXCLUDE = ./src/helper/glew \
- ./src/helper/haikuttf \
+ ./src/helper/chipmunk \
+ ./src/helper/glm \
./src/helper/libzip \
./src/helper/SOIL \
./src/helper/stb_vorbis \
- ./src/helper/zlib
+ ./src/helper/zlib \
+ ./src/helper/PlusCallback \
+ ./src/helper/sophist \
+ ./src/fluid \
+ ./src/test \
+ ./src/eeiv
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
diff --git a/ee.win.cbp b/ee.win.cbp
index 8fe967d46..2084fd4d5 100644
--- a/ee.win.cbp
+++ b/ee.win.cbp
@@ -7,7 +7,7 @@
-
+
@@ -19,7 +19,7 @@
-
+
@@ -33,8 +33,9 @@
-
+
+
@@ -795,6 +796,10 @@
+
+
+
+
@@ -806,6 +811,10 @@
+
+
+
+
@@ -817,6 +826,10 @@
+
+
+
+
@@ -829,6 +842,10 @@
+
+
+
+
@@ -841,6 +858,7 @@
+
@@ -855,8 +873,12 @@
+
+
+
+
diff --git a/src/ee.h b/src/ee.h
index 7a3c3e293..3b92a3190 100755
--- a/src/ee.h
+++ b/src/ee.h
@@ -25,7 +25,7 @@
@TODO Check for endianness problems, and make EEPP endianness agnostic.
@TODO Add backend for SDL 1.3 ( support for Android ). And may be SFML backend ( just for fun ).
@TODO Support for Android and iOS.
- @TODO Support color cursors - Imposible with SDL 1.2. Allegro 5 have this implemented ( could implement this for the Allegro backend at least ).
+ @TODO Support color cursors - Imposible with SDL 1.2. Allegro 5 have this implemented ( could implement this for the Allegro backend at least - DONE ).
@TODO Remove std::wstring dependency ( wchar_t ), and create an eeString class to manage strings without wchar_t platform restrictions ( Android only supports wchar_t in 2.3 ).
@TODO Add Scripting support ( squirrel or python ).
*/
diff --git a/src/test/ee.cpp b/src/test/ee.cpp
index dba9770d2..2d3322122 100644
--- a/src/test/ee.cpp
+++ b/src/test/ee.cpp
@@ -1026,9 +1026,11 @@ void cEETest::LoadTextures() {
Cursor[1] = TF->LoadFromPack( &PAK, "cursor.tga" );
CursorP[1] = TF->GetTexture( Cursor[1] );
- mWindow->GetCursorManager()->Visible( false );
- //mWindow->GetCursorManager()->Set( mWindow->GetCursorManager()->Add( mWindow->GetCursorManager()->Create( MyPath + "data/cursor.tga", eeVector2i( 2, 2 ), "cursor_special" ) ) );
- //mWindow->GetCursorManager()->Set( Window::Cursor::SYS_CURSOR_EDIT );
+ //cCursorManager * CurMan = mWindow->GetCursorManager();
+ //CurMan->Visible( false );
+ //CurMan->Visible( true );
+ //CurMan->Set( Window::Cursor::SYS_CURSOR_DEFAULT );
+ //CurMan->Set( CurMan->Add( CurMan->Create( MyPath + "data/cursor.tga", eeVector2i( 2, 2 ), "cursor_special" ) ) );
CL1.AddFrame(TN[2]);
CL1.Position( 500, 400 );
@@ -1664,7 +1666,7 @@ void cEETest::Process() {
else
mFontLoader.Update();
- if ( KM->IsKeyUp(KEY_F12) ) mWindow->TakeScreenshot( MyPath + "data/screenshots/" ); //After render and before Display
+ if ( KM->IsKeyUp(KEY_F12) ) mWindow->TakeScreenshot( MyPath + "data/screenshots/" ); //After render and before Display
mWindow->Display();
} while( mWindow->Running() );
diff --git a/src/window/backend/SDL/ccursormanagersdl.cpp b/src/window/backend/SDL/ccursormanagersdl.cpp
index 82918cd0d..d78fb305f 100644
--- a/src/window/backend/SDL/ccursormanagersdl.cpp
+++ b/src/window/backend/SDL/ccursormanagersdl.cpp
@@ -11,21 +11,35 @@ cCursorManagerSDL::cCursorManagerSDL( cWindow * window ) :
}
cCursor * cCursorManagerSDL::Create( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) {
+ #if defined( EE_X11_PLATFORM ) || EE_PLATFORM == EE_PLATFORM_WIN
+ return mWindow->GetPlatform()->CreateMouseCursor( tex, hotspot, name );
+ #else
return eeNew( cCursorSDL, ( tex, hotspot, name, mWindow ) );
+ #endif
}
cCursor * cCursorManagerSDL::Create( cImage * img, const eeVector2i& hotspot, const std::string& name ) {
+ #if defined( EE_X11_PLATFORM ) || EE_PLATFORM == EE_PLATFORM_WIN
+ return mWindow->GetPlatform()->CreateMouseCursor( img, hotspot, name );
+ #else
return eeNew( cCursorSDL, ( img, hotspot, name, mWindow ) );
+ #endif
}
cCursor * cCursorManagerSDL::Create( const std::string& path, const eeVector2i& hotspot, const std::string& name ) {
+ #if defined( EE_X11_PLATFORM ) || EE_PLATFORM == EE_PLATFORM_WIN
+ return mWindow->GetPlatform()->CreateMouseCursor( path, hotspot, name );
+ #else
return eeNew( cCursorSDL, ( path, hotspot, name, mWindow ) );
+ #endif
}
void cCursorManagerSDL::Set( cCursor * cursor ) {
+ mWindow->GetPlatform()->SetMouseCursor( cursor );
}
void cCursorManagerSDL::Set( EE_SYSTEM_CURSOR syscurid ) {
+ mWindow->GetPlatform()->SetSystemMouseCursor( syscurid );
}
void cCursorManagerSDL::Show() {
@@ -38,17 +52,30 @@ void cCursorManagerSDL::Hide() {
void cCursorManagerSDL::Visible( bool visible ) {
if ( visible ) {
- SDL_ShowCursor( SDL_ENABLE );
+ SDL_ShowCursor( SDL_ENABLE );
+
+ mWindow->GetPlatform()->ShowMouseCursor();
+
mVisible = true;
} else {
- SDL_ShowCursor( SDL_DISABLE );
+ SDL_ShowCursor( SDL_DISABLE );
+
+ mWindow->GetPlatform()->HideMouseCursor();
+
mVisible = false;
}
+}
+
+void cCursorManagerSDL::Remove( cCursor * cursor, bool Delete ) {
+ //! FIXME: Implement Secure Deletion
+ cCursorManager::Remove( cursor, Delete );
}
void cCursorManagerSDL::Reload() {
if ( mVisible ) {
- Show();
+ Show();
+
+ mWindow->GetPlatform()->RestoreCursor();
} else {
Hide();
}
diff --git a/src/window/backend/SDL/ccursormanagersdl.hpp b/src/window/backend/SDL/ccursormanagersdl.hpp
index cad40af81..a21fa6cb7 100644
--- a/src/window/backend/SDL/ccursormanagersdl.hpp
+++ b/src/window/backend/SDL/ccursormanagersdl.hpp
@@ -29,7 +29,9 @@ class cCursorManagerSDL : public cCursorManager {
void Hide();
- void Visible( bool visible );
+ void Visible( bool visible );
+
+ void Remove( cCursor * cursor, bool Delete = false );
void Reload();
};
diff --git a/src/window/backend/SDL/cinputsdl.cpp b/src/window/backend/SDL/cinputsdl.cpp
index 39ee10bee..484640382 100644
--- a/src/window/backend/SDL/cinputsdl.cpp
+++ b/src/window/backend/SDL/cinputsdl.cpp
@@ -1,5 +1,6 @@
#include "cinputsdl.hpp"
#include "cjoystickmanagersdl.hpp"
+#include "ccursormanagersdl.hpp"
#ifdef EE_BACKEND_SDL_ACTIVE
diff --git a/src/window/backend/SDL/cwindowsdl.cpp b/src/window/backend/SDL/cwindowsdl.cpp
index 03c69647e..f9625cea4 100644
--- a/src/window/backend/SDL/cwindowsdl.cpp
+++ b/src/window/backend/SDL/cwindowsdl.cpp
@@ -121,6 +121,8 @@ bool cWindowSDL::Create( WindowSettings Settings, ContextSettings Context ) {
/// Init the input after the window creation
reinterpret_cast ( mInput )->Init();
+ mCursorManager->Set( Cursor::SYS_CURSOR_DEFAULT );
+
return true;
} catch (...) {
LogFailureInit( "cWindowSDL", "SDL" );
@@ -135,7 +137,7 @@ void cWindowSDL::CreatePlatform() {
SDL_GetWMInfo ( &mWMinfo );
#if defined( EE_X11_PLATFORM )
- mPlatform = eeNew( Platform::cX11Impl, ( this, mWMinfo.info.x11.display, mWMinfo.info.x11.wmwindow, mWMinfo.info.x11.lock_func, mWMinfo.info.x11.unlock_func ) );
+ mPlatform = eeNew( Platform::cX11Impl, ( this, mWMinfo.info.x11.display, mWMinfo.info.x11.wmwindow, mWMinfo.info.x11.window, mWMinfo.info.x11.lock_func, mWMinfo.info.x11.unlock_func ) );
#elif EE_PLATFORM == EE_PLATFORM_WIN
mPlatform = eeNew( Platform::cWinImpl, ( this, GetWindowHandler() ) );
#elif EE_PLATFORM == EE_PLATFORM_MACOSX
@@ -271,8 +273,6 @@ void cWindowSDL::Size( Uint32 Width, Uint32 Height, bool Windowed ) {
Uint32 oldWidth = mWindow.WindowConfig.Width;
Uint32 oldHeight = mWindow.WindowConfig.Height;
- SetFlagValue( &mWindow.WindowConfig.Style, WindowStyle::Fullscreen, !Windowed );
-
mWindow.WindowConfig.Width = Width;
mWindow.WindowConfig.Height = Height;
@@ -282,6 +282,10 @@ void cWindowSDL::Size( Uint32 Width, Uint32 Height, bool Windowed ) {
mWindow.WindowSize = eeSize( oldWidth, oldHeight );
}
+ if ( this->Windowed() && !Windowed ) {
+ mWinPos = Position();
+ }
+
SetGLConfig();
if ( Windowed ) {
@@ -303,12 +307,20 @@ void cWindowSDL::Size( Uint32 Width, Uint32 Height, bool Windowed ) {
}
#endif
+ if ( !this->Windowed() && Windowed ) {
+ Position( mWinPos.x, mWinPos.y );
+ }
+
+ SetFlagValue( &mWindow.WindowConfig.Style, WindowStyle::Fullscreen, !Windowed );
+
mDefaultView.SetView( 0, 0, Width, Height );
Setup2D();
SendVideoResizeCb();
+ mCursorManager->Reload();
+
if ( NULL == mSurface ) {
mWindow.Created = false;
}
diff --git a/src/window/backend/SDL/cwindowsdl.hpp b/src/window/backend/SDL/cwindowsdl.hpp
index 540c11555..dafde5879 100644
--- a/src/window/backend/SDL/cwindowsdl.hpp
+++ b/src/window/backend/SDL/cwindowsdl.hpp
@@ -41,6 +41,7 @@ class EE_API cWindowSDL : public cWindow {
SDL_Surface * mSurface;
SDL_SysWMinfo mWMinfo;
+ eeVector2i mWinPos;
void CreatePlatform();
diff --git a/src/window/backend/allegro5/ccursormanageral.cpp b/src/window/backend/allegro5/ccursormanageral.cpp
index 07000e20d..6c7a22515 100644
--- a/src/window/backend/allegro5/ccursormanageral.cpp
+++ b/src/window/backend/allegro5/ccursormanageral.cpp
@@ -49,6 +49,11 @@ void cCursorManagerAl::Visible( bool visible ) {
mVisible = false;
}
}
+
+void cCursorManagerAl::Remove( cCursor * cursor, bool Delete ) {
+ //! FIXME: Implement Secure Deletion
+ cCursorManager::Remove( cursor, Delete );
+}
void cCursorManagerAl::Show() {
Visible( true );
diff --git a/src/window/backend/allegro5/ccursormanageral.hpp b/src/window/backend/allegro5/ccursormanageral.hpp
index c23c98a64..b97c2574d 100644
--- a/src/window/backend/allegro5/ccursormanageral.hpp
+++ b/src/window/backend/allegro5/ccursormanageral.hpp
@@ -27,7 +27,9 @@ class cCursorManagerAl : public cCursorManager {
void Hide();
- void Visible( bool visible );
+ void Visible( bool visible );
+
+ void Remove( cCursor * cursor, bool Delete = false );
void Reload();
};
diff --git a/src/window/backend/allegro5/cwindowal.cpp b/src/window/backend/allegro5/cwindowal.cpp
index 997f2ed72..7819977c5 100644
--- a/src/window/backend/allegro5/cwindowal.cpp
+++ b/src/window/backend/allegro5/cwindowal.cpp
@@ -74,8 +74,8 @@ struct ALLEGRO_DISPLAY_XGLX
bool is_mapped;
int resize_count;
bool programmatic_resize;
- Cursor invisible_cursor;
- Cursor current_cursor;
+ X11Cursor invisible_cursor;
+ X11Cursor current_cursor;
bool cursor_hidden;
Pixmap icon, icon_mask;
int x, y;
@@ -229,7 +229,7 @@ void cWindowAl::CreatePlatform() {
#if defined( EE_X11_PLATFORM )
SetCurrent();
- mPlatform = eeNew( Platform::cX11Impl, ( this, GetWindowHandler(), ((ALLEGRO_DISPLAY_XGLX *)mDisplay)->window, al_display_lock, al_display_unlock ) );
+ mPlatform = eeNew( Platform::cX11Impl, ( this, GetWindowHandler(), ((ALLEGRO_DISPLAY_XGLX *)mDisplay)->window, ((ALLEGRO_DISPLAY_XGLX *)mDisplay)->window, al_display_lock, al_display_unlock ) );
#elif EE_PLATFORM == EE_PLATFORM_WIN
mPlatform = eeNew( Platform::cWinImpl, ( this, GetWindowHandler() ) );
#elif EE_PLATFORM == EE_PLATFORM_MACOSX
diff --git a/src/window/backend/null/ccursormanagernull.cpp b/src/window/backend/null/ccursormanagernull.cpp
index 11e7abcd7..83873d386 100644
--- a/src/window/backend/null/ccursormanagernull.cpp
+++ b/src/window/backend/null/ccursormanagernull.cpp
@@ -33,6 +33,10 @@ void cCursorManagerNull::Hide() {
}
void cCursorManagerNull::Visible( bool visible ) {
+}
+
+void cCursorManagerNull::Remove( cCursor * cursor, bool Delete ) {
+ cCursorManager::Remove( cursor, Delete );
}
void cCursorManagerNull::Reload() {
diff --git a/src/window/backend/null/ccursormanagernull.hpp b/src/window/backend/null/ccursormanagernull.hpp
index 4385ccd82..1342b8cd5 100644
--- a/src/window/backend/null/ccursormanagernull.hpp
+++ b/src/window/backend/null/ccursormanagernull.hpp
@@ -25,7 +25,9 @@ class cCursorManagerNull : public cCursorManager {
void Hide();
- void Visible( bool visible );
+ void Visible( bool visible );
+
+ void Remove( cCursor * cursor, bool Delete = false );
void Reload();
};
diff --git a/src/window/base.hpp b/src/window/base.hpp
index 68e4af6ff..0d3cf85ac 100644
--- a/src/window/base.hpp
+++ b/src/window/base.hpp
@@ -32,11 +32,15 @@ using namespace EE::Graphics;
#endif
#elif defined( EE_X11_PLATFORM )
#include
+ #include
+ #include
typedef Atom eeScrapType;
typedef Window X11Window;
typedef Display * eeWindowHandler;
+ typedef Cursor X11Cursor;
#undef Window
#undef Display
+ #undef Cursor
#elif EE_PLATFORM == EE_PLATFORM_MACOSX
typedef unsigned int eeScrapType;
typedef void * eeWindowHandler; // NSWindow *
diff --git a/src/window/ccursormanager.hpp b/src/window/ccursormanager.hpp
index 3e21be893..1f8db461e 100644
--- a/src/window/ccursormanager.hpp
+++ b/src/window/ccursormanager.hpp
@@ -17,7 +17,7 @@ namespace EE { namespace Window {
class EE_API cCursorManager {
public:
cCursorManager( cWindow * window );
-
+
virtual ~cCursorManager();
virtual cCursor * Create( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) = 0;
@@ -27,33 +27,33 @@ class EE_API cCursorManager {
virtual cCursor * Create( const std::string& path, const eeVector2i& hotspot, const std::string& name ) = 0;
virtual cCursor * Add( cCursor * cursor );
-
- virtual void Remove( cCursor * cursor, bool Delete = false );
-
+
+ virtual void Remove( cCursor * cursor, bool Delete = false ) = 0;
+
virtual void Remove( const std::string& name, bool Delete = false );
-
+
virtual void Remove( const Uint32& id, bool Delete = false );
-
+
virtual cCursor * Get( const std::string& name );
-
+
virtual cCursor * Get( const Uint32& id );
-
+
virtual void Set( const std::string& name );
-
+
virtual void Set( const Uint32& id );
-
+
virtual void Set( cCursor * cursor ) = 0;
-
+
virtual void Set( EE_SYSTEM_CURSOR syscurid ) = 0;
-
+
virtual void Show() = 0;
-
+
virtual void Hide() = 0;
virtual void Reload() = 0;
virtual void Visible( bool visible ) = 0;
-
+
virtual bool Visible();
protected:
typedef std::set CursorsList;
diff --git a/src/window/cengine.cpp b/src/window/cengine.cpp
index de723c1f6..0302ef3f4 100755
--- a/src/window/cengine.cpp
+++ b/src/window/cengine.cpp
@@ -18,7 +18,7 @@
#define BACKEND_SDL 1
#define BACKEND_ALLEGRO 2
-#define DEFAULT_BACKEND BACKEND_ALLEGRO
+#define DEFAULT_BACKEND BACKEND_SDL
#ifndef DEFAULT_BACKEND
diff --git a/src/window/cplatformimpl.hpp b/src/window/cplatformimpl.hpp
index ab81b7b11..1cc2e829a 100644
--- a/src/window/cplatformimpl.hpp
+++ b/src/window/cplatformimpl.hpp
@@ -2,10 +2,21 @@
#define EE_WINDOWCPLATFORMIMPL_HPP
#include "base.hpp"
+#include "cursorhelper.hpp"
-namespace EE { namespace Window {
+namespace EE {
+
+namespace Graphics {
+class cTexture;
+class cImage;
+}
+
+namespace Window {
class cWindow;
-}}
+class cCursor;
+}
+
+}
namespace EE { namespace Window { namespace Platform {
@@ -32,6 +43,22 @@ class cPlatformImpl {
virtual void SetContext( eeWindowContex Context ) = 0;
virtual eeVector2i Position() = 0;
+
+ virtual void ShowMouseCursor() = 0;
+
+ virtual void HideMouseCursor() = 0;
+
+ virtual cCursor * CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) = 0;
+
+ virtual cCursor * CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name ) = 0;
+
+ virtual cCursor * CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name ) = 0;
+
+ virtual void SetMouseCursor( cCursor * cursor ) = 0;
+
+ virtual void SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor ) = 0;
+
+ virtual void RestoreCursor() = 0;
protected:
cWindow * mWindow;
};
diff --git a/src/window/platform/null/cnullimpl.cpp b/src/window/platform/null/cnullimpl.cpp
index a31337e63..2ad80f1f4 100644
--- a/src/window/platform/null/cnullimpl.cpp
+++ b/src/window/platform/null/cnullimpl.cpp
@@ -35,4 +35,31 @@ eeVector2i cNullImpl::Position() {
return eeVector2i(0,0);
}
+void cNullImpl::ShowMouseCursor() {
+}
+
+void cNullImpl::HideMouseCursor() {
+}
+
+cCursor * cNullImpl::CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) {
+ return NULL;
+}
+
+cCursor * cNullImpl::CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name ) {
+ return NULL;
+}
+
+cCursor * cNullImpl::CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name ) {
+ return NULL;
+}
+
+void cNullImpl::SetMouseCursor( cCursor * cursor ) {
+}
+
+void cNullImpl::SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor ) {
+}
+
+void cNullImpl::RestoreCursor() {
+}
+
}}}
diff --git a/src/window/platform/null/cnullimpl.hpp b/src/window/platform/null/cnullimpl.hpp
index d7288daf3..9cf02c296 100644
--- a/src/window/platform/null/cnullimpl.hpp
+++ b/src/window/platform/null/cnullimpl.hpp
@@ -29,7 +29,22 @@ class cNullImpl : public cPlatformImpl {
void SetContext( eeWindowContex Context );
eeVector2i Position();
- protected:
+
+ void ShowMouseCursor();
+
+ void HideMouseCursor();
+
+ cCursor * CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name );
+
+ void SetMouseCursor( cCursor * cursor );
+
+ void SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor );
+
+ void RestoreCursor();
};
}}}
diff --git a/src/window/platform/osx/cosximpl.cpp b/src/window/platform/osx/cosximpl.cpp
index e0af15c99..00fd389fc 100644
--- a/src/window/platform/osx/cosximpl.cpp
+++ b/src/window/platform/osx/cosximpl.cpp
@@ -38,6 +38,33 @@ eeVector2i cOSXImpl::Position() {
return eeVector2i(0,0);
}
+void cOSXImpl::ShowMouseCursor() {
+}
+
+void cOSXImpl::HideMouseCursor() {
+}
+
+cCursor * cOSXImpl::CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) {
+ return NULL;
+}
+
+cCursor * cOSXImpl::CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name ) {
+ return NULL;
+}
+
+cCursor * cOSXImpl::CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name ) {
+ return NULL;
+}
+
+void cOSXImpl::SetMouseCursor( cCursor * cursor ) {
+}
+
+void cOSXImpl::SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor ) {
+}
+
+void cOSXImpl::RestoreCursor() {
+}
+
}}}
#endif
diff --git a/src/window/platform/osx/cosximpl.hpp b/src/window/platform/osx/cosximpl.hpp
index 099977fdc..9bd95dc04 100644
--- a/src/window/platform/osx/cosximpl.hpp
+++ b/src/window/platform/osx/cosximpl.hpp
@@ -31,7 +31,22 @@ class cOSXImpl : public cPlatformImpl {
void SetContext( eeWindowContex Context );
eeVector2i Position();
- protected:
+
+ void ShowMouseCursor();
+
+ void HideMouseCursor();
+
+ cCursor * CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name );
+
+ void SetMouseCursor( cCursor * cursor );
+
+ void SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor );
+
+ void RestoreCursor();
};
}}}
diff --git a/src/window/platform/win/ccursorwin.cpp b/src/window/platform/win/ccursorwin.cpp
new file mode 100644
index 000000000..239290c7c
--- /dev/null
+++ b/src/window/platform/win/ccursorwin.cpp
@@ -0,0 +1,216 @@
+#include "ccursorwin.hpp"
+
+#if EE_PLATFORM == EE_PLATFORM_WIN
+
+#include "cwinimpl.hpp"
+
+#define WINDOWS_RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
+
+namespace EE { namespace Window { namespace Platform {
+
+cCursorWin::cCursorWin( cTexture * tex, const eeVector2i& hotspot, const std::string& name, cWindow * window ) :
+ cCursor( tex, hotspot, name, window )
+{
+ Create();
+}
+
+cCursorWin::cCursorWin( cImage * img, const eeVector2i& hotspot, const std::string& name, cWindow * window ) :
+ cCursor( img, hotspot, name, window )
+{
+ Create();
+}
+
+cCursorWin::cCursorWin( const std::string& path, const eeVector2i& hotspot, const std::string& name, cWindow * window ) :
+ cCursor( path, hotspot, name, window )
+{
+ Create();
+}
+
+cCursorWin::~cCursorWin() {
+ if ( NULL != mCursor )
+ DestroyIcon( mCursor );
+}
+
+static BITMAPINFO *get_bitmap_info( cImage * bitmap ) {
+ BITMAPINFO *bi;
+ int i;
+
+ bi = (BITMAPINFO *) eeMalloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 256);
+
+ ZeroMemory(&bi->bmiHeader, sizeof(BITMAPINFOHEADER));
+
+ bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi->bmiHeader.biBitCount = 32;
+ bi->bmiHeader.biPlanes = 1;
+ bi->bmiHeader.biWidth = (int)bitmap->Width();
+ bi->bmiHeader.biHeight = -((int)bitmap->Height());
+ bi->bmiHeader.biClrUsed = 256;
+ bi->bmiHeader.biCompression = BI_RGB;
+
+ for (i = 0; i < 256; i++) {
+ bi->bmiColors[i].rgbRed = 0;
+ bi->bmiColors[i].rgbGreen = 0;
+ bi->bmiColors[i].rgbBlue = 0;
+ bi->bmiColors[i].rgbReserved = 0;
+ }
+
+ return bi;
+}
+
+static BYTE *get_dib_from_bitmap_32(cImage *bitmap) {
+ int w, h;
+ int x, y;
+ int pitch;
+ BYTE *pixels;
+ BYTE *dst;
+
+ w = (int)bitmap->Width();
+ h = (int)bitmap->Height();
+ pitch = w * 4;
+
+ pixels = (BYTE *) eeMalloc(h * pitch);
+ if (!pixels)
+ return NULL;
+
+ for (y = 0; y < h; y++) {
+ dst = pixels + y * pitch;
+
+ for (x = 0; x < w; x++) {
+ eeColorA C = bitmap->GetPixel( x, y );
+
+ /* BGR */
+ dst[0] = C.B();
+ dst[1] = C.G();
+ dst[2] = C.R();
+ dst[3] = C.A();
+
+ dst += 4;
+ }
+ }
+
+ return pixels;
+}
+
+static void local_stretch_blit_to_hdc( cImage *bitmap, HDC dc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h) {
+ const int bitmap_h = (const int)bitmap->Height();
+ const int bottom_up_src_y = bitmap_h - src_y - src_h;
+ BYTE *pixels;
+ BITMAPINFO *bi;
+
+ bi = get_bitmap_info(bitmap);
+ pixels = get_dib_from_bitmap_32(bitmap);
+
+ /* Windows treats all source bitmaps as bottom-up when using StretchDIBits
+ * unless the source (x,y) is (0,0). To work around this buggy behavior, we
+ * can use negative heights to reverse the direction of the blits.
+ *
+ * See for a detailed explanation.
+ */
+ if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) {
+ StretchDIBits( dc, dest_x, dest_h+dest_y-1, dest_w, -dest_h, src_x, bitmap_h - src_y + 1, src_w, -src_h, pixels, bi, DIB_RGB_COLORS, SRCCOPY );
+ }
+ else {
+ StretchDIBits( dc, dest_x, dest_y, dest_w, dest_h, src_x, bottom_up_src_y, src_w, src_h, pixels, bi, DIB_RGB_COLORS, SRCCOPY );
+ }
+
+ eeFree(pixels);
+ eeFree(bi);
+}
+
+static void local_draw_to_hdc( HDC dc, cImage * bitmap, int x, int y ) {
+ int w = bitmap->Width();
+ int h = bitmap->Height();
+ local_stretch_blit_to_hdc(bitmap, dc, 0, 0, w, h, x, y, w, h);
+}
+
+void cCursorWin::Create() {
+ if ( NULL == mImage && mImage->Size() )
+ return;
+
+ int x, y;
+ int sys_sm_cx, sys_sm_cy;
+ HDC h_dc;
+ HDC h_and_dc;
+ HDC h_xor_dc;
+ ICONINFO iconinfo;
+ HBITMAP and_mask;
+ HBITMAP xor_mask;
+ HBITMAP hOldAndMaskBitmap;
+ HBITMAP hOldXorMaskBitmap;
+ HICON icon;
+
+ /* Get allowed cursor size - Windows can't make cursors of arbitrary size */
+ sys_sm_cx = GetSystemMetrics(SM_CXCURSOR);
+ sys_sm_cy = GetSystemMetrics(SM_CYCURSOR);
+
+ if ( ( (int)mImage->Width() > sys_sm_cx ) || ( (int)mImage->Height() > sys_sm_cy ) ) {
+ return;
+ }
+
+ /* Create bitmap */
+ h_dc = GetDC( GetPlatform()->GetHandler() );
+ h_xor_dc = CreateCompatibleDC(h_dc);
+ h_and_dc = CreateCompatibleDC(h_dc);
+
+ /* Prepare AND (monochrome) and XOR (colour) mask */
+ and_mask = CreateBitmap(sys_sm_cx, sys_sm_cy, 1, 1, NULL);
+ xor_mask = CreateCompatibleBitmap(h_dc, sys_sm_cx, sys_sm_cy);
+ hOldAndMaskBitmap = (HBITMAP) SelectObject(h_and_dc, and_mask);
+ hOldXorMaskBitmap = (HBITMAP) SelectObject(h_xor_dc, xor_mask);
+
+ /* Create transparent cursor */
+ for (y = 0; y < sys_sm_cy; y++) {
+ for (x = 0; x < sys_sm_cx; x++) {
+ SetPixel(h_and_dc, x, y, WINDOWS_RGB(255, 255, 255));
+ SetPixel(h_xor_dc, x, y, WINDOWS_RGB(0, 0, 0));
+ }
+ }
+
+ local_draw_to_hdc( h_xor_dc, mImage, 0, 0 );
+
+ /* Make cursor background transparent */
+ for (y = 0; y < (int)mImage->Height(); y++) {
+ for (x = 0; x < (int)mImage->Width(); x++) {
+ eeColorA C = mImage->GetPixel( x, y );
+
+ if ( C.A() != 0 ) {
+ /* Don't touch XOR value */
+ SetPixel( h_and_dc, x, y, 0 );
+ } else {
+ /* No need to touch AND value */
+ SetPixel( h_xor_dc, x, y, WINDOWS_RGB( 0, 0, 0 ) );
+ }
+ }
+ }
+
+ SelectObject(h_and_dc, hOldAndMaskBitmap);
+ SelectObject(h_xor_dc, hOldXorMaskBitmap);
+ DeleteDC(h_and_dc);
+ DeleteDC(h_xor_dc);
+ ReleaseDC( GetPlatform()->GetHandler() , h_dc );
+
+ iconinfo.fIcon = false;
+ iconinfo.xHotspot = mHotSpot.x;
+ iconinfo.yHotspot = mHotSpot.y;
+ iconinfo.hbmMask = and_mask;
+ iconinfo.hbmColor = xor_mask;
+
+ icon = CreateIconIndirect(&iconinfo);
+
+ DeleteObject(and_mask);
+ DeleteObject(xor_mask);
+
+ mCursor = (HCURSOR)icon;
+}
+
+cWinImpl * cCursorWin::GetPlatform() {
+ return reinterpret_cast( mWindow->GetPlatform() );
+}
+
+HCURSOR cCursorWin::GetCursor() const {
+ return mCursor;
+}
+
+}}}
+
+#endif
diff --git a/src/window/platform/win/ccursorwin.hpp b/src/window/platform/win/ccursorwin.hpp
new file mode 100644
index 000000000..a2cab3dc6
--- /dev/null
+++ b/src/window/platform/win/ccursorwin.hpp
@@ -0,0 +1,39 @@
+#ifndef EE_WINDOWCCURSORWIN_HPP
+#define EE_WINDOWCCURSORWIN_HPP
+
+#include "../../ccursor.hpp"
+
+#if EE_PLATFORM == EE_PLATFORM_WIN
+
+using namespace EE::Window;
+
+namespace EE { namespace Window { namespace Platform {
+
+class cWinImpl;
+
+class cCursorWin : public cCursor {
+ public:
+ HCURSOR GetCursor() const;
+ protected:
+ friend class cWinImpl;
+
+ HCURSOR mCursor;
+
+ cCursorWin( cTexture * tex, const eeVector2i& hotspot, const std::string& name, cWindow * window );
+
+ cCursorWin( cImage * img, const eeVector2i& hotspot, const std::string& name, cWindow * window );
+
+ cCursorWin( const std::string& path, const eeVector2i& hotspot, const std::string& name, cWindow * window );
+
+ ~cCursorWin();
+
+ void Create();
+
+ cWinImpl * GetPlatform();
+};
+
+}}}
+
+#endif
+
+#endif
diff --git a/src/window/platform/win/cwinimpl.cpp b/src/window/platform/win/cwinimpl.cpp
index 85f1849a8..801141cf9 100644
--- a/src/window/platform/win/cwinimpl.cpp
+++ b/src/window/platform/win/cwinimpl.cpp
@@ -1,14 +1,20 @@
#include "cwinimpl.hpp"
#if EE_PLATFORM == EE_PLATFORM_WIN
+
+#include "../../cwindow.hpp"
-#include "../../cwindow.hpp"
+#include "ccursorwin.hpp"
+
+using namespace EE::Window::Cursor;
namespace EE { namespace Window { namespace Platform {
cWinImpl::cWinImpl( cWindow * window, eeWindowHandler handler ) :
cPlatformImpl( window ),
- mHandler( handler )
+ mHandler( handler ),
+ mCursorCurrent( NULL ),
+ mCursorHidden( false )
{
}
@@ -56,6 +62,114 @@ eeVector2i cWinImpl::Position() {
return eeVector2i( r.left, r.top );
}
+void cWinImpl::ShowMouseCursor() {
+ mCursorHidden = false;
+
+ if ( !mCursorCurrent ) {
+ SetSystemMouseCursor( Cursor::SYS_CURSOR_DEFAULT );
+ } else {
+ SetCursor( mCursorCurrent );
+ POINT p;
+ GetCursorPos( &p );
+ SetCursorPos( p.x, p.y );
+ }
+}
+
+void cWinImpl::HideMouseCursor() {
+ if ( mCursorHidden )
+ return;
+
+ mCursorHidden = true;
+
+ PostMessage( mHandler, WM_SETCURSOR, 0, 0 );
+}
+
+cCursor * cWinImpl::CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) {
+ return eeNew( cCursorWin, ( tex, hotspot, name, mWindow ) );
+}
+
+cCursor * cWinImpl::CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name ) {
+ return eeNew( cCursorWin, ( img, hotspot, name, mWindow ) );
+}
+
+cCursor * cWinImpl::CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name ) {
+ return eeNew( cCursorWin, ( path, hotspot, name, mWindow ) );
+}
+
+void cWinImpl::SetMouseCursor( cCursor * cursor ) {
+ mCursorCurrent = reinterpret_cast ( cursor )->GetCursor();
+
+ if ( !mCursorHidden ) {
+ SetCursor( mCursorCurrent );
+ POINT p;
+ GetCursorPos( &p );
+ SetCursorPos( p.x, p.y );
+ }
+}
+
+void cWinImpl::SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor ) {
+ HCURSOR mc;
+
+ switch ( syscursor ) {
+ case SYS_CURSOR_DEFAULT:
+ case SYS_CURSOR_ARROW:
+ mc = LoadCursor(NULL, IDC_ARROW); break;
+ case SYS_CURSOR_BUSY:
+ mc = LoadCursor(NULL, IDC_WAIT); break;
+ case SYS_CURSOR_QUESTION:
+ mc = LoadCursor(NULL, IDC_HELP); break;
+ case SYS_CURSOR_EDIT:
+ mc = LoadCursor(NULL, IDC_IBEAM); break;
+ case SYS_CURSOR_MOVE:
+ mc = LoadCursor(NULL, IDC_SIZEALL); break;
+ case SYS_CURSOR_RESIZE_N:
+ case SYS_CURSOR_RESIZE_S:
+ mc = LoadCursor(NULL, IDC_SIZENS); break;
+ case SYS_CURSOR_RESIZE_E:
+ case SYS_CURSOR_RESIZE_W:
+ mc = LoadCursor(NULL, IDC_SIZEWE); break;
+ case SYS_CURSOR_RESIZE_NE:
+ case SYS_CURSOR_RESIZE_SW:
+ mc = LoadCursor(NULL, IDC_SIZENESW); break;
+ case SYS_CURSOR_RESIZE_NW:
+ case SYS_CURSOR_RESIZE_SE:
+ mc = LoadCursor(NULL, IDC_SIZENWSE); break;
+ case SYS_CURSOR_PROGRESS:
+ mc = LoadCursor(NULL, IDC_APPSTARTING); break;
+ case SYS_CURSOR_PRECISION:
+ mc = LoadCursor(NULL, IDC_CROSS); break;
+ case SYS_CURSOR_LINK:
+ mc = LoadCursor(NULL, IDC_HAND); break;
+ case SYS_CURSOR_ALT_SELECT:
+ mc = LoadCursor(NULL, IDC_UPARROW); break;
+ case SYS_CURSOR_UNAVAILABLE:
+ mc = LoadCursor(NULL, IDC_NO); break;
+ default:
+ return;
+
+ mCursorCurrent = mc;
+
+ if ( !mCursorHidden ) {
+ SetCursor( mc );
+ POINT p;
+ GetCursorPos( &p );
+ SetCursorPos( p.x, p.y );
+ }
+ }
+}
+
+void cWinImpl::RestoreCursor() {
+ if ( !mCursorHidden ) {
+ ShowMouseCursor();
+ } else {
+ HideMouseCursor();
+ }
+}
+
+eeWindowHandler cWinImpl::GetHandler() const {
+ return mHandler;
+}
+
}}}
#endif
diff --git a/src/window/platform/win/cwinimpl.hpp b/src/window/platform/win/cwinimpl.hpp
index 1ed291345..8e6498bc4 100644
--- a/src/window/platform/win/cwinimpl.hpp
+++ b/src/window/platform/win/cwinimpl.hpp
@@ -31,8 +31,28 @@ class cWinImpl : public cPlatformImpl {
void SetContext( eeWindowContex Context );
eeVector2i Position();
+
+ void ShowMouseCursor();
+
+ void HideMouseCursor();
+
+ cCursor * CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name );
+
+ void SetMouseCursor( cCursor * cursor );
+
+ void SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor );
+
+ void RestoreCursor();
+
+ eeWindowHandler GetHandler() const;
protected:
eeWindowHandler mHandler;
+ HCURSOR mCursorCurrent;
+ bool mCursorHidden;
};
}}}
diff --git a/src/window/platform/x11/ccursorx11.cpp b/src/window/platform/x11/ccursorx11.cpp
new file mode 100644
index 000000000..aa2339f0a
--- /dev/null
+++ b/src/window/platform/x11/ccursorx11.cpp
@@ -0,0 +1,77 @@
+#include "ccursorx11.hpp"
+#include "cx11impl.hpp"
+
+#if defined( EE_X11_PLATFORM )
+
+namespace EE { namespace Window { namespace Platform {
+
+cCursorX11::cCursorX11( cTexture * tex, const eeVector2i& hotspot, const std::string& name, cWindow * window ) :
+ cCursor( tex, hotspot, name, window ),
+ mCursor( None )
+{
+ Create();
+}
+
+cCursorX11::cCursorX11( cImage * img, const eeVector2i& hotspot, const std::string& name, cWindow * window ) :
+ cCursor( img, hotspot, name, window ),
+ mCursor( None )
+{
+ Create();
+}
+
+cCursorX11::cCursorX11( const std::string& path, const eeVector2i& hotspot, const std::string& name, cWindow * window ) :
+ cCursor( path, hotspot, name, window ),
+ mCursor( None )
+{
+ Create();
+}
+
+cCursorX11::~cCursorX11() {
+ if ( None != mCursor )
+ XFreeCursor( GetPlatform()->GetDisplay(), mCursor );
+}
+
+void cCursorX11::Create() {
+ if ( NULL == mImage && mImage->Size() )
+ return;
+
+ XcursorImage * image;
+ unsigned int c, ix, iy;
+
+ image = XcursorImageCreate( mImage->Width(), mImage->Height() );
+
+ if ( image == None )
+ return;
+
+ c = 0;
+ for ( iy = 0; iy < mImage->Height(); iy++ ) {
+ for ( ix = 0; ix < mImage->Width(); ix++ ) {
+ eeColorA C = mImage->GetPixel( ix, iy );
+
+ image->pixels[c++] = ( C.A() << 24 ) | ( C.R() << 16 ) | ( C.G() <<8 ) | ( C.B() );
+ }
+ }
+
+ image->xhot = mHotSpot.x;
+ image->yhot = mHotSpot.y;
+
+ GetPlatform()->Lock();
+
+ mCursor = XcursorImageLoadCursor( GetPlatform()->GetDisplay(), image );
+
+ GetPlatform()->Unlock();
+
+ XcursorImageDestroy( image );
+}
+
+cX11Impl * cCursorX11::GetPlatform() {
+ return reinterpret_cast( mWindow->GetPlatform() );
+}
+
+X11Cursor cCursorX11::GetCursor() const {
+ return mCursor;
+}
+
+}}}
+
+#endif
diff --git a/src/window/platform/x11/ccursorx11.hpp b/src/window/platform/x11/ccursorx11.hpp
new file mode 100644
index 000000000..aad83d62b
--- /dev/null
+++ b/src/window/platform/x11/ccursorx11.hpp
@@ -0,0 +1,39 @@
+#ifndef EE_WINDOWCCURSORX11_HPP
+#define EE_WINDOWCCURSORX11_HPP
+
+#include "../../ccursor.hpp"
+
+#if defined( EE_X11_PLATFORM )
+
+using namespace EE::Window;
+
+namespace EE { namespace Window { namespace Platform {
+
+class cX11Impl;
+
+class cCursorX11 : public cCursor {
+ public:
+ X11Cursor GetCursor() const;
+ protected:
+ friend class cX11Impl;
+
+ X11Cursor mCursor;
+
+ cCursorX11( cTexture * tex, const eeVector2i& hotspot, const std::string& name, cWindow * window );
+
+ cCursorX11( cImage * img, const eeVector2i& hotspot, const std::string& name, cWindow * window );
+
+ cCursorX11( const std::string& path, const eeVector2i& hotspot, const std::string& name, cWindow * window );
+
+ ~cCursorX11();
+
+ void Create();
+
+ cX11Impl * GetPlatform();
+};
+
+}}}
+
+#endif
+
+#endif
diff --git a/src/window/platform/x11/cx11impl.cpp b/src/window/platform/x11/cx11impl.cpp
index bedb4109b..353c1b731 100644
--- a/src/window/platform/x11/cx11impl.cpp
+++ b/src/window/platform/x11/cx11impl.cpp
@@ -1,25 +1,41 @@
#include "cx11impl.hpp"
+#include "ccursorx11.hpp"
#if defined( EE_X11_PLATFORM )
+using namespace EE::Window::Cursor;
+
namespace EE { namespace Window { namespace Platform {
-cX11Impl::cX11Impl( cWindow * window, eeWindowHandler display, X11Window xwindow, LockFunc lock, UnlockFunc unlock ) :
+cX11Impl::cX11Impl( cWindow * window, eeWindowHandler display, X11Window xwindow, X11Window mainwindow, LockFunc lock, UnlockFunc unlock ) :
cPlatformImpl( window ),
mDisplay( display ),
- mWindow( xwindow ),
+ mX11Window( xwindow ),
+ mMainWindow( mainwindow ),
mLock( lock ),
- mUnlock( unlock )
+ mUnlock( unlock ),
+ mCursorCurrent( 0 ),
+ mCursorInvisible( None ),
+ mCursorSystemLast( None ),
+ mCursorHidden( false )
{
}
cX11Impl::~cX11Impl() {
+ if ( None != mCursorInvisible )
+ XFreeCursor( mDisplay, mCursorInvisible );
+
+ if ( None != mCursorSystemLast )
+ XFreeCursor( mDisplay, mCursorSystemLast );
}
void cX11Impl::MinimizeWindow() {
mLock();
- XIconifyWindow( mDisplay, mWindow, 0 );
- XFlush(mDisplay);
+
+ XIconifyWindow( mDisplay, mX11Window, 0 );
+
+ XFlush( mDisplay );
+
mUnlock();
}
@@ -34,7 +50,7 @@ void cX11Impl::MaximizeWindow() {
memset( &xev, 0, sizeof(xev) );
xev.type = ClientMessage;
- xev.xclient.window = mWindow;
+ xev.xclient.window = mX11Window;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 1;
@@ -50,40 +66,228 @@ void cX11Impl::MaximizeWindow() {
void cX11Impl::HideWindow() {
mLock();
- XUnmapWindow( mDisplay, mWindow );
+
+ XUnmapWindow( mDisplay, mX11Window );
+
mUnlock();
}
void cX11Impl::RaiseWindow() {
mLock();
- XRaiseWindow( mDisplay, mWindow );
+
+ XRaiseWindow( mDisplay, mX11Window );
+
mUnlock();
}
void cX11Impl::ShowWindow() {
mLock();
- XMapRaised( mDisplay, mWindow );
+
+ XMapRaised( mDisplay, mX11Window );
+
mUnlock();
}
void cX11Impl::MoveWindow( int left, int top ) {
mLock();
- XMoveWindow( mDisplay, mWindow, left, top );
+
+ XMoveWindow( mDisplay, mX11Window, left, top );
+
XFlush( mDisplay );
+
mUnlock();
}
void cX11Impl::SetContext( eeWindowContex Context ) {
/// FIXME: This is wrong
/*mLock();
- glXMakeCurrent( mDisplay, mWindow, Context );
+ glXMakeCurrent( mDisplay, mX11Window, Context );
mUnlock();*/
}
eeVector2i cX11Impl::Position() {
- XWindowAttributes Attrs;
- XGetWindowAttributes( mDisplay, mWindow, &Attrs );
- return eeVector2i( Attrs.x, Attrs.y );
+ int x, y;
+ X11Window child_return;
+
+ XTranslateCoordinates ( mDisplay, mX11Window, DefaultRootWindow( mDisplay ), 0, 0, &x, &y, &child_return );
+
+ return eeVector2i( x, y );
+}
+
+void cX11Impl::ShowMouseCursor() {
+ if ( !mCursorHidden )
+ return;
+
+ mLock();
+
+ XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
+
+ mCursorHidden = false;
+
+ mUnlock();
+}
+
+void cX11Impl::HideMouseCursor() {
+ if ( mCursorHidden )
+ return;
+
+ mLock();
+
+ if ( mCursorInvisible == None ) {
+ unsigned long gcmask;
+ XGCValues gcvalues;
+
+ Pixmap pixmap = XCreatePixmap( mDisplay, mMainWindow, 1, 1, 1 );
+
+ GC temp_gc;
+ XColor color;
+
+ gcmask = GCFunction | GCForeground | GCBackground;
+ gcvalues.function = GXcopy;
+ gcvalues.foreground = 0;
+ gcvalues.background = 0;
+ temp_gc = XCreateGC( mDisplay, pixmap, gcmask, &gcvalues);
+ XDrawPoint( mDisplay, pixmap, temp_gc, 0, 0 );
+ XFreeGC( mDisplay, temp_gc );
+ color.pixel = 0;
+ color.red = color.green = color.blue = 0;
+ color.flags = DoRed | DoGreen | DoBlue;
+
+ mCursorInvisible = XCreatePixmapCursor( mDisplay, pixmap, pixmap, &color, &color, 0, 0 );
+
+ XFreePixmap( mDisplay, pixmap );
+ }
+
+ XDefineCursor( mDisplay, mX11Window, mCursorInvisible );
+
+ mCursorHidden = true;
+
+ mUnlock();
+}
+
+cCursor * cX11Impl::CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name ) {
+ return eeNew( cCursorX11, ( tex, hotspot, name, mWindow ) );
+}
+
+cCursor * cX11Impl::CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name ) {
+ return eeNew( cCursorX11, ( img, hotspot, name, mWindow ) );
+}
+
+cCursor * cX11Impl::CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name ) {
+ return eeNew( cCursorX11, ( path, hotspot, name, mWindow ) );
+}
+
+void cX11Impl::SetMouseCursor( cCursor * cursor ) {
+ mCursorCurrent = reinterpret_cast( cursor )->GetCursor();
+
+ if ( !mCursorHidden ) {
+ mLock();
+
+ XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
+
+ mUnlock();
+ }
+}
+
+void cX11Impl::RestoreCursor() {
+ if ( !mCursorHidden ) {
+ mLock();
+
+ XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
+
+ mUnlock();
+ } else {
+ HideMouseCursor();
+ }
+}
+
+void cX11Impl::SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor ) {
+ unsigned int cursor_shape;
+
+ switch ( syscursor ) {
+ case SYS_CURSOR_DEFAULT:
+ case SYS_CURSOR_ARROW:
+ case SYS_CURSOR_PROGRESS:
+ cursor_shape = XC_left_ptr;
+ break;
+ case SYS_CURSOR_BUSY:
+ cursor_shape = XC_watch;
+ break;
+ case SYS_CURSOR_QUESTION:
+ cursor_shape = XC_question_arrow;
+ break;
+ case SYS_CURSOR_EDIT:
+ cursor_shape = XC_xterm;
+ break;
+ case SYS_CURSOR_MOVE:
+ cursor_shape = XC_fleur;
+ break;
+ case SYS_CURSOR_RESIZE_N:
+ cursor_shape = XC_top_side;
+ break;
+ case SYS_CURSOR_RESIZE_S:
+ cursor_shape = XC_bottom_side;
+ break;
+ case SYS_CURSOR_RESIZE_E:
+ cursor_shape = XC_right_side;
+ break;
+ case SYS_CURSOR_RESIZE_W:
+ cursor_shape = XC_left_side;
+ break;
+ case SYS_CURSOR_RESIZE_NE:
+ cursor_shape = XC_top_right_corner;
+ break;
+ case SYS_CURSOR_RESIZE_SW:
+ cursor_shape = XC_bottom_left_corner;
+ break;
+ case SYS_CURSOR_RESIZE_NW:
+ cursor_shape = XC_top_left_corner;
+ break;
+ case SYS_CURSOR_RESIZE_SE:
+ cursor_shape = XC_bottom_right_corner;
+ break;
+ case SYS_CURSOR_PRECISION:
+ cursor_shape = XC_crosshair;
+ break;
+ case SYS_CURSOR_LINK:
+ cursor_shape = XC_hand2;
+ break;
+ case SYS_CURSOR_ALT_SELECT:
+ cursor_shape = XC_hand1;
+ break;
+ case SYS_CURSOR_UNAVAILABLE:
+ cursor_shape = XC_X_cursor;
+ break;
+ default:
+ return;
+ }
+
+ if ( None != mCursorCurrent ) {
+ XFreeCursor( mDisplay, mCursorSystemLast );
+ }
+
+ mLock();
+
+ mCursorCurrent = XCreateFontCursor( mDisplay, cursor_shape );
+ mCursorSystemLast = mCursorCurrent;
+
+ if ( !mCursorHidden ) {
+ XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
+ }
+
+ mUnlock();
+}
+
+eeWindowHandler cX11Impl::GetDisplay() const {
+ return mDisplay;
+}
+
+void cX11Impl::Lock() {
+ mLock();
+}
+
+void cX11Impl::Unlock() {
+ mUnlock();
}
}}}
diff --git a/src/window/platform/x11/cx11impl.hpp b/src/window/platform/x11/cx11impl.hpp
index 4c5b8c041..254bc88cd 100644
--- a/src/window/platform/x11/cx11impl.hpp
+++ b/src/window/platform/x11/cx11impl.hpp
@@ -15,7 +15,7 @@ class cX11Impl : public cPlatformImpl {
typedef void (*LockFunc)(void);
typedef void (*UnlockFunc)(void);
- cX11Impl( cWindow * window, eeWindowHandler display, X11Window xwindow, LockFunc lock, UnlockFunc unlock );
+ cX11Impl( cWindow * window, eeWindowHandler display, X11Window xwindow, X11Window mainwindow, LockFunc lock, UnlockFunc unlock );
~cX11Impl();
@@ -34,11 +34,38 @@ class cX11Impl : public cPlatformImpl {
void SetContext( eeWindowContex Context );
eeVector2i Position();
+
+ void ShowMouseCursor();
+
+ void HideMouseCursor();
+
+ cCursor * CreateMouseCursor( cTexture * tex, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( cImage * img, const eeVector2i& hotspot, const std::string& name );
+
+ cCursor * CreateMouseCursor( const std::string& path, const eeVector2i& hotspot, const std::string& name );
+
+ void SetMouseCursor( cCursor * cursor );
+
+ void SetSystemMouseCursor( Cursor::EE_SYSTEM_CURSOR syscursor );
+
+ void RestoreCursor();
+
+ eeWindowHandler GetDisplay() const;
+
+ void Lock();
+
+ void Unlock();
protected:
eeWindowHandler mDisplay;
- X11Window mWindow;
+ X11Window mX11Window;
+ X11Window mMainWindow;
LockFunc mLock;
UnlockFunc mUnlock;
+ X11Cursor mCursorCurrent;
+ X11Cursor mCursorInvisible;
+ X11Cursor mCursorSystemLast;
+ bool mCursorHidden;
};
}}}