runs but quite broken
							parent
							
								
									1e7da9c06c
								
							
						
					
					
						commit
						56f5d78fa2
					
				|  | @ -15,11 +15,6 @@ | |||
| #define SLASH '/' | ||||
| #define DLL "so" | ||||
| 
 | ||||
| #define container_of(ptr, type, member) ({            \ | ||||
| 	const typeof(((type*)0)->member)* __mptr = (ptr); \ | ||||
| 	(type*)((char*)__mptr - offsetof(type, member));  \ | ||||
| }) | ||||
| 
 | ||||
| #include "4coder_base_types.h" | ||||
| #include "4coder_version.h" | ||||
| #include "4coder_events.h" | ||||
|  | @ -95,6 +90,10 @@ | |||
| #define function static | ||||
| #undef Cursor | ||||
| 
 | ||||
| #undef internal | ||||
| #include <fontconfig/fontconfig.h> | ||||
| #define internal static | ||||
| 
 | ||||
| #include <GL/glx.h> | ||||
| #include <GL/glext.h> | ||||
| 
 | ||||
|  | @ -149,6 +148,7 @@ struct Linux_Vars { | |||
|     int xfixes_selection_event; | ||||
|     XIM xim; | ||||
|     XIC xic; | ||||
|     FcConfig* fontconfig; | ||||
| 
 | ||||
|     Linux_Input_Chunk input; | ||||
| 
 | ||||
|  | @ -291,6 +291,20 @@ linux_free_object(Linux_Object *object){ | |||
| 
 | ||||
| ////////////////////////////
 | ||||
| 
 | ||||
| internal int | ||||
| linux_compare_file_infos(File_Info** a, File_Info** b) { | ||||
|     b32 a_hidden = (*a)->file_name.str[0] == '.'; | ||||
|     b32 b_hidden = (*b)->file_name.str[0] == '.'; | ||||
| 
 | ||||
|     // hidden files lower in list
 | ||||
|     if(a_hidden != b_hidden) { | ||||
|         return a_hidden - b_hidden; | ||||
|     } | ||||
| 
 | ||||
|     // push_stringf seems to null terminate
 | ||||
|     return strcoll((char*)(*a)->file_name.str, (char*)(*b)->file_name.str); | ||||
| } | ||||
| 
 | ||||
| internal int | ||||
| linux_system_get_file_list_filter(const struct dirent *dirent) { | ||||
|     String_Const_u8 file_name = SCu8((u8*)dirent->d_name); | ||||
|  | @ -316,11 +330,11 @@ linux_convert_file_attribute_flags(int mode) { | |||
| } | ||||
| 
 | ||||
| internal File_Attributes | ||||
| linux_file_attributes_from_struct_stat(struct stat file_stat) { | ||||
| linux_file_attributes_from_struct_stat(struct stat* file_stat) { | ||||
|     File_Attributes result = {}; | ||||
|     result.size = file_stat.st_size; | ||||
|     result.last_write_time = linux_u64_from_timespec(file_stat.st_mtim); | ||||
|     result.flags = linux_convert_file_attribute_flags(file_stat.st_mode); | ||||
|     result.size = file_stat->st_size; | ||||
|     result.last_write_time = linux_u64_from_timespec(file_stat->st_mtim); | ||||
|     result.flags = linux_convert_file_attribute_flags(file_stat->st_mode); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -501,8 +515,74 @@ graphics_fill_texture_sig(){ | |||
| 
 | ||||
| ////////////////////////////
 | ||||
| 
 | ||||
| internal Face_Description | ||||
| linux_find_font(Face_Description* desc) { | ||||
|     Face_Description result = *desc; | ||||
| 
 | ||||
|     char* name = strndupa((char*)desc->font.file_name.str, desc->font.file_name.size); | ||||
| 
 | ||||
|     double size; | ||||
|     const char* style; | ||||
|     { | ||||
|         Face_Load_Parameters* p = &desc->parameters; | ||||
|         size = p->pt_size; | ||||
| 
 | ||||
|         if(p->bold && p->italic) { | ||||
|             style = "Bold Italic"; | ||||
|         } else if(p->bold) { | ||||
|             style = "Bold"; | ||||
|         } else if(p->italic) { | ||||
|             style = "Italic"; | ||||
|         } else { | ||||
|             style = "Regular"; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     FcPattern *pattern = FcPatternBuild( | ||||
|         0, | ||||
|         FC_POSTSCRIPT_NAME, FcTypeString, name, | ||||
|         FC_SIZE, FcTypeDouble, size, | ||||
|         FC_FONTFORMAT, FcTypeString, "TrueType", | ||||
|         FC_STYLE, FcTypeString, (FcChar8*)style, | ||||
|         NULL); | ||||
| 
 | ||||
|     if(!pattern) { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     if (FcConfigSubstitute(linuxvars.fontconfig, pattern, FcMatchPattern)){ | ||||
|         FcDefaultSubstitute(pattern); | ||||
| 
 | ||||
|         FcResult res; | ||||
|         FcPattern *font = FcFontMatch(linuxvars.fontconfig, pattern, &res); | ||||
|         if (!font){ | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         FcChar8 *filename = 0; | ||||
|         FcPatternGetString(font, FC_FILE, 0, &filename); | ||||
|         if(filename) { | ||||
|             printf("FONTCONFIG FILENAME = %s\n", filename); | ||||
|             result.font.file_name = push_u8_stringf(linuxvars.frame_arena, "%s", filename); | ||||
|         } | ||||
| 
 | ||||
|         FcPatternDestroy(font); | ||||
|     } | ||||
| 
 | ||||
|     FcPatternDestroy(pattern); | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| internal | ||||
| 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); | ||||
| 
 | ||||
|     if(!result) { | ||||
|  | @ -690,7 +770,7 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) { | |||
|     render_target.height = h; | ||||
| 
 | ||||
|     XSetWindowAttributes swa = {}; | ||||
|     swa.backing_store = WhenMapped; | ||||
|     swa.backing_store = NotUseful; | ||||
|     swa.event_mask = StructureNotifyMask; | ||||
|     swa.bit_gravity = NorthWestGravity; | ||||
|     swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi.screen), vi.visual, AllocNone); | ||||
|  | @ -892,7 +972,6 @@ linux_keycode_init(Display* dpy){ | |||
|     *p++ = { XK_equal, KeyCode_Equal }; | ||||
|     *p++ = { XK_bracketleft, KeyCode_LeftBracket }; | ||||
|     *p++ = { XK_bracketright, KeyCode_RightBracket }; | ||||
|     *p++ = { XK_bracketright, KeyCode_RightBracket }; | ||||
|     *p++ = { XK_semicolon, KeyCode_Semicolon }; | ||||
|     *p++ = { XK_apostrophe, KeyCode_Quote }; | ||||
|     *p++ = { XK_comma, KeyCode_Comma }; | ||||
|  | @ -957,7 +1036,7 @@ linux_keycode_init(Display* dpy){ | |||
|     XFree(syms); | ||||
| } | ||||
| 
 | ||||
| internal b32 | ||||
| internal void | ||||
| linux_handle_x11_events() { | ||||
|     static XEvent prev_event = {}; | ||||
|     b32 should_step = false; | ||||
|  | @ -993,9 +1072,9 @@ linux_handle_x11_events() { | |||
| 
 | ||||
|                 Status status; | ||||
|                 KeySym keysym = NoSymbol; | ||||
|                 u8 buff[32] = {}; | ||||
|                 u8 buff[256] = {}; | ||||
| 
 | ||||
|                 Xutf8LookupString(linuxvars.xic, &event.xkey, (char*)buff, sizeof(buff) - 1, &keysym, &status); | ||||
|                 int len = Xutf8LookupString(linuxvars.xic, &event.xkey, (char*)buff, sizeof(buff) - 1, &keysym, &status); | ||||
| 
 | ||||
|                 if (status == XBufferOverflow){ | ||||
|                     //TODO(inso): handle properly
 | ||||
|  | @ -1003,17 +1082,27 @@ linux_handle_x11_events() { | |||
|                     XSetICFocus(linuxvars.xic); | ||||
|                 } | ||||
| 
 | ||||
|                 // don't push modifiers
 | ||||
|                 if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R){ | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 if (keysym == XK_ISO_Left_Tab){ | ||||
|                     //text = '\t';
 | ||||
|                     add_modifier(mods, KeyCode_Shift); | ||||
|                 } | ||||
| 
 | ||||
|                 // TODO: use keycode_lookup_table, push the key and text.
 | ||||
|                 Key_Code key = keycode_lookup_table[(u8)event.xkey.keycode]; | ||||
|                 printf("key [%d] = %s\n", event.xkey.keycode, key_code_name[key]); | ||||
| 
 | ||||
|                 if(key) { | ||||
|                     Input_Event *ev = push_input_event(linuxvars.frame_arena, &linuxvars.input.trans.event_list); | ||||
|                     ev->kind = InputEventKind_KeyStroke; | ||||
|                     ev->key.code = key; | ||||
|                     ev->key.modifiers = copy_modifier_set(linuxvars.frame_arena, mods); | ||||
|                 } | ||||
| 
 | ||||
|                 if(status == XLookupChars || status == XLookupBoth) { | ||||
|                     u8* ptr = push_array_write(linuxvars.frame_arena, u8, len, buff); | ||||
|                     Input_Event* ev = push_input_event(linuxvars.frame_arena, &linuxvars.input.trans.event_list); | ||||
|                     ev->kind = InputEventKind_TextInsert; | ||||
|                     ev->text.string = SCu8(ptr, len); | ||||
|                 } | ||||
| 
 | ||||
|             } break; | ||||
| 
 | ||||
|  | @ -1023,8 +1112,23 @@ linux_handle_x11_events() { | |||
|                     linux_keycode_init(linuxvars.dpy); | ||||
|                 } | ||||
|             } break; | ||||
| 
 | ||||
|             case ConfigureNotify: { | ||||
|                 should_step = true; | ||||
|                 i32 w = event.xconfigure.width; | ||||
|                 i32 h = event.xconfigure.height; | ||||
| 
 | ||||
|                 if (w != render_target.width || h != render_target.height){ | ||||
|                     render_target.width = w; | ||||
|                     render_target.height = h; | ||||
|                 } | ||||
|             } break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(should_step) { | ||||
|         linux_schedule_step(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| internal b32 | ||||
|  | @ -1058,7 +1162,7 @@ linux_epoll_process(struct epoll_event* events, int num_events) { | |||
|             } break; | ||||
| 
 | ||||
|             case EPOLL_USER_TIMER: { | ||||
|                 Linux_Object* obj = container_of(tag, Linux_Object, timer.epoll_tag); | ||||
|                 Linux_Object* obj = CastFromMember(Linux_Object, timer.epoll_tag, tag); | ||||
|                 close(obj->timer.fd); | ||||
|                 obj->timer.fd = -1; | ||||
|                 do_step = true; | ||||
|  | @ -1092,6 +1196,8 @@ main(int argc, char **argv){ | |||
|     // TODO(allen): *arena;
 | ||||
|     render_target.arena = make_arena_system(KB(256)); | ||||
| 
 | ||||
|     linuxvars.fontconfig = FcInitLoadConfigAndFonts(); | ||||
| 
 | ||||
|     linuxvars.cursor_show = MouseCursorShow_Always; | ||||
|     linuxvars.prev_cursor_show = MouseCursorShow_Always; | ||||
| 
 | ||||
|  | @ -1262,6 +1368,7 @@ main(int argc, char **argv){ | |||
| 
 | ||||
|     linux_schedule_step(); | ||||
| 
 | ||||
|     b32 first_step = true; | ||||
|     b32 keep_running = true; | ||||
|     for (;keep_running;){ | ||||
| 
 | ||||
|  | @ -1288,7 +1395,6 @@ main(int argc, char **argv){ | |||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         b32 first_step = true; | ||||
|         linuxvars.last_step_time = system_now_time(); | ||||
| 
 | ||||
|         // NOTE(allen): Frame Clipboard Input
 | ||||
|  | @ -1297,21 +1403,24 @@ main(int argc, char **argv){ | |||
|             XConvertSelection(linuxvars.dpy, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.win, CurrentTime); | ||||
|         } | ||||
| 
 | ||||
|         Application_Step_Input frame_input = {}; | ||||
|         Application_Step_Input input = {}; | ||||
| 
 | ||||
|         if (linuxvars.received_new_clipboard){ | ||||
|             frame_input.clipboard = linuxvars.clipboard_contents; | ||||
|             input.clipboard = linuxvars.clipboard_contents; | ||||
|             linuxvars.received_new_clipboard = false; | ||||
|         } | ||||
| 
 | ||||
|         // TODO: fill the rest of it
 | ||||
|         frame_input.trying_to_kill = !keep_running; | ||||
|         input.trying_to_kill = !keep_running; | ||||
|         input.dt = frame_useconds/1000000.f; | ||||
|         input.events = linuxvars.input.trans.event_list; | ||||
|         input.first_step = first_step; | ||||
| 
 | ||||
|         // NOTE(allen): Application Core Update
 | ||||
|         // render_target.buffer.pos = 0;
 | ||||
|         Application_Step_Result result = {}; | ||||
|         if (app.step != 0){ | ||||
|             result = app.step(&linuxvars.tctx, &render_target, base_ptr, &frame_input); | ||||
|             result = app.step(&linuxvars.tctx, &render_target, base_ptr, &input); | ||||
|         } | ||||
|         else{ | ||||
|             //LOG("app.step == 0 -- skipping\n");
 | ||||
|  | @ -1346,6 +1455,9 @@ main(int argc, char **argv){ | |||
|         glXSwapBuffers(linuxvars.dpy, linuxvars.win); | ||||
| 
 | ||||
|         first_step = false; | ||||
| 
 | ||||
|         linalloc_clear(linuxvars.frame_arena); | ||||
|         block_zero_struct(&linuxvars.input.trans); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
|  |  | |||
|  | @ -64,41 +64,52 @@ 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 = {}; | ||||
| 
 | ||||
|     if (character_is_slash(string_get_character(directory, directory.size - 1))){ | ||||
|         search_pattern = push_u8_stringf(arena, "%.*s*", string_expand(directory)); | ||||
|     } | ||||
|     else{ | ||||
|         search_pattern = push_u8_stringf(arena, "%.*s/*", string_expand(directory)); | ||||
|     char* path = strndupa((char*)directory.str, directory.size); | ||||
|     int fd = open(path, O_RDONLY | O_DIRECTORY); | ||||
|     if(fd == -1) { | ||||
|         perror("open"); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     struct dirent** dir_ents = NULL; | ||||
|     int num_ents = scandir( | ||||
|         (const char*)search_pattern.str, &dir_ents, linux_system_get_file_list_filter, alphasort); | ||||
|     DIR* dir = fdopendir(fd); | ||||
|     struct dirent* d; | ||||
| 
 | ||||
|     File_Info *first = 0; | ||||
|     File_Info *last = 0; | ||||
|     for (int i = 0; i < num_ents; ++i) { | ||||
|         struct dirent* dirent = dir_ents[i]; | ||||
|         File_Info *info = push_array(arena, File_Info, 1); | ||||
|         sll_queue_push(first, last, info); | ||||
|     File_Info* head = NULL; | ||||
|     File_Info** fip = &head; | ||||
| 
 | ||||
|         info->file_name = SCu8((u8*)dirent->d_name); | ||||
|     while((d = readdir(dir))) { | ||||
|         const char* name = d->d_name; | ||||
| 
 | ||||
|         struct stat file_stat; | ||||
|         stat((const char*)dirent->d_name, &file_stat); | ||||
|         info->attributes = linux_file_attributes_from_struct_stat(file_stat); | ||||
|         // ignore . and ..
 | ||||
|         if(*name == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         *fip = push_array(arena, File_Info, 1); | ||||
|         (*fip)->file_name = push_u8_stringf(arena, "%.*s", d->d_reclen, name); | ||||
| 
 | ||||
|         struct stat st; | ||||
|         if(fstatat(fd, name, &st, 0) == -1){ | ||||
|             perror("fstatat"); | ||||
|         } | ||||
| 
 | ||||
|         (*fip)->attributes = linux_file_attributes_from_struct_stat(&st); | ||||
|         fip = &(*fip)->next; | ||||
|         result.count++; | ||||
|     } | ||||
|     closedir(dir); | ||||
| 
 | ||||
|     result.infos = fip = push_array(arena, File_Info*, result.count); | ||||
| 
 | ||||
|     for(File_Info* f = head; f; f = f->next) { | ||||
|         *fip++ = f; | ||||
|     } | ||||
| 
 | ||||
|     result.infos = push_array(arena, File_Info*, num_ents); | ||||
|     result.count = num_ents; | ||||
|     qsort(result.infos, result.count, sizeof(File_Info*), (__compar_fn_t)&linux_compare_file_infos); | ||||
| 
 | ||||
|     i32 info_index = 0; | ||||
|     for (File_Info* node = first; node != NULL; node = node->next) { | ||||
|         result.infos[info_index] = node; | ||||
|         info_index += 1; | ||||
|     } | ||||
| 
 | ||||
|     // TODO: relink in new order?
 | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
|  | @ -108,7 +119,7 @@ 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); | ||||
|     return linux_file_attributes_from_struct_stat(&file_stat); | ||||
| } | ||||
| 
 | ||||
| internal b32 | ||||
|  | @ -127,7 +138,7 @@ 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); | ||||
|     return linux_file_attributes_from_struct_stat(&file_stat); | ||||
| } | ||||
| 
 | ||||
| internal b32 | ||||
|  | @ -158,7 +169,7 @@ system_save_file(Arena* scratch, char* file_name, String_Const_u8 data){ | |||
|         if (bytes_written != -1) { | ||||
|             struct stat file_stat; | ||||
|             fstat(fd, &file_stat); | ||||
|             return linux_file_attributes_from_struct_stat(file_stat); | ||||
|             return linux_file_attributes_from_struct_stat(&file_stat); | ||||
|         } | ||||
|     } | ||||
|     return result; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Alex Baines
						Alex Baines