Linux: Added basic support for Xutf8LookupString, providing better support for international characters

This commit is contained in:
Elias Naur 2004-10-16 21:59:20 +00:00
parent 8ae823dd4a
commit 78c086a01c
1 changed files with 86 additions and 5 deletions

View File

@ -44,6 +44,8 @@
#include <X11/Xutil.h>
#include <string.h>
#include <assert.h>
#include <iconv.h>
#include <errno.h>
#include "Window.h"
#include "common_tools.h"
#include "org_lwjgl_input_Keyboard.h"
@ -62,6 +64,11 @@ static bool buffer_enabled;
static bool translation_enabled;
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) {
if (!keyboard_grabbed) {
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
(JNIEnv * env, jclass clazz)
{
@ -122,11 +142,25 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate
buffer_enabled = false;
initEventQueue(&event_queue, 3);
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
(JNIEnv * env, jclass clazz)
{
closeUnicodeStructs();
ungrabKeyboard();
created = false;
decDisplay();
@ -143,9 +177,56 @@ static void putKeyboardEvent(jint keycode, jint state, jint ch) {
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;
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;
jint ch;
@ -153,12 +234,12 @@ static void translateEvent(XKeyEvent *event, jint keycode, jint state) {
putKeyboardEvent(keycode, state, 0);
return;
}
num_chars = XLookupString(event, temp_translation_buffer, KEYBOARD_BUFFER_SIZE, NULL, &status);
num_chars = lookupString(event, temp_translation_buffer);
if (num_chars > 0) {
ch = ((jint)temp_translation_buffer[0]) & 0xFF;
ch = temp_translation_buffer[0];
putKeyboardEvent(keycode, state, ch);
for (i = 1; i < num_chars; i++) {
ch = ((jint)temp_translation_buffer[i]) & 0xFF;
ch = temp_translation_buffer[i];
putKeyboardEvent(0, 0, ch);
}
} else {