mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-13 21:34:48 +00:00
Fixed: #1028 Implement GlWndProc for X11
This commit is contained in:
parent
0da812d348
commit
4220215132
6 changed files with 263 additions and 198 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,28 +1459,24 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
|
||||||
#if !defined(NL_OS_MAC)
|
#if !defined(NL_OS_MAC)
|
||||||
|
|
||||||
// Toggle fullscreen
|
// Toggle fullscreen
|
||||||
if (windowStyle != getWindowStyle())
|
|
||||||
{
|
|
||||||
XEvent xev;
|
XEvent xev;
|
||||||
memset(&xev, 0, sizeof(xev));
|
xev.xclient.type = ClientMessage;
|
||||||
xev.type = ClientMessage;
|
xev.xclient.serial = 0;
|
||||||
// xev.xclient.serial = 0;
|
xev.xclient.send_event = True;
|
||||||
// xev.xclient.send_event = True;
|
xev.xclient.display = _dpy;
|
||||||
// xev.xclient.display = _dpy;
|
|
||||||
xev.xclient.window = _win;
|
xev.xclient.window = _win;
|
||||||
xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False);
|
xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False);
|
||||||
xev.xclient.format = 32;
|
xev.xclient.format = 32;
|
||||||
xev.xclient.data.l[0] = windowStyle == EWSFullscreen ? 1:0;
|
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[1] = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
xev.xclient.data.l[2] = 0;
|
xev.xclient.data.l[2] = 0;
|
||||||
xev.xclient.data.l[3] = 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;
|
xev.xclient.data.l[4] = 0;
|
||||||
if (XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureNotifyMask, &xev) != Success)
|
if (XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev) != Success)
|
||||||
{
|
{
|
||||||
nlwarning("3D: Failed to toggle to fullscreen");
|
nlwarning("3D: Failed to toggle to fullscreen");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -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,16 +2100,17 @@ 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
|
||||||
{
|
{
|
||||||
if (_win)
|
if (_win)
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
|
@ -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,14 +88,29 @@ 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);
|
||||||
|
if (_driver)
|
||||||
|
{
|
||||||
|
// forward X events to OpenGL driver
|
||||||
|
x11Proc proc = (x11Proc)_driver->getWindowProc();
|
||||||
|
|
||||||
|
if (proc)
|
||||||
|
proc(_driver, &Event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
processMessage (Event, server);
|
processMessage (Event, server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dispatch sent messages
|
||||||
|
_InternalServer.setServer (&server);
|
||||||
|
_InternalServer.pump (allWindows);
|
||||||
|
}
|
||||||
|
|
||||||
void CUnixEventEmitter::emulateMouseRawMode(bool enable)
|
void CUnixEventEmitter::emulateMouseRawMode(bool enable)
|
||||||
{
|
{
|
||||||
_emulateRawMode = enable;
|
_emulateRawMode = enable;
|
||||||
|
@ -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,7 +449,7 @@ 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));
|
||||||
|
@ -434,7 +458,6 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
|
||||||
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
|
||||||
|
|
|
@ -46,21 +46,49 @@ 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;
|
||||||
|
@ -69,6 +97,8 @@ private:
|
||||||
XIM _im;
|
XIM _im;
|
||||||
XIC _ic;
|
XIC _ic;
|
||||||
bool _emulateRawMode;
|
bool _emulateRawMode;
|
||||||
|
NL3D::IDriver* _driver;
|
||||||
|
CUnixEventServer _InternalServer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue