start linux keyboard stuff
parent
21625b646b
commit
1e7da9c06c
|
@ -82,6 +82,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/timerfd.h>
|
#include <sys/timerfd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
#define Cursor XCursor
|
#define Cursor XCursor
|
||||||
#undef function
|
#undef function
|
||||||
|
@ -90,6 +91,7 @@
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
#define function static
|
#define function static
|
||||||
#undef Cursor
|
#undef Cursor
|
||||||
|
|
||||||
|
@ -113,6 +115,29 @@
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
||||||
|
struct Linux_Input_Chunk_Transient {
|
||||||
|
Input_List event_list;
|
||||||
|
b8 mouse_l_press;
|
||||||
|
b8 mouse_l_release;
|
||||||
|
b8 mouse_r_press;
|
||||||
|
b8 mouse_r_release;
|
||||||
|
b8 out_of_window;
|
||||||
|
i8 mouse_wheel;
|
||||||
|
b8 trying_to_kill;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Linux_Input_Chunk_Persistent {
|
||||||
|
Vec2_i32 mouse;
|
||||||
|
Input_Modifier_Set_Fixed modifiers;
|
||||||
|
b8 mouse_l;
|
||||||
|
b8 mouse_r;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Linux_Input_Chunk {
|
||||||
|
Linux_Input_Chunk_Transient trans;
|
||||||
|
Linux_Input_Chunk_Persistent pers;
|
||||||
|
};
|
||||||
|
|
||||||
struct Linux_Vars {
|
struct Linux_Vars {
|
||||||
Thread_Context tctx;
|
Thread_Context tctx;
|
||||||
Arena *frame_arena;
|
Arena *frame_arena;
|
||||||
|
@ -125,7 +150,7 @@ struct Linux_Vars {
|
||||||
XIM xim;
|
XIM xim;
|
||||||
XIC xic;
|
XIC xic;
|
||||||
|
|
||||||
Application_Step_Input input;
|
Linux_Input_Chunk input;
|
||||||
|
|
||||||
int epoll;
|
int epoll;
|
||||||
int step_timer_fd;
|
int step_timer_fd;
|
||||||
|
@ -280,7 +305,7 @@ linux_system_get_file_list_filter(const struct dirent *dirent) {
|
||||||
|
|
||||||
internal int
|
internal int
|
||||||
linux_u64_from_timespec(const struct timespec timespec) {
|
linux_u64_from_timespec(const struct timespec timespec) {
|
||||||
return timespec.tv_nsec + 1000000000 * timespec.tv_sec;
|
return timespec.tv_nsec + UINT64_C(1000000000) * timespec.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal File_Attribute_Flag
|
internal File_Attribute_Flag
|
||||||
|
@ -841,10 +866,102 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
|
||||||
XSelectInput(linuxvars.dpy, linuxvars.win, event_mask);
|
XSelectInput(linuxvars.dpy, linuxvars.win, event_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global Key_Code keycode_lookup_table[255];
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
linux_keycode_init(Display* dpy){
|
||||||
|
|
||||||
|
struct SymCode { KeySym sym; Key_Code code; };
|
||||||
|
SymCode sym_table[100];
|
||||||
|
|
||||||
|
block_zero_array(sym_table);
|
||||||
|
block_zero_array(keycode_lookup_table);
|
||||||
|
|
||||||
|
SymCode* p = sym_table;
|
||||||
|
for(Key_Code k = KeyCode_A; k <= KeyCode_Z; ++k) {
|
||||||
|
*p++ = { XK_a + (k - KeyCode_A), k };
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Key_Code k = KeyCode_0; k <= KeyCode_9; ++k) {
|
||||||
|
*p++ = { XK_0 + (k - KeyCode_0), k };
|
||||||
|
}
|
||||||
|
|
||||||
|
*p++ = { XK_space, KeyCode_Space };
|
||||||
|
*p++ = { XK_grave, KeyCode_Tick };
|
||||||
|
*p++ = { XK_minus, KeyCode_Minus };
|
||||||
|
*p++ = { XK_equal, KeyCode_Equal };
|
||||||
|
*p++ = { XK_bracketleft, KeyCode_LeftBracket };
|
||||||
|
*p++ = { XK_bracketright, KeyCode_RightBracket };
|
||||||
|
*p++ = { XK_bracketright, KeyCode_RightBracket };
|
||||||
|
*p++ = { XK_semicolon, KeyCode_Semicolon };
|
||||||
|
*p++ = { XK_apostrophe, KeyCode_Quote };
|
||||||
|
*p++ = { XK_comma, KeyCode_Comma };
|
||||||
|
*p++ = { XK_period, KeyCode_Period };
|
||||||
|
*p++ = { XK_slash, KeyCode_ForwardSlash };
|
||||||
|
*p++ = { XK_backslash, KeyCode_BackwardSlash };
|
||||||
|
*p++ = { XK_Tab, KeyCode_Tab };
|
||||||
|
*p++ = { XK_Escape, KeyCode_Escape };
|
||||||
|
*p++ = { XK_Pause, KeyCode_Pause };
|
||||||
|
*p++ = { XK_Up, KeyCode_Up };
|
||||||
|
*p++ = { XK_Down, KeyCode_Down };
|
||||||
|
*p++ = { XK_Left, KeyCode_Left };
|
||||||
|
*p++ = { XK_Right, KeyCode_Right };
|
||||||
|
*p++ = { XK_BackSpace, KeyCode_Backspace };
|
||||||
|
*p++ = { XK_Return, KeyCode_Return };
|
||||||
|
*p++ = { XK_Delete, KeyCode_Delete };
|
||||||
|
*p++ = { XK_Insert, KeyCode_Insert };
|
||||||
|
*p++ = { XK_Home, KeyCode_Home };
|
||||||
|
*p++ = { XK_End, KeyCode_End };
|
||||||
|
*p++ = { XK_Page_Up, KeyCode_PageUp };
|
||||||
|
*p++ = { XK_Page_Down, KeyCode_PageDown };
|
||||||
|
*p++ = { XK_Caps_Lock, KeyCode_CapsLock };
|
||||||
|
*p++ = { XK_Num_Lock, KeyCode_NumLock };
|
||||||
|
*p++ = { XK_Scroll_Lock, KeyCode_ScrollLock };
|
||||||
|
*p++ = { XK_Menu, KeyCode_Menu };
|
||||||
|
*p++ = { XK_Shift_L, KeyCode_Shift };
|
||||||
|
*p++ = { XK_Shift_R, KeyCode_Shift };
|
||||||
|
*p++ = { XK_Control_L, KeyCode_Control };
|
||||||
|
*p++ = { XK_Control_R, KeyCode_Control };
|
||||||
|
*p++ = { XK_Alt_L, KeyCode_Alt };
|
||||||
|
*p++ = { XK_Alt_R, KeyCode_Alt };
|
||||||
|
*p++ = { XK_Super_L, KeyCode_Command };
|
||||||
|
*p++ = { XK_Super_R, KeyCode_Command };
|
||||||
|
|
||||||
|
for(Key_Code k = KeyCode_F1; k <= KeyCode_F16; ++k) {
|
||||||
|
*p++ = { XK_F1 + (k - KeyCode_F1), k };
|
||||||
|
}
|
||||||
|
|
||||||
|
const int table_size = p - sym_table;
|
||||||
|
Assert(table_size < ArrayCount(sym_table));
|
||||||
|
|
||||||
|
int key_min, key_max, syms_per_code;
|
||||||
|
XDisplayKeycodes(dpy, &key_min, &key_max);
|
||||||
|
|
||||||
|
int key_count = (key_max - key_min) + 1;
|
||||||
|
KeySym* syms = XGetKeyboardMapping(dpy, key_min, key_count, &syms_per_code);
|
||||||
|
|
||||||
|
if (syms == 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int key = key_min;
|
||||||
|
for(int i = 0; i < key_count * syms_per_code; ++i){
|
||||||
|
for(int j = 0; j < table_size; ++j){
|
||||||
|
if (sym_table[j].sym == syms[i]){
|
||||||
|
keycode_lookup_table[key + (i/syms_per_code)] = sym_table[j].code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(syms);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
linux_handle_x11_events() {
|
linux_handle_x11_events() {
|
||||||
static XEvent prev_event = {};
|
static XEvent prev_event = {};
|
||||||
b32 should_step = false;
|
b32 should_step = false;
|
||||||
|
|
||||||
while (XPending(linuxvars.dpy)) {
|
while (XPending(linuxvars.dpy)) {
|
||||||
XEvent event;
|
XEvent event;
|
||||||
XNextEvent(linuxvars.dpy, &event);
|
XNextEvent(linuxvars.dpy, &event);
|
||||||
|
@ -854,6 +971,58 @@ linux_handle_x11_events() {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
|
case KeyPress: {
|
||||||
|
should_step = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
b32 is_hold = (prev_event.type == KeyRelease &&
|
||||||
|
prev_event.xkey.time == event.xkey.time &&
|
||||||
|
prev_event.xkey.keycode == event.xkey.keycode);
|
||||||
|
*/
|
||||||
|
|
||||||
|
Input_Modifier_Set_Fixed* mods = &linuxvars.input.pers.modifiers;
|
||||||
|
block_zero_struct(mods);
|
||||||
|
|
||||||
|
int state = event.xkey.state;
|
||||||
|
set_modifier(mods, KeyCode_Shift, state & ShiftMask);
|
||||||
|
set_modifier(mods, KeyCode_Control, state & ControlMask);
|
||||||
|
set_modifier(mods, KeyCode_CapsLock, state & LockMask);
|
||||||
|
set_modifier(mods, KeyCode_Alt, state & Mod1Mask);
|
||||||
|
|
||||||
|
event.xkey.state &= ~(ControlMask);
|
||||||
|
|
||||||
|
Status status;
|
||||||
|
KeySym keysym = NoSymbol;
|
||||||
|
u8 buff[32] = {};
|
||||||
|
|
||||||
|
Xutf8LookupString(linuxvars.xic, &event.xkey, (char*)buff, sizeof(buff) - 1, &keysym, &status);
|
||||||
|
|
||||||
|
if (status == XBufferOverflow){
|
||||||
|
//TODO(inso): handle properly
|
||||||
|
Xutf8ResetIC(linuxvars.xic);
|
||||||
|
XSetICFocus(linuxvars.xic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't push modifiers
|
||||||
|
if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysym == XK_ISO_Left_Tab){
|
||||||
|
//text = '\t';
|
||||||
|
add_modifier(mods, KeyCode_Shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use keycode_lookup_table, push the key and text.
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MappingNotify: {
|
||||||
|
if (event.xmapping.request == MappingModifier || event.xmapping.request == MappingKeyboard){
|
||||||
|
XRefreshKeyboardMapping(&event.xmapping);
|
||||||
|
linux_keycode_init(linuxvars.dpy);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1043,6 +1212,7 @@ main(int argc, char **argv){
|
||||||
}
|
}
|
||||||
|
|
||||||
linux_x11_init(argc, argv, &plat_settings);
|
linux_x11_init(argc, argv, &plat_settings);
|
||||||
|
linux_keycode_init(linuxvars.dpy);
|
||||||
|
|
||||||
// TODO(inso): move to x11 init?
|
// TODO(inso): move to x11 init?
|
||||||
XCursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
|
XCursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
|
||||||
|
@ -1127,15 +1297,14 @@ main(int argc, char **argv){
|
||||||
XConvertSelection(linuxvars.dpy, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.win, CurrentTime);
|
XConvertSelection(linuxvars.dpy, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.win, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application_Step_Input frame_input = {};
|
||||||
|
|
||||||
if (linuxvars.received_new_clipboard){
|
if (linuxvars.received_new_clipboard){
|
||||||
linuxvars.input.clipboard = linuxvars.clipboard_contents;
|
frame_input.clipboard = linuxvars.clipboard_contents;
|
||||||
linuxvars.received_new_clipboard = false;
|
linuxvars.received_new_clipboard = false;
|
||||||
} else {
|
|
||||||
linuxvars.input.clipboard = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Application_Step_Input frame_input = linuxvars.input;
|
// TODO: fill the rest of it
|
||||||
// TODO:
|
|
||||||
frame_input.trying_to_kill = !keep_running;
|
frame_input.trying_to_kill = !keep_running;
|
||||||
|
|
||||||
// NOTE(allen): Application Core Update
|
// NOTE(allen): Application Core Update
|
||||||
|
@ -1165,7 +1334,7 @@ main(int argc, char **argv){
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(allen): Switch to New Cursor
|
// NOTE(allen): Switch to New Cursor
|
||||||
if (result.mouse_cursor_type != linuxvars.cursor && !linuxvars.input.mouse.l){
|
if (result.mouse_cursor_type != linuxvars.cursor && !linuxvars.input.pers.mouse_l){
|
||||||
XCursor c = xcursors[result.mouse_cursor_type];
|
XCursor c = xcursors[result.mouse_cursor_type];
|
||||||
if (linuxvars.cursor_show){
|
if (linuxvars.cursor_show){
|
||||||
XDefineCursor(linuxvars.dpy, linuxvars.win, c);
|
XDefineCursor(linuxvars.dpy, linuxvars.win, c);
|
||||||
|
|
|
@ -231,7 +231,7 @@ system_wake_up_timer_set(Plat_Handle handle, u32 time_milliseconds){
|
||||||
|
|
||||||
struct itimerspec it = {};
|
struct itimerspec it = {};
|
||||||
it.it_value.tv_sec = time_milliseconds / 1000;
|
it.it_value.tv_sec = time_milliseconds / 1000;
|
||||||
it.it_value.tv_nsec = (time_milliseconds % 1000) * 1000000UL;
|
it.it_value.tv_nsec = (time_milliseconds % 1000) * UINT64_C(1000000);
|
||||||
|
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
|
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
|
||||||
|
@ -449,13 +449,9 @@ system_thread_free(System_Thread thread){
|
||||||
|
|
||||||
internal i32
|
internal i32
|
||||||
system_thread_get_id(void){
|
system_thread_get_id(void){
|
||||||
LINUX_FN_DEBUG();
|
pid_t id = syscall(__NR_gettid);
|
||||||
pthread_t tid = pthread_self();
|
LINUX_FN_DEBUG("%d", id);
|
||||||
|
return id;
|
||||||
// WELP hope it doesn't collide
|
|
||||||
i32 shorter_id = ((u64)tid >> 32) ^ ((u32)tid & bitmask_32);
|
|
||||||
|
|
||||||
return shorter_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
Loading…
Reference in New Issue