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)
{
nlinfo("3D: glop %d %d", e->type, e->xmap.window);
CDriverGL *pDriver = (CDriverGL*)arg;
if (pDriver != NULL)
{
// Process the message by the emitter
pDriver->_EventEmitter.processMessage();
}
// TODO i'don t know what to return exactly
return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
nlinfo("3D: glop %d %d", e->type, e->xmap.window);
CDriverGL *pDriver = (CDriverGL*)arg;
if (pDriver != NULL)
{
// Process the message by the emitter
pDriver->_EventEmitter.processMessage();
}
// TODO i'don t know what to return exactly
return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
}
*/
#endif // NL_OS_UNIX
@ -867,7 +867,7 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
_hDC = NULL;
return false;
}
}
}
else
{
_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);
if(visual_info == NULL)
{
nlerror("glXChooseVisual() failed");
nlerror("glXChooseVisual() failed");
}
else
{
nldebug("3D: glXChooseVisual OK");
nldebug("3D: glXChooseVisual OK");
}
ctx = glXCreateContext (dpy, visual_info, None, GL_TRUE);
if(ctx == NULL)
{
nlerror("glXCreateContext() failed");
nlerror("glXCreateContext() failed");
}
else
{
nldebug("3D: glXCreateContext() OK");
nldebug("3D: glXCreateContext() OK");
}
XSetWindowAttributes attr;
@ -1136,6 +1136,8 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
XChangeWindowAttributes(dpy, win, attr_flags, &attr);
}
const char *title="NeL window";
XSizeHints size_hints;
size_hints.x = 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_height = height;
#ifdef X_HAVE_UTF8_STRING
Xutf8SetWMProperties (dpy, win, (char*)title, (char*)title, NULL, 0, &size_hints, NULL, NULL);
#else
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);
XSetWMProperties (dpy, win, &text_property, &text_property, 0, 0, &size_hints, 0, 0);
#endif
glXMakeCurrent (dpy, win, ctx);
XMapRaised (dpy, win);
@ -1310,8 +1313,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
if(_Extensions.EXTSeparateSpecularColor)
{
glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
}
_VertexProgramEnabled= false;
@ -3594,7 +3595,7 @@ void CDriverGL::initFragmentShaders()
//
nglEndFragmentShaderATI();
GLenum error = glGetError();
nlassert(error == GL_NONE);
nlassert(error == GL_NONE);
// The same but with a diffuse map added
nglBindFragmentShaderATI(ATIWaterShaderHandle);
@ -3608,7 +3609,7 @@ void CDriverGL::initFragmentShaders()
nglEndFragmentShaderATI();
error = glGetError();
nlassert(error == GL_NONE);
nlassert(error == GL_NONE);
nglBindFragmentShaderATI(0);
}
@ -4139,8 +4140,8 @@ void CDriverGL::checkTextureOn() const
nlassert(!flag2D);
nlassert(flagCM);
break;
default:
break;
default:
break;
}
}
dgs.activeTextureARB(currTexStage);

View file

@ -29,12 +29,42 @@ namespace NLMISC {
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)
{
_dpy = dpy;
_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)
@ -352,14 +382,28 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
}
Case(KeyPress)
{
uint keyCode = event.xkey.keycode;
KeySym k = XKeycodeToKeysym(_dpy, keyCode, 0);
char Text[256];
KeySym k;
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);
if(key == KeyNOKEY)
key = getKeyFromKeycode(event.xkey.keycode);
key = getKeyFromKeycode(keyCode);
server.postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), _PreviousKey != key, this));
_PreviousKey = key;
@ -371,10 +415,9 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
Text[c] = '\0';
if(c>0)
{
for (int i = 0; i < c; i++)
{
server.postEvent (new CEventChar ((ucchar)(unsigned char)Text[i], noKeyButton, this));
}
ucstring ucstr;
ucstr.fromUtf8(Text);
server.postEvent (new CEventChar (ucstr[0], noKeyButton, this));
}
break;
}
@ -389,8 +432,10 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
break;
}
Case(FocusIn)
if (_ic) XSetICFocus(_ic);
return;
Case(FocusOut)
if (_ic) XUnsetICFocus(_ic);
return;
Case(Expose)
break;
@ -398,6 +443,8 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
XRefreshKeyboardMapping((XMappingEvent *)&event);
break;
Case(DestroyNotify)
// XIM server has crashed
createIM();
break;
Case(ConfigureNotify)
/* if (event.xconfigure.width==gmaxx && event.xconfigure.height==gmaxy) {

View file

@ -41,6 +41,7 @@ public:
/// Constructor
CUnixEventEmitter();
virtual ~CUnixEventEmitter();
void init (Display *dpy, Window win);
@ -55,9 +56,13 @@ public:
void processMessage (XEvent &event, CEventServer &server);
private:
void createIM();
Display *_dpy;
Window _win;
TKey _PreviousKey;
XIM _im;
XIC _ic;
};