diff --git a/platform_linux/linux_4ed.cpp b/platform_linux/linux_4ed.cpp index 2f915764..fa9cd582 100644 --- a/platform_linux/linux_4ed.cpp +++ b/platform_linux/linux_4ed.cpp @@ -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; } diff --git a/platform_linux/linux_4ed_functions.cpp b/platform_linux/linux_4ed_functions.cpp index ede1ee41..ab956b92 100644 --- a/platform_linux/linux_4ed_functions.cpp +++ b/platform_linux/linux_4ed_functions.cpp @@ -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)); } diff --git a/platform_linux/linux_error_box.cpp b/platform_linux/linux_error_box.cpp index 83f439ab..f61aa3d6 100644 --- a/platform_linux/linux_error_box.cpp +++ b/platform_linux/linux_error_box.cpp @@ -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;