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

View file

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

View file

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

View file

@ -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<GfxMode> &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
}
// --------------------------------------------------

View file

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

View file

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