implement mouse cursor set in x11 platform
This commit is contained in:
		
							parent
							
								
									c1787c2a50
								
							
						
					
					
						commit
						34af633b47
					
				|  | @ -1 +1 @@ | |||
| Subproject commit dd648e1431171bffe091b748744395780df7eba1 | ||||
| Subproject commit 9beb17daaeb170c127c39c5a5e4feb9d95ebed92 | ||||
|  | @ -333,9 +333,11 @@ void Application::registerLuaFunctions() | |||
|     g_lua.bindClassStaticFunction("g_window", "show", std::bind(&PlatformWindow::show, &g_window)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "hide", std::bind(&PlatformWindow::hide, &g_window)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "maximize", std::bind(&PlatformWindow::maximize, &g_window)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "restoreMouseCursor", std::bind(&PlatformWindow::restoreMouseCursor, &g_window)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "showMouse", std::bind(&PlatformWindow::showMouse, &g_window)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "hideMouse", std::bind(&PlatformWindow::hideMouse, &g_window)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "setTitle", std::bind(&PlatformWindow::setTitle, &g_window, _1)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "setMouseCursor", std::bind(&PlatformWindow::setMouseCursor, &g_window, _1)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "setMinimumSize", std::bind(&PlatformWindow::setMinimumSize, &g_window, _1)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "setFullscreen", std::bind(&PlatformWindow::setFullscreen, &g_window, _1)); | ||||
|     g_lua.bindClassStaticFunction("g_window", "setVerticalSync", std::bind(&PlatformWindow::setVerticalSync, &g_window, _1)); | ||||
|  |  | |||
|  | @ -42,10 +42,12 @@ public: | |||
|     virtual void maximize() = 0; | ||||
|     virtual void poll() = 0; | ||||
|     virtual void swapBuffers() = 0; | ||||
|     virtual void restoreMouseCursor() = 0; | ||||
|     virtual void showMouse() = 0; | ||||
|     virtual void displayFatalError(const std::string& message) { } | ||||
|     virtual void hideMouse() = 0; | ||||
|     virtual void displayFatalError(const std::string& message) { } | ||||
| 
 | ||||
|     virtual void setMouseCursor(const std::string& file) = 0; | ||||
|     virtual void setTitle(const std::string& title) = 0; | ||||
|     virtual void setMinimumSize(const Size& minimumSize) = 0; | ||||
|     virtual void setFullscreen(bool fullscreen) = 0; | ||||
|  |  | |||
|  | @ -526,6 +526,16 @@ void WIN32Window::hideMouse() | |||
|     ShowCursor(false); | ||||
| } | ||||
| 
 | ||||
| void WIN32Window::displayFatalError(const std::string& message) | ||||
| { | ||||
|     MessageBoxA(m_window, message.c_str(), "FATAL ERROR", MB_OK | MB_ICONERROR); | ||||
| } | ||||
| 
 | ||||
| void WIN32Window::setMouseCursor(const std::string& file) | ||||
| { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void WIN32Window::setTitle(const std::string& title) | ||||
| { | ||||
|     SetWindowTextA(m_window, title.c_str()); | ||||
|  | @ -662,8 +672,3 @@ std::string WIN32Window::getPlatformType() | |||
| { | ||||
|     return "WIN32-WGL"; | ||||
| } | ||||
| 
 | ||||
| void WIN32Window::displayFatalError(const std::string& message) | ||||
| { | ||||
|     MessageBoxA(m_window, message.c_str(), "FATAL ERROR", MB_OK | MB_ICONERROR); | ||||
| } | ||||
|  |  | |||
|  | @ -56,10 +56,12 @@ public: | |||
|     void maximize(); | ||||
|     void poll(); | ||||
|     void swapBuffers(); | ||||
|     void restoreMouseCursor(); | ||||
|     void showMouse(); | ||||
|     void hideMouse(); | ||||
|     void displayFatalError(const std::string& message); | ||||
| 
 | ||||
|     void setMouseCursor(const std::string& file); | ||||
|     void setTitle(const std::string& title); | ||||
|     void setMinimumSize(const Size& minimumSize); | ||||
|     void setFullscreen(bool fullscreen); | ||||
|  |  | |||
|  | @ -24,6 +24,8 @@ | |||
| #include <framework/core/resourcemanager.h> | ||||
| #include <framework/thirdparty/apngloader.h> | ||||
| 
 | ||||
| #define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8))) | ||||
| 
 | ||||
| X11Window::X11Window() | ||||
| { | ||||
|     m_display = 0; | ||||
|  | @ -728,6 +730,25 @@ void X11Window::swapBuffers() | |||
| } | ||||
| 
 | ||||
| void X11Window::showMouse() | ||||
| { | ||||
|     restoreMouseCursor(); | ||||
| } | ||||
| 
 | ||||
| void X11Window::hideMouse() | ||||
| { | ||||
|     if(m_cursor != None) | ||||
|         restoreMouseCursor(); | ||||
| 
 | ||||
|     char bm[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||||
|     Pixmap pix = XCreateBitmapFromData(m_display, m_window, bm, 8, 8); | ||||
|     XColor black = {0}; | ||||
|     black.flags = DoRed | DoGreen | DoBlue; | ||||
|     m_cursor = XCreatePixmapCursor(m_display, pix, pix, &black, &black, 0, 0); | ||||
|     XFreePixmap(m_display, pix); | ||||
|     XDefineCursor(m_display, m_window, m_cursor); | ||||
| } | ||||
| 
 | ||||
| void X11Window::restoreMouseCursor() | ||||
| { | ||||
|     XUndefineCursor(m_display, m_window); | ||||
|     if(m_cursor != None) { | ||||
|  | @ -736,17 +757,69 @@ void X11Window::showMouse() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void X11Window::hideMouse() | ||||
| void X11Window::setMouseCursor(const std::string& file) | ||||
| { | ||||
|     if(m_cursor == None) { | ||||
|         char bm[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||||
|         Pixmap pix = XCreateBitmapFromData(m_display, m_window, bm, 8, 8); | ||||
|         XColor black = {0}; | ||||
|         black.flags = DoRed | DoGreen | DoBlue; | ||||
|         m_cursor = XCreatePixmapCursor(m_display, pix, pix, &black, &black, 0, 0); | ||||
|         XFreePixmap(m_display, pix); | ||||
|     std::stringstream fin; | ||||
|     g_resources.loadFile(file, fin); | ||||
| 
 | ||||
|     apng_data apng; | ||||
|     if(load_apng(fin, &apng) != 0) { | ||||
|         logTraceError("unable to load png file ", file); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if(apng.bpp != 4) { | ||||
|         logError("the cursor png must have 4 channels"); | ||||
|         free_apng(&apng); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if(apng.width % 8 != 0 || apng.height % 8 != 0) { | ||||
|         logError("the cursor png must have dimensions multiple of 8"); | ||||
|         free_apng(&apng); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if(m_cursor != None) | ||||
|         restoreMouseCursor(); | ||||
| 
 | ||||
|     int width = apng.width; | ||||
|     int height = apng.height; | ||||
|     int numbits = width * height; | ||||
|     int numbytes = (width * height)/8; | ||||
| 
 | ||||
|     XColor bg, fg; | ||||
|     bg.red   = 255 << 8; | ||||
|     bg.green = 255 << 8; | ||||
|     bg.blue  = 255 << 8; | ||||
|     fg.red   = 0; | ||||
|     fg.green = 0; | ||||
|     fg.blue  = 0; | ||||
| 
 | ||||
|     std::vector<uchar> mapBits(numbytes, 0); | ||||
|     std::vector<uchar> maskBits(numbytes, 0); | ||||
| 
 | ||||
|     for(int i=0;i<numbits;++i) { | ||||
|         uchar r = apng.pdata[i*4+0]; | ||||
|         uchar g = apng.pdata[i*4+1]; | ||||
|         uchar b = apng.pdata[i*4+2]; | ||||
|         uchar a = apng.pdata[i*4+3]; | ||||
|         Color color(r,g,b,a); | ||||
|         if(color == Fw::white) { //background
 | ||||
|             LSB_BIT_SET(maskBits, i); | ||||
|         } else if(color == Fw::black) { //foreground
 | ||||
|             LSB_BIT_SET(mapBits, i); | ||||
|             LSB_BIT_SET(maskBits, i); | ||||
|         } //otherwise alpha
 | ||||
|     } | ||||
|     free_apng(&apng); | ||||
| 
 | ||||
|     Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height); | ||||
|     Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height); | ||||
|     m_cursor = XCreatePixmapCursor(m_display, cp, mp, &fg, &bg, width/2, height/2); | ||||
|     XDefineCursor(m_display, m_window, m_cursor); | ||||
|     XFreePixmap(m_display, cp); | ||||
|     XFreePixmap(m_display, mp); | ||||
| } | ||||
| 
 | ||||
| void X11Window::setTitle(const std::string& title) | ||||
|  |  | |||
|  | @ -63,9 +63,11 @@ public: | |||
|     void maximize(); | ||||
|     void poll(); | ||||
|     void swapBuffers(); | ||||
|     void restoreMouseCursor(); | ||||
|     void showMouse(); | ||||
|     void hideMouse(); | ||||
| 
 | ||||
|     void setMouseCursor(const std::string& file); | ||||
|     void setTitle(const std::string& title); | ||||
|     void setMinimumSize(const Size& minimumSize); | ||||
|     void setFullscreen(bool fullscreen); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Eduardo Bart
						Eduardo Bart