runs but quite broken

master
Alex Baines 2020-02-04 21:38:37 +00:00
parent 1e7da9c06c
commit 56f5d78fa2
2 changed files with 178 additions and 55 deletions

View File

@ -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;

View File

@ -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;