Linux keyboard input fixup
							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
	
	 Allen Webster
						Allen Webster