implement mouse cursor set in x11 platform

This commit is contained in:
Eduardo Bart 2012-01-11 23:12:25 -02:00
parent c1787c2a50
commit 34af633b47
7 changed files with 101 additions and 15 deletions

@ -1 +1 @@
Subproject commit dd648e1431171bffe091b748744395780df7eba1
Subproject commit 9beb17daaeb170c127c39c5a5e4feb9d95ebed92

View File

@ -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));

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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);