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", "show", std::bind(&PlatformWindow::show, &g_window));
|
||||||
g_lua.bindClassStaticFunction("g_window", "hide", std::bind(&PlatformWindow::hide, &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", "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", "showMouse", std::bind(&PlatformWindow::showMouse, &g_window));
|
||||||
g_lua.bindClassStaticFunction("g_window", "hideMouse", std::bind(&PlatformWindow::hideMouse, &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", "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", "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", "setFullscreen", std::bind(&PlatformWindow::setFullscreen, &g_window, _1));
|
||||||
g_lua.bindClassStaticFunction("g_window", "setVerticalSync", std::bind(&PlatformWindow::setVerticalSync, &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 maximize() = 0;
|
||||||
virtual void poll() = 0;
|
virtual void poll() = 0;
|
||||||
virtual void swapBuffers() = 0;
|
virtual void swapBuffers() = 0;
|
||||||
|
virtual void restoreMouseCursor() = 0;
|
||||||
virtual void showMouse() = 0;
|
virtual void showMouse() = 0;
|
||||||
virtual void displayFatalError(const std::string& message) { }
|
|
||||||
virtual void hideMouse() = 0;
|
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 setTitle(const std::string& title) = 0;
|
||||||
virtual void setMinimumSize(const Size& minimumSize) = 0;
|
virtual void setMinimumSize(const Size& minimumSize) = 0;
|
||||||
virtual void setFullscreen(bool fullscreen) = 0;
|
virtual void setFullscreen(bool fullscreen) = 0;
|
||||||
|
|
|
@ -526,6 +526,16 @@ void WIN32Window::hideMouse()
|
||||||
ShowCursor(false);
|
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)
|
void WIN32Window::setTitle(const std::string& title)
|
||||||
{
|
{
|
||||||
SetWindowTextA(m_window, title.c_str());
|
SetWindowTextA(m_window, title.c_str());
|
||||||
|
@ -662,8 +672,3 @@ std::string WIN32Window::getPlatformType()
|
||||||
{
|
{
|
||||||
return "WIN32-WGL";
|
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 maximize();
|
||||||
void poll();
|
void poll();
|
||||||
void swapBuffers();
|
void swapBuffers();
|
||||||
|
void restoreMouseCursor();
|
||||||
void showMouse();
|
void showMouse();
|
||||||
void hideMouse();
|
void hideMouse();
|
||||||
void displayFatalError(const std::string& message);
|
void displayFatalError(const std::string& message);
|
||||||
|
|
||||||
|
void setMouseCursor(const std::string& file);
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setMinimumSize(const Size& minimumSize);
|
void setMinimumSize(const Size& minimumSize);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/thirdparty/apngloader.h>
|
#include <framework/thirdparty/apngloader.h>
|
||||||
|
|
||||||
|
#define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
|
||||||
|
|
||||||
X11Window::X11Window()
|
X11Window::X11Window()
|
||||||
{
|
{
|
||||||
m_display = 0;
|
m_display = 0;
|
||||||
|
@ -728,6 +730,25 @@ void X11Window::swapBuffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::showMouse()
|
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);
|
XUndefineCursor(m_display, m_window);
|
||||||
if(m_cursor != None) {
|
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) {
|
std::stringstream fin;
|
||||||
char bm[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
g_resources.loadFile(file, fin);
|
||||||
Pixmap pix = XCreateBitmapFromData(m_display, m_window, bm, 8, 8);
|
|
||||||
XColor black = {0};
|
apng_data apng;
|
||||||
black.flags = DoRed | DoGreen | DoBlue;
|
if(load_apng(fin, &apng) != 0) {
|
||||||
m_cursor = XCreatePixmapCursor(m_display, pix, pix, &black, &black, 0, 0);
|
logTraceError("unable to load png file ", file);
|
||||||
XFreePixmap(m_display, pix);
|
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);
|
XDefineCursor(m_display, m_window, m_cursor);
|
||||||
|
XFreePixmap(m_display, cp);
|
||||||
|
XFreePixmap(m_display, mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::setTitle(const std::string& title)
|
void X11Window::setTitle(const std::string& title)
|
||||||
|
|
|
@ -63,9 +63,11 @@ public:
|
||||||
void maximize();
|
void maximize();
|
||||||
void poll();
|
void poll();
|
||||||
void swapBuffers();
|
void swapBuffers();
|
||||||
|
void restoreMouseCursor();
|
||||||
void showMouse();
|
void showMouse();
|
||||||
void hideMouse();
|
void hideMouse();
|
||||||
|
|
||||||
|
void setMouseCursor(const std::string& file);
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setMinimumSize(const Size& minimumSize);
|
void setMinimumSize(const Size& minimumSize);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
|
Loading…
Reference in New Issue