Fixed: #1028 Implement GlWndProc for X11

This commit is contained in:
kervala 2010-07-24 23:09:43 +02:00
parent 0da812d348
commit 4220215132
6 changed files with 263 additions and 198 deletions

View file

@ -966,28 +966,20 @@ void CDriverGL::setupViewport (const class CViewport& viewport)
if (_win == EmptyWindow) return; if (_win == EmptyWindow) return;
#ifdef NL_OS_WINDOWS #ifdef NL_MAC_NATIVE
// Setup gl viewport
int clientWidth = _WindowWidth;
int clientHeight = _WindowHeight;
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
uint32 clientWidth, clientHeight; uint32 clientWidth, clientHeight;
NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight); NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight);
#elif defined (NL_OS_UNIX) getWindowSize(clientWidth, clientHeight);
XWindowAttributes win_attributes; #else
if (!XGetWindowAttributes(_dpy, _win, &win_attributes))
throw EBadDisplay("Can't get window attributes.");
// Setup gl viewport // Setup gl viewport
int clientWidth=win_attributes.width; sint clientWidth = _WindowWidth;
int clientHeight=win_attributes.height; sint clientHeight = _WindowHeight;
#endif // NL_OS_WINDOWS #endif // NL_MAC_NATIVE
// Backup the viewport // Backup the viewport
_CurrViewport = viewport; _CurrViewport = viewport;
@ -1037,31 +1029,21 @@ void CDriverGL::getViewport(CViewport &viewport)
void CDriverGL::setupScissor (const class CScissor& scissor) void CDriverGL::setupScissor (const class CScissor& scissor)
{ {
H_AUTO_OGL(CDriverGL_setupScissor ) H_AUTO_OGL(CDriverGL_setupScissor )
#ifdef NL_OS_WINDOWS
if (_win == EmptyWindow) return; if (_win == EmptyWindow) return;
// Setup gl viewport #ifdef NL_MAC_NATIVE
int clientWidth = _WindowWidth;
int clientHeight = _WindowHeight;
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) uint32 clientWidth, clientHeight;
NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight);
uint32 clientWidth = 0; #else
uint32 clientHeight = 0;
getWindowSize(clientWidth, clientHeight);
#elif defined (NL_OS_UNIX)
XWindowAttributes win_attributes;
if (!XGetWindowAttributes(_dpy, _win, &win_attributes))
throw EBadDisplay("Can't get window attributes.");
// Setup gl viewport // Setup gl viewport
int clientWidth=win_attributes.width; sint clientWidth = _WindowWidth;
int clientHeight=win_attributes.height; sint clientHeight = _WindowHeight;
#endif // NL_OS_WINDOWS #endif // NL_MAC_NATIVE
// Backup the scissor // Backup the scissor
_CurrScissor= scissor; _CurrScissor= scissor;

View file

@ -107,6 +107,21 @@ class IVertexArrayRange;
class IVertexBufferHardGL; class IVertexBufferHardGL;
class COcclusionQueryGL; class COcclusionQueryGL;
#ifdef NL_OS_WINDOWS
bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
#elif defined (NL_MAC_NATIVE)
// TODO: change that
bool GlWndProc(CDriverGL *driver);
#elif defined (NL_OS_UNIX)
bool GlWndProc(CDriverGL *driver, XEvent &e);
#endif
typedef std::list<COcclusionQueryGL *> TOcclusionQueryList; typedef std::list<COcclusionQueryGL *> TOcclusionQueryList;
// *************************************************************************** // ***************************************************************************
@ -660,14 +675,15 @@ private:
uint _Interval; uint _Interval;
sint8 _AntiAliasing; sint8 _AntiAliasing;
sint32 _WindowWidth, _WindowHeight, _WindowX, _WindowY; uint32 _WindowWidth, _WindowHeight;
sint32 _WindowX, _WindowY;
nlWindow _win; nlWindow _win;
bool _DestroyWindow; bool _DestroyWindow;
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
friend static bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); friend bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HDC _hDC; HDC _hDC;
PIXELFORMATDESCRIPTOR _pfd; PIXELFORMATDESCRIPTOR _pfd;
@ -685,6 +701,8 @@ private:
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
friend bool GlWndProc(CDriverGL *driver, XEvent &e);
Display* _dpy; Display* _dpy;
GLXContext _ctx; GLXContext _ctx;
Cursor _cursor; Cursor _cursor;

View file

@ -1939,22 +1939,8 @@ bool CDriverGL::getRenderTargetSize (uint32 &width, uint32 &height)
} }
else else
{ {
#ifdef NL_OS_WINDOWS
width = _WindowWidth; width = _WindowWidth;
height = _WindowHeight; height = _WindowHeight;
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
#elif defined (NL_OS_UNIX)
XWindowAttributes win_attributes;
if (!XGetWindowAttributes(_dpy, _win, &win_attributes))
throw EBadDisplay("Can't get window attributes.");
// Setup gl viewport
width = win_attributes.width;
height = win_attributes.height;
#endif // NL_OS_WINDOWS
} }
return false; return false;

View file

@ -51,7 +51,7 @@ namespace NL3D
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
static bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
H_AUTO_OGL(GlWndProc) H_AUTO_OGL(GlWndProc)
if(message == WM_SIZE) if(message == WM_SIZE)
@ -137,7 +137,76 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
return trapMessage ? 0 : DefWindowProcW(hWnd, message, wParam, lParam); return trapMessage ? 0 : DefWindowProcW(hWnd, message, wParam, lParam);
} }
#endif // NL_OS_WINDOWS #elif defined (NL_MAC_NATIVE)
bool GlWndProc(CDriverGL *driver)
{
return false;
}
#elif defined (NL_OS_UNIX)
bool GlWndProc(CDriverGL *driver, XEvent &e)
{
H_AUTO_OGL(GlWndProc)
if (!driver)
return false;
// nlinfo("3D: glop %d %d", e.type, e.xmap.window);
// disable menu (default ALT-F4 behavior is disabled)
switch(e.type)
{
case DestroyNotify:
if(driver && driver->ExitFunc)
{
driver->ExitFunc();
}
else
{
#ifndef NL_DISABLE_MENU
// if we don't disable menu, alt F4 make a direct exit else we discard the message
exit(0);
#endif // NL_DISABLE_MENU
}
break;
case ConfigureNotify:
driver->_WindowWidth = e.xconfigure.width;
driver->_WindowHeight = e.xconfigure.height;
driver->_WindowX = e.xconfigure.x;
driver->_WindowY = e.xconfigure.y;
break;
default:
// Process the message by the emitter
return driver->_EventEmitter.processMessage(e);
}
return true;
/*
else if (message == WM_ACTIVATE)
{
WORD fActive = LOWORD(wParam);
if (fActive == WA_INACTIVE)
{
driver->_WndActive = false;
}
else
{
driver->_WndActive = true;
}
}
*/
}
#endif // NL_OS_UNIX
// *************************************************************************** // ***************************************************************************
bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
@ -860,11 +929,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
glXMakeCurrent (_dpy, _win, _ctx); glXMakeCurrent (_dpy, _win, _ctx);
// XMapRaised (_dpy, _win); // XMapRaised (_dpy, _win);
XSelectInput (_dpy, _win, KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask);
// XMapWindow(_dpy, _win); // XMapWindow(_dpy, _win);
_EventEmitter.init (_dpy, _win); _EventEmitter.init (_dpy, _win, this);
// XEvent event; // XEvent event;
// XIfEvent(dpy, &event, WaitForNotify, (char *)this); // XIfEvent(dpy, &event, WaitForNotify, (char *)this);
@ -1333,7 +1400,7 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
H_AUTO_OGL(CDriverGL_setWindowStyle) H_AUTO_OGL(CDriverGL_setWindowStyle)
// don't change window style, if we did not create the window // don't change window style, if we did not create the window
if (!_DestroyWindow) if (_win == EmptyWindow || !_DestroyWindow)
return true; return true;
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
@ -1392,27 +1459,23 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
#if !defined(NL_OS_MAC) #if !defined(NL_OS_MAC)
// Toggle fullscreen // Toggle fullscreen
if (windowStyle != getWindowStyle()) XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.display = _dpy;
xev.xclient.window = _win;
xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False);
xev.xclient.format = 32;
xev.xclient.data.l[0] = windowStyle == EWSFullscreen ? _NET_WM_STATE_ADD:_NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False);
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 1; // 1 for Application, 2 for Page or Taskbar, 0 for old source
xev.xclient.data.l[4] = 0;
if (XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev) != Success)
{ {
XEvent xev; nlwarning("3D: Failed to toggle to fullscreen");
memset(&xev, 0, sizeof(xev)); return false;
xev.type = ClientMessage;
// xev.xclient.serial = 0;
// xev.xclient.send_event = True;
// xev.xclient.display = _dpy;
xev.xclient.window = _win;
xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False);
xev.xclient.format = 32;
xev.xclient.data.l[0] = windowStyle == EWSFullscreen ? 1:0;
xev.xclient.data.l[1] = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False);
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
if (XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureNotifyMask, &xev) != Success)
{
nlwarning("3D: Failed to toggle to fullscreen");
return false;
}
} }
#endif #endif
@ -1431,7 +1494,7 @@ bool CDriverGL::setMode(const GfxMode& mode)
return false; return false;
// when changing window style, it's possible system change window size too // when changing window style, it's possible system change window size too
setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); setWindowStyle(mode.Windowed ? EWSWindowed:EWSFullscreen);
_WindowWidth = mode.Width; _WindowWidth = mode.Width;
_WindowHeight = mode.Height; _WindowHeight = mode.Height;
@ -1455,6 +1518,7 @@ bool CDriverGL::setMode(const GfxMode& mode)
bool CDriverGL::getModes(std::vector<GfxMode> &modes) bool CDriverGL::getModes(std::vector<GfxMode> &modes)
{ {
H_AUTO_OGL(CDriverGL_getModes) H_AUTO_OGL(CDriverGL_getModes)
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
sint modeIndex = 0; sint modeIndex = 0;
DEVMODE devMode; DEVMODE devMode;
@ -1701,6 +1765,11 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
// -------------------------------------------------- // --------------------------------------------------
void CDriverGL::setWindowTitle(const ucstring &title) void CDriverGL::setWindowTitle(const ucstring &title)
{ {
H_AUTO_OGL(CDriverGL_setWindowTitle)
if (_win == EmptyWindow)
return;
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
SetWindowTextW(_win, (WCHAR*)title.c_str()); SetWindowTextW(_win, (WCHAR*)title.c_str());
@ -1725,6 +1794,8 @@ void CDriverGL::setWindowTitle(const ucstring &title)
// *************************************************************************** // ***************************************************************************
void CDriverGL::setWindowPos(sint32 x, sint32 y) void CDriverGL::setWindowPos(sint32 x, sint32 y)
{ {
H_AUTO_OGL(CDriverGL_setWindowPos)
_WindowX = x; _WindowX = x;
_WindowY = y; _WindowY = y;
@ -1749,7 +1820,7 @@ void CDriverGL::showWindow(bool show)
H_AUTO_OGL(CDriverGL_showWindow) H_AUTO_OGL(CDriverGL_showWindow)
// don't change window visibility, if we didn't create the window // don't change window visibility, if we didn't create the window
if (!_DestroyWindow) if (_win == EmptyWindow || !_DestroyWindow)
return; return;
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
@ -1778,11 +1849,7 @@ emptyProc CDriverGL::getWindowProc()
{ {
H_AUTO_OGL(CDriverGL_getWindowProc) H_AUTO_OGL(CDriverGL_getWindowProc)
#ifdef NL_OS_WINDOWS
return (emptyProc)GlWndProc; return (emptyProc)GlWndProc;
#else // NL_OS_WINDOWS
return NULL;
#endif // NL_OS_WINDOWS
} }
// -------------------------------------------------- // --------------------------------------------------
@ -1932,10 +1999,8 @@ void CDriverGL::setMousePos(float x, float y)
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
XWindowAttributes xwa; sint x1 = (sint)((float)_WindowWidth*x);
XGetWindowAttributes (_dpy, _win, &xwa); sint y1 = (sint)((float)_WindowHeight*(1.0f-y));
int x1 = (int)(x * (float) xwa.width);
int y1 = (int)((1.0f - y) * (float) xwa.height);
XWarpPointer (_dpy, None, _win, None, None, None, None, x1, y1); XWarpPointer (_dpy, None, _win, None, None, None, None, x1, y1);
#endif // NL_OS_UNIX #endif // NL_OS_UNIX
@ -1945,38 +2010,33 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
{ {
H_AUTO_OGL(CDriverGL_getWindowSize) H_AUTO_OGL(CDriverGL_getWindowSize)
#ifdef NL_OS_WINDOWS #ifdef NL_MAC_NATIVE
NL3D::MAC::getWindowSize(_win, width, height);
#else
// Off-screen rendering ? // Off-screen rendering ?
if (_OffScreen) if (_OffScreen)
{ {
#ifdef NL_OS_WINDOWS
if (_PBuffer) if (_PBuffer)
{ {
nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width ); nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width );
nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height ); nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height );
} }
#endif
} }
else else
{ {
if (_win) if (_win)
{ {
width = (uint32)_WindowWidth; width = _WindowWidth;
height = (uint32)_WindowHeight; height = _WindowHeight;
} }
} }
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #endif // NL_MAC_NATIVE
NL3D::MAC::getWindowSize(_win, width, height);
#elif defined (NL_OS_UNIX)
XWindowAttributes xwa;
XGetWindowAttributes (_dpy, _win, &xwa);
width = (uint32) xwa.width;
height = (uint32) xwa.height;
#endif // NL_OS_UNIX
} }
void CDriverGL::setWindowSize(uint32 width, uint32 height) void CDriverGL::setWindowSize(uint32 width, uint32 height)
@ -2040,15 +2100,16 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y)
{ {
H_AUTO_OGL(CDriverGL_getWindowPos) H_AUTO_OGL(CDriverGL_getWindowPos)
#ifdef NL_OS_WINDOWS #ifdef NL_MAC_NATIVE
NL3D::MAC::getWindowPos(_win, x, y);
#else
// Off-screen rendering ? // Off-screen rendering ?
if (_OffScreen) if (_OffScreen)
{ {
if (_PBuffer) x = y = 0;
{
x = y = 0;
}
} }
else else
{ {
@ -2059,35 +2120,7 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y)
} }
} }
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #endif // NL_MAC_NATIVE
NL3D::MAC::getWindowPos(_win, x, y);
#elif defined (NL_OS_UNIX)
int screen = DefaultScreen(_dpy);
#if 0
// Display size is a member of display structure
int display_width = DisplayWidth(_dpy, screen);
int display_height = DisplayHeight(_dpy, screen);
#endif
int xtmp = 0, ytmp = 0;
unsigned int width = 0, height = 0;
unsigned int border_width = 0;
unsigned int depth = 0;
// Get geometry information about root window
if (!XGetGeometry(_dpy, RootWindow(_dpy, screen), (Window*)&_win, &xtmp, &ytmp, &width, &height, &border_width, &depth))
{
nlwarning("can't get root window geometry");
}
x = xtmp;
y = ytmp;
#endif // NL_OS_UNIX
} }
// -------------------------------------------------- // --------------------------------------------------

View file

@ -27,9 +27,11 @@
#include "nel/misc/debug.h" #include "nel/misc/debug.h"
#include "unix_event_emitter.h" #include "unix_event_emitter.h"
typedef void (*x11Proc)(NL3D::IDriver *drv, XEvent *e);
namespace NLMISC { namespace NLMISC {
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY), _emulateRawMode(false) CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY), _emulateRawMode(false), _driver(NULL)
{ {
_im = 0; _im = 0;
_ic = 0; _ic = 0;
@ -41,10 +43,21 @@ CUnixEventEmitter::~CUnixEventEmitter()
if (_im) XCloseIM(_im); if (_im) XCloseIM(_im);
} }
void CUnixEventEmitter::init (Display *dpy, Window win) void CUnixEventEmitter::init(Display *dpy, Window win, NL3D::IDriver *driver)
{ {
_dpy = dpy; _dpy = dpy;
_win = win; _win = win;
_driver = driver;
XSelectInput (_dpy, _win, KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|StructureNotifyMask);
/*
TODO: implements all useful events processing
EnterWindowMask|LeaveWindowMask|ButtonMotionMask|Button1MotionMask|Button2MotionMask|
Button3MotionMask|Button4MotionMask|Button5MotionMask|KeymapStateMask|ExposureMask|
SubstructureNotifyMask|VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|
ColormapChangeMask|OwnerGrabButtonMask
*/
createIM(); createIM();
} }
@ -75,12 +88,27 @@ void CUnixEventEmitter::submitEvents(CEventServer & server, bool allWindows)
{ {
XEvent Event; XEvent Event;
XNextEvent(_dpy, &Event); XNextEvent(_dpy, &Event);
if(Event.xany.window==_win) if (allWindows || Event.xany.window == _win)
{ {
// nlinfo("event: %d", Event.type); // nlinfo("event: %d", Event.type);
processMessage (Event, server); if (_driver)
{
// forward X events to OpenGL driver
x11Proc proc = (x11Proc)_driver->getWindowProc();
if (proc)
proc(_driver, &Event);
}
else
{
processMessage (Event, server);
}
} }
} }
// Dispatch sent messages
_InternalServer.setServer (&server);
_InternalServer.pump (allWindows);
} }
void CUnixEventEmitter::emulateMouseRawMode(bool enable) void CUnixEventEmitter::emulateMouseRawMode(bool enable)
@ -91,7 +119,7 @@ void CUnixEventEmitter::emulateMouseRawMode(bool enable)
{ {
XWindowAttributes xwa; XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa); XGetWindowAttributes(_dpy, _win, &xwa);
XWarpPointer(_dpy, None, _win, None, None, None, None, XWarpPointer(_dpy, None, _win, None, None, None, None,
(xwa.width / 2), (xwa.height / 2)); (xwa.width / 2), (xwa.height / 2));
} }
} }
@ -354,21 +382,17 @@ TKey getKeyFromKeySym (KeySym keysym)
return KeyNOKEY; return KeyNOKEY;
} }
void CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
#define Case(a) case(a): // nlinfo("event: "#a);
void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
{ {
if (!server)
server=&_InternalServer;
XWindowAttributes xwa; XWindowAttributes xwa;
XGetWindowAttributes (_dpy, _win, &xwa); XGetWindowAttributes (_dpy, _win, &xwa);
switch (event.type) switch (event.type)
{ {
Case(ReparentNotify) case ButtonPress:
Case(UnmapNotify)
Case(VisibilityNotify)
break;
Case(ButtonPress)
{ {
//nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y); //nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y);
float fX = (float) event.xbutton.x / (float) xwa.width; float fX = (float) event.xbutton.x / (float) xwa.width;
@ -377,24 +401,24 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
switch(event.xbutton.button) switch(event.xbutton.button)
{ {
case Button1: case Button1:
server.postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(leftButton|(button&~(leftButton|middleButton|rightButton))), this)); server->postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(leftButton|(button&~(leftButton|middleButton|rightButton))), this));
break; break;
case Button2: case Button2:
server.postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(middleButton|(button&~(leftButton|middleButton|rightButton))), this)); server->postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(middleButton|(button&~(leftButton|middleButton|rightButton))), this));
break; break;
case Button3: case Button3:
server.postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(rightButton|(button&~(leftButton|middleButton|rightButton))), this)); server->postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(rightButton|(button&~(leftButton|middleButton|rightButton))), this));
break; break;
case Button4: case Button4:
server.postEvent(new CEventMouseWheel(fX, fY, button, true, this)); server->postEvent(new CEventMouseWheel(fX, fY, button, true, this));
break; break;
case Button5: case Button5:
server.postEvent(new CEventMouseWheel(fX, fY, button, false, this)); server->postEvent(new CEventMouseWheel(fX, fY, button, false, this));
break; break;
} }
break; break;
} }
Case(ButtonRelease) case ButtonRelease:
{ {
//nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y); //nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y);
float fX = (float) event.xbutton.x / (float) xwa.width; float fX = (float) event.xbutton.x / (float) xwa.width;
@ -402,13 +426,13 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
switch(event.xbutton.button) switch(event.xbutton.button)
{ {
case Button1: case Button1:
server.postEvent(new CEventMouseUp(fX, fY, leftButton, this)); server->postEvent(new CEventMouseUp(fX, fY, leftButton, this));
break; break;
case Button2: case Button2:
server.postEvent(new CEventMouseUp(fX, fY, middleButton, this)); server->postEvent(new CEventMouseUp(fX, fY, middleButton, this));
break; break;
case Button3: case Button3:
server.postEvent(new CEventMouseUp(fX, fY, rightButton, this)); server->postEvent(new CEventMouseUp(fX, fY, rightButton, this));
break; break;
} }
break; break;
@ -425,16 +449,15 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
break; break;
// post a CGDMouseMove with the movement delta to the event server // post a CGDMouseMove with the movement delta to the event server
server.postEvent( server->postEvent(
new CGDMouseMove(this, NULL /* no mouse device */, new CGDMouseMove(this, NULL /* no mouse device */,
event.xbutton.x - (xwa.width / 2), event.xbutton.x - (xwa.width / 2),
(xwa.height / 2) - event.xbutton.y)); (xwa.height / 2) - event.xbutton.y));
// move the pointer back to the center of the window // move the pointer back to the center of the window
XWarpPointer(_dpy, None, _win, None, None, None, None, XWarpPointer(_dpy, None, _win, None, None, None, None,
(xwa.width / 2), (xwa.height / 2)); (xwa.width / 2), (xwa.height / 2));
} }
// if in normal mouse mode // if in normal mouse mode
else else
{ {
@ -443,11 +466,11 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height; float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
// post a normal mouse move event to the event server // post a normal mouse move event to the event server
server.postEvent (new CEventMouseMove (fX, fY, button, this)); server->postEvent (new CEventMouseMove (fX, fY, button, this));
} }
break; break;
} }
Case(KeyPress) case KeyPress:
{ {
// save keycode because XFilterEvent could set it to 0 // save keycode because XFilterEvent could set it to 0
uint keyCode = event.xkey.keycode; uint keyCode = event.xkey.keycode;
@ -483,7 +506,7 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
if(key == KeyNOKEY) if(key == KeyNOKEY)
key = getKeyFromKeycode(keyCode); key = getKeyFromKeycode(keyCode);
server.postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), _PreviousKey != key, this)); server->postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), _PreviousKey != key, this));
_PreviousKey = key; _PreviousKey = key;
// don't send a control character when deleting // don't send a control character when deleting
@ -497,51 +520,44 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
#ifdef X_HAVE_UTF8_STRING #ifdef X_HAVE_UTF8_STRING
ucstring ucstr; ucstring ucstr;
ucstr.fromUtf8(Text); ucstr.fromUtf8(Text);
server.postEvent (new CEventChar (ucstr[0], noKeyButton, this)); server->postEvent (new CEventChar (ucstr[0], noKeyButton, this));
#else #else
for (int i = 0; i < c; i++) for (int i = 0; i < c; i++)
server.postEvent (new CEventChar ((ucchar)(unsigned char)Text[i], noKeyButton, this)); server->postEvent (new CEventChar ((ucchar)(unsigned char)Text[i], noKeyButton, this));
#endif #endif
} }
break; break;
} }
Case (KeyRelease) case KeyRelease:
{ {
TKey key = getKeyFromKeySym(XKeycodeToKeysym(_dpy, event.xkey.keycode, 0)); TKey key = getKeyFromKeySym(XKeycodeToKeysym(_dpy, event.xkey.keycode, 0));
if(key == KeyNOKEY) if(key == KeyNOKEY)
key = getKeyFromKeycode(event.xkey.keycode); key = getKeyFromKeycode(event.xkey.keycode);
server.postEvent (new CEventKeyUp (key, getKeyButton(event.xbutton.state), this)); server->postEvent (new CEventKeyUp (key, getKeyButton(event.xbutton.state), this));
_PreviousKey = KeyNOKEY; _PreviousKey = KeyNOKEY;
break; break;
} }
Case(FocusIn) case FocusIn:
if (_ic) XSetICFocus(_ic); if (_ic) XSetICFocus(_ic);
return;
Case(FocusOut)
if (_ic) XUnsetICFocus(_ic);
return;
Case(Expose)
break; break;
Case(MappingNotify) case FocusOut:
if (_ic) XUnsetICFocus(_ic);
break;
case MappingNotify:
XRefreshKeyboardMapping((XMappingEvent *)&event); XRefreshKeyboardMapping((XMappingEvent *)&event);
break; break;
Case(DestroyNotify) case DestroyNotify:
// XIM server has crashed // XIM server has crashed
createIM(); createIM();
break; break;
Case(ConfigureNotify)
/* if (event.xconfigure.width==gmaxx && event.xconfigure.height==gmaxy) {
UpdateGWin();
} else {
XResizeWindow(display, gwindow, gmaxx, gmaxy);
} */
break;
default: default:
nlinfo("UnknownEvent"); // nlinfo("UnknownEvent");
// XtDispatchEvent(&event); // XtDispatchEvent(&event);
break; return false;
} }
return true;
} }
} // NLMISC } // NLMISC

View file

@ -46,29 +46,59 @@ public:
CUnixEventEmitter(); CUnixEventEmitter();
virtual ~CUnixEventEmitter(); virtual ~CUnixEventEmitter();
void init (Display *dpy, Window win); /**
* initialize CUnixEventEmitter
*/
void init(Display *dpy, Window win, NL3D::IDriver *driver = NULL);
/** /**
* sends all events to server * sends all events to server
* (should call CEventServer method postEvent() ) * (should call CEventServer method postEvent() )
* \param server
*/ */
virtual void submitEvents(CEventServer & server, bool allWindows); virtual void submitEvents(CEventServer & server, bool allWindows);
virtual void emulateMouseRawMode(bool); /**
* enable or disable mouse raw mode
*/
virtual void emulateMouseRawMode(bool emulate);
public: /**
void processMessage (XEvent &event, CEventServer &server); * process input-related events (mouse and keyboard)
*/
bool processMessage(XEvent &event, CEventServer *server = NULL);
private: private:
// Private internal server message
class CUnixEventServer : CEventServer
{
friend class CUnixEventEmitter;
public:
void setServer (CEventServer *server)
{
_Server=server;
}
private:
virtual bool pumpEvent(CEvent* event)
{
CEventServer::pumpEvent(event);
_Server->postEvent (event);
return false;
}
private:
CEventServer *_Server;
};
void createIM(); void createIM();
Display *_dpy; Display* _dpy;
Window _win; Window _win;
TKey _PreviousKey; TKey _PreviousKey;
XIM _im; XIM _im;
XIC _ic; XIC _ic;
bool _emulateRawMode; bool _emulateRawMode;
NL3D::IDriver* _driver;
CUnixEventServer _InternalServer;
}; };