Changed: #941 Dead keys are not working on Linux

This commit is contained in:
kervala 2010-05-27 10:04:43 +02:00
parent e0a5ebf20f
commit 2522e93604
3 changed files with 84 additions and 31 deletions

View file

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

View file

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

View file

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