linux input handling improvements
This commit is contained in:
parent
73b964c3ea
commit
d1e86d78bb
|
@ -83,16 +83,17 @@
|
||||||
|
|
||||||
#define Cursor XCursor
|
#define Cursor XCursor
|
||||||
#undef function
|
#undef function
|
||||||
|
#undef internal
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#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/XKBlib.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#define function static
|
#define function static
|
||||||
#undef Cursor
|
#undef Cursor
|
||||||
|
|
||||||
#undef internal
|
|
||||||
#include <fontconfig/fontconfig.h>
|
#include <fontconfig/fontconfig.h>
|
||||||
#define internal static
|
#define internal static
|
||||||
|
|
||||||
|
@ -151,8 +152,11 @@ struct Linux_Vars {
|
||||||
XIM xim;
|
XIM xim;
|
||||||
XIC xic;
|
XIC xic;
|
||||||
FcConfig* fontconfig;
|
FcConfig* fontconfig;
|
||||||
|
XkbDescPtr xkb;
|
||||||
|
|
||||||
Linux_Input_Chunk input;
|
Linux_Input_Chunk input;
|
||||||
|
int xkb_event;
|
||||||
|
int xkb_group; // active keyboard layout (0-3)
|
||||||
|
|
||||||
int epoll;
|
int epoll;
|
||||||
int step_timer_fd;
|
int step_timer_fd;
|
||||||
|
@ -593,7 +597,7 @@ linux_find_font(Face_Description* desc) {
|
||||||
FcChar8 *filename = 0;
|
FcChar8 *filename = 0;
|
||||||
FcPatternGetString(font, FC_FILE, 0, &filename);
|
FcPatternGetString(font, FC_FILE, 0, &filename);
|
||||||
if(filename) {
|
if(filename) {
|
||||||
printf("FONTCONFIG FILENAME = %s\n", filename);
|
LINUX_FN_DEBUG("FONTCONFIG FILENAME = %s\n", filename);
|
||||||
result.font.file_name = push_u8_stringf(linuxvars.frame_arena, "%s", filename);
|
result.font.file_name = push_u8_stringf(linuxvars.frame_arena, "%s", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,14 +612,19 @@ linux_find_font(Face_Description* desc) {
|
||||||
internal
|
internal
|
||||||
font_make_face_sig() {
|
font_make_face_sig() {
|
||||||
|
|
||||||
// FIXME
|
|
||||||
if(description->font.file_name.str[0] != '/') {
|
|
||||||
Face_Description desc2 = linux_find_font(description);
|
|
||||||
description = &desc2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Face* result = ft__font_make_face(arena, description, scale_factor);
|
Face* result = ft__font_make_face(arena, description, scale_factor);
|
||||||
|
|
||||||
|
// if it failed to load the font directly, try via fontconfig.
|
||||||
|
if(!result) {
|
||||||
|
Face_Description desc2 = {};
|
||||||
|
desc2.parameters = description->parameters;
|
||||||
|
desc2.font.file_name = string_front_of_path(description->font.file_name);
|
||||||
|
|
||||||
|
printf("FONT %.*s\n", string_expand(desc2.font.file_name));
|
||||||
|
desc2 = linux_find_font(&desc2);
|
||||||
|
result = ft__font_make_face(arena, &desc2, scale_factor);
|
||||||
|
}
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
// is this fatal? 4ed.cpp:277 (caller) does not check for null.
|
// is this fatal? 4ed.cpp:277 (caller) does not check for null.
|
||||||
String_Const_u8 s = description->font.file_name;
|
String_Const_u8 s = description->font.file_name;
|
||||||
|
@ -882,12 +891,6 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
|
||||||
|
|
||||||
XSync(linuxvars.dpy, False);
|
XSync(linuxvars.dpy, False);
|
||||||
|
|
||||||
XWindowAttributes attr;
|
|
||||||
if (XGetWindowAttributes(linuxvars.dpy, linuxvars.win, &attr)){
|
|
||||||
//*window_width = WinAttribs.width;
|
|
||||||
//*window_height = WinAttribs.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
Atom wm_protos[] = {
|
Atom wm_protos[] = {
|
||||||
linuxvars.atom_WM_DELETE_WINDOW,
|
linuxvars.atom_WM_DELETE_WINDOW,
|
||||||
linuxvars.atom__NET_WM_PING
|
linuxvars.atom__NET_WM_PING
|
||||||
|
@ -913,12 +916,8 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
|
||||||
XSetLocaleModifiers("");
|
XSetLocaleModifiers("");
|
||||||
b32 locale_supported = XSupportsLocale();
|
b32 locale_supported = XSupportsLocale();
|
||||||
|
|
||||||
//LOGF("Supported locale?: %s.\n", locale_supported ? "Yes" : "No");
|
|
||||||
if (!locale_supported){
|
if (!locale_supported){
|
||||||
//LOG("Reverting to 'C' ... ");
|
|
||||||
setlocale(LC_ALL, "C");
|
setlocale(LC_ALL, "C");
|
||||||
locale_supported = XSupportsLocale();
|
|
||||||
//LOGF("C is supported? %s.\n", locale_supported ? "Yes" : "No");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
linuxvars.xim = XOpenIM(dpy, 0, 0, 0);
|
linuxvars.xim = XOpenIM(dpy, 0, 0, 0);
|
||||||
|
@ -975,12 +974,27 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
|
||||||
| EnterWindowMask | LeaveWindowMask
|
| EnterWindowMask | LeaveWindowMask
|
||||||
| PointerMotionMask
|
| PointerMotionMask
|
||||||
| FocusChangeMask
|
| FocusChangeMask
|
||||||
| StructureNotifyMask | MappingNotify
|
| StructureNotifyMask
|
||||||
| ExposureMask | VisibilityChangeMask
|
| ExposureMask | VisibilityChangeMask
|
||||||
| xim_event_mask;
|
| xim_event_mask;
|
||||||
|
|
||||||
XSelectInput(linuxvars.dpy, linuxvars.win, event_mask);
|
XSelectInput(linuxvars.dpy, linuxvars.win, event_mask);
|
||||||
|
|
||||||
|
// init XKB keyboard extension
|
||||||
|
|
||||||
|
if(!XkbQueryExtension(linuxvars.dpy, 0, &linuxvars.xkb_event, 0, 0, 0)) {
|
||||||
|
system_error_box("XKB Extension not available.");
|
||||||
|
}
|
||||||
|
|
||||||
|
XkbSelectEvents(linuxvars.dpy, XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask);
|
||||||
|
linuxvars.xkb = XkbGetKeyboard(linuxvars.dpy, XkbAllComponentsMask, XkbUseCoreKbd);
|
||||||
|
if(!linuxvars.xkb) {
|
||||||
|
system_error_box("Error getting XKB keyboard details.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// closer to windows behaviour (holding key doesn't generate release events)
|
||||||
|
XkbSetDetectableAutoRepeat(linuxvars.dpy, True, NULL);
|
||||||
|
|
||||||
XCursor cursors[APP_MOUSE_CURSOR_COUNT] = {
|
XCursor cursors[APP_MOUSE_CURSOR_COUNT] = {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
@ -1007,33 +1021,56 @@ global Key_Code keycode_lookup_table[255];
|
||||||
internal void
|
internal void
|
||||||
linux_keycode_init(Display* dpy){
|
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);
|
block_zero_array(keycode_lookup_table);
|
||||||
|
|
||||||
SymCode* p = sym_table;
|
// Find these keys by physical position, and map to QWERTY KeyCodes
|
||||||
for(Key_Code k = KeyCode_A; k <= KeyCode_Z; ++k) {
|
#define K(k) glue(KeyCode_, k)
|
||||||
*p++ = { XK_a + (k - KeyCode_A), k };
|
static const u8 positional_keys[] = {
|
||||||
|
K(1), K(2), K(3), K(4), K(5), K(6), K(7), K(8), K(9), K(0), K(Minus), K(Equal),
|
||||||
|
K(Q), K(W), K(E), K(R), K(T), K(Y), K(U), K(I), K(O), K(P), K(LeftBracket), K(RightBracket),
|
||||||
|
K(A), K(S), K(D), K(F), K(G), K(H), K(J), K(K), K(L), K(Semicolon), K(Quote), /*uk hash*/0,
|
||||||
|
K(Z), K(X), K(C), K(V), K(B), K(N), K(M), K(Comma), K(Period), K(ForwardSlash), 0, 0
|
||||||
|
};
|
||||||
|
#undef K
|
||||||
|
|
||||||
|
// XKB gives the alphanumeric keys names like AE01 -> E is the row (from B-E), 01 is the column (01-12).
|
||||||
|
// to get key names in .ps file: setxkbmap -print | xkbcomp - - | xkbprint -label name - out.ps
|
||||||
|
|
||||||
|
static const int ncols = 12;
|
||||||
|
static const int nrows = 4;
|
||||||
|
|
||||||
|
for(int i = XkbMinLegalKeyCode; i <= XkbMaxLegalKeyCode; ++i) {
|
||||||
|
const char* name = linuxvars.xkb->names->keys[i].name;
|
||||||
|
|
||||||
|
if(name[0] == 'A' && name[1] >= 'B' && name[1] <= 'E') {
|
||||||
|
int row = (nrows - 1) - (name[1] - 'B');
|
||||||
|
int col = (name[2] - '0') * 10 + (name[3] - '0') - 1;
|
||||||
|
|
||||||
|
if(row >= 0 && row < nrows && col >= 0 && col < ncols) {
|
||||||
|
keycode_lookup_table[i] = positional_keys[row * ncols + col];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Key_Code k = KeyCode_0; k <= KeyCode_9; ++k) {
|
// a few special cases:
|
||||||
*p++ = { XK_0 + (k - KeyCode_0), k };
|
|
||||||
|
else if(memcmp(name, "TLDE", XkbKeyNameLength) == 0) {
|
||||||
|
keycode_lookup_table[i] = KeyCode_Tick;
|
||||||
|
} else if(memcmp(name, "BKSL", XkbKeyNameLength) == 0) {
|
||||||
|
keycode_lookup_table[i] = KeyCode_BackwardSlash;
|
||||||
|
} else if(memcmp(name, "LSGT", XkbKeyNameLength) == 0) {
|
||||||
|
// UK extra key between left shift and Z, not sure what to do with it...
|
||||||
|
// Setting to F13-F16 seems to break text input.
|
||||||
|
// it prints \ and | with shift. KeyCode_Backslash will be where UK # is.
|
||||||
|
// keycode_lookup_table[i] =
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the rest by their key label
|
||||||
|
struct SymCode { KeySym sym; Key_Code code; };
|
||||||
|
SymCode sym_table[100];
|
||||||
|
SymCode* p = sym_table;
|
||||||
|
|
||||||
*p++ = { XK_space, KeyCode_Space };
|
*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_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_Tab, KeyCode_Tab };
|
||||||
*p++ = { XK_Escape, KeyCode_Escape };
|
*p++ = { XK_Escape, KeyCode_Escape };
|
||||||
*p++ = { XK_Pause, KeyCode_Pause };
|
*p++ = { XK_Pause, KeyCode_Pause };
|
||||||
|
@ -1069,27 +1106,21 @@ linux_keycode_init(Display* dpy){
|
||||||
const int table_size = p - sym_table;
|
const int table_size = p - sym_table;
|
||||||
Assert(table_size < ArrayCount(sym_table));
|
Assert(table_size < ArrayCount(sym_table));
|
||||||
|
|
||||||
int key_min, key_max, syms_per_code;
|
for(int i = XkbMinLegalKeyCode; i <= XkbMaxLegalKeyCode; ++i) {
|
||||||
XDisplayKeycodes(dpy, &key_min, &key_max);
|
KeySym sym = NoSymbol;
|
||||||
|
|
||||||
int key_count = (key_max - key_min) + 1;
|
// lookup key in current layout with no modifiers held (0)
|
||||||
KeySym* syms = XGetKeyboardMapping(dpy, key_min, key_count, &syms_per_code);
|
if(!XkbTranslateKeyCode(linuxvars.xkb, i, XkbBuildCoreState(0, linuxvars.xkb_group), NULL, &sym)) {
|
||||||
|
continue;
|
||||||
if (syms == 0){
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int key = key_min;
|
for(int j = 0; j < table_size; ++j) {
|
||||||
for(int i = 0; i < key_count * syms_per_code; ++i){
|
if(sym_table[j].sym == sym) {
|
||||||
for(int j = 0; j < table_size; ++j){
|
keycode_lookup_table[i] = sym_table[j].code;
|
||||||
if (sym_table[j].sym == syms[i]){
|
|
||||||
keycode_lookup_table[key + (i/syms_per_code)] = sym_table[j].code;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree(syms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -1097,7 +1128,6 @@ linux_epoll_init(void) {
|
||||||
struct epoll_event e = {};
|
struct epoll_event e = {};
|
||||||
e.events = EPOLLIN | EPOLLET;
|
e.events = EPOLLIN | EPOLLET;
|
||||||
|
|
||||||
//linuxvars.inotify_fd = inotify_init1(IN_NONBLOCK);
|
|
||||||
linuxvars.step_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
linuxvars.step_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
||||||
linuxvars.epoll = epoll_create(16);
|
linuxvars.epoll = epoll_create(16);
|
||||||
|
|
||||||
|
@ -1261,18 +1291,16 @@ linux_handle_x11_events() {
|
||||||
int len = Xutf8LookupString(linuxvars.xic, &event.xkey, (char*)buf, sizeof(buf) - 1, &keysym, &status);
|
int len = Xutf8LookupString(linuxvars.xic, &event.xkey, (char*)buf, sizeof(buf) - 1, &keysym, &status);
|
||||||
|
|
||||||
if (status == XBufferOverflow){
|
if (status == XBufferOverflow){
|
||||||
//TODO(inso): handle properly
|
|
||||||
Xutf8ResetIC(linuxvars.xic);
|
Xutf8ResetIC(linuxvars.xic);
|
||||||
XSetICFocus(linuxvars.xic);
|
XSetICFocus(linuxvars.xic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysym == XK_ISO_Left_Tab){
|
if (keysym == XK_ISO_Left_Tab){
|
||||||
printf("left tab? [%.*s]\n", len, buf);
|
|
||||||
add_modifier(mods, KeyCode_Shift);
|
add_modifier(mods, KeyCode_Shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
Key_Code key = keycode_lookup_table[(u8)event.xkey.keycode];
|
Key_Code key = keycode_lookup_table[(u8)event.xkey.keycode];
|
||||||
printf("key [%d] = %s\n", event.xkey.keycode, key_code_name[key]);
|
//printf("key %d = %s\n", event.xkey.keycode, key_code_name[key]);
|
||||||
|
|
||||||
Input_Event* key_event = NULL;
|
Input_Event* key_event = NULL;
|
||||||
if(key) {
|
if(key) {
|
||||||
|
@ -1323,7 +1351,9 @@ linux_handle_x11_events() {
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MotionNotify: {
|
case MotionNotify: {
|
||||||
linuxvars.input.pers.mouse = { event.xmotion.x, event.xmotion.y };
|
int x = clamp(0, event.xmotion.x, render_target.width - 1);
|
||||||
|
int y = clamp(0, event.xmotion.y, render_target.height - 1);
|
||||||
|
linuxvars.input.pers.mouse = { x, y };
|
||||||
should_step = true;
|
should_step = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -1333,6 +1363,16 @@ linux_handle_x11_events() {
|
||||||
case Button1: {
|
case Button1: {
|
||||||
linuxvars.input.trans.mouse_l_press = true;
|
linuxvars.input.trans.mouse_l_press = true;
|
||||||
linuxvars.input.pers.mouse_l = true;
|
linuxvars.input.pers.mouse_l = true;
|
||||||
|
|
||||||
|
// NOTE(inso): improves selection dragging (especially in notepad-like mode).
|
||||||
|
// we will still get mouse events when the pointer leaves the window if it's dragging.
|
||||||
|
XGrabPointer(
|
||||||
|
linuxvars.dpy,
|
||||||
|
linuxvars.win,
|
||||||
|
True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
|
||||||
|
GrabModeAsync, GrabModeAsync,
|
||||||
|
None, None, CurrentTime);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Button3: {
|
case Button3: {
|
||||||
|
@ -1356,6 +1396,8 @@ linux_handle_x11_events() {
|
||||||
case Button1: {
|
case Button1: {
|
||||||
linuxvars.input.trans.mouse_l_release = true;
|
linuxvars.input.trans.mouse_l_release = true;
|
||||||
linuxvars.input.pers.mouse_l = false;
|
linuxvars.input.pers.mouse_l = false;
|
||||||
|
|
||||||
|
XUngrabPointer(linuxvars.dpy, CurrentTime);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Button3: {
|
case Button3: {
|
||||||
|
@ -1365,13 +1407,6 @@ linux_handle_x11_events() {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MappingNotify: {
|
|
||||||
if (event.xmapping.request == MappingModifier || event.xmapping.request == MappingKeyboard){
|
|
||||||
XRefreshKeyboardMapping(&event.xmapping);
|
|
||||||
linux_keycode_init(linuxvars.dpy);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
case FocusOut: {
|
case FocusOut: {
|
||||||
linuxvars.input.pers.mouse_l = false;
|
linuxvars.input.pers.mouse_l = false;
|
||||||
|
@ -1454,6 +1489,16 @@ linux_handle_x11_events() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(event.type == linuxvars.xkb_event) {
|
||||||
|
XkbEvent* kb = (XkbEvent*)&event;
|
||||||
|
|
||||||
|
// Keyboard layout changed, refresh lookup table.
|
||||||
|
if(kb->any.xkb_type == XkbStateNotify && kb->state.group != linuxvars.xkb_group) {
|
||||||
|
linuxvars.xkb_group = kb->state.group;
|
||||||
|
XkbRefreshKeyboardMapping((XkbMapNotifyEvent*)kb);
|
||||||
|
linux_keycode_init(linuxvars.dpy);
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,6 @@ system_get_path(Arena* arena, System_Path_Code path_code){
|
||||||
case SystemPath_CurrentDirectory: {
|
case SystemPath_CurrentDirectory: {
|
||||||
// glibc extension: getcwd allocates its own memory if passed NULL
|
// glibc extension: getcwd allocates its own memory if passed NULL
|
||||||
char *working_dir = getcwd(NULL, 0);
|
char *working_dir = getcwd(NULL, 0);
|
||||||
LINUX_FN_DEBUG("cwd = [%s]", working_dir);
|
|
||||||
|
|
||||||
u64 working_dir_len = cstring_length(working_dir);
|
u64 working_dir_len = cstring_length(working_dir);
|
||||||
u8 *out = push_array(arena, u8, working_dir_len + 1);
|
u8 *out = push_array(arena, u8, working_dir_len + 1);
|
||||||
block_copy(out, working_dir, working_dir_len);
|
block_copy(out, working_dir, working_dir_len);
|
||||||
|
@ -43,8 +41,6 @@ system_get_path(Arena* arena, System_Path_Code path_code){
|
||||||
}
|
}
|
||||||
|
|
||||||
result = string_remove_last_folder(SCu8(buf, n));
|
result = string_remove_last_folder(SCu8(buf, n));
|
||||||
|
|
||||||
LINUX_FN_DEBUG("bin dir = [%.*s]", (int)result.size, result.str);
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +100,7 @@ system_get_canonical(Arena* arena, String_Const_u8 name){
|
||||||
|
|
||||||
internal File_List
|
internal File_List
|
||||||
system_get_file_list(Arena* arena, String_Const_u8 directory){
|
system_get_file_list(Arena* arena, String_Const_u8 directory){
|
||||||
LINUX_FN_DEBUG("%.*s", (int)directory.size, directory.str);
|
//LINUX_FN_DEBUG("%.*s", (int)directory.size, directory.str);
|
||||||
File_List result = {};
|
File_List result = {};
|
||||||
|
|
||||||
char* path = strndupa((char*)directory.str, directory.size);
|
char* path = strndupa((char*)directory.str, directory.size);
|
||||||
|
@ -162,7 +158,7 @@ system_get_file_list(Arena* arena, String_Const_u8 directory){
|
||||||
|
|
||||||
internal File_Attributes
|
internal File_Attributes
|
||||||
system_quick_file_attributes(Arena* scratch, String_Const_u8 file_name){
|
system_quick_file_attributes(Arena* scratch, String_Const_u8 file_name){
|
||||||
LINUX_FN_DEBUG("%.*s", (int)file_name.size, file_name.str);
|
//LINUX_FN_DEBUG("%.*s", (int)file_name.size, file_name.str);
|
||||||
struct stat file_stat;
|
struct stat file_stat;
|
||||||
stat((const char*)file_name.str, &file_stat);
|
stat((const char*)file_name.str, &file_stat);
|
||||||
return linux_file_attributes_from_struct_stat(&file_stat);
|
return linux_file_attributes_from_struct_stat(&file_stat);
|
||||||
|
@ -306,7 +302,7 @@ system_signal_step(u32 code){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
system_sleep(u64 microseconds){
|
system_sleep(u64 microseconds){
|
||||||
LINUX_FN_DEBUG("%" PRIu64, microseconds);
|
//LINUX_FN_DEBUG("%" PRIu64, microseconds);
|
||||||
struct timespec requested;
|
struct timespec requested;
|
||||||
struct timespec remaining;
|
struct timespec remaining;
|
||||||
u64 seconds = microseconds / Million(1);
|
u64 seconds = microseconds / Million(1);
|
||||||
|
@ -317,7 +313,7 @@ system_sleep(u64 microseconds){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
system_post_clipboard(String_Const_u8 str){
|
system_post_clipboard(String_Const_u8 str){
|
||||||
LINUX_FN_DEBUG("%.*s", (int)str.size, str.str);
|
//LINUX_FN_DEBUG("%.*s", (int)str.size, str.str);
|
||||||
linalloc_clear(linuxvars.clipboard_out_arena);
|
linalloc_clear(linuxvars.clipboard_out_arena);
|
||||||
linuxvars.clipboard_out_contents = push_u8_stringf(linuxvars.clipboard_out_arena, "%.*s", str.size, str.str);
|
linuxvars.clipboard_out_contents = push_u8_stringf(linuxvars.clipboard_out_arena, "%.*s", str.size, str.str);
|
||||||
XSetSelectionOwner(linuxvars.dpy, linuxvars.atom_CLIPBOARD, linuxvars.win, CurrentTime);
|
XSetSelectionOwner(linuxvars.dpy, linuxvars.atom_CLIPBOARD, linuxvars.win, CurrentTime);
|
||||||
|
@ -377,7 +373,7 @@ system_cli_call(Arena* scratch, char* path, char* script, CLI_Handles* cli_out){
|
||||||
internal void
|
internal void
|
||||||
system_cli_begin_update(CLI_Handles* cli){
|
system_cli_begin_update(CLI_Handles* cli){
|
||||||
// NOTE(inso): I don't think anything needs to be done here.
|
// NOTE(inso): I don't think anything needs to be done here.
|
||||||
LINUX_FN_DEBUG();
|
//LINUX_FN_DEBUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
|
@ -507,7 +503,7 @@ system_thread_get_id(void){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
system_acquire_global_frame_mutex(Thread_Context* tctx){
|
system_acquire_global_frame_mutex(Thread_Context* tctx){
|
||||||
LINUX_FN_DEBUG();
|
//LINUX_FN_DEBUG();
|
||||||
if (tctx->kind == ThreadKind_AsyncTasks){
|
if (tctx->kind == ThreadKind_AsyncTasks){
|
||||||
system_mutex_acquire(linuxvars.global_frame_mutex);
|
system_mutex_acquire(linuxvars.global_frame_mutex);
|
||||||
}
|
}
|
||||||
|
@ -515,7 +511,7 @@ system_acquire_global_frame_mutex(Thread_Context* tctx){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
system_release_global_frame_mutex(Thread_Context* tctx){
|
system_release_global_frame_mutex(Thread_Context* tctx){
|
||||||
LINUX_FN_DEBUG();
|
//LINUX_FN_DEBUG();
|
||||||
if (tctx->kind == ThreadKind_AsyncTasks){
|
if (tctx->kind == ThreadKind_AsyncTasks){
|
||||||
system_mutex_release(linuxvars.global_frame_mutex);
|
system_mutex_release(linuxvars.global_frame_mutex);
|
||||||
}
|
}
|
||||||
|
@ -599,7 +595,7 @@ system_memory_allocate(u64 size, String_Const_u8 location){
|
||||||
void* result = mmap(
|
void* result = mmap(
|
||||||
NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
// TODO(andrew): Allocation tracking?
|
// TODO(andrew): Allocation tracking?
|
||||||
//LINUX_FN_DEBUG("%" PRIu64 ", %.*s %p", size, (int)location.size, location.str, result);
|
LINUX_FN_DEBUG("%" PRIu64 ", %.*s %p", size, (int)location.size, location.str, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,6 +668,6 @@ system_is_fullscreen(void){
|
||||||
|
|
||||||
internal Input_Modifier_Set
|
internal Input_Modifier_Set
|
||||||
system_get_keyboard_modifiers(Arena* arena){
|
system_get_keyboard_modifiers(Arena* arena){
|
||||||
LINUX_FN_DEBUG();
|
//LINUX_FN_DEBUG();
|
||||||
return(copy_modifier_set(arena, &linuxvars.input.pers.modifiers));
|
return(copy_modifier_set(arena, &linuxvars.input.pers.modifiers));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue