Changed: #941 Dead keys are not working on Linux
This commit is contained in:
parent
f79449af27
commit
efc6cbef2e
3 changed files with 84 additions and 31 deletions
|
@ -245,15 +245,15 @@ extern "C"
|
||||||
/*
|
/*
|
||||||
static Bool WndProc(Display *d, XEvent *e, char *arg)
|
static Bool WndProc(Display *d, XEvent *e, char *arg)
|
||||||
{
|
{
|
||||||
nlinfo("3D: glop %d %d", e->type, e->xmap.window);
|
nlinfo("3D: glop %d %d", e->type, e->xmap.window);
|
||||||
CDriverGL *pDriver = (CDriverGL*)arg;
|
CDriverGL *pDriver = (CDriverGL*)arg;
|
||||||
if (pDriver != NULL)
|
if (pDriver != NULL)
|
||||||
{
|
{
|
||||||
// Process the message by the emitter
|
// Process the message by the emitter
|
||||||
pDriver->_EventEmitter.processMessage();
|
pDriver->_EventEmitter.processMessage();
|
||||||
}
|
}
|
||||||
// TODO i'don t know what to return exactly
|
// TODO i'don t know what to return exactly
|
||||||
return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
|
return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
#endif // NL_OS_UNIX
|
#endif // NL_OS_UNIX
|
||||||
|
@ -867,7 +867,7 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
_hDC = NULL;
|
_hDC = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_FullScreen= false;
|
_FullScreen= false;
|
||||||
|
@ -1074,21 +1074,21 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), sAttribList16bpp);
|
visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), sAttribList16bpp);
|
||||||
if(visual_info == NULL)
|
if(visual_info == NULL)
|
||||||
{
|
{
|
||||||
nlerror("glXChooseVisual() failed");
|
nlerror("glXChooseVisual() failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nldebug("3D: glXChooseVisual OK");
|
nldebug("3D: glXChooseVisual OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = glXCreateContext (dpy, visual_info, None, GL_TRUE);
|
ctx = glXCreateContext (dpy, visual_info, None, GL_TRUE);
|
||||||
if(ctx == NULL)
|
if(ctx == NULL)
|
||||||
{
|
{
|
||||||
nlerror("glXCreateContext() failed");
|
nlerror("glXCreateContext() failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nldebug("3D: glXCreateContext() OK");
|
nldebug("3D: glXCreateContext() OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
XSetWindowAttributes attr;
|
XSetWindowAttributes attr;
|
||||||
|
@ -1136,6 +1136,8 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
XChangeWindowAttributes(dpy, win, attr_flags, &attr);
|
XChangeWindowAttributes(dpy, win, attr_flags, &attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *title="NeL window";
|
||||||
|
|
||||||
XSizeHints size_hints;
|
XSizeHints size_hints;
|
||||||
size_hints.x = 0;
|
size_hints.x = 0;
|
||||||
size_hints.y = 0;
|
size_hints.y = 0;
|
||||||
|
@ -1147,13 +1149,14 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
size_hints.max_width = width;
|
size_hints.max_width = width;
|
||||||
size_hints.max_height = height;
|
size_hints.max_height = height;
|
||||||
|
|
||||||
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
|
Xutf8SetWMProperties (dpy, win, (char*)title, (char*)title, NULL, 0, &size_hints, NULL, NULL);
|
||||||
|
#else
|
||||||
XTextProperty text_property;
|
XTextProperty text_property;
|
||||||
// FIXME char*s are created as const char*, but that doesn't work
|
|
||||||
// with XStringListToTextProperty()'s char** ...
|
|
||||||
const char *title="NeL window";
|
|
||||||
XStringListToTextProperty((char**)&title, 1, &text_property);
|
XStringListToTextProperty((char**)&title, 1, &text_property);
|
||||||
|
|
||||||
XSetWMProperties (dpy, win, &text_property, &text_property, 0, 0, &size_hints, 0, 0);
|
XSetWMProperties (dpy, win, &text_property, &text_property, 0, 0, &size_hints, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
glXMakeCurrent (dpy, win, ctx);
|
glXMakeCurrent (dpy, win, ctx);
|
||||||
XMapRaised (dpy, win);
|
XMapRaised (dpy, win);
|
||||||
|
|
||||||
|
@ -1310,8 +1313,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
if(_Extensions.EXTSeparateSpecularColor)
|
if(_Extensions.EXTSeparateSpecularColor)
|
||||||
{
|
{
|
||||||
glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
|
glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_VertexProgramEnabled= false;
|
_VertexProgramEnabled= false;
|
||||||
|
@ -3594,7 +3595,7 @@ void CDriverGL::initFragmentShaders()
|
||||||
//
|
//
|
||||||
nglEndFragmentShaderATI();
|
nglEndFragmentShaderATI();
|
||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
nlassert(error == GL_NONE);
|
nlassert(error == GL_NONE);
|
||||||
|
|
||||||
// The same but with a diffuse map added
|
// The same but with a diffuse map added
|
||||||
nglBindFragmentShaderATI(ATIWaterShaderHandle);
|
nglBindFragmentShaderATI(ATIWaterShaderHandle);
|
||||||
|
@ -3608,7 +3609,7 @@ void CDriverGL::initFragmentShaders()
|
||||||
|
|
||||||
nglEndFragmentShaderATI();
|
nglEndFragmentShaderATI();
|
||||||
error = glGetError();
|
error = glGetError();
|
||||||
nlassert(error == GL_NONE);
|
nlassert(error == GL_NONE);
|
||||||
nglBindFragmentShaderATI(0);
|
nglBindFragmentShaderATI(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4139,8 +4140,8 @@ void CDriverGL::checkTextureOn() const
|
||||||
nlassert(!flag2D);
|
nlassert(!flag2D);
|
||||||
nlassert(flagCM);
|
nlassert(flagCM);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dgs.activeTextureARB(currTexStage);
|
dgs.activeTextureARB(currTexStage);
|
||||||
|
|
|
@ -29,12 +29,42 @@ namespace NLMISC {
|
||||||
|
|
||||||
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY)
|
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY)
|
||||||
{
|
{
|
||||||
|
_im = 0;
|
||||||
|
_ic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CUnixEventEmitter::~CUnixEventEmitter()
|
||||||
|
{
|
||||||
|
if (_ic) XDestroyIC(_ic);
|
||||||
|
if (_im) XCloseIM(_im);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUnixEventEmitter::init (Display *dpy, Window win)
|
void CUnixEventEmitter::init (Display *dpy, Window win)
|
||||||
{
|
{
|
||||||
_dpy = dpy;
|
_dpy = dpy;
|
||||||
_win = win;
|
_win = win;
|
||||||
|
|
||||||
|
createIM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUnixEventEmitter::createIM()
|
||||||
|
{
|
||||||
|
_im = XOpenIM(_dpy, NULL, NULL, NULL);
|
||||||
|
if (_im)
|
||||||
|
{
|
||||||
|
_ic = XCreateIC(_im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, _win, XNFocusWindow, _win, NULL);
|
||||||
|
// XSetICFocus(_ic);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ic = 0;
|
||||||
|
nlwarning("XCreateIM failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_ic)
|
||||||
|
{
|
||||||
|
nlwarning("XCreateIC failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUnixEventEmitter::submitEvents(CEventServer & server, bool allWindows)
|
void CUnixEventEmitter::submitEvents(CEventServer & server, bool allWindows)
|
||||||
|
@ -352,14 +382,28 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
|
||||||
}
|
}
|
||||||
Case(KeyPress)
|
Case(KeyPress)
|
||||||
{
|
{
|
||||||
|
uint keyCode = event.xkey.keycode;
|
||||||
|
KeySym k = XKeycodeToKeysym(_dpy, keyCode, 0);
|
||||||
char Text[256];
|
char Text[256];
|
||||||
KeySym k;
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
c = XLookupString(&event.xkey, Text, sizeof(Text), &k, NULL);
|
|
||||||
|
// if key event is filtered, we must NOT use XLookupString
|
||||||
|
if (!XFilterEvent(&event, _win))
|
||||||
|
{
|
||||||
|
Status status = XLookupNone;
|
||||||
|
|
||||||
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
|
if (_ic)
|
||||||
|
c = Xutf8LookupString(_ic, &event.xkey, Text, sizeof(Text), &k, &status);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (status == XLookupNone)
|
||||||
|
c = XLookupString(&event.xkey, Text, sizeof(Text), &k, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
TKey key = getKeyFromKeySym(k);
|
TKey key = getKeyFromKeySym(k);
|
||||||
if(key == KeyNOKEY)
|
if(key == KeyNOKEY)
|
||||||
key = getKeyFromKeycode(event.xkey.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;
|
||||||
|
@ -371,10 +415,9 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
|
||||||
Text[c] = '\0';
|
Text[c] = '\0';
|
||||||
if(c>0)
|
if(c>0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < c; i++)
|
ucstring ucstr;
|
||||||
{
|
ucstr.fromUtf8(Text);
|
||||||
server.postEvent (new CEventChar ((ucchar)(unsigned char)Text[i], noKeyButton, this));
|
server.postEvent (new CEventChar (ucstr[0], noKeyButton, this));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -389,8 +432,10 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Case(FocusIn)
|
Case(FocusIn)
|
||||||
|
if (_ic) XSetICFocus(_ic);
|
||||||
return;
|
return;
|
||||||
Case(FocusOut)
|
Case(FocusOut)
|
||||||
|
if (_ic) XUnsetICFocus(_ic);
|
||||||
return;
|
return;
|
||||||
Case(Expose)
|
Case(Expose)
|
||||||
break;
|
break;
|
||||||
|
@ -398,6 +443,8 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
|
||||||
XRefreshKeyboardMapping((XMappingEvent *)&event);
|
XRefreshKeyboardMapping((XMappingEvent *)&event);
|
||||||
break;
|
break;
|
||||||
Case(DestroyNotify)
|
Case(DestroyNotify)
|
||||||
|
// XIM server has crashed
|
||||||
|
createIM();
|
||||||
break;
|
break;
|
||||||
Case(ConfigureNotify)
|
Case(ConfigureNotify)
|
||||||
/* if (event.xconfigure.width==gmaxx && event.xconfigure.height==gmaxy) {
|
/* if (event.xconfigure.width==gmaxx && event.xconfigure.height==gmaxy) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CUnixEventEmitter();
|
CUnixEventEmitter();
|
||||||
|
virtual ~CUnixEventEmitter();
|
||||||
|
|
||||||
void init (Display *dpy, Window win);
|
void init (Display *dpy, Window win);
|
||||||
|
|
||||||
|
@ -55,9 +56,13 @@ public:
|
||||||
void processMessage (XEvent &event, CEventServer &server);
|
void processMessage (XEvent &event, CEventServer &server);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void createIM();
|
||||||
|
|
||||||
Display *_dpy;
|
Display *_dpy;
|
||||||
Window _win;
|
Window _win;
|
||||||
TKey _PreviousKey;
|
TKey _PreviousKey;
|
||||||
|
XIM _im;
|
||||||
|
XIC _ic;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue