|
|
|
@ -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); |
|
|
|
|