336 lines
8.4 KiB
C
336 lines
8.4 KiB
C
// ::Platform::Linux::Globals::Start::
|
|
|
|
static pPlatformWindow linux_window = {
|
|
.w = 1920,
|
|
.h = 1080,
|
|
};
|
|
|
|
b32 global_quit = false;
|
|
|
|
// ::Platform::Linux::Globals::End::
|
|
|
|
// ::Platform::Linux::Print::Functions::Start::
|
|
|
|
i32 pWriteStdOut(rawptr buf, i32 len)
|
|
{
|
|
return (i32)write(STDOUT, buf, len);
|
|
}
|
|
|
|
i32 pWriteStdErr(rawptr buf, i32 len)
|
|
{
|
|
return (i32)write(STDERR, buf, len);
|
|
}
|
|
|
|
// ::Platform::Linux::Window::Functions::Start::
|
|
|
|
void pWindowEventsGet(pGameInput *inputs, u32 *i_count)
|
|
{
|
|
pWindowEventHandle(inputs, i_count, false);
|
|
}
|
|
|
|
b32 pWindowEventWaitFor(pGameInput *input)
|
|
{
|
|
u32 i_count;
|
|
pWindowEventHandle(input, &i_count, true);
|
|
return i_count > 0;
|
|
}
|
|
|
|
void pWindowEventHandle(pGameInput *inputs, u32 *i_count, b32 wait_for_event)
|
|
{
|
|
b32 has_max_inputs = false;
|
|
*i_count = 0;
|
|
|
|
do
|
|
{
|
|
xcb_generic_event_t *e;
|
|
if (wait_for_event)
|
|
e = xcb_wait_for_event(linux_window.connection);
|
|
else
|
|
e = xcb_poll_for_event(linux_window.connection);
|
|
|
|
// XCB_UNMAP_NOTIFY
|
|
if (e != NULL)
|
|
{
|
|
switch (e->response_type & ~0x80)
|
|
{
|
|
case XCB_CLIENT_MESSAGE:
|
|
{
|
|
xcb_client_message_event_t *msg = (xcb_client_message_event_t *)e;
|
|
if (msg->window != linux_window.window)
|
|
break;
|
|
|
|
if (msg->data.data32[0] == linux_window.close_event)
|
|
global_quit = true;
|
|
} break;
|
|
case XCB_CONFIGURE_NOTIFY:
|
|
{
|
|
xcb_configure_notify_event_t *configure_event = (xcb_configure_notify_event_t *)e;
|
|
|
|
if (linux_window.w != configure_event->width || linux_window.h != configure_event->height)
|
|
{
|
|
linux_window.w = configure_event->width;
|
|
linux_window.h = configure_event->height;
|
|
}
|
|
} break;
|
|
case XCB_KEY_RELEASE:
|
|
case XCB_KEY_PRESS:
|
|
{
|
|
xcb_key_press_event_t *keyboard_e = (xcb_key_press_event_t *)e;
|
|
b8 pressed = e->response_type == XCB_KEY_PRESS;
|
|
xcb_keycode_t code = keyboard_e->detail;
|
|
KeySym keysym = XkbKeycodeToKeysym(linux_window.display, (KeyCode)code, 0, 0);
|
|
pKeyboardInput input = pInputEventConvert(keysym);
|
|
if (input != KB_NONE)
|
|
{
|
|
inputs[*i_count].kb_code = input;
|
|
inputs[*i_count].pressed = pressed;
|
|
inputs[*i_count].type = GI_KEYBOARD;
|
|
*i_count += 1;
|
|
|
|
if (*i_count == 10)
|
|
has_max_inputs = true;
|
|
}
|
|
|
|
} break;
|
|
case XCB_BUTTON_PRESS:
|
|
case XCB_BUTTON_RELEASE:
|
|
{
|
|
xcb_button_press_event_t *mouse_ev = (xcb_button_press_event_t *)e;
|
|
b8 pressed = e->response_type == XCB_BUTTON_PRESS;
|
|
pMouseInput input = M_NONE;
|
|
|
|
if (mouse_ev->detail == XCB_BUTTON_INDEX_1)
|
|
input = M_LEFT_CLICK;
|
|
else if (mouse_ev->detail == XCB_BUTTON_INDEX_2)
|
|
input = M_MIDDLE_CLICK;
|
|
else if (mouse_ev->detail == XCB_BUTTON_INDEX_3)
|
|
input = M_RIGHT_CLICK;
|
|
|
|
if (input != M_NONE)
|
|
{
|
|
inputs[*i_count].m_code = input;
|
|
inputs[*i_count].pressed = pressed;
|
|
inputs[*i_count].type = GI_MOUSE;
|
|
*i_count += 1;
|
|
|
|
if (*i_count == 10)
|
|
has_max_inputs = true;
|
|
}
|
|
} break;
|
|
case XCB_MOTION_NOTIFY:
|
|
{
|
|
xcb_motion_notify_event_t *move_ev = (xcb_motion_notify_event_t *)e;
|
|
|
|
if (move_ev->event_x > 0 || move_ev->event_y > 0)
|
|
{
|
|
inputs[*i_count].motion_ev.x = move_ev->event_x;
|
|
inputs[*i_count].motion_ev.y = move_ev->event_y;
|
|
inputs[*i_count].type = GI_MOTION;
|
|
|
|
*i_count += 1;
|
|
if (*i_count == 10)
|
|
has_max_inputs = true;
|
|
}
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
free(e);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
} while(!wait_for_event && !has_max_inputs);
|
|
}
|
|
|
|
pKeyboardInput pInputEventConvert(u32 x_key)
|
|
{
|
|
switch (x_key)
|
|
{
|
|
case XK_BackSpace: return KB_BACKSPACE;
|
|
case XK_Return: return KB_ENTER;
|
|
case XK_Tab: return KB_TAB;
|
|
case XK_Pause: return KB_PAUSE;
|
|
case XK_Caps_Lock: return KB_CAPS_LOCK;
|
|
case XK_Escape: return KB_ESC;
|
|
case XK_space: return KB_SPACE;
|
|
case XK_Prior: return KB_PAGE_UP;
|
|
case XK_Next: return KB_PAGE_DOWN;
|
|
case XK_End: return KB_END;
|
|
case XK_Home: return KB_HOME;
|
|
case XK_Left: return KB_LEFT;
|
|
case XK_Up: return KB_UP;
|
|
case XK_Right: return KB_RIGHT;
|
|
case XK_Down: return KB_DOWN;
|
|
case XK_Print: return KB_PRINT_SCREEN;
|
|
case XK_Insert: return KB_INSERT;
|
|
case XK_Delete: return KB_DELETE;
|
|
case XK_Meta_L:
|
|
case XK_Super_L: return KB_LEFT_SUPER;
|
|
case XK_Meta_R:
|
|
case XK_Super_R: return KB_RIGHT_SUPER;
|
|
case XK_KP_0: return KB_NUM_0;
|
|
case XK_KP_1: return KB_NUM_1;
|
|
case XK_KP_2: return KB_NUM_2;
|
|
case XK_KP_3: return KB_NUM_3;
|
|
case XK_KP_4: return KB_NUM_4;
|
|
case XK_KP_5: return KB_NUM_5;
|
|
case XK_KP_6: return KB_NUM_6;
|
|
case XK_KP_7: return KB_NUM_7;
|
|
case XK_KP_8: return KB_NUM_8;
|
|
case XK_KP_9: return KB_NUM_9;
|
|
case XK_multiply: return KB_NUM_STAR;
|
|
case XK_KP_Subtract: return KB_NUM_MINUS;
|
|
case XK_KP_Decimal: return KB_NUM_PERIOD;
|
|
case XK_KP_Divide: return KB_NUM_SLASH;
|
|
case XK_KP_Add: return KB_NUM_PLUS;
|
|
case XK_F1: return KB_F1;
|
|
case XK_F2: return KB_F2;
|
|
case XK_F3: return KB_F3;
|
|
case XK_F4: return KB_F4;
|
|
case XK_F5: return KB_F5;
|
|
case XK_F6: return KB_F6;
|
|
case XK_F7: return KB_F7;
|
|
case XK_F8: return KB_F8;
|
|
case XK_F9: return KB_F9;
|
|
case XK_F10: return KB_F10;
|
|
case XK_F11: return KB_F11;
|
|
case XK_F12: return KB_F12;
|
|
case XK_Num_Lock: return KB_NUM_LOCK;
|
|
case XK_Scroll_Lock: return KB_SCROLL_LOCK;
|
|
case XK_Shift_L: return KB_LEFT_SHIFT;
|
|
case XK_Shift_R: return KB_RIGHT_SHIFT;
|
|
case XK_Control_L: return KB_LEFT_CTRL;
|
|
case XK_Control_R: return KB_RIGHT_CTRL;
|
|
case XK_Alt_L: return KB_LEFT_ALT;
|
|
case XK_Alt_R: return KB_RIGHT_ALT;
|
|
case XK_semicolon: return KB_SEMICOLON;
|
|
case XK_bracketleft: return KB_LEFT_BRACE;
|
|
case XK_bracketright: return KB_RIGHT_BRACE;
|
|
case XK_plus: return KB_PLUS;
|
|
case XK_comma: return KB_COMMA;
|
|
case XK_minus: return KB_MINUS;
|
|
case XK_backslash: return KB_BACK_SLASH;
|
|
case XK_slash: return KB_FORWARD_SLASH;
|
|
case XK_grave: return KB_TILDE;
|
|
case XK_0: return KB_0;
|
|
case XK_1: return KB_1;
|
|
case XK_2: return KB_2;
|
|
case XK_3: return KB_3;
|
|
case XK_4: return KB_4;
|
|
case XK_5: return KB_5;
|
|
case XK_6: return KB_6;
|
|
case XK_7: return KB_7;
|
|
case XK_8: return KB_8;
|
|
case XK_9: return KB_9;
|
|
case XK_a:
|
|
case XK_A: return KB_A;
|
|
case XK_b:
|
|
case XK_B: return KB_B;
|
|
case XK_c:
|
|
case XK_C: return KB_C;
|
|
case XK_d:
|
|
case XK_D: return KB_D;
|
|
case XK_e:
|
|
case XK_E: return KB_E;
|
|
case XK_f:
|
|
case XK_F: return KB_F;
|
|
case XK_g:
|
|
case XK_G: return KB_G;
|
|
case XK_h:
|
|
case XK_H: return KB_H;
|
|
case XK_i:
|
|
case XK_I: return KB_I;
|
|
case XK_j:
|
|
case XK_J: return KB_J;
|
|
case XK_k:
|
|
case XK_K: return KB_K;
|
|
case XK_l:
|
|
case XK_L: return KB_L;
|
|
case XK_m:
|
|
case XK_M: return KB_M;
|
|
case XK_n:
|
|
case XK_N: return KB_N;
|
|
case XK_o:
|
|
case XK_O: return KB_O;
|
|
case XK_p:
|
|
case XK_P: return KB_P;
|
|
case XK_q:
|
|
case XK_Q: return KB_Q;
|
|
case XK_r:
|
|
case XK_R: return KB_R;
|
|
case XK_s:
|
|
case XK_S: return KB_S;
|
|
case XK_t:
|
|
case XK_T: return KB_T;
|
|
case XK_u:
|
|
case XK_U: return KB_U;
|
|
case XK_v:
|
|
case XK_V: return KB_V;
|
|
case XK_w:
|
|
case XK_W: return KB_W;
|
|
case XK_x:
|
|
case XK_X: return KB_X;
|
|
case XK_y:
|
|
case XK_Y: return KB_Y;
|
|
case XK_z:
|
|
case XK_Z: return KB_Z;
|
|
default: return KB_NONE;
|
|
}
|
|
}
|
|
|
|
// ::Platform::Linux::Window::Functions::Start::
|
|
|
|
|
|
|
|
// ::Platform::Linux::Utils::Functions::Start::
|
|
|
|
b32 pSyscallErrCheck(void *ptr)
|
|
{
|
|
return (isize)ptr == SYS_ERR ? true : false;
|
|
}
|
|
|
|
// ::Platform::Linux::Utils::Functions::End::
|
|
|
|
|
|
|
|
// ::Platform::Linux::Async::Start::
|
|
|
|
static pThread pThreadInit(pThreadProc proc, rawptr param)
|
|
{
|
|
pThread thread = {0};
|
|
pthread_mutex_init(&thread.mut, NULL);
|
|
pthread_create(&thread.handle, NULL, proc, param);
|
|
|
|
return thread;
|
|
}
|
|
|
|
static void pThreadSuspend(pThread *thread)
|
|
{
|
|
pthread_mutex_lock(&thread->mut);
|
|
pthread_cond_wait(&thread->cond, &thread->mut);
|
|
pthread_mutex_unlock(&thread->mut);
|
|
}
|
|
|
|
static void pThreadWake(pThread *thread)
|
|
{
|
|
pthread_cond_signal(&thread->cond);
|
|
}
|
|
|
|
static void pThreadKill()
|
|
{
|
|
pthread_exit(NULL);
|
|
}
|
|
|
|
// ::Platform::Linux::Async::Start::
|
|
|
|
|
|
|
|
// ::Platform::Linux::Includes::CFile::
|
|
|
|
#include "platform_linux_public.c"
|
|
|
|
|