linux: change key handling code

it should work better with dead-key sequences now
master
insofaras 2016-05-08 00:01:47 +01:00
parent 353d08fa2b
commit ad6645295b
2 changed files with 46 additions and 24 deletions

View File

@ -2,7 +2,7 @@ CPP_FILES := $(wildcard *.cpp) $(wildcard **/*.cpp)
H_FILES := $(wildcard *.h) $(wildcard **/*.h) H_FILES := $(wildcard *.h) $(wildcard **/*.h)
WARNINGS := -Wno-write-strings WARNINGS := -Wno-write-strings
PLAT_LINKS := -L/usr/local/lib -lX11 -lpthread -lm -lrt -lGL -ldl -lXfixes PLAT_LINKS := -L/usr/local/lib -lX11 -lpthread -lm -lrt -lGL -ldl -lXfixes
FLAGS := -fPIC -fno-threadsafe-statics -pthread -I../foreign -g FLAGS := -fPIC -fno-threadsafe-statics -pthread -I../foreign -g -O0
all: ../4ed_app.so ../4ed all: ../4ed_app.so ../4ed

View File

@ -1761,43 +1761,65 @@ LinuxHandleX11Events(void)
if(Event.xkey.state & ControlMask) mods[MDFR_CONTROL_INDEX] = 1; if(Event.xkey.state & ControlMask) mods[MDFR_CONTROL_INDEX] = 1;
if(Event.xkey.state & LockMask) mods[MDFR_CAPS_INDEX] = 1; if(Event.xkey.state & LockMask) mods[MDFR_CAPS_INDEX] = 1;
if(Event.xkey.state & Mod1Mask) mods[MDFR_ALT_INDEX] = 1; if(Event.xkey.state & Mod1Mask) mods[MDFR_ALT_INDEX] = 1;
// NOTE(inso): mod5 == AltGr
// if(Event.xkey.state & Mod5Mask) mods[MDFR_ALT_INDEX] = 1;
KeySym keysym = NoSymbol;
char buff[32], no_caps_buff[32];
// NOTE(inso): Turn ControlMask off like the win32 code does.
if(mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]){
Event.xkey.state &= ~(ControlMask); Event.xkey.state &= ~(ControlMask);
Status status;
KeySym keysym = NoSymbol;
char buff[32] = {};
Xutf8LookupString(
linuxvars.input_context,
&Event.xkey,
buff,
sizeof(buff) - 1,
&keysym,
&status
);
if(status == XBufferOverflow){
//TODO(inso): handle properly
Xutf8ResetIC(linuxvars.input_context);
XSetICFocus(linuxvars.input_context);
fputs("FIXME: XBufferOverflow from LookupString.\n", stderr);
} }
// TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars u8 key = *buff, key_no_caps = key;
XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
Event.xkey.state &= ~LockMask; if(mods[MDFR_CAPS_INDEX] && status == XLookupBoth && Event.xkey.keycode){
XLookupString(&Event.xkey, no_caps_buff, sizeof(no_caps_buff), NULL, NULL); char buff_no_caps[32] = {};
Event.xkey.state &= ~(LockMask);
XLookupString(
&Event.xkey,
buff_no_caps,
sizeof(buff_no_caps) - 1,
NULL,
NULL
);
if(*buff_no_caps){
key_no_caps = *buff_no_caps;
}
}
if(key == '\r') key = '\n';
if(key_no_caps == '\r') key_no_caps = '\n';
if(keysym == XK_ISO_Left_Tab){ if(keysym == XK_ISO_Left_Tab){
*buff = *no_caps_buff = '\t'; key = key_no_caps = '\t';
mods[MDFR_SHIFT_INDEX] = 1; mods[MDFR_SHIFT_INDEX] = 1;
} }
u8 key = keycode_lookup(Event.xkey.keycode); u8 special_key = keycode_lookup(Event.xkey.keycode);
if(key){ if(special_key){
LinuxPushKey(key, 0, 0, &mods, is_hold); LinuxPushKey(special_key, 0, 0, &mods, is_hold);
} else { } else if(key < 128){
key = buff[0] & 0xFF; LinuxPushKey(key, key, key_no_caps, &mods, is_hold);
if(key < 128){
u8 no_caps_key = no_caps_buff[0] & 0xFF;
if(key == '\r') key = '\n';
if(no_caps_key == '\r') no_caps_key = '\n';
LinuxPushKey(key, key, no_caps_key, &mods, is_hold);
} else { } else {
LinuxPushKey(0, 0, 0, &mods, is_hold); LinuxPushKey(0, 0, 0, &mods, is_hold);
} }
}
}break; }break;
case KeyRelease: { case KeyRelease: {