From 4220215132aa99eb5eba2562853d5a2268762b6d Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 24 Jul 2010 23:09:43 +0200 Subject: [PATCH] Fixed: #1028 Implement GlWndProc for X11 --- .../src/3d/driver/opengl/driver_opengl.cpp | 46 ++-- code/nel/src/3d/driver/opengl/driver_opengl.h | 22 +- .../driver/opengl/driver_opengl_texture.cpp | 14 -- .../3d/driver/opengl/driver_opengl_window.cpp | 203 ++++++++++-------- .../3d/driver/opengl/unix_event_emitter.cpp | 124 ++++++----- .../src/3d/driver/opengl/unix_event_emitter.h | 52 ++++- 6 files changed, 263 insertions(+), 198 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 61b782297..4c308267b 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -966,28 +966,20 @@ void CDriverGL::setupViewport (const class CViewport& viewport) if (_win == EmptyWindow) return; -#ifdef NL_OS_WINDOWS - - // Setup gl viewport - int clientWidth = _WindowWidth; - int clientHeight = _WindowHeight; - -#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) +#ifdef NL_MAC_NATIVE uint32 clientWidth, clientHeight; NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight); -#elif defined (NL_OS_UNIX) + getWindowSize(clientWidth, clientHeight); - XWindowAttributes win_attributes; - if (!XGetWindowAttributes(_dpy, _win, &win_attributes)) - throw EBadDisplay("Can't get window attributes."); +#else // Setup gl viewport - int clientWidth=win_attributes.width; - int clientHeight=win_attributes.height; + sint clientWidth = _WindowWidth; + sint clientHeight = _WindowHeight; -#endif // NL_OS_WINDOWS +#endif // NL_MAC_NATIVE // Backup the viewport _CurrViewport = viewport; @@ -1037,31 +1029,21 @@ void CDriverGL::getViewport(CViewport &viewport) void CDriverGL::setupScissor (const class CScissor& scissor) { H_AUTO_OGL(CDriverGL_setupScissor ) -#ifdef NL_OS_WINDOWS + if (_win == EmptyWindow) return; - // Setup gl viewport - int clientWidth = _WindowWidth; - int clientHeight = _WindowHeight; +#ifdef NL_MAC_NATIVE -#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) + uint32 clientWidth, clientHeight; + NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight); - uint32 clientWidth = 0; - 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."); +#else // Setup gl viewport - int clientWidth=win_attributes.width; - int clientHeight=win_attributes.height; + sint clientWidth = _WindowWidth; + sint clientHeight = _WindowHeight; -#endif // NL_OS_WINDOWS +#endif // NL_MAC_NATIVE // Backup the scissor _CurrScissor= scissor; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 540a73aca..33c02f69a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -107,6 +107,21 @@ class IVertexArrayRange; class IVertexBufferHardGL; 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 TOcclusionQueryList; // *************************************************************************** @@ -660,14 +675,15 @@ private: uint _Interval; sint8 _AntiAliasing; - sint32 _WindowWidth, _WindowHeight, _WindowX, _WindowY; + uint32 _WindowWidth, _WindowHeight; + sint32 _WindowX, _WindowY; nlWindow _win; bool _DestroyWindow; #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; PIXELFORMATDESCRIPTOR _pfd; @@ -685,6 +701,8 @@ private: #elif defined (NL_OS_UNIX) + friend bool GlWndProc(CDriverGL *driver, XEvent &e); + Display* _dpy; GLXContext _ctx; Cursor _cursor; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 83a07038a..417851f58 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -1939,22 +1939,8 @@ bool CDriverGL::getRenderTargetSize (uint32 &width, uint32 &height) } else { -#ifdef NL_OS_WINDOWS width = _WindowWidth; 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; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 3fecf8188..12e68b1c4 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -51,7 +51,7 @@ namespace NL3D #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) 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); } -#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) @@ -860,11 +929,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re glXMakeCurrent (_dpy, _win, _ctx); // XMapRaised (_dpy, _win); - XSelectInput (_dpy, _win, KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask); - // XMapWindow(_dpy, _win); - _EventEmitter.init (_dpy, _win); + _EventEmitter.init (_dpy, _win, this); // XEvent event; // XIfEvent(dpy, &event, WaitForNotify, (char *)this); @@ -1333,7 +1400,7 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) H_AUTO_OGL(CDriverGL_setWindowStyle) // don't change window style, if we did not create the window - if (!_DestroyWindow) + if (_win == EmptyWindow || !_DestroyWindow) return true; #if defined(NL_OS_WINDOWS) @@ -1392,27 +1459,23 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) #if !defined(NL_OS_MAC) // 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; - memset(&xev, 0, sizeof(xev)); - 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; - } + nlwarning("3D: Failed to toggle to fullscreen"); + return false; } #endif @@ -1431,7 +1494,7 @@ bool CDriverGL::setMode(const GfxMode& mode) return false; // 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; _WindowHeight = mode.Height; @@ -1455,6 +1518,7 @@ bool CDriverGL::setMode(const GfxMode& mode) bool CDriverGL::getModes(std::vector &modes) { H_AUTO_OGL(CDriverGL_getModes) + #ifdef NL_OS_WINDOWS sint modeIndex = 0; DEVMODE devMode; @@ -1701,6 +1765,11 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode) // -------------------------------------------------- void CDriverGL::setWindowTitle(const ucstring &title) { + H_AUTO_OGL(CDriverGL_setWindowTitle) + + if (_win == EmptyWindow) + return; + #ifdef NL_OS_WINDOWS SetWindowTextW(_win, (WCHAR*)title.c_str()); @@ -1725,6 +1794,8 @@ void CDriverGL::setWindowTitle(const ucstring &title) // *************************************************************************** void CDriverGL::setWindowPos(sint32 x, sint32 y) { + H_AUTO_OGL(CDriverGL_setWindowPos) + _WindowX = x; _WindowY = y; @@ -1749,7 +1820,7 @@ void CDriverGL::showWindow(bool show) H_AUTO_OGL(CDriverGL_showWindow) // don't change window visibility, if we didn't create the window - if (!_DestroyWindow) + if (_win == EmptyWindow || !_DestroyWindow) return; #ifdef NL_OS_WINDOWS @@ -1778,11 +1849,7 @@ emptyProc CDriverGL::getWindowProc() { H_AUTO_OGL(CDriverGL_getWindowProc) -#ifdef NL_OS_WINDOWS 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) - XWindowAttributes xwa; - XGetWindowAttributes (_dpy, _win, &xwa); - int x1 = (int)(x * (float) xwa.width); - int y1 = (int)((1.0f - y) * (float) xwa.height); + sint x1 = (sint)((float)_WindowWidth*x); + sint y1 = (sint)((float)_WindowHeight*(1.0f-y)); XWarpPointer (_dpy, None, _win, None, None, None, None, x1, y1); #endif // NL_OS_UNIX @@ -1945,38 +2010,33 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height) { H_AUTO_OGL(CDriverGL_getWindowSize) -#ifdef NL_OS_WINDOWS +#ifdef NL_MAC_NATIVE + + NL3D::MAC::getWindowSize(_win, width, height); + +#else // Off-screen rendering ? if (_OffScreen) { +#ifdef NL_OS_WINDOWS if (_PBuffer) { nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width ); nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height ); } +#endif } else { if (_win) { - width = (uint32)_WindowWidth; - height = (uint32)_WindowHeight; + width = _WindowWidth; + height = _WindowHeight; } } -#elif defined(NL_OS_MAC) && defined(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 +#endif // NL_MAC_NATIVE } void CDriverGL::setWindowSize(uint32 width, uint32 height) @@ -2040,15 +2100,16 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y) { H_AUTO_OGL(CDriverGL_getWindowPos) -#ifdef NL_OS_WINDOWS +#ifdef NL_MAC_NATIVE + + NL3D::MAC::getWindowPos(_win, x, y); + +#else // Off-screen rendering ? if (_OffScreen) { - if (_PBuffer) - { - x = y = 0; - } + x = y = 0; } else { @@ -2059,35 +2120,7 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y) } } -#elif defined(NL_OS_MAC) && defined(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 +#endif // NL_MAC_NATIVE } // -------------------------------------------------- diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp index d2d8f5a66..f814b130f 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp @@ -27,9 +27,11 @@ #include "nel/misc/debug.h" #include "unix_event_emitter.h" +typedef void (*x11Proc)(NL3D::IDriver *drv, XEvent *e); + 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; _ic = 0; @@ -41,10 +43,21 @@ CUnixEventEmitter::~CUnixEventEmitter() if (_im) XCloseIM(_im); } -void CUnixEventEmitter::init (Display *dpy, Window win) +void CUnixEventEmitter::init(Display *dpy, Window win, NL3D::IDriver *driver) { _dpy = dpy; _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(); } @@ -75,12 +88,27 @@ void CUnixEventEmitter::submitEvents(CEventServer & server, bool allWindows) { XEvent Event; XNextEvent(_dpy, &Event); - if(Event.xany.window==_win) + if (allWindows || Event.xany.window == _win) { // 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) @@ -91,7 +119,7 @@ void CUnixEventEmitter::emulateMouseRawMode(bool enable) { XWindowAttributes 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)); } } @@ -354,21 +382,17 @@ TKey getKeyFromKeySym (KeySym keysym) return KeyNOKEY; } - -#define Case(a) case(a): // nlinfo("event: "#a); - -void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) +void CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server) { + if (!server) + server=&_InternalServer; + XWindowAttributes xwa; XGetWindowAttributes (_dpy, _win, &xwa); switch (event.type) { - Case(ReparentNotify) - Case(UnmapNotify) - Case(VisibilityNotify) - break; - Case(ButtonPress) + case ButtonPress: { //nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y); float fX = (float) event.xbutton.x / (float) xwa.width; @@ -377,24 +401,24 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) switch(event.xbutton.button) { 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; 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; 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; case Button4: - server.postEvent(new CEventMouseWheel(fX, fY, button, true, this)); + server->postEvent(new CEventMouseWheel(fX, fY, button, true, this)); break; case Button5: - server.postEvent(new CEventMouseWheel(fX, fY, button, false, this)); + server->postEvent(new CEventMouseWheel(fX, fY, button, false, this)); break; } break; } - Case(ButtonRelease) + case ButtonRelease: { //nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y); float fX = (float) event.xbutton.x / (float) xwa.width; @@ -402,13 +426,13 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) switch(event.xbutton.button) { case Button1: - server.postEvent(new CEventMouseUp(fX, fY, leftButton, this)); + server->postEvent(new CEventMouseUp(fX, fY, leftButton, this)); break; case Button2: - server.postEvent(new CEventMouseUp(fX, fY, middleButton, this)); + server->postEvent(new CEventMouseUp(fX, fY, middleButton, this)); break; case Button3: - server.postEvent(new CEventMouseUp(fX, fY, rightButton, this)); + server->postEvent(new CEventMouseUp(fX, fY, rightButton, this)); break; } break; @@ -425,16 +449,15 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) break; // post a CGDMouseMove with the movement delta to the event server - server.postEvent( - new CGDMouseMove(this, NULL /* no mouse device */, - event.xbutton.x - (xwa.width / 2), + server->postEvent( + new CGDMouseMove(this, NULL /* no mouse device */, + event.xbutton.x - (xwa.width / 2), (xwa.height / 2) - event.xbutton.y)); - + // 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)); } - // if in normal mouse mode else { @@ -443,11 +466,11 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height; // 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; } - Case(KeyPress) + case KeyPress: { // save keycode because XFilterEvent could set it to 0 uint keyCode = event.xkey.keycode; @@ -483,7 +506,7 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) if(key == KeyNOKEY) 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; // don't send a control character when deleting @@ -497,51 +520,44 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server) #ifdef X_HAVE_UTF8_STRING ucstring ucstr; ucstr.fromUtf8(Text); - server.postEvent (new CEventChar (ucstr[0], noKeyButton, this)); + server->postEvent (new CEventChar (ucstr[0], noKeyButton, this)); #else 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 } break; } - Case (KeyRelease) + case KeyRelease: { TKey key = getKeyFromKeySym(XKeycodeToKeysym(_dpy, event.xkey.keycode, 0)); if(key == KeyNOKEY) 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; break; } - Case(FocusIn) + case FocusIn: if (_ic) XSetICFocus(_ic); - return; - Case(FocusOut) - if (_ic) XUnsetICFocus(_ic); - return; - Case(Expose) break; - Case(MappingNotify) + case FocusOut: + if (_ic) XUnsetICFocus(_ic); + break; + case MappingNotify: XRefreshKeyboardMapping((XMappingEvent *)&event); break; - Case(DestroyNotify) + case DestroyNotify: // XIM server has crashed createIM(); break; - Case(ConfigureNotify) - /* if (event.xconfigure.width==gmaxx && event.xconfigure.height==gmaxy) { - UpdateGWin(); - } else { - XResizeWindow(display, gwindow, gmaxx, gmaxy); - } */ - break; default: - nlinfo("UnknownEvent"); - // XtDispatchEvent(&event); - break; + // nlinfo("UnknownEvent"); + // XtDispatchEvent(&event); + return false; } + + return true; } } // NLMISC diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.h b/code/nel/src/3d/driver/opengl/unix_event_emitter.h index 45c5e868a..bb4e6db94 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.h @@ -46,29 +46,59 @@ public: 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 * (should call CEventServer method postEvent() ) - * \param server */ 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 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(); - Display *_dpy; - Window _win; - TKey _PreviousKey; - XIM _im; - XIC _ic; - bool _emulateRawMode; + Display* _dpy; + Window _win; + TKey _PreviousKey; + XIM _im; + XIC _ic; + bool _emulateRawMode; + NL3D::IDriver* _driver; + CUnixEventServer _InternalServer; };