Linux: Added basic support for Xutf8LookupString, providing better support for international characters
This commit is contained in:
parent
8ae823dd4a
commit
78c086a01c
|
@ -44,6 +44,8 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <iconv.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "common_tools.h"
|
#include "common_tools.h"
|
||||||
#include "org_lwjgl_input_Keyboard.h"
|
#include "org_lwjgl_input_Keyboard.h"
|
||||||
|
@ -62,6 +64,11 @@ static bool buffer_enabled;
|
||||||
static bool translation_enabled;
|
static bool translation_enabled;
|
||||||
static bool created = false;
|
static bool created = false;
|
||||||
|
|
||||||
|
// X input manager values
|
||||||
|
static iconv_t iconv_descriptor;
|
||||||
|
static XIM xim = NULL;
|
||||||
|
static XIC xic = NULL;
|
||||||
|
|
||||||
static void grabKeyboard(void) {
|
static void grabKeyboard(void) {
|
||||||
if (!keyboard_grabbed) {
|
if (!keyboard_grabbed) {
|
||||||
int result = XGrabKeyboard(getDisplay(), getCurrentWindow(), False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
int result = XGrabKeyboard(getDisplay(), getCurrentWindow(), False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
@ -87,6 +94,19 @@ void updateKeyboardGrab(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void closeUnicodeStructs() {
|
||||||
|
if (iconv_descriptor != (iconv_t)-1)
|
||||||
|
iconv_close(iconv_descriptor);
|
||||||
|
if (xic != NULL) {
|
||||||
|
XDestroyIC(xic);
|
||||||
|
xic = NULL;
|
||||||
|
}
|
||||||
|
if (xim != NULL) {
|
||||||
|
XCloseIM(xim);
|
||||||
|
xim = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
|
@ -122,11 +142,25 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
||||||
buffer_enabled = false;
|
buffer_enabled = false;
|
||||||
initEventQueue(&event_queue, 3);
|
initEventQueue(&event_queue, 3);
|
||||||
updateKeyboardGrab();
|
updateKeyboardGrab();
|
||||||
|
|
||||||
|
// Allocate unicode structures
|
||||||
|
iconv_descriptor = iconv_open("UCS-2", "UTF-8");
|
||||||
|
if (iconv_descriptor != (iconv_t)-1) {
|
||||||
|
xim = XOpenIM(getDisplay(), NULL, NULL, NULL);
|
||||||
|
if (xim != NULL) {
|
||||||
|
xic = XCreateIC(xim, XNClientWindow, getCurrentWindow(), XNFocusWindow, getCurrentWindow(), XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
|
||||||
|
if (xic == NULL) {
|
||||||
|
closeUnicodeStructs();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
closeUnicodeStructs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
|
closeUnicodeStructs();
|
||||||
ungrabKeyboard();
|
ungrabKeyboard();
|
||||||
created = false;
|
created = false;
|
||||||
decDisplay();
|
decDisplay();
|
||||||
|
@ -143,9 +177,56 @@ static void putKeyboardEvent(jint keycode, jint state, jint ch) {
|
||||||
putEvent(&event_queue, event_list);
|
putEvent(&event_queue, event_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void translateEvent(XKeyEvent *event, jint keycode, jint state) {
|
static int lookupStringISO88591(XKeyEvent *event, jint *translation_buffer) {
|
||||||
static XComposeStatus status;
|
static XComposeStatus status;
|
||||||
char temp_translation_buffer[KEYBOARD_BUFFER_SIZE];
|
char char_translation_buffer[KEYBOARD_BUFFER_SIZE];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
int num_chars = XLookupString(event, char_translation_buffer, KEYBOARD_BUFFER_SIZE*sizeof(char), NULL, &status);
|
||||||
|
for (i = 0; i < num_chars; i++)
|
||||||
|
translation_buffer[i] = ((jint)char_translation_buffer[i]) & 0xff;
|
||||||
|
return num_chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lookupStringUnicode(XKeyEvent *event, jint *translation_buffer) {
|
||||||
|
char utf8_translation_buffer[KEYBOARD_BUFFER_SIZE];
|
||||||
|
jchar ucs2_translation_buffer[KEYBOARD_BUFFER_SIZE];
|
||||||
|
char *utf8_buf = utf8_translation_buffer;
|
||||||
|
jchar *ucs2_buf = ucs2_translation_buffer;
|
||||||
|
size_t ucs2_bytes = KEYBOARD_BUFFER_SIZE*sizeof(jchar);
|
||||||
|
Status status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
XSetICFocus(xic);
|
||||||
|
size_t utf8_bytes = Xutf8LookupString(xic, event, utf8_translation_buffer, KEYBOARD_BUFFER_SIZE*sizeof(char), NULL, &status);
|
||||||
|
if (status != XLookupChars && status != XLookupBoth)
|
||||||
|
return 0;
|
||||||
|
XUnsetICFocus(xic);
|
||||||
|
// reset converter
|
||||||
|
iconv(iconv_descriptor, NULL, NULL, NULL, NULL);
|
||||||
|
// convert from UTF-8 to UCS-2
|
||||||
|
size_t iconv_result = iconv(iconv_descriptor, &utf8_buf, &utf8_bytes, (void *)&ucs2_buf, &ucs2_bytes);
|
||||||
|
// compute number of characters converted
|
||||||
|
int num_chars_converted = KEYBOARD_BUFFER_SIZE - ucs2_bytes/sizeof(jchar);
|
||||||
|
if (iconv_result == (size_t)-1) {
|
||||||
|
errno = 0; // ignore conversion error and return no chars converted
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_chars_converted; i++) {
|
||||||
|
translation_buffer[i] = ((jint)ucs2_translation_buffer[i]) & 0xffff;
|
||||||
|
}
|
||||||
|
return num_chars_converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lookupString(XKeyEvent *event, jint *translation_buffer) {
|
||||||
|
if (xic != NULL) {
|
||||||
|
return lookupStringUnicode(event, translation_buffer);
|
||||||
|
} else
|
||||||
|
return lookupStringISO88591(event, translation_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void translateEvent(XKeyEvent *event, jint keycode, jint state) {
|
||||||
|
jint temp_translation_buffer[KEYBOARD_BUFFER_SIZE];
|
||||||
int num_chars, i;
|
int num_chars, i;
|
||||||
jint ch;
|
jint ch;
|
||||||
|
|
||||||
|
@ -153,12 +234,12 @@ static void translateEvent(XKeyEvent *event, jint keycode, jint state) {
|
||||||
putKeyboardEvent(keycode, state, 0);
|
putKeyboardEvent(keycode, state, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
num_chars = XLookupString(event, temp_translation_buffer, KEYBOARD_BUFFER_SIZE, NULL, &status);
|
num_chars = lookupString(event, temp_translation_buffer);
|
||||||
if (num_chars > 0) {
|
if (num_chars > 0) {
|
||||||
ch = ((jint)temp_translation_buffer[0]) & 0xFF;
|
ch = temp_translation_buffer[0];
|
||||||
putKeyboardEvent(keycode, state, ch);
|
putKeyboardEvent(keycode, state, ch);
|
||||||
for (i = 1; i < num_chars; i++) {
|
for (i = 1; i < num_chars; i++) {
|
||||||
ch = ((jint)temp_translation_buffer[i]) & 0xFF;
|
ch = temp_translation_buffer[i];
|
||||||
putKeyboardEvent(0, 0, ch);
|
putKeyboardEvent(0, 0, ch);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue