Changed: #941 Dead keys are not working on Linux
This commit is contained in:
parent
ba9443f84b
commit
4b2a9a5718
3 changed files with 84 additions and 31 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
// 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);
|
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