Cleanup of basic XIM support.

Shortened and simplified the code.  Removed reporting of XIM sentinel
key press event.  Added credit.  Updated changelog.

Closes #151.
This commit is contained in:
Camilla Berglund
2014-09-21 02:13:41 +02:00
parent cec63f3cb5
commit c769061a8a
4 changed files with 89 additions and 116 deletions
+45 -69
View File
@@ -95,58 +95,6 @@ static int translateKey(int keycode)
return _glfw.x11.keyCodeLUT[keycode];
}
// Translates an X Window event to Unicode
//
static wchar_t * translateChar(XEvent * event, _GLFWwindow * window, int * count)
{
KeySym keysym;
static wchar_t buffer[16];
// If there is no input method / context available, use the old fallback
// mechanism
if (!window || !window->x11.ic)
{
long uc;
// Get X11 keysym
XLookupString(&event->xkey, NULL, 0, &keysym, NULL);
// Convert to Unicode (see x11_unicode.c)
uc = _glfwKeySym2Unicode(keysym);
if (uc < 0 || uc > 0xFFFF)
{
*count = 0;
return NULL;
}
buffer[0] = (unsigned int)uc;
*count = 1;
}
// Else lookup the wide char string with respect to dead characters
else
{
Status dummy;
// Check if the given event is a dead char. In that case, it does not
// produce a unicode char.
if (XFilterEvent(event, None))
{
*count = 0;
return NULL;
}
// Retrieve unicode string
*count = XwcLookupString(window->x11.ic, &event->xkey, buffer, 16 * sizeof(wchar_t), 0, &dummy);
if (*count < 0)
{
*count = 0;
return NULL;
}
}
return buffer;
}
// Return the GLFW window corresponding to the specified X11 window
//
static _GLFWwindow* findWindowByHandle(Window handle)
@@ -240,8 +188,6 @@ static GLboolean createWindow(_GLFWwindow* window,
unsigned long wamask;
XSetWindowAttributes wa;
XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL;
window->x11.ic = NULL;
// Every window needs a colormap
// Create one based on the visual used by the current context
@@ -477,13 +423,18 @@ static GLboolean createWindow(_GLFWwindow* window,
XRRSelectInput(_glfw.x11.display, window->x11.handle,
RRScreenChangeNotifyMask);
// Try to create an input context. If this function returns NULL, ic is
// set to NULL and we know we have to use fallback mechanisms to parse
// char events.
window->x11.ic = XCreateIC(_glfw.x11.im, XNInputStyle,
XIMPreeditNothing | XIMStatusNothing, XNClientWindow,
window->x11.handle, XNFocusWindow, window->x11.handle, NULL);
if (_glfw.x11.im)
{
window->x11.ic = XCreateIC(_glfw.x11.im,
XNInputStyle,
XIMPreeditNothing | XIMStatusNothing,
XNClientWindow,
window->x11.handle,
XNFocusWindow,
window->x11.handle,
NULL);
}
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
@@ -876,20 +827,45 @@ static void processEvent(XEvent *event)
{
case KeyPress:
{
int i, n_chars;
const int key = translateKey(event->xkey.keycode);
const int mods = translateState(event->xkey.state);
const wchar_t * characters = translateChar(event, window, &n_chars);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
_glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods);
if (event->xkey.keycode)
_glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods);
for (i = 0; i < n_chars; i++)
if (window->x11.ic)
{
if (characters[i] != -1)
// Translate keys to characters with XIM input context
int i;
Status status;
wchar_t buffer[16];
if (XFilterEvent(event, None))
{
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
_glfwInputChar(window, (unsigned int)characters[i], mods, plain);
// Discard intermediary (dead key) events for character input
break;
}
const int count = XwcLookupString(window->x11.ic,
&event->xkey,
buffer, sizeof(buffer),
NULL, &status);
for (i = 0; i < count; i++)
_glfwInputChar(window, buffer[i], mods, plain);
}
else
{
// Translate keys to characters with fallback lookup table
KeySym keysym;
XLookupString(&event->xkey, NULL, 0, &keysym, NULL);
const long character = _glfwKeySym2Unicode(keysym);
if (character != -1)
_glfwInputChar(window, character, mods, plain);
}
break;
@@ -1418,7 +1394,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (window->monitor)
leaveFullscreenMode(window);
if (window->x11.ic)
{
XDestroyIC(window->x11.ic);