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