Fix XIM input on non-UTF-8 locales

This commit is contained in:
Camilla Berglund 2015-10-09 13:23:34 +02:00
parent 842aeb8c47
commit 87ad8c0561
3 changed files with 44 additions and 1 deletions

View File

@ -99,6 +99,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
- [X11] Bugfix: `glfwWaitEvents` did not handle `EINTR` for `select` - [X11] Bugfix: `glfwWaitEvents` did not handle `EINTR` for `select`
- [X11] Bugfix: `glfwWaitEvents` could return when no events were available - [X11] Bugfix: `glfwWaitEvents` could return when no events were available
- [X11] Bugfix: `XkbGetKeyboard` fails on XWayland - [X11] Bugfix: `XkbGetKeyboard` fails on XWayland
- [X11] Bugfix: Character input did not work correctly for non-UTF-8 locales
- [WGL] Made all WGL functions dynamically loaded - [WGL] Made all WGL functions dynamically loaded
- [WGL] Removed `GLFW_USE_DWM_SWAP_INTERVAL` compile-time option - [WGL] Removed `GLFW_USE_DWM_SWAP_INTERVAL` compile-time option
- [WGL] Bugfix: Swap interval was ignored when DWM was enabled - [WGL] Bugfix: Swap interval was ignored when DWM was enabled

View File

@ -709,10 +709,12 @@ Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
int _glfwPlatformInit(void) int _glfwPlatformInit(void)
{ {
#if !defined(X_HAVE_UTF8_STRING)
// HACK: If the current locale is C, apply the environment's locale // HACK: If the current locale is C, apply the environment's locale
// This is done because the C locale breaks character input // This is done because the C locale breaks wide character input
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0) if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
#endif
XInitThreads(); XInitThreads();

View File

@ -37,6 +37,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
// Action for EWMH client messages // Action for EWMH client messages
#define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_REMOVE 0
@ -845,6 +846,31 @@ static void leaveFullscreenMode(_GLFWwindow* window)
} }
} }
// Decode a Unicode code point from a UTF-8 stream
// Based on cutef8 by Jeff Bezanson (Public Domain)
//
#if defined(X_HAVE_UTF8_STRING)
static unsigned int decodeUTF8(const char** s)
{
unsigned int ch = 0, count = 0;
static const unsigned int offsets[] =
{
0x00000000u, 0x00003080u, 0x000e2080u,
0x03c82080u, 0xfa082080u, 0x82082080u
};
do
{
ch = (ch << 6) + (unsigned char) **s;
(*s)++;
count++;
} while ((**s & 0xc0) == 0x80);
assert(count <= 6);
return ch - offsets[count - 1];
}
#endif /*X_HAVE_UTF8_STRING*/
// Process the specified X event // Process the specified X event
// //
static void processEvent(XEvent *event) static void processEvent(XEvent *event)
@ -895,6 +921,19 @@ static void processEvent(XEvent *event)
if (!filtered) if (!filtered)
{ {
#if defined(X_HAVE_UTF8_STRING)
Status status;
char buffer[96];
const char* c = buffer;
const int count = Xutf8LookupString(window->x11.ic,
&event->xkey,
buffer, sizeof(buffer),
NULL, &status);
while (c - buffer < count)
_glfwInputChar(window, decodeUTF8(&c), mods, plain);
#else
int i; int i;
Status status; Status status;
wchar_t buffer[16]; wchar_t buffer[16];
@ -906,6 +945,7 @@ static void processEvent(XEvent *event)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
_glfwInputChar(window, buffer[i], mods, plain); _glfwInputChar(window, buffer[i], mods, plain);
#endif
} }
} }
else else