master
Alex Baines 2020-02-02 20:20:27 +00:00
parent 2a856634d0
commit 21625b646b
3 changed files with 219 additions and 22 deletions

View File

@ -100,6 +100,13 @@
#define LINUX_FN_DEBUG(fmt, ...) do { \
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);\
} while (0)
// I want to see a message
#undef AssertBreak
#define AssertBreak(m) ({\
fprintf(stderr, "\n** ASSERTION FAILURE: %s:%d: %s\n\n", __FILE__, __LINE__, #m);\
*((volatile u64*)0) = 0xba771e70ad5;\
})
#else
#define LINUX_FN_DEBUG(...)
#endif
@ -107,6 +114,9 @@
////////////////////////////
struct Linux_Vars {
Thread_Context tctx;
Arena *frame_arena;
Display* dpy;
Window win;
@ -131,8 +141,6 @@ struct Linux_Vars {
Node free_linux_objects;
Node timer_objects;
Thread_Context tctx;
System_Mutex global_frame_mutex;
Arena clipboard_out_arena;
@ -216,22 +224,31 @@ handle_to_object(Plat_Handle ph){
internal Linux_Object*
linux_alloc_object(Linux_Object_Kind kind){
Linux_Object* result = NULL;
if (linuxvars.free_linux_objects.next != &linuxvars.free_linux_objects) {
result = CastFromMember(Linux_Object, node, linuxvars.free_linux_objects.next);
}
if (result == NULL) {
i32 count = 512;
Linux_Object* objects = (Linux_Object*)system_memory_allocate(
sizeof(Linux_Object), file_name_line_number_lit_u8);
sizeof(Linux_Object) * count,
file_name_line_number_lit_u8
);
objects[0].node.prev = &linuxvars.free_linux_objects;
linuxvars.free_linux_objects.next = &objects[0].node;
for (i32 i = 1; i < count; ++i) {
objects[i - 1].node.next = &objects[i].node;
objects[i].node.prev = &objects[i - 1].node;
}
objects[count - 1].node.next = &linuxvars.free_linux_objects;
linuxvars.free_linux_objects.prev = &objects[count - 1].node;
result = CastFromMember(Linux_Object, node, linuxvars.free_linux_objects.next);
}
Assert(result != 0);
dll_remove(&result->node);
block_zero_struct(result);
@ -462,6 +479,15 @@ graphics_fill_texture_sig(){
internal
font_make_face_sig() {
Face* result = ft__font_make_face(arena, description, scale_factor);
if(!result) {
// is this fatal? 4ed.cpp:277 (caller) does not check for null.
String_Const_u8 s = description->font.file_name;
char msg[4096];
snprintf(msg, sizeof(msg), "Unable to load font: %.*s", (int)s.size, s.str);
system_error_box(msg);
}
return(result);
}
@ -469,17 +495,123 @@ font_make_face_sig() {
internal b32
glx_init(void) {
return false;
int glx_maj, glx_min;
if(!glXQueryVersion(linuxvars.dpy, &glx_maj, &glx_min)) {
return false;
}
return glx_maj > 1 || (glx_maj == 1 && glx_min >= 3);
}
internal b32
glx_get_config(GLXFBConfig* fb_config, XVisualInfo* vi) {
return false;
static const int attrs[] = {
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_ALPHA_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , True,
None
};
int conf_count = 0;
GLXFBConfig* conf_list = glXChooseFBConfig(linuxvars.dpy, DefaultScreen(linuxvars.dpy), attrs, &conf_count);
if(!conf_count || conf_count <= 0) {
return false;
}
*fb_config = *conf_list;
XFree(conf_list);
XVisualInfo* xvi = glXGetVisualFromFBConfig(linuxvars.dpy, *fb_config);
if(!xvi) {
return false;
}
*vi = *xvi;
XFree(xvi);
return true;
}
internal b32 glx_ctx_error;
internal int
glx_error_handler(Display* dpy, XErrorEvent* ev){
glx_ctx_error = true;
return 0;
}
typedef GLXContext (glXCreateContextAttribsARB_Function)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
typedef void (glXSwapIntervalEXT_Function) (Display *dpy, GLXDrawable drawable, int interval);
typedef int (glXSwapIntervalMESA_Function) (unsigned int interval);
typedef int (glXGetSwapIntervalMESA_Function) (void);
typedef int (glXSwapIntervalSGI_Function) (int interval);
internal b32
glx_create_context(GLXFBConfig* fb_config){
return false;
glx_create_context(GLXFBConfig fb_config){
const char *glx_exts = glXQueryExtensionsString(linuxvars.dpy, DefaultScreen(linuxvars.dpy));
glXCreateContextAttribsARB_Function *glXCreateContextAttribsARB = 0;
glXSwapIntervalEXT_Function *glXSwapIntervalEXT = 0;
glXSwapIntervalMESA_Function *glXSwapIntervalMESA = 0;
glXGetSwapIntervalMESA_Function *glXGetSwapIntervalMESA = 0;
glXSwapIntervalSGI_Function *glXSwapIntervalSGI = 0;
#define GLXLOAD(f) f = (f##_Function*) glXGetProcAddressARB((const GLubyte*) #f);
GLXLOAD(glXCreateContextAttribsARB);
GLXContext ctx = NULL;
int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(&glx_error_handler);
if (glXCreateContextAttribsARB == NULL){
//LOG("glXCreateContextAttribsARB() not found, using old-style GLX context\n" );
ctx = glXCreateNewContext(linuxvars.dpy, fb_config, GLX_RGBA_TYPE, 0, True);
} else {
static const int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
#if defined(FRED_INTERNAL)
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_DEBUG_BIT_ARB,
#endif
None
};
//LOG("Creating GL 2.1 context... ");
ctx = glXCreateContextAttribsARB(linuxvars.dpy, fb_config, 0, True, context_attribs);
}
XSync(linuxvars.dpy, False);
if(glx_ctx_error || !ctx) {
return false;
}
XSync(linuxvars.dpy, False);
XSetErrorHandler(old_handler);
//b32 direct = glXIsDirect(linuxvars.dpy, ctx);
//LOG("Making context current\n");
glXMakeCurrent(linuxvars.dpy, linuxvars.win, ctx);
//glx_enable_vsync();
// NOTE(allen): Load gl functions
#define GL_FUNC(f,R,P) GLXLOAD(f)
#include "opengl/4ed_opengl_funcs.h"
#undef GLXLOAD
return true;
}
////////////////////////////
@ -513,8 +645,7 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
#undef LOAD_ATOM
if (!glx_init()){
//system_error_box("Your XServer's GLX version is too old. GLX 1.3+ is required.");
system_error_box("TODO: Everything.");
system_error_box("Your XServer's GLX version is too old. GLX 1.3+ is required.");
}
GLXFBConfig fb_config;
@ -529,6 +660,10 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
int w = WINDOW_W_DEFAULT;
int h = WINDOW_H_DEFAULT;
// TEMP
render_target.width = w;
render_target.height = h;
XSetWindowAttributes swa = {};
swa.backing_store = WhenMapped;
swa.event_mask = StructureNotifyMask;
@ -593,7 +728,7 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
// NOTE(inso): make the window visible
XMapWindow(linuxvars.dpy, linuxvars.win);
if(!glx_create_context(&fb_config)) {
if(!glx_create_context(fb_config)) {
system_error_box("Unable to create GLX context.");
}
@ -659,30 +794,35 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
}
XIMStyles *styles = NULL;
XIMStyle got_style = None;
const XIMStyle style_want = (XIMPreeditNothing | XIMStatusNothing);
b32 found_style = false;
if (!XGetIMValues(linuxvars.xim, XNQueryInputStyle, &styles, NULL) && styles){
for (i32 i = 0; i < styles->count_styles; ++i){
XIMStyle style = styles->supported_styles[i];
if (style == (XIMPreeditNothing | XIMStatusNothing)){
got_style = true;
if (style == style_want) {
found_style = true;
break;
}
}
}
if(got_style == None) {
if(!found_style) {
system_error_box("Could not find supported X Input style.");
}
XFree(styles);
linuxvars.xic = XCreateIC(linuxvars.xim,
XNInputStyle, got_style,
XNInputStyle, style_want,
XNClientWindow, linuxvars.win,
XNFocusWindow, linuxvars.win,
NULL);
if(!linuxvars.xic) {
system_error_box("Error creating X Input context.");
}
int xim_event_mask;
if (XGetICValues(linuxvars.xic, XNFilterEvents, &xim_event_mask, NULL)){
xim_event_mask = 0;
@ -779,9 +919,9 @@ main(int argc, char **argv){
font_api_fill_vtable(&font_vtable);
// NOTE(allen): memory
//win32vars.frame_arena = reserve_arena(win32vars.tctx);
linuxvars.frame_arena = reserve_arena(&linuxvars.tctx);
// TODO(allen): *arena;
//target.arena = make_arena_system(KB(256));
render_target.arena = make_arena_system(KB(256));
linuxvars.cursor_show = MouseCursorShow_Always;
linuxvars.prev_cursor_show = MouseCursorShow_Always;
@ -822,6 +962,8 @@ main(int argc, char **argv){
// NOTE(allen): send system vtable to core
app.load_vtables(&system_vtable, &font_vtable, &graphics_vtable);
// get_logger calls log_init which is needed.
app.get_logger();
//linuxvars.log_string = app.get_logger();
// NOTE(allen): init & command line parameters
@ -942,7 +1084,7 @@ main(int argc, char **argv){
{
Scratch_Block scratch(&linuxvars.tctx, Scratch_Share);
String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory);
//app.init(&linuxvars.tctx, &render_target, base_ptr, linuxvars.clipboard_contents, curdir, custom);
app.init(&linuxvars.tctx, &render_target, base_ptr, linuxvars.clipboard_contents, curdir, custom);
}
linuxvars.global_frame_mutex = system_mutex_make();
@ -1031,6 +1173,9 @@ main(int argc, char **argv){
linuxvars.cursor = result.mouse_cursor_type;
}
gl_render(&render_target);
glXSwapBuffers(linuxvars.dpy, linuxvars.win);
first_step = false;
}

View File

@ -53,6 +53,7 @@ system_get_path(Arena* arena, System_Path_Code path_code){
internal String_Const_u8
system_get_canonical(Arena* arena, String_Const_u8 name){
LINUX_FN_DEBUG("%.*s", (int)name.size, name.str);
// TODO(andrew): Resolve symlinks ?
// TODO(andrew): Resolve . and .. in paths
// TODO(andrew): Use realpath(3)
@ -61,6 +62,7 @@ system_get_canonical(Arena* arena, String_Const_u8 name){
internal File_List
system_get_file_list(Arena* arena, String_Const_u8 directory){
LINUX_FN_DEBUG("%.*s", (int)directory.size, directory.str);
File_List result = {};
String_Const_u8 search_pattern = {};
@ -103,6 +105,7 @@ system_get_file_list(Arena* arena, String_Const_u8 directory){
internal File_Attributes
system_quick_file_attributes(Arena* scratch, String_Const_u8 file_name){
LINUX_FN_DEBUG("%.*s", (int)file_name.size, file_name.str);
struct stat file_stat;
stat((const char*)file_name.str, &file_stat);
return linux_file_attributes_from_struct_stat(file_stat);
@ -110,6 +113,7 @@ system_quick_file_attributes(Arena* scratch, String_Const_u8 file_name){
internal b32
system_load_handle(Arena* scratch, char* file_name, Plat_Handle* out){
LINUX_FN_DEBUG("%s", file_name);
int fd = open(file_name, O_RDONLY);
if (fd != -1) {
*(int*)out = fd;
@ -120,6 +124,7 @@ system_load_handle(Arena* scratch, char* file_name, Plat_Handle* out){
internal File_Attributes
system_load_attributes(Plat_Handle handle){
LINUX_FN_DEBUG();
struct stat file_stat;
fstat(*(int*)&handle, &file_stat);
return linux_file_attributes_from_struct_stat(file_stat);
@ -127,6 +132,7 @@ system_load_attributes(Plat_Handle handle){
internal b32
system_load_file(Plat_Handle handle, char* buffer, u32 size){
LINUX_FN_DEBUG("%.*s", size, buffer);
int fd = *(int*)&handle;
int bytes_read = read(fd, buffer, size);
if (bytes_read == size) {
@ -137,12 +143,14 @@ system_load_file(Plat_Handle handle, char* buffer, u32 size){
internal b32
system_load_close(Plat_Handle handle){
LINUX_FN_DEBUG();
int fd = *(int*)&handle;
return close(fd) == 0;
}
internal File_Attributes
system_save_file(Arena* scratch, char* file_name, String_Const_u8 data){
LINUX_FN_DEBUG("%s", file_name);
File_Attributes result = {};
int fd = open(file_name, O_WRONLY, O_CREAT);
if (fd != -1) {
@ -158,6 +166,7 @@ system_save_file(Arena* scratch, char* file_name, String_Const_u8 data){
internal b32
system_load_library(Arena* scratch, String_Const_u8 file_name, System_Library* out){
LINUX_FN_DEBUG("%.*s", (int)file_name.size, file_name.str);
void* library = dlopen((const char*)file_name.str, RTLD_LAZY);
if (library != NULL) {
*(void**)out = library;
@ -168,16 +177,19 @@ system_load_library(Arena* scratch, String_Const_u8 file_name, System_Library* o
internal b32
system_release_library(System_Library handle){
LINUX_FN_DEBUG();
return dlclose(*(void**)&handle) == 0;
}
internal Void_Func*
system_get_proc(System_Library handle, char* proc_name){
LINUX_FN_DEBUG("%s", proc_name);
return (Void_Func*)dlsym(*(void**)&handle, proc_name);
}
internal u64
system_now_time(void){
LINUX_FN_DEBUG();
struct timespec time;
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
return linux_u64_from_timespec(time);
@ -185,6 +197,7 @@ system_now_time(void){
internal Plat_Handle
system_wake_up_timer_create(void){
LINUX_FN_DEBUG();
Linux_Object* object = linux_alloc_object(LinuxObjectKind_Timer);
dll_insert(&linuxvars.timer_objects, &object->node);
@ -194,6 +207,7 @@ system_wake_up_timer_create(void){
internal void
system_wake_up_timer_release(Plat_Handle handle){
LINUX_FN_DEBUG();
Linux_Object* object = handle_to_object(handle);
if (object->kind == LinuxObjectKind_Timer){
if(object->timer.fd != -1) {
@ -207,6 +221,7 @@ system_wake_up_timer_release(Plat_Handle handle){
internal void
system_wake_up_timer_set(Plat_Handle handle, u32 time_milliseconds){
LINUX_FN_DEBUG("%d", time_milliseconds);
Linux_Object* object = handle_to_object(handle);
if (object->kind == LinuxObjectKind_Timer){
@ -229,11 +244,13 @@ system_wake_up_timer_set(Plat_Handle handle, u32 time_milliseconds){
internal void
system_signal_step(u32 code){
LINUX_FN_DEBUG("%d", code);
linux_schedule_step();
}
internal void
system_sleep(u64 microseconds){
LINUX_FN_DEBUG("%" PRIu64, microseconds);
struct timespec requested;
struct timespec remaining;
u64 seconds = microseconds / Million(1);
@ -244,6 +261,7 @@ system_sleep(u64 microseconds){
internal void
system_post_clipboard(String_Const_u8 str){
LINUX_FN_DEBUG("%.*s", (int)str.size, str.str);
linalloc_clear(&linuxvars.clipboard_out_arena);
char* p = push_array(&linuxvars.clipboard_out_arena, char, str.size + 1);
block_copy(p, str.data, str.size);
@ -253,6 +271,7 @@ system_post_clipboard(String_Const_u8 str){
internal b32
system_cli_call(Arena* scratch, char* path, char* script, CLI_Handles* cli_out){
LINUX_FN_DEBUG("%s / %s", path, script);
int pipe_fds[2];
if (pipe(pipe_fds) == -1){
perror("system_cli_call: pipe");
@ -304,10 +323,12 @@ system_cli_call(Arena* scratch, char* path, char* script, CLI_Handles* cli_out){
internal void
system_cli_begin_update(CLI_Handles* cli){
// NOTE(inso): I don't think anything needs to be done here.
LINUX_FN_DEBUG();
}
internal b32
system_cli_update_step(CLI_Handles* cli, char* dest, u32 max, u32* amount){
LINUX_FN_DEBUG();
int pipe_read_fd = *(int*)&cli->out_read;
fd_set fds;
@ -338,6 +359,7 @@ system_cli_update_step(CLI_Handles* cli, char* dest, u32 max, u32* amount){
internal b32
system_cli_end_update(CLI_Handles* cli){
LINUX_FN_DEBUG();
pid_t pid = *(pid_t*)&cli->proc;
b32 close_me = false;
@ -359,10 +381,12 @@ system_cli_end_update(CLI_Handles* cli){
internal void
system_open_color_picker(Color_Picker* picker){
// TODO?
LINUX_FN_DEBUG();
}
internal f32
system_get_screen_scale_factor(void){
LINUX_FN_DEBUG();
// TODO: correct screen number somehow
int dpi = linux_get_xsettings_dpi(linuxvars.dpy, 0);
if(dpi == -1){
@ -380,6 +404,7 @@ system_get_screen_scale_factor(void){
internal System_Thread
system_thread_launch(Thread_Function* proc, void* ptr){
LINUX_FN_DEBUG();
System_Thread result = {};
Linux_Object* thread_info = linux_alloc_object(LinuxObjectKind_Thread);
@ -408,6 +433,7 @@ system_thread_launch(Thread_Function* proc, void* ptr){
internal void
system_thread_join(System_Thread thread){
LINUX_FN_DEBUG();
Linux_Object* object = *(Linux_Object**)&thread;
void* retval_ignored;
int result = pthread_join(object->thread.pthread, &retval_ignored);
@ -415,6 +441,7 @@ system_thread_join(System_Thread thread){
internal void
system_thread_free(System_Thread thread){
LINUX_FN_DEBUG();
Linux_Object* object = *(Linux_Object**)&thread;
Assert(object->kind == LinuxObjectKind_Thread);
linux_free_object(object);
@ -422,13 +449,18 @@ system_thread_free(System_Thread thread){
internal i32
system_thread_get_id(void){
LINUX_FN_DEBUG();
pthread_t tid = pthread_self();
Assert(tid <= (u64)max_i32);
return (i32)tid;
// WELP hope it doesn't collide
i32 shorter_id = ((u64)tid >> 32) ^ ((u32)tid & bitmask_32);
return shorter_id;
}
internal void
system_acquire_global_frame_mutex(Thread_Context* tctx){
LINUX_FN_DEBUG();
if (tctx->kind == ThreadKind_AsyncTasks){
system_mutex_acquire(linuxvars.global_frame_mutex);
}
@ -436,6 +468,7 @@ system_acquire_global_frame_mutex(Thread_Context* tctx){
internal void
system_release_global_frame_mutex(Thread_Context* tctx){
LINUX_FN_DEBUG();
if (tctx->kind == ThreadKind_AsyncTasks){
system_mutex_release(linuxvars.global_frame_mutex);
}
@ -447,12 +480,14 @@ system_mutex_make(void){
Linux_Object* object = linux_alloc_object(LinuxObjectKind_Mutex);
pthread_mutex_init(&object->mutex, NULL);
*(Linux_Object**)&result = object;
LINUX_FN_DEBUG("%p", object);
return result;
}
internal void
system_mutex_acquire(System_Mutex mutex){
Linux_Object* object = *(Linux_Object**)&mutex;
LINUX_FN_DEBUG("%p", object);
Assert(object->kind == LinuxObjectKind_Mutex);
pthread_mutex_lock(&object->mutex);
}
@ -460,6 +495,7 @@ system_mutex_acquire(System_Mutex mutex){
internal void
system_mutex_release(System_Mutex mutex){
Linux_Object* object = *(Linux_Object**)&mutex;
LINUX_FN_DEBUG("%p", object);
Assert(object->kind == LinuxObjectKind_Mutex);
pthread_mutex_unlock(&object->mutex);
}
@ -467,6 +503,7 @@ system_mutex_release(System_Mutex mutex){
internal void
system_mutex_free(System_Mutex mutex){
Linux_Object* object = *(Linux_Object**)&mutex;
LINUX_FN_DEBUG("%p", object);
Assert(object->kind == LinuxObjectKind_Mutex);
pthread_mutex_destroy(&object->mutex);
linux_free_object(object);
@ -476,6 +513,7 @@ internal System_Condition_Variable
system_condition_variable_make(void){
System_Condition_Variable result = {};
Linux_Object* object = linux_alloc_object(LinuxObjectKind_ConditionVariable);
LINUX_FN_DEBUG("%p", object);
pthread_cond_init(&object->condition_variable, NULL);
*(Linux_Object**)&result = object;
return result;
@ -485,6 +523,7 @@ internal void
system_condition_variable_wait(System_Condition_Variable cv, System_Mutex mutex){
Linux_Object* cv_object = *(Linux_Object**)&cv;
Linux_Object* mutex_object = *(Linux_Object**)&mutex;
LINUX_FN_DEBUG("%p / %p", cv_object, mutex_object);
Assert(cv_object->kind == LinuxObjectKind_ConditionVariable);
Assert(mutex_object->kind == LinuxObjectKind_Mutex);
pthread_cond_wait(&cv_object->condition_variable, &mutex_object->mutex);
@ -493,6 +532,7 @@ system_condition_variable_wait(System_Condition_Variable cv, System_Mutex mutex)
internal void
system_condition_variable_signal(System_Condition_Variable cv){
Linux_Object* object = *(Linux_Object**)&cv;
LINUX_FN_DEBUG("%p", object);
Assert(object->kind == LinuxObjectKind_ConditionVariable);
pthread_cond_signal(&object->condition_variable);
}
@ -500,6 +540,7 @@ system_condition_variable_signal(System_Condition_Variable cv){
internal void
system_condition_variable_free(System_Condition_Variable cv){
Linux_Object* object = *(Linux_Object**)&cv;
LINUX_FN_DEBUG("%p", object);
Assert(object->kind == LinuxObjectKind_ConditionVariable);
pthread_cond_destroy(&object->condition_variable);
linux_free_object(object);
@ -507,14 +548,17 @@ system_condition_variable_free(System_Condition_Variable cv){
internal void*
system_memory_allocate(u64 size, String_Const_u8 location){
void* result = mmap(
NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// TODO(andrew): Allocation tracking?
LINUX_FN_DEBUG("%" PRIu64 ", %.*s %p", size, (int)location.size, location.str, result);
return result;
}
internal b32
system_memory_set_protection(void* ptr, u64 size, u32 flags){
LINUX_FN_DEBUG("%p / %ld / %d", ptr, size, flags);
int protect = 0;
MovFlag(flags, MemProtect_Read, protect, PROT_READ);
MovFlag(flags, MemProtect_Write, protect, PROT_WRITE);
@ -525,16 +569,20 @@ system_memory_set_protection(void* ptr, u64 size, u32 flags){
internal void
system_memory_free(void* ptr, u64 size){
LINUX_FN_DEBUG("%p / %ld", ptr, size);
munmap(ptr, size);
}
internal Memory_Annotation
system_memory_annotation(Arena* arena){
LINUX_FN_DEBUG();
// TODO;
}
internal void
system_show_mouse_cursor(i32 show){
LINUX_FN_DEBUG("%d", show);
linuxvars.cursor_show = show;
XDefineCursor(
@ -545,17 +593,21 @@ system_show_mouse_cursor(i32 show){
internal b32
system_set_fullscreen(b32 full_screen){
LINUX_FN_DEBUG("%d", full_screen);
linuxvars.should_be_full_screen = full_screen;
return true;
}
internal b32
system_is_fullscreen(void){
LINUX_FN_DEBUG();
return linuxvars.is_full_screen;
}
internal Input_Modifier_Set
system_get_keyboard_modifiers(Arena* arena){
LINUX_FN_DEBUG();
// TODO:
//return(copy_modifier_set(arena, &linuxvars.input_chunk.pers.modifiers));
}

View File

@ -76,13 +76,12 @@ system_error_box(char *msg, b32 shutdown = true){
int button_trigger = 0;
int button_hi = 0;
int redraw = 1;
XEvent ev;
while (1){
XNextEvent(dpy, &ev);
int redraw = 0;
if (ev.type == Expose) redraw = 1;
if (ev.type == ConfigureNotify){
@ -137,6 +136,7 @@ system_error_box(char *msg, b32 shutdown = true){
XDrawString(dpy, w, gc1, (x) , (y) , (str), (len))
if (redraw){
redraw = 0;
XClearWindow(dpy, w);
const char* line_start = msg;