Linux keyboard input fixup
							parent
							
								
									27da2172dc
								
							
						
					
					
						commit
						5e7e7bceba
					
				|  | @ -958,8 +958,7 @@ LinuxInputInit(Display *dpy, Window XWindow){ | |||
| // Keyboard handling funcs
 | ||||
| //
 | ||||
| 
 | ||||
| global Key_Code keycode_lookup_table[255]; | ||||
| 
 | ||||
| #if 0 | ||||
| internal void | ||||
| LinuxKeycodeInit(Display* dpy){ | ||||
|      | ||||
|  | @ -1018,7 +1017,9 @@ LinuxKeycodeInit(Display* dpy){ | |||
|      | ||||
|     KeySym* syms = XGetKeyboardMapping(dpy, key_min, key_count, &syms_per_code); | ||||
|      | ||||
|     if (!syms) return; | ||||
|     if (syms == 0){ | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     int key = key_min; | ||||
|     for(int i = 0; i < key_count * syms_per_code; ++i){ | ||||
|  | @ -1031,8 +1032,8 @@ LinuxKeycodeInit(Display* dpy){ | |||
|     } | ||||
|      | ||||
|     XFree(syms); | ||||
|      | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| internal void | ||||
| 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 | ||||
| LinuxHandleX11Events(void) | ||||
| { | ||||
|     static XEvent PrevEvent = {}; | ||||
|     static XEvent prev_event = {}; | ||||
|     b32 should_step = false; | ||||
|      | ||||
|     while (XPending(linuxvars.XDisplay)) | ||||
|     { | ||||
|         XEvent Event; | ||||
|         XNextEvent(linuxvars.XDisplay, &Event); | ||||
|         XEvent event; | ||||
|         XNextEvent(linuxvars.XDisplay, &event); | ||||
|          | ||||
|         if (XFilterEvent(&Event, None) == True){ | ||||
|         if (XFilterEvent(&event, None) == True){ | ||||
|             continue; | ||||
|         } | ||||
|          | ||||
|         switch (Event.type){ | ||||
|         switch (event.type){ | ||||
|             case KeyPress: { | ||||
|                 should_step = true; | ||||
|                  | ||||
|                 b32 is_hold = (PrevEvent.type         == KeyRelease && | ||||
|                                PrevEvent.xkey.time    == Event.xkey.time && | ||||
|                                PrevEvent.xkey.keycode == Event.xkey.keycode); | ||||
|                 b32 is_hold = (prev_event.type         == KeyRelease && | ||||
|                                prev_event.xkey.time    == event.xkey.time && | ||||
|                                prev_event.xkey.keycode == event.xkey.keycode); | ||||
|                  | ||||
|                 b8 mods[MDFR_INDEX_COUNT] = {}; | ||||
|                 mods[MDFR_HOLD_INDEX] = is_hold; | ||||
|                  | ||||
|                 if (Event.xkey.state & ShiftMask) mods[MDFR_SHIFT_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 & Mod1Mask) mods[MDFR_ALT_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 & LockMask) mods[MDFR_CAPS_INDEX] = 1; | ||||
|                 if (event.xkey.state & Mod1Mask) mods[MDFR_ALT_INDEX] = 1; | ||||
|                  | ||||
|                 Event.xkey.state &= ~(ControlMask); | ||||
|                 event.xkey.state &= ~(ControlMask); | ||||
|                  | ||||
|                 Status status; | ||||
|                 KeySym keysym = NoSymbol; | ||||
|                 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){ | ||||
|                     //TODO(inso): handle properly
 | ||||
|  | @ -1380,14 +1381,26 @@ LinuxHandleX11Events(void) | |||
|                     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_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}; | ||||
|                     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){ | ||||
|                         key_no_caps = utf8_to_u32_unchecked(buff_no_caps); | ||||
|  | @ -1397,17 +1410,156 @@ LinuxHandleX11Events(void) | |||
|                 if (key         == '\r') key         = '\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){ | ||||
|                     key = key_no_caps = '\t'; | ||||
|                     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){ | ||||
|                     LinuxPushKey(special_key, 0, 0, mods); | ||||
|  | @ -1424,13 +1576,13 @@ LinuxHandleX11Events(void) | |||
|              | ||||
|             case MotionNotify: { | ||||
|                 should_step = true; | ||||
|                 linuxvars.input.mouse.x = Event.xmotion.x; | ||||
|                 linuxvars.input.mouse.y = Event.xmotion.y; | ||||
|                 linuxvars.input.mouse.x = event.xmotion.x; | ||||
|                 linuxvars.input.mouse.y = event.xmotion.y; | ||||
|             }break; | ||||
|              | ||||
|             case ButtonPress: { | ||||
|                 should_step = true; | ||||
|                 switch(Event.xbutton.button){ | ||||
|                 switch(event.xbutton.button){ | ||||
|                     case Button1: { | ||||
|                         linuxvars.input.mouse.press_l = 1; | ||||
|                         linuxvars.input.mouse.l = 1; | ||||
|  | @ -1454,7 +1606,7 @@ LinuxHandleX11Events(void) | |||
|              | ||||
|             case ButtonRelease: { | ||||
|                 should_step = true; | ||||
|                 switch(Event.xbutton.button){ | ||||
|                 switch(event.xbutton.button){ | ||||
|                     case Button1: { | ||||
|                         linuxvars.input.mouse.release_l = 1; | ||||
|                         linuxvars.input.mouse.l = 0; | ||||
|  | @ -1485,8 +1637,8 @@ LinuxHandleX11Events(void) | |||
|              | ||||
|             case ConfigureNotify: { | ||||
|                 should_step = true; | ||||
|                 i32 w = Event.xconfigure.width; | ||||
|                 i32 h = Event.xconfigure.height; | ||||
|                 i32 w = event.xconfigure.width; | ||||
|                 i32 h = event.xconfigure.height; | ||||
|                  | ||||
|                 if (w != target.width || h != target.height){ | ||||
|                     LinuxResizeTarget(w, h); | ||||
|  | @ -1494,32 +1646,31 @@ LinuxHandleX11Events(void) | |||
|             }break; | ||||
|              | ||||
|             case MappingNotify: { | ||||
|                 if (Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){ | ||||
|                     XRefreshKeyboardMapping(&Event.xmapping); | ||||
|                     LinuxKeycodeInit(linuxvars.XDisplay); | ||||
|                 if (event.xmapping.request == MappingModifier || event.xmapping.request == MappingKeyboard){ | ||||
|                     XRefreshKeyboardMapping(&event.xmapping); | ||||
|                     //LinuxKeycodeInit(linuxvars.XDisplay);
 | ||||
|                 } | ||||
|             }break; | ||||
|              | ||||
|             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; | ||||
|                     linuxvars.keep_running = 0; | ||||
|                 } | ||||
|                 else if ((Atom)Event.xclient.data.l[0] == linuxvars.atom__NET_WM_PING) { | ||||
|                     Event.xclient.window = DefaultRootWindow(linuxvars.XDisplay); | ||||
|                 else if ((Atom)event.xclient.data.l[0] == linuxvars.atom__NET_WM_PING) { | ||||
|                     event.xclient.window = DefaultRootWindow(linuxvars.XDisplay); | ||||
|                     XSendEvent( | ||||
|                         linuxvars.XDisplay, | ||||
|                         Event.xclient.window, | ||||
|                         event.xclient.window, | ||||
|                         False, | ||||
|                         SubstructureRedirectMask | SubstructureNotifyMask, | ||||
|                         &Event | ||||
|                         ); | ||||
|                         &event); | ||||
|                 } | ||||
|             }break; | ||||
|              | ||||
|             // NOTE(inso): Someone wants us to give them the clipboard data.
 | ||||
|             case SelectionRequest: { | ||||
|                 XSelectionRequestEvent request = Event.xselectionrequest; | ||||
|                 XSelectionRequestEvent request = event.xselectionrequest; | ||||
|                  | ||||
|                 XSelectionEvent response = {}; | ||||
|                 response.type = SelectionNotify; | ||||
|  | @ -1584,14 +1735,14 @@ LinuxHandleX11Events(void) | |||
|              | ||||
|             // NOTE(inso): Another program is now the clipboard owner.
 | ||||
|             case SelectionClear: { | ||||
|                 if (Event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){ | ||||
|                 if (event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){ | ||||
|                     linuxvars.clipboard_outgoing.size = 0; | ||||
|                 } | ||||
|             }break; | ||||
|              | ||||
|             // NOTE(inso): A program is giving us the clipboard data we asked for.
 | ||||
|             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){ | ||||
|                     Atom type; | ||||
|                     int fmt; | ||||
|  | @ -1619,8 +1770,8 @@ LinuxHandleX11Events(void) | |||
|             }break; | ||||
|              | ||||
|             default: { | ||||
|                 if (Event.type == linuxvars.xfixes_selection_event){ | ||||
|                     XFixesSelectionNotifyEvent* sne = (XFixesSelectionNotifyEvent*)&Event; | ||||
|                 if (event.type == linuxvars.xfixes_selection_event){ | ||||
|                     XFixesSelectionNotifyEvent* sne = (XFixesSelectionNotifyEvent*)&event; | ||||
|                     if (sne->subtype == XFixesSelectionNotify && sne->owner != linuxvars.XWindow){ | ||||
|                         XConvertSelection(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime); | ||||
|                     } | ||||
|  | @ -1628,7 +1779,7 @@ LinuxHandleX11Events(void) | |||
|             }break; | ||||
|         } | ||||
|          | ||||
|         PrevEvent = Event; | ||||
|         prev_event = event; | ||||
|     } | ||||
|      | ||||
|     if (should_step){ | ||||
|  | @ -1771,7 +1922,7 @@ main(int argc, char **argv){ | |||
|     linuxvars.input_style = input_result.best_style; | ||||
|     linuxvars.input_context = input_result.xic; | ||||
|      | ||||
|     LinuxKeycodeInit(linuxvars.XDisplay); | ||||
|     //LinuxKeycodeInit(linuxvars.XDisplay);
 | ||||
|      | ||||
|     Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = { | ||||
|         None, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster