Changed: #941 Dead keys are not working on Linux

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

View file

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

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

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