diff options
Diffstat (limited to 'app.cpp')
-rw-r--r-- | app.cpp | 300 |
1 files changed, 300 insertions, 0 deletions
@@ -0,0 +1,300 @@ +#include "app.hpp" + +extern "C" { +#include "memory.h" +} + +#ifdef plat_x11 +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include <stdlib.h> + +Key key_from_xkey(unsigned key) { + switch (key) { + case 0x61: return key_A; + case 0x62: return key_B; + case 0x63: return key_C; + case 0x64: return key_D; + case 0x65: return key_E; + case 0x66: return key_F; + case 0x67: return key_G; + case 0x68: return key_H; + case 0x69: return key_I; + case 0x6A: return key_J; + case 0x6B: return key_K; + case 0x6C: return key_L; + case 0x6D: return key_M; + case 0x6E: return key_N; + case 0x6F: return key_O; + case 0x70: return key_P; + case 0x71: return key_Q; + case 0x72: return key_R; + case 0x73: return key_S; + case 0x74: return key_T; + case 0x75: return key_U; + case 0x76: return key_V; + case 0x77: return key_W; + case 0x78: return key_X; + case 0x79: return key_Y; + case 0x7A: return key_Z; + case XK_F1: return key_f1; + case XK_F2: return key_f2; + case XK_F3: return key_f3; + case XK_F4: return key_f4; + case XK_F5: return key_f5; + case XK_F6: return key_f6; + case XK_F7: return key_f7; + case XK_F8: return key_f8; + case XK_F9: return key_f9; + case XK_F10: return key_f10; + case XK_F11: return key_f11; + case XK_F12: return key_f12; + case XK_Down: return key_down; + case XK_Left: return key_left; + case XK_Right: return key_right; + case XK_Up: return key_up; + case XK_Escape: return key_escape; + case XK_Return: return key_return; + case XK_BackSpace: return key_backspace; + case XK_Linefeed: return key_return; + case XK_Tab: return key_tab; + case XK_Delete: return key_delete; + case XK_Home: return key_home; + case XK_End: return key_end; + case XK_Page_Up: return key_page_up; + case XK_Page_Down: return key_page_down; + case XK_Insert: return key_insert; + case XK_Shift_L: return key_shift; + case XK_Shift_R: return key_shift; + case XK_Control_L: return key_control; + case XK_Control_R: return key_control; + case XK_Super_L: return key_super; + case XK_Super_R: return key_super; + case XK_Alt_L: return key_alt; + case XK_Alt_R: return key_alt; + case XK_space: return key_space; + case XK_period: return key_period; + case XK_0: return key_0; + case XK_1: return key_1; + case XK_2: return key_2; + case XK_3: return key_3; + case XK_4: return key_4; + case XK_5: return key_5; + case XK_6: return key_6; + case XK_7: return key_7; + case XK_8: return key_8; + case XK_9: return key_9; + default: return key_unknown; + } +} + +struct App_Internal { + Display* d; + Window wi; + Atom wm_delete; + + void init(App* app, const char* name) { + const int default_w = 1920; + const int default_h = 1080; + XWindowAttributes wa; + XSetWindowAttributes attribs = { + .event_mask = + ExposureMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask + }; + Window root; + Visual* v; + d = XOpenDisplay(0); + wm_delete = XInternAtom( + d, + "WM_DELETE_WINDOW", + 0 + ); + root = DefaultRootWindow(d); + v = XDefaultVisual(d, 0); + wi = XCreateWindow( + d, + root, + 0, + 0, + default_w, + default_h, + 0, + 0, + InputOutput, + v, + CWEventMask, + &attribs + ); + XSetWMProtocols(d, wi, &wm_delete, 1); + XStoreName(d, wi, name); + XMapRaised(d, wi); + XGetWindowAttributes(d, wi, &wa); + app->w = wa.width; + app->h = wa.height; + } + + void begin(App* app) { + while (XPending(d)) { + XEvent e; + KeySym sym; + Key key; + int btn; + XNextEvent(d, &e); + switch (e.type) { + case ClientMessage: + if ( + (Atom)e.xclient.data.l[0] == + wm_delete + ) { + app->running = 0; + } + break; + case MotionNotify: + app->mx = e.xmotion.x; + app->my = e.xmotion.y; + break; + case ButtonPress: + switch (e.xbutton.button) { + case 1: + case 2: + case 3: + app->mbtn_states[e.xbutton.button - 1] |= + key_state_pressed | + key_state_just_pressed; + break; + case 4: + app->scrolly++; + break; + case 5: + app->scrolly--; + break; + case 6: + app->scrollx++; + break; + case 7: + app->scrollx--; + break; + } + break; + case ButtonRelease: + switch (e.xbutton.button) { + case 1: + case 2: + case 3: + btn = e.xbutton.button - 1; + app->mbtn_states[btn] &= ~key_state_pressed; + app->mbtn_states[btn] |= key_state_just_released; + break; + case 4: + app->scrolly++; + break; + case 5: + app->scrolly--; + break; + case 6: + app->scrollx++; + break; + case 7: + app->scrollx--; + break; + } + break; + case KeyPress: + sym = XLookupKeysym(&e.xkey, 0); + key = key_from_xkey(sym); + app->key_states[key] |= + key_state_pressed | + key_state_just_pressed; + break; + case KeyRelease: + sym = XLookupKeysym(&e.xkey, 0); + key = key_from_xkey(sym); + app->key_states[key] &= ~key_state_pressed; + app->key_states[key] |= key_state_just_released; + break; + } + } + } + + void end(App* app) { + (void)app; + } +}; + +#endif + +App* App::create(const char* name) { + App* app; + App_Internal* i; + char* mem = (char*)malloc(app_memory_size); + Arena* a = (Arena*)mem; + mem += sizeof *a; + init_arena(a, mem, app_memory_size - sizeof *a); + app = (App*)arena_alloc(a, sizeof *app + sizeof *i); + app->running = 0; + app->arena = a; + i = (App_Internal*)&app[1]; + i->init(app, name); + return app; +} + +void App::destroy() { + free(arena); +} + +void App::begin() { + int j; + App_Internal* i = (App_Internal*)&this[1]; + for (j = 0; j < key_count; j++) + key_states[j] &= ~( + key_state_just_pressed | key_state_just_released + ); + for (j = 0; j < mbtn_count; j++) + mbtn_states[j] &= ~( + key_state_just_pressed | key_state_just_released + ); + i->begin(this); +} + +void App::end() { + App_Internal* i = (App_Internal*)&this[1]; + i->end(this); +} + +Key_State App::ks(Key k) { + return (Key_State)key_states[k]; +} + +Key_State App::ms(Mbtn k) { + return (Key_State)mbtn_states[k]; +} + +bool App::kp(Key k) { + return key_states[k] & key_state_pressed; +} + +bool App::kjp(Key k) { + return key_states[k] & key_state_just_pressed; +} + +bool App::kjr(Key k) { + return key_states[k] & key_state_just_released; +} + +bool App::mp(Mbtn b) { + return mbtn_states[b] & key_state_pressed; +} + +bool App::mjp(Mbtn b) { + return mbtn_states[b] & key_state_just_pressed; +} + +bool App::mjr(Mbtn b) { + return mbtn_states[b] & key_state_just_released; +} |