Linux keyboard input fixup
This commit is contained in:
parent
27da2172dc
commit
5e7e7bceba
|
@ -958,8 +958,7 @@ LinuxInputInit(Display *dpy, Window XWindow){
|
||||||
// Keyboard handling funcs
|
// Keyboard handling funcs
|
||||||
//
|
//
|
||||||
|
|
||||||
global Key_Code keycode_lookup_table[255];
|
#if 0
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
LinuxKeycodeInit(Display* dpy){
|
LinuxKeycodeInit(Display* dpy){
|
||||||
|
|
||||||
|
@ -1018,7 +1017,9 @@ LinuxKeycodeInit(Display* dpy){
|
||||||
|
|
||||||
KeySym* syms = XGetKeyboardMapping(dpy, key_min, key_count, &syms_per_code);
|
KeySym* syms = XGetKeyboardMapping(dpy, key_min, key_count, &syms_per_code);
|
||||||
|
|
||||||
if (!syms) return;
|
if (syms == 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int key = key_min;
|
int key = key_min;
|
||||||
for(int i = 0; i < key_count * syms_per_code; ++i){
|
for(int i = 0; i < key_count * syms_per_code; ++i){
|
||||||
|
@ -1031,8 +1032,8 @@ LinuxKeycodeInit(Display* dpy){
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree(syms);
|
XFree(syms);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
LinuxPushKey(Key_Code code, Key_Code chr, Key_Code chr_nocaps, b8 *mods)
|
LinuxPushKey(Key_Code code, Key_Code chr, Key_Code chr_nocaps, b8 *mods)
|
||||||
|
@ -1337,41 +1338,41 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
|
||||||
internal void
|
internal void
|
||||||
LinuxHandleX11Events(void)
|
LinuxHandleX11Events(void)
|
||||||
{
|
{
|
||||||
static XEvent PrevEvent = {};
|
static XEvent prev_event = {};
|
||||||
b32 should_step = false;
|
b32 should_step = false;
|
||||||
|
|
||||||
while (XPending(linuxvars.XDisplay))
|
while (XPending(linuxvars.XDisplay))
|
||||||
{
|
{
|
||||||
XEvent Event;
|
XEvent event;
|
||||||
XNextEvent(linuxvars.XDisplay, &Event);
|
XNextEvent(linuxvars.XDisplay, &event);
|
||||||
|
|
||||||
if (XFilterEvent(&Event, None) == True){
|
if (XFilterEvent(&event, None) == True){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Event.type){
|
switch (event.type){
|
||||||
case KeyPress: {
|
case KeyPress: {
|
||||||
should_step = true;
|
should_step = true;
|
||||||
|
|
||||||
b32 is_hold = (PrevEvent.type == KeyRelease &&
|
b32 is_hold = (prev_event.type == KeyRelease &&
|
||||||
PrevEvent.xkey.time == Event.xkey.time &&
|
prev_event.xkey.time == event.xkey.time &&
|
||||||
PrevEvent.xkey.keycode == Event.xkey.keycode);
|
prev_event.xkey.keycode == event.xkey.keycode);
|
||||||
|
|
||||||
b8 mods[MDFR_INDEX_COUNT] = {};
|
b8 mods[MDFR_INDEX_COUNT] = {};
|
||||||
mods[MDFR_HOLD_INDEX] = is_hold;
|
mods[MDFR_HOLD_INDEX] = is_hold;
|
||||||
|
|
||||||
if (Event.xkey.state & ShiftMask) mods[MDFR_SHIFT_INDEX] = 1;
|
if (event.xkey.state & ShiftMask) mods[MDFR_SHIFT_INDEX] = 1;
|
||||||
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;
|
||||||
|
|
||||||
Event.xkey.state &= ~(ControlMask);
|
event.xkey.state &= ~(ControlMask);
|
||||||
|
|
||||||
Status status;
|
Status status;
|
||||||
KeySym keysym = NoSymbol;
|
KeySym keysym = NoSymbol;
|
||||||
u8 buff[32] = {};
|
u8 buff[32] = {};
|
||||||
|
|
||||||
Xutf8LookupString(linuxvars.input_context, &Event.xkey, (char*)buff, sizeof(buff) - 1, &keysym, &status);
|
Xutf8LookupString(linuxvars.input_context, &event.xkey, (char*)buff, sizeof(buff) - 1, &keysym, &status);
|
||||||
|
|
||||||
if (status == XBufferOverflow){
|
if (status == XBufferOverflow){
|
||||||
//TODO(inso): handle properly
|
//TODO(inso): handle properly
|
||||||
|
@ -1380,14 +1381,26 @@ LinuxHandleX11Events(void)
|
||||||
LOG("FIXME: XBufferOverflow from LookupString.\n");
|
LOG("FIXME: XBufferOverflow from LookupString.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't push modifiers
|
||||||
|
if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
u32 key = utf8_to_u32_unchecked(buff);
|
u32 key = utf8_to_u32_unchecked(buff);
|
||||||
u32 key_no_caps = key;
|
u32 key_no_caps = key;
|
||||||
|
|
||||||
if (mods[MDFR_CAPS_INDEX] && status == XLookupBoth && Event.xkey.keycode){
|
if (mods[MDFR_CAPS_INDEX] && status == XLookupBoth && event.xkey.keycode){
|
||||||
u8 buff_no_caps[32] = {0};
|
u8 buff_no_caps[32] = {0};
|
||||||
Event.xkey.state &= ~(LockMask);
|
event.xkey.state &= ~(LockMask);
|
||||||
|
|
||||||
XLookupString(&Event.xkey, (char*)buff_no_caps, sizeof(buff_no_caps) - 1, NULL, NULL);
|
Xutf8LookupString(linuxvars.input_context, &event.xkey, (char*)buff_no_caps, sizeof(buff_no_caps) - 1, NULL, &status);
|
||||||
|
|
||||||
|
if (status == XBufferOverflow){
|
||||||
|
//TODO(inso): handle properly
|
||||||
|
Xutf8ResetIC(linuxvars.input_context);
|
||||||
|
XSetICFocus(linuxvars.input_context);
|
||||||
|
LOG("FIXME: XBufferOverflow from LookupString.\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (*buff_no_caps){
|
if (*buff_no_caps){
|
||||||
key_no_caps = utf8_to_u32_unchecked(buff_no_caps);
|
key_no_caps = utf8_to_u32_unchecked(buff_no_caps);
|
||||||
|
@ -1397,17 +1410,156 @@ LinuxHandleX11Events(void)
|
||||||
if (key == '\r') key = '\n';
|
if (key == '\r') key = '\n';
|
||||||
if (key_no_caps == '\r') key_no_caps = '\n';
|
if (key_no_caps == '\r') key_no_caps = '\n';
|
||||||
|
|
||||||
// don't push modifiers
|
|
||||||
if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keysym == XK_ISO_Left_Tab){
|
if (keysym == XK_ISO_Left_Tab){
|
||||||
key = key_no_caps = '\t';
|
key = key_no_caps = '\t';
|
||||||
mods[MDFR_SHIFT_INDEX] = 1;
|
mods[MDFR_SHIFT_INDEX] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key_Code special_key = keycode_lookup_table[(u8)Event.xkey.keycode];
|
//Key_Code special_key = keycode_lookup_table[keysym];
|
||||||
|
|
||||||
|
Key_Code special_key = 0;
|
||||||
|
switch (keysym){
|
||||||
|
case XK_BackSpace:
|
||||||
|
{
|
||||||
|
special_key = key_back;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Delete:
|
||||||
|
{
|
||||||
|
special_key = key_del;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Up:
|
||||||
|
{
|
||||||
|
special_key = key_up;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Down:
|
||||||
|
{
|
||||||
|
special_key = key_down;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Left:
|
||||||
|
{
|
||||||
|
special_key = key_left;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Right:
|
||||||
|
{
|
||||||
|
special_key = key_right;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Insert:
|
||||||
|
{
|
||||||
|
special_key = key_insert;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Home:
|
||||||
|
{
|
||||||
|
special_key = key_home;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_End:
|
||||||
|
{
|
||||||
|
special_key = key_end;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Page_Up:
|
||||||
|
{
|
||||||
|
special_key = key_page_up;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Page_Down:
|
||||||
|
{
|
||||||
|
special_key = key_page_down;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_Escape:
|
||||||
|
{
|
||||||
|
special_key = key_esc;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F1:
|
||||||
|
{
|
||||||
|
special_key = key_f1;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F2:
|
||||||
|
{
|
||||||
|
special_key = key_f2;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F3:
|
||||||
|
{
|
||||||
|
special_key = key_f3;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F4:
|
||||||
|
{
|
||||||
|
special_key = key_f4;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F5:
|
||||||
|
{
|
||||||
|
special_key = key_f5;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F6:
|
||||||
|
{
|
||||||
|
special_key = key_f6;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F7:
|
||||||
|
{
|
||||||
|
special_key = key_f7;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F8:
|
||||||
|
{
|
||||||
|
special_key = key_f8;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F9:
|
||||||
|
{
|
||||||
|
special_key = key_f9;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F10:
|
||||||
|
{
|
||||||
|
special_key = key_f10;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F11:
|
||||||
|
{
|
||||||
|
special_key = key_f11;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F12:
|
||||||
|
{
|
||||||
|
special_key = key_f12;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F13:
|
||||||
|
{
|
||||||
|
special_key = key_f13;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F14:
|
||||||
|
{
|
||||||
|
special_key = key_f14;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F15:
|
||||||
|
{
|
||||||
|
special_key = key_f15;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case XK_F16:
|
||||||
|
{
|
||||||
|
special_key = key_f16;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (special_key){
|
if (special_key){
|
||||||
LinuxPushKey(special_key, 0, 0, mods);
|
LinuxPushKey(special_key, 0, 0, mods);
|
||||||
|
@ -1424,13 +1576,13 @@ LinuxHandleX11Events(void)
|
||||||
|
|
||||||
case MotionNotify: {
|
case MotionNotify: {
|
||||||
should_step = true;
|
should_step = true;
|
||||||
linuxvars.input.mouse.x = Event.xmotion.x;
|
linuxvars.input.mouse.x = event.xmotion.x;
|
||||||
linuxvars.input.mouse.y = Event.xmotion.y;
|
linuxvars.input.mouse.y = event.xmotion.y;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case ButtonPress: {
|
case ButtonPress: {
|
||||||
should_step = true;
|
should_step = true;
|
||||||
switch(Event.xbutton.button){
|
switch(event.xbutton.button){
|
||||||
case Button1: {
|
case Button1: {
|
||||||
linuxvars.input.mouse.press_l = 1;
|
linuxvars.input.mouse.press_l = 1;
|
||||||
linuxvars.input.mouse.l = 1;
|
linuxvars.input.mouse.l = 1;
|
||||||
|
@ -1454,7 +1606,7 @@ LinuxHandleX11Events(void)
|
||||||
|
|
||||||
case ButtonRelease: {
|
case ButtonRelease: {
|
||||||
should_step = true;
|
should_step = true;
|
||||||
switch(Event.xbutton.button){
|
switch(event.xbutton.button){
|
||||||
case Button1: {
|
case Button1: {
|
||||||
linuxvars.input.mouse.release_l = 1;
|
linuxvars.input.mouse.release_l = 1;
|
||||||
linuxvars.input.mouse.l = 0;
|
linuxvars.input.mouse.l = 0;
|
||||||
|
@ -1485,8 +1637,8 @@ LinuxHandleX11Events(void)
|
||||||
|
|
||||||
case ConfigureNotify: {
|
case ConfigureNotify: {
|
||||||
should_step = true;
|
should_step = true;
|
||||||
i32 w = Event.xconfigure.width;
|
i32 w = event.xconfigure.width;
|
||||||
i32 h = Event.xconfigure.height;
|
i32 h = event.xconfigure.height;
|
||||||
|
|
||||||
if (w != target.width || h != target.height){
|
if (w != target.width || h != target.height){
|
||||||
LinuxResizeTarget(w, h);
|
LinuxResizeTarget(w, h);
|
||||||
|
@ -1494,32 +1646,31 @@ LinuxHandleX11Events(void)
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case MappingNotify: {
|
case MappingNotify: {
|
||||||
if (Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){
|
if (event.xmapping.request == MappingModifier || event.xmapping.request == MappingKeyboard){
|
||||||
XRefreshKeyboardMapping(&Event.xmapping);
|
XRefreshKeyboardMapping(&event.xmapping);
|
||||||
LinuxKeycodeInit(linuxvars.XDisplay);
|
//LinuxKeycodeInit(linuxvars.XDisplay);
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case ClientMessage: {
|
case ClientMessage: {
|
||||||
if ((Atom)Event.xclient.data.l[0] == linuxvars.atom_WM_DELETE_WINDOW) {
|
if ((Atom)event.xclient.data.l[0] == linuxvars.atom_WM_DELETE_WINDOW) {
|
||||||
should_step = true;
|
should_step = true;
|
||||||
linuxvars.keep_running = 0;
|
linuxvars.keep_running = 0;
|
||||||
}
|
}
|
||||||
else if ((Atom)Event.xclient.data.l[0] == linuxvars.atom__NET_WM_PING) {
|
else if ((Atom)event.xclient.data.l[0] == linuxvars.atom__NET_WM_PING) {
|
||||||
Event.xclient.window = DefaultRootWindow(linuxvars.XDisplay);
|
event.xclient.window = DefaultRootWindow(linuxvars.XDisplay);
|
||||||
XSendEvent(
|
XSendEvent(
|
||||||
linuxvars.XDisplay,
|
linuxvars.XDisplay,
|
||||||
Event.xclient.window,
|
event.xclient.window,
|
||||||
False,
|
False,
|
||||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||||
&Event
|
&event);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
// NOTE(inso): Someone wants us to give them the clipboard data.
|
// NOTE(inso): Someone wants us to give them the clipboard data.
|
||||||
case SelectionRequest: {
|
case SelectionRequest: {
|
||||||
XSelectionRequestEvent request = Event.xselectionrequest;
|
XSelectionRequestEvent request = event.xselectionrequest;
|
||||||
|
|
||||||
XSelectionEvent response = {};
|
XSelectionEvent response = {};
|
||||||
response.type = SelectionNotify;
|
response.type = SelectionNotify;
|
||||||
|
@ -1584,14 +1735,14 @@ LinuxHandleX11Events(void)
|
||||||
|
|
||||||
// NOTE(inso): Another program is now the clipboard owner.
|
// NOTE(inso): Another program is now the clipboard owner.
|
||||||
case SelectionClear: {
|
case SelectionClear: {
|
||||||
if (Event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){
|
if (event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){
|
||||||
linuxvars.clipboard_outgoing.size = 0;
|
linuxvars.clipboard_outgoing.size = 0;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
// NOTE(inso): A program is giving us the clipboard data we asked for.
|
// NOTE(inso): A program is giving us the clipboard data we asked for.
|
||||||
case SelectionNotify: {
|
case SelectionNotify: {
|
||||||
XSelectionEvent* e = (XSelectionEvent*)&Event;
|
XSelectionEvent* e = (XSelectionEvent*)&event;
|
||||||
if (e->selection == linuxvars.atom_CLIPBOARD && e->target == linuxvars.atom_UTF8_STRING && e->property != None){
|
if (e->selection == linuxvars.atom_CLIPBOARD && e->target == linuxvars.atom_UTF8_STRING && e->property != None){
|
||||||
Atom type;
|
Atom type;
|
||||||
int fmt;
|
int fmt;
|
||||||
|
@ -1619,8 +1770,8 @@ LinuxHandleX11Events(void)
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
if (Event.type == linuxvars.xfixes_selection_event){
|
if (event.type == linuxvars.xfixes_selection_event){
|
||||||
XFixesSelectionNotifyEvent* sne = (XFixesSelectionNotifyEvent*)&Event;
|
XFixesSelectionNotifyEvent* sne = (XFixesSelectionNotifyEvent*)&event;
|
||||||
if (sne->subtype == XFixesSelectionNotify && sne->owner != linuxvars.XWindow){
|
if (sne->subtype == XFixesSelectionNotify && sne->owner != linuxvars.XWindow){
|
||||||
XConvertSelection(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
|
XConvertSelection(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
|
||||||
}
|
}
|
||||||
|
@ -1628,7 +1779,7 @@ LinuxHandleX11Events(void)
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrevEvent = Event;
|
prev_event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_step){
|
if (should_step){
|
||||||
|
@ -1771,7 +1922,7 @@ main(int argc, char **argv){
|
||||||
linuxvars.input_style = input_result.best_style;
|
linuxvars.input_style = input_result.best_style;
|
||||||
linuxvars.input_context = input_result.xic;
|
linuxvars.input_context = input_result.xic;
|
||||||
|
|
||||||
LinuxKeycodeInit(linuxvars.XDisplay);
|
//LinuxKeycodeInit(linuxvars.XDisplay);
|
||||||
|
|
||||||
Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
|
Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
|
||||||
None,
|
None,
|
||||||
|
|
Loading…
Reference in New Issue