setting up better organization for file system
This commit is contained in:
parent
5f00639970
commit
1ef304558e
158
4coder_string.h
158
4coder_string.h
|
@ -2019,102 +2019,110 @@ typedef struct Absolutes{
|
|||
|
||||
static void
|
||||
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
|
||||
int32_t count = 0;
|
||||
int32_t max = ArrayCount(absolutes->a) - 1;
|
||||
if (implicit_last) --max;
|
||||
if (name.size != 0){
|
||||
int32_t count = 0;
|
||||
int32_t max = ArrayCount(absolutes->a) - 1;
|
||||
if (implicit_last) --max;
|
||||
|
||||
String str;
|
||||
str.str = name.str;
|
||||
str.size = 0;
|
||||
str.memory_size = 0;
|
||||
fstr_bool prev_was_wild = 0;
|
||||
|
||||
if (implicit_first){
|
||||
absolutes->a[count++] = str;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < name.size; ++i){
|
||||
if (name.str[i] == '*' && count < max){
|
||||
if (!prev_was_wild){
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
str.size = 0;
|
||||
}
|
||||
str.str = name.str + i + 1;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
else{
|
||||
++str.size;
|
||||
prev_was_wild = 0;
|
||||
}
|
||||
}
|
||||
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
|
||||
if (implicit_last){
|
||||
String str;
|
||||
str.str = name.str;
|
||||
str.size = 0;
|
||||
str.memory_size = 0;
|
||||
absolutes->a[count++] = str;
|
||||
}
|
||||
fstr_bool prev_was_wild = 0;
|
||||
|
||||
absolutes->count = count;
|
||||
if (implicit_first){
|
||||
absolutes->a[count++] = str;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < name.size; ++i){
|
||||
if (name.str[i] == '*' && count < max){
|
||||
if (!prev_was_wild){
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
str.size = 0;
|
||||
}
|
||||
str.str = name.str + i + 1;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
else{
|
||||
++str.size;
|
||||
prev_was_wild = 0;
|
||||
}
|
||||
}
|
||||
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
|
||||
if (implicit_last){
|
||||
str.size = 0;
|
||||
str.memory_size = 0;
|
||||
absolutes->a[count++] = str;
|
||||
}
|
||||
|
||||
absolutes->count = count;
|
||||
}
|
||||
else{
|
||||
absolutes->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static fstr_bool
|
||||
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
|
||||
fstr_bool r = 1;
|
||||
String *a = absolutes->a;
|
||||
|
||||
fstr_bool (*match_func)(char*, String);
|
||||
fstr_bool (*match_part_func)(char*, String);
|
||||
if (absolutes->count > 0){
|
||||
String *a = absolutes->a;
|
||||
|
||||
if (case_sensitive){
|
||||
match_func = match_cs;
|
||||
match_part_func = match_part_cs;
|
||||
}
|
||||
else{
|
||||
match_func = match_insensitive_cs;
|
||||
match_part_func = match_part_insensitive_cs;
|
||||
}
|
||||
fstr_bool (*match_func)(char*, String);
|
||||
fstr_bool (*match_part_func)(char*, String);
|
||||
|
||||
if (absolutes->count == 1){
|
||||
r = match_func(x, *a);
|
||||
}
|
||||
else{
|
||||
if (!match_part_func(x, *a)){
|
||||
r = 0;
|
||||
if (case_sensitive){
|
||||
match_func = match_cs;
|
||||
match_part_func = match_part_cs;
|
||||
}
|
||||
else{
|
||||
String *max = a + absolutes->count - 1;
|
||||
x += a->size;
|
||||
++a;
|
||||
while (a < max){
|
||||
if (*x == 0){
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
if (match_part_func(x, *a)){
|
||||
x += a->size;
|
||||
++a;
|
||||
}
|
||||
else{
|
||||
++x;
|
||||
}
|
||||
}
|
||||
if (r && a->size > 0){
|
||||
match_func = match_insensitive_cs;
|
||||
match_part_func = match_part_insensitive_cs;
|
||||
}
|
||||
|
||||
if (absolutes->count == 1){
|
||||
r = match_func(x, *a);
|
||||
}
|
||||
else{
|
||||
if (!match_part_func(x, *a)){
|
||||
r = 0;
|
||||
while (*x != 0){
|
||||
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
||||
r = 1;
|
||||
}
|
||||
else{
|
||||
String *max = a + absolutes->count - 1;
|
||||
x += a->size;
|
||||
++a;
|
||||
while (a < max){
|
||||
if (*x == 0){
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
if (match_part_func(x, *a)){
|
||||
x += a->size;
|
||||
++a;
|
||||
}
|
||||
else{
|
||||
++x;
|
||||
}
|
||||
}
|
||||
if (r && a->size > 0){
|
||||
r = 0;
|
||||
while (*x != 0){
|
||||
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
++x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
4ed.cpp
4
4ed.cpp
|
@ -1732,7 +1732,7 @@ App_Init_Sig(app_init){
|
|||
models->layout.active_panel = p.id;
|
||||
|
||||
String hdbase = make_fixed_width_string(models->hot_dir_base_);
|
||||
hot_directory_init(&models->hot_directory, hdbase, current_directory, system->slash);
|
||||
hot_directory_init(&models->hot_directory, hdbase, current_directory);
|
||||
|
||||
// NOTE(allen): child proc list setup
|
||||
i32 max_children = 16;
|
||||
|
@ -2870,7 +2870,7 @@ App_Step_Sig(app_step){
|
|||
// end-of-app_step
|
||||
}
|
||||
|
||||
external App_Get_Functions_Sig(app_get_functions){
|
||||
extern "C" App_Get_Functions_Sig(app_get_functions){
|
||||
App_Functions result = {};
|
||||
|
||||
result.read_command_line = app_read_command_line;
|
||||
|
|
|
@ -45,7 +45,10 @@
|
|||
#include "buffer/4coder_gap_buffer.cpp"
|
||||
#define Buffer_Type Gap_Buffer
|
||||
#include "buffer/4coder_buffer_abstract.cpp"
|
||||
#include "4ed_file.cpp"
|
||||
|
||||
#include "file/4coder_file.cpp"
|
||||
#include "file/4coder_working_set.cpp"
|
||||
#include "file/4coder_hot_directory.cpp"
|
||||
|
||||
#include "4ed_gui.cpp"
|
||||
#include "4ed_layout.cpp"
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
#define FRED_DEFINES_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined (FRED_TYPES)
|
||||
#include <stdint.h>
|
||||
#define FRED_TYPES
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
|
@ -34,12 +36,12 @@ typedef double real64;
|
|||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#define external extern "C"
|
||||
#define internal static
|
||||
#define globalvar static
|
||||
#define persist static
|
||||
|
||||
#define globalconst static const
|
||||
#endif
|
||||
|
||||
#define COMP_ID_(a,b,c,d) (d << 24) | (c << 16) | (b << 8) | a
|
||||
#define COMPOSE_ID(a,b,c,d) (COMP_ID_((a),(b),(c),(d)))
|
||||
|
@ -97,13 +99,13 @@ TMin(i64, -9223372036854775807-1);
|
|||
|
||||
internal i32
|
||||
LargeRoundUp(i32 x, i32 granularity){
|
||||
i32 original_x = x;
|
||||
x /= granularity;
|
||||
x *= granularity;
|
||||
if (x < original_x){
|
||||
x += granularity;
|
||||
}
|
||||
return x;
|
||||
i32 original_x = x;
|
||||
x /= granularity;
|
||||
x *= granularity;
|
||||
if (x < original_x){
|
||||
x += granularity;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
#define Bit_0 (1 << 0)
|
||||
|
|
|
@ -596,11 +596,9 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll,
|
|||
}
|
||||
|
||||
internal void
|
||||
view_set_cursor(View *view, Full_Cursor cursor,
|
||||
b32 set_preferred_x, b32 unwrapped_lines){
|
||||
view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
|
||||
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
||||
edit_pos_set_cursor_(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
|
||||
edit_pos_set_cursor(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
GUI_Scroll_Vars scroll = view->edit_pos->scroll;
|
||||
if (view_move_view_to_cursor(view, &scroll, 0)){
|
||||
view->edit_pos->scroll = scroll;
|
||||
|
@ -609,11 +607,9 @@ view_set_cursor(View *view, Full_Cursor cursor,
|
|||
}
|
||||
|
||||
internal void
|
||||
view_set_scroll(View *view,
|
||||
GUI_Scroll_Vars scroll){
|
||||
view_set_scroll(View *view, GUI_Scroll_Vars scroll){
|
||||
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
||||
edit_pos_set_scroll_(view->edit_pos, scroll);
|
||||
|
||||
edit_pos_set_scroll(view->edit_pos, scroll);
|
||||
Full_Cursor cursor = view->edit_pos->cursor;
|
||||
if (view_move_cursor_to_view(view, view->edit_pos->scroll,
|
||||
&cursor, view->edit_pos->preferred_x)){
|
||||
|
@ -623,15 +619,11 @@ view_set_scroll(View *view,
|
|||
}
|
||||
|
||||
internal void
|
||||
view_set_cursor_and_scroll(View *view,
|
||||
Full_Cursor cursor,
|
||||
b32 set_preferred_x,
|
||||
b32 unwrapped_lines,
|
||||
GUI_Scroll_Vars scroll){
|
||||
view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines, GUI_Scroll_Vars scroll){
|
||||
File_Edit_Positions *edit_pos = view->edit_pos;
|
||||
if (edit_pos_move_to_front(view->file_data.file, edit_pos)){
|
||||
edit_pos_set_cursor_(edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
edit_pos_set_scroll_(edit_pos, scroll);
|
||||
edit_pos_set_cursor(edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
edit_pos_set_scroll(edit_pos, scroll);
|
||||
edit_pos->last_set_type = EditPos_None;
|
||||
}
|
||||
}
|
||||
|
@ -1251,12 +1243,15 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16
|
|||
}
|
||||
else if (type == CPP_TOKEN_PARENTHESE_OPEN){
|
||||
if (on_left){
|
||||
guess = 0;
|
||||
guess = 100;
|
||||
}
|
||||
else{
|
||||
if (other_is_words){
|
||||
guess = 100;
|
||||
}
|
||||
else{
|
||||
guess = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == CPP_TOKEN_SEMICOLON){
|
||||
|
@ -3700,7 +3695,7 @@ view_show_interactive(System_Functions *system, View *view,
|
|||
view->map = &models->map_ui;
|
||||
|
||||
hot_directory_clean_end(&models->hot_directory);
|
||||
hot_directory_reload(system, &models->hot_directory, &models->working_set);
|
||||
hot_directory_reload(system, &models->hot_directory);
|
||||
view->changed_context_in_step = 1;
|
||||
}
|
||||
|
||||
|
@ -4271,11 +4266,10 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti
|
|||
file = working_set_canon_contains(working_set, canon_name.name);
|
||||
}
|
||||
|
||||
String filename = make_string_cap(result.info->filename,
|
||||
result.info->filename_len, result.info->filename_len+1);
|
||||
String filename = make_string_cap(result.info->filename, result.info->filename_len, result.info->filename_len+1);
|
||||
|
||||
result.is_folder = (result.info->folder != 0);
|
||||
result.name_match = (filename_match(loop->front_name, &loop->absolutes, filename) != 0);
|
||||
result.name_match = (wildcard_match_s(&loop->absolutes, filename, 0) != 0);
|
||||
result.is_loaded = (file != 0 && file_is_ready(file));
|
||||
|
||||
result.message = null_string;
|
||||
|
@ -4379,7 +4373,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
|
|||
if (char_is_slash(end_character)){
|
||||
mode.string->size = reverse_seek_slash(*mode.string) + 1;
|
||||
mode.string->str[mode.string->size] = 0;
|
||||
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
|
||||
hot_directory_set(system, mode.hot_directory, *mode.string);
|
||||
}
|
||||
else{
|
||||
mode.string->str[mode.string->size] = 0;
|
||||
|
@ -4411,7 +4405,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
|
|||
mode.string->size++;
|
||||
mode.string->str[mode.string->size] = 0;
|
||||
if (mode.type == SINGLE_LINE_FILE && char_is_slash(new_character)){
|
||||
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
|
||||
hot_directory_set(system, mode.hot_directory, *mode.string);
|
||||
}
|
||||
result.made_a_change = 1;
|
||||
}
|
||||
|
@ -5021,7 +5015,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
|
|||
}
|
||||
|
||||
if (do_new_directory){
|
||||
hot_directory_reload(system, hdir, &models->working_set);
|
||||
hot_directory_reload(system, hdir);
|
||||
}
|
||||
|
||||
gui_end_scrollable(target);
|
||||
|
@ -5088,7 +5082,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
|
|||
Editing_File *file = (Editing_File*)node;
|
||||
Assert(!file->is_dummy);
|
||||
|
||||
if (filename_match(view->dest, &absolutes, file->name.live_name)){
|
||||
if (wildcard_match_s(&absolutes, file->name.live_name, 0) != 0){
|
||||
View_Iter iter = file_view_iter_init(layout, file, 0);
|
||||
if (file_view_iter_good(iter)){
|
||||
reserved_files[reserved_top++] = file;
|
||||
|
@ -6530,7 +6524,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
|
|||
String m = gui_read_string(&ptr);
|
||||
|
||||
if (folder){
|
||||
append_s_char(&f, system->slash);
|
||||
append_s_char(&f, '/');
|
||||
}
|
||||
|
||||
draw_fat_option_block(gui_target, target, view, font_id, gui_session.rect, b->id, f, m);
|
||||
|
|
11
4ed_system.h
11
4ed_system.h
|
@ -146,10 +146,10 @@ struct Thread_Exchange;
|
|||
struct System_Functions;
|
||||
|
||||
#define Job_Callback_Sig(name) void name( \
|
||||
System_Functions *system, \
|
||||
Thread_Context *thread, \
|
||||
Thread_Memory *memory, \
|
||||
void *data[2])
|
||||
System_Functions *system, \
|
||||
Thread_Context *thread, \
|
||||
Thread_Memory *memory, \
|
||||
void *data[2])
|
||||
typedef Job_Callback_Sig(Job_Callback);
|
||||
|
||||
struct Job_Data{
|
||||
|
@ -258,9 +258,6 @@ struct System_Functions{
|
|||
|
||||
// debug: 1
|
||||
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
|
||||
|
||||
// non-function details
|
||||
char slash;
|
||||
};
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -0,0 +1,434 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 03.01.2017
|
||||
*
|
||||
* File layer for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
//
|
||||
// Edit Position Basics
|
||||
//
|
||||
|
||||
enum Edit_Pos_Set_Type{
|
||||
EditPos_None,
|
||||
EditPos_CursorSet,
|
||||
EditPos_ScrollSet
|
||||
};
|
||||
struct File_Edit_Positions{
|
||||
GUI_Scroll_Vars scroll;
|
||||
Full_Cursor cursor;
|
||||
i32 mark;
|
||||
f32 preferred_x;
|
||||
i32 scroll_i;
|
||||
i32 last_set_type;
|
||||
b32 in_view;
|
||||
};
|
||||
static File_Edit_Positions null_edit_pos = {0};
|
||||
|
||||
internal void
|
||||
edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
|
||||
edit_pos->cursor = cursor;
|
||||
if (set_preferred_x){
|
||||
edit_pos->preferred_x = cursor.wrapped_x;
|
||||
if (unwrapped_lines){
|
||||
edit_pos->preferred_x = cursor.unwrapped_x;
|
||||
}
|
||||
}
|
||||
edit_pos->last_set_type = EditPos_CursorSet;
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_pos_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
|
||||
edit_pos->scroll = scroll;
|
||||
edit_pos->last_set_type = EditPos_ScrollSet;
|
||||
}
|
||||
|
||||
//
|
||||
// Undo Basics
|
||||
//
|
||||
|
||||
enum Edit_Type{
|
||||
ED_NORMAL,
|
||||
ED_REVERSE_NORMAL,
|
||||
ED_UNDO,
|
||||
ED_REDO,
|
||||
};
|
||||
|
||||
struct Edit_Step{
|
||||
Edit_Type type;
|
||||
union{
|
||||
struct{
|
||||
b32 can_merge;
|
||||
Buffer_Edit edit;
|
||||
i32 next_block;
|
||||
i32 prev_block;
|
||||
};
|
||||
struct{
|
||||
i32 first_child;
|
||||
i32 inverse_first_child;
|
||||
i32 inverse_child_count;
|
||||
i32 special_type;
|
||||
};
|
||||
};
|
||||
i32 child_count;
|
||||
};
|
||||
|
||||
struct Edit_Stack{
|
||||
u8 *strings;
|
||||
i32 size, max;
|
||||
|
||||
Edit_Step *edits;
|
||||
i32 edit_count, edit_max;
|
||||
};
|
||||
|
||||
struct Small_Edit_Stack{
|
||||
u8 *strings;
|
||||
i32 size, max;
|
||||
|
||||
Buffer_Edit *edits;
|
||||
i32 edit_count, edit_max;
|
||||
};
|
||||
|
||||
struct Undo_Data{
|
||||
Edit_Stack undo;
|
||||
Edit_Stack redo;
|
||||
Edit_Stack history;
|
||||
Small_Edit_Stack children;
|
||||
|
||||
i32 history_block_count, history_head_block;
|
||||
i32 edit_history_cursor;
|
||||
b32 current_block_normal;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Highlighting Information
|
||||
//
|
||||
|
||||
struct Text_Effect{
|
||||
i32 start, end;
|
||||
u32 color;
|
||||
f32 seconds_down, seconds_max;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Editing_File
|
||||
//
|
||||
|
||||
struct Editing_File_Settings{
|
||||
i32 base_map_id;
|
||||
i32 display_width;
|
||||
i32 minimum_base_display_width;
|
||||
i32 wrap_indicator;
|
||||
b32 dos_write_mode;
|
||||
b32 virtual_white;
|
||||
i16 font_id;
|
||||
b8 unwrapped_lines;
|
||||
b8 tokens_exist;
|
||||
b8 is_initialized;
|
||||
b8 unimportant;
|
||||
b8 read_only;
|
||||
b8 never_kill;
|
||||
};
|
||||
static Editing_File_Settings null_editing_file_settings = {0};
|
||||
|
||||
struct Editing_File_State{
|
||||
Buffer_Type buffer;
|
||||
|
||||
i32 *wrap_line_index;
|
||||
i32 wrap_max;
|
||||
|
||||
i32 *character_starts;
|
||||
i32 character_start_max;
|
||||
|
||||
f32 *line_indents;
|
||||
i32 line_indent_max;
|
||||
|
||||
i32 wrap_line_count;
|
||||
|
||||
i32 *wrap_positions;
|
||||
i32 wrap_position_count;
|
||||
i32 wrap_position_max;
|
||||
|
||||
Undo_Data undo;
|
||||
|
||||
Cpp_Token_Array token_array;
|
||||
Cpp_Token_Array swap_array;
|
||||
u32 lex_job;
|
||||
b32 tokens_complete;
|
||||
b32 still_lexing;
|
||||
|
||||
Text_Effect paste_effect;
|
||||
|
||||
Dirty_State dirty;
|
||||
u32 ignore_behind_os;
|
||||
|
||||
File_Edit_Positions edit_pos_space[16];
|
||||
File_Edit_Positions *edit_poss[16];
|
||||
i32 edit_poss_count;
|
||||
};
|
||||
static Editing_File_State null_editing_file_state = {0};
|
||||
|
||||
struct Editing_File_Name{
|
||||
char live_name_[256];
|
||||
char source_path_[256];
|
||||
char extension_[16];
|
||||
String live_name;
|
||||
String source_path;
|
||||
String extension;
|
||||
};
|
||||
|
||||
struct Editing_File_Canon_Name{
|
||||
char name_[256];
|
||||
String name;
|
||||
};
|
||||
|
||||
struct File_Node{
|
||||
File_Node *next, *prev;
|
||||
};
|
||||
|
||||
union Buffer_Slot_ID{
|
||||
i32 id;
|
||||
i16 part[2];
|
||||
};
|
||||
|
||||
inline Buffer_Slot_ID
|
||||
to_file_id(i32 id){
|
||||
Buffer_Slot_ID result;
|
||||
result.id = id;
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct Editing_File{
|
||||
// NOTE(allen): node must be the first member of Editing_File!
|
||||
File_Node node;
|
||||
Editing_File_Settings settings;
|
||||
struct{
|
||||
b32 is_loading;
|
||||
b32 is_dummy;
|
||||
Editing_File_State state;
|
||||
};
|
||||
Editing_File_Name name;
|
||||
Editing_File_Canon_Name canon;
|
||||
Buffer_Slot_ID id;
|
||||
u64 unique_buffer_id;
|
||||
};
|
||||
static Editing_File null_editing_file = {0};
|
||||
|
||||
|
||||
//
|
||||
// Manipulating a file's Edit_Pos array
|
||||
//
|
||||
|
||||
internal i32
|
||||
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||
i32 edit_pos_index = -1;
|
||||
|
||||
i32 count = file->state.edit_poss_count;
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
for (i32 i = 0; i < count; ++i){
|
||||
if (edit_poss[i] == edit_pos){
|
||||
edit_pos_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(edit_pos_index);
|
||||
}
|
||||
|
||||
internal b32
|
||||
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||
b32 result = false;
|
||||
|
||||
if (file && edit_pos){
|
||||
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
||||
Assert(edit_pos_index != -1);
|
||||
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
|
||||
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
|
||||
|
||||
edit_poss[0] = edit_pos;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||
b32 result = false;
|
||||
|
||||
if (file && edit_pos){
|
||||
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
||||
Assert(edit_pos_index != -1);
|
||||
|
||||
i32 count = file->state.edit_poss_count;
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
|
||||
memmove(edit_poss + edit_pos_index,
|
||||
edit_poss + edit_pos_index + 1,
|
||||
(count - edit_pos_index - 1)*sizeof(*edit_poss));
|
||||
|
||||
edit_pos->in_view = false;
|
||||
|
||||
if (file->state.edit_poss_count > 1){
|
||||
file->state.edit_poss_count -= 1;
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal File_Edit_Positions*
|
||||
edit_pos_get_new(Editing_File *file, i32 index){
|
||||
File_Edit_Positions *result = 0;
|
||||
|
||||
if (file && 0 <= index && index < 16){
|
||||
result = file->state.edit_pos_space + index;
|
||||
i32 edit_pos_index = edit_pos_get_index(file, result);
|
||||
|
||||
if (edit_pos_index == -1){
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
i32 count = file->state.edit_poss_count;
|
||||
|
||||
if (count > 0){
|
||||
if (edit_poss[0]->in_view){
|
||||
memcpy(result, edit_poss[0], sizeof(*result));
|
||||
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
|
||||
file->state.edit_poss_count = count + 1;
|
||||
}
|
||||
else{
|
||||
Assert(count == 1);
|
||||
memcpy(result, edit_poss[0], sizeof(*result));
|
||||
}
|
||||
}
|
||||
else{
|
||||
memset(result, 0, sizeof(*result));
|
||||
file->state.edit_poss_count = 1;
|
||||
}
|
||||
|
||||
edit_poss[0] = result;
|
||||
}
|
||||
|
||||
result->in_view = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Cursor Seeking
|
||||
//
|
||||
|
||||
inline Partial_Cursor
|
||||
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
|
||||
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline Partial_Cursor
|
||||
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
|
||||
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline b32
|
||||
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
|
||||
b32 result = 1;
|
||||
switch (seek.type){
|
||||
case buffer_seek_pos:
|
||||
{
|
||||
*cursor = file_compute_cursor_from_pos(file, seek.pos);
|
||||
}break;
|
||||
|
||||
case buffer_seek_line_char:
|
||||
{
|
||||
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
result = 0;
|
||||
}break;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Dirty Flags
|
||||
//
|
||||
|
||||
inline b32
|
||||
buffer_needs_save(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (!file->settings.unimportant){
|
||||
if (file->state.dirty == DirtyState_UnsavedChanges){
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline b32
|
||||
buffer_can_save(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (!file->settings.unimportant){
|
||||
if (file->state.dirty == DirtyState_UnsavedChanges ||
|
||||
file->state.dirty == DirtyState_UnloadedChanges){
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline b32
|
||||
file_is_ready(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (file && file->is_loading == 0){
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_to_loading(Editing_File *file){
|
||||
file->state = null_editing_file_state;
|
||||
file->settings = null_editing_file_settings;
|
||||
file->is_loading = 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_clean(Editing_File *file){
|
||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_dirty(Editing_File *file){
|
||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||
file->state.dirty = DirtyState_UnsavedChanges;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_behind_os(Editing_File *file){
|
||||
file->state.dirty = DirtyState_UnloadedChanges;
|
||||
}
|
||||
|
||||
inline Dirty_State
|
||||
file_get_sync(Editing_File *file){
|
||||
return (file->state.dirty);
|
||||
}
|
||||
|
||||
|
||||
// BOTTOM
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 03.01.2017
|
||||
*
|
||||
* File layer for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#include "4coder_file.cpp"
|
||||
|
||||
int main(){
|
||||
return(0);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 03.01.2017
|
||||
*
|
||||
* Hot_Directory data structure for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
struct Hot_Directory{
|
||||
String string;
|
||||
File_List file_list;
|
||||
};
|
||||
|
||||
internal void
|
||||
hot_directory_clean_end(Hot_Directory *hot_directory){
|
||||
String *str = &hot_directory->string;
|
||||
if (str->size != 0 && str->str[str->size-1] != '/'){
|
||||
str->size = reverse_seek_slash(*str) + 1;
|
||||
str->str[str->size] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal i32
|
||||
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
|
||||
File_Info *p = infos + pivot;
|
||||
File_Info *a = infos + start;
|
||||
for (i32 i = start; i < pivot; ++i, ++a){
|
||||
i32 comp = 0;
|
||||
comp = p->folder - a->folder;
|
||||
if (comp == 0){
|
||||
comp = compare_cc(a->filename, p->filename);
|
||||
}
|
||||
if (comp < 0){
|
||||
Swap(File_Info, *a, infos[start]);
|
||||
++start;
|
||||
}
|
||||
}
|
||||
Swap(File_Info, *p, infos[start]);
|
||||
return start;
|
||||
}
|
||||
|
||||
internal void
|
||||
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
|
||||
i32 mid = hot_directory_quick_partition(infos, start, pivot);
|
||||
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
|
||||
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
|
||||
}
|
||||
|
||||
inline void
|
||||
hot_directory_fixup(Hot_Directory *hot_directory){
|
||||
File_List *files = &hot_directory->file_list;
|
||||
if (files->count >= 2){
|
||||
hot_directory_quick_sort(files->infos, 0, files->count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String str){
|
||||
b32 success = copy_checked_ss(&hot_directory->string, str);
|
||||
terminate_with_null(&hot_directory->string);
|
||||
if (success){
|
||||
if (str.size > 0){
|
||||
system->set_file_list(&hot_directory->file_list, str);
|
||||
}
|
||||
else{
|
||||
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0));
|
||||
}
|
||||
}
|
||||
hot_directory_fixup(hot_directory);
|
||||
}
|
||||
|
||||
inline void
|
||||
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){
|
||||
system->set_file_list(&hot_directory->file_list, hot_directory->string);
|
||||
hot_directory_fixup(hot_directory);
|
||||
}
|
||||
|
||||
internal void
|
||||
hot_directory_init(Hot_Directory *hot_directory, String base, String dir){
|
||||
hot_directory->string = base;
|
||||
hot_directory->string.str[255] = 0;
|
||||
hot_directory->string.size = 0;
|
||||
copy_ss(&hot_directory->string, dir);
|
||||
if (hot_directory->string.str[hot_directory->string.size-1] != '/'){
|
||||
append_s_char(&hot_directory->string, '/');
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -1,193 +1,17 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 20.02.2016
|
||||
* 03.01.2017
|
||||
*
|
||||
* File editing view for 4coder
|
||||
* Working_Set data structure for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
enum Edit_Pos_Set_Type{
|
||||
EditPos_None,
|
||||
EditPos_CursorSet,
|
||||
EditPos_ScrollSet
|
||||
};
|
||||
struct File_Edit_Positions{
|
||||
GUI_Scroll_Vars scroll;
|
||||
Full_Cursor cursor;
|
||||
i32 mark;
|
||||
f32 preferred_x;
|
||||
i32 scroll_i;
|
||||
i32 last_set_type;
|
||||
b32 in_view;
|
||||
};
|
||||
static File_Edit_Positions null_edit_pos = {0};
|
||||
|
||||
enum Edit_Type{
|
||||
ED_NORMAL,
|
||||
ED_REVERSE_NORMAL,
|
||||
ED_UNDO,
|
||||
ED_REDO,
|
||||
};
|
||||
|
||||
struct Edit_Step{
|
||||
Edit_Type type;
|
||||
union{
|
||||
struct{
|
||||
b32 can_merge;
|
||||
Buffer_Edit edit;
|
||||
i32 next_block;
|
||||
i32 prev_block;
|
||||
};
|
||||
struct{
|
||||
i32 first_child;
|
||||
i32 inverse_first_child;
|
||||
i32 inverse_child_count;
|
||||
i32 special_type;
|
||||
};
|
||||
};
|
||||
i32 child_count;
|
||||
};
|
||||
|
||||
struct Edit_Stack{
|
||||
u8 *strings;
|
||||
i32 size, max;
|
||||
|
||||
Edit_Step *edits;
|
||||
i32 edit_count, edit_max;
|
||||
};
|
||||
|
||||
struct Small_Edit_Stack{
|
||||
u8 *strings;
|
||||
i32 size, max;
|
||||
|
||||
Buffer_Edit *edits;
|
||||
i32 edit_count, edit_max;
|
||||
};
|
||||
|
||||
struct Undo_Data{
|
||||
Edit_Stack undo;
|
||||
Edit_Stack redo;
|
||||
Edit_Stack history;
|
||||
Small_Edit_Stack children;
|
||||
|
||||
i32 history_block_count, history_head_block;
|
||||
i32 edit_history_cursor;
|
||||
b32 current_block_normal;
|
||||
};
|
||||
|
||||
struct Text_Effect{
|
||||
i32 start, end;
|
||||
u32 color;
|
||||
f32 seconds_down, seconds_max;
|
||||
};
|
||||
|
||||
// NOTE(allen): The Editing_File struct is now divided into two
|
||||
// parts. Variables in the Settings part can be set even when the
|
||||
// file is still streaming in, and persists thorugh all operations except
|
||||
// for the initial allocation of the file.
|
||||
struct Editing_File_Settings{
|
||||
i32 base_map_id;
|
||||
i32 display_width;
|
||||
i32 minimum_base_display_width;
|
||||
i32 wrap_indicator;
|
||||
b32 dos_write_mode;
|
||||
b32 virtual_white;
|
||||
i16 font_id;
|
||||
b8 unwrapped_lines;
|
||||
b8 tokens_exist;
|
||||
b8 is_initialized;
|
||||
b8 unimportant;
|
||||
b8 read_only;
|
||||
b8 never_kill;
|
||||
};
|
||||
static Editing_File_Settings null_editing_file_settings = {0};
|
||||
|
||||
// NOTE(allen): This part of the Editing_File is cleared whenever
|
||||
// the contents of the file is set.
|
||||
struct Editing_File_State{
|
||||
Buffer_Type buffer;
|
||||
|
||||
i32 *wrap_line_index;
|
||||
i32 wrap_max;
|
||||
|
||||
i32 *character_starts;
|
||||
i32 character_start_max;
|
||||
|
||||
f32 *line_indents;
|
||||
i32 line_indent_max;
|
||||
|
||||
i32 wrap_line_count;
|
||||
|
||||
i32 *wrap_positions;
|
||||
i32 wrap_position_count;
|
||||
i32 wrap_position_max;
|
||||
|
||||
Undo_Data undo;
|
||||
|
||||
Cpp_Token_Array token_array;
|
||||
Cpp_Token_Array swap_array;
|
||||
u32 lex_job;
|
||||
b32 tokens_complete;
|
||||
b32 still_lexing;
|
||||
|
||||
Text_Effect paste_effect;
|
||||
|
||||
Dirty_State dirty;
|
||||
u32 ignore_behind_os;
|
||||
|
||||
File_Edit_Positions edit_pos_space[16];
|
||||
File_Edit_Positions *edit_poss[16];
|
||||
i32 edit_poss_count;
|
||||
};
|
||||
static Editing_File_State null_editing_file_state = {0};
|
||||
|
||||
struct Editing_File_Name{
|
||||
char live_name_[256];
|
||||
char source_path_[256];
|
||||
char extension_[16];
|
||||
String live_name;
|
||||
String source_path;
|
||||
String extension;
|
||||
};
|
||||
|
||||
struct Editing_File_Canon_Name{
|
||||
char name_[256];
|
||||
String name;
|
||||
};
|
||||
|
||||
struct File_Node{
|
||||
File_Node *next, *prev;
|
||||
};
|
||||
|
||||
union Buffer_Slot_ID{
|
||||
i32 id;
|
||||
i16 part[2];
|
||||
};
|
||||
|
||||
inline Buffer_Slot_ID
|
||||
to_file_id(i32 id){
|
||||
Buffer_Slot_ID result;
|
||||
result.id = id;
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct Editing_File{
|
||||
// NOTE(allen): node must be the first member of Editing_File!
|
||||
File_Node node;
|
||||
Editing_File_Settings settings;
|
||||
struct{
|
||||
b32 is_loading;
|
||||
b32 is_dummy;
|
||||
Editing_File_State state;
|
||||
};
|
||||
Editing_File_Name name;
|
||||
Editing_File_Canon_Name canon;
|
||||
Buffer_Slot_ID id;
|
||||
u64 unique_buffer_id;
|
||||
};
|
||||
//
|
||||
// Working_Set of files
|
||||
//
|
||||
|
||||
struct Non_File_Table_Entry{
|
||||
String name;
|
||||
|
@ -204,15 +28,15 @@ struct Working_Set{
|
|||
i32 file_count, file_max;
|
||||
i16 array_count, array_max;
|
||||
|
||||
File_Node free_sentinel;
|
||||
File_Node free_sentinel;
|
||||
File_Node used_sentinel;
|
||||
|
||||
Table canon_table;
|
||||
Table name_table;
|
||||
|
||||
String clipboards[64];
|
||||
i32 clipboard_size, clipboard_max_size;
|
||||
i32 clipboard_current, clipboard_rolling;
|
||||
String clipboards[64];
|
||||
i32 clipboard_size, clipboard_max_size;
|
||||
i32 clipboard_current, clipboard_rolling;
|
||||
|
||||
u64 unique_file_counter;
|
||||
|
||||
|
@ -222,176 +46,12 @@ struct Working_Set{
|
|||
i32 default_minimum_base_display_width;
|
||||
};
|
||||
|
||||
//
|
||||
// File_Edit_Positions stuff
|
||||
//
|
||||
|
||||
internal void
|
||||
edit_pos_set_cursor_(File_Edit_Positions *edit_pos,
|
||||
Full_Cursor cursor,
|
||||
b32 set_preferred_x,
|
||||
b32 unwrapped_lines){
|
||||
edit_pos->cursor = cursor;
|
||||
if (set_preferred_x){
|
||||
edit_pos->preferred_x = cursor.wrapped_x;
|
||||
if (unwrapped_lines){
|
||||
edit_pos->preferred_x = cursor.unwrapped_x;
|
||||
}
|
||||
}
|
||||
edit_pos->last_set_type = EditPos_CursorSet;
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_pos_set_scroll_(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
|
||||
edit_pos->scroll = scroll;
|
||||
edit_pos->last_set_type = EditPos_ScrollSet;
|
||||
}
|
||||
|
||||
internal i32
|
||||
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||
i32 edit_pos_index = -1;
|
||||
|
||||
i32 count = file->state.edit_poss_count;
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
for (i32 i = 0; i < count; ++i){
|
||||
if (edit_poss[i] == edit_pos){
|
||||
edit_pos_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(edit_pos_index);
|
||||
}
|
||||
|
||||
internal b32
|
||||
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||
b32 result = false;
|
||||
|
||||
if (file && edit_pos){
|
||||
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
||||
Assert(edit_pos_index != -1);
|
||||
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
|
||||
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
|
||||
|
||||
edit_poss[0] = edit_pos;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||
b32 result = false;
|
||||
|
||||
if (file && edit_pos){
|
||||
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
||||
Assert(edit_pos_index != -1);
|
||||
|
||||
i32 count = file->state.edit_poss_count;
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
|
||||
memmove(edit_poss + edit_pos_index,
|
||||
edit_poss + edit_pos_index + 1,
|
||||
(count - edit_pos_index - 1)*sizeof(*edit_poss));
|
||||
|
||||
edit_pos->in_view = false;
|
||||
|
||||
if (file->state.edit_poss_count > 1){
|
||||
file->state.edit_poss_count -= 1;
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal File_Edit_Positions*
|
||||
edit_pos_get_new(Editing_File *file, i32 index){
|
||||
File_Edit_Positions *result = 0;
|
||||
|
||||
if (file && 0 <= index && index < 16){
|
||||
result = file->state.edit_pos_space + index;
|
||||
i32 edit_pos_index = edit_pos_get_index(file, result);
|
||||
|
||||
if (edit_pos_index == -1){
|
||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||
i32 count = file->state.edit_poss_count;
|
||||
|
||||
if (count > 0){
|
||||
if (edit_poss[0]->in_view){
|
||||
memcpy(result, edit_poss[0], sizeof(*result));
|
||||
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
|
||||
file->state.edit_poss_count = count + 1;
|
||||
}
|
||||
else{
|
||||
Assert(count == 1);
|
||||
memcpy(result, edit_poss[0], sizeof(*result));
|
||||
}
|
||||
}
|
||||
else{
|
||||
memset(result, 0, sizeof(*result));
|
||||
file->state.edit_poss_count = 1;
|
||||
}
|
||||
|
||||
edit_poss[0] = result;
|
||||
}
|
||||
|
||||
result->in_view = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
//
|
||||
// File Cursor Seeking
|
||||
//
|
||||
|
||||
inline Partial_Cursor
|
||||
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
|
||||
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline Partial_Cursor
|
||||
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
|
||||
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline b32
|
||||
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
|
||||
b32 result = 1;
|
||||
switch (seek.type){
|
||||
case buffer_seek_pos:
|
||||
{
|
||||
*cursor = file_compute_cursor_from_pos(file, seek.pos);
|
||||
}break;
|
||||
|
||||
case buffer_seek_line_char:
|
||||
{
|
||||
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
result = 0;
|
||||
}break;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
//
|
||||
// Working_Set stuff
|
||||
//
|
||||
|
||||
struct File_Name_Entry{
|
||||
String name;
|
||||
Buffer_Slot_ID id;
|
||||
};
|
||||
|
||||
|
||||
internal i32
|
||||
tbl_name_compare(void *a, void *b, void *arg){
|
||||
String *fa = (String*)a;
|
||||
|
@ -431,12 +91,6 @@ working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16
|
|||
}
|
||||
}
|
||||
|
||||
inline Editing_File
|
||||
editing_file_zero(){
|
||||
Editing_File file = {0};
|
||||
return(file);
|
||||
}
|
||||
|
||||
internal Editing_File*
|
||||
working_set_alloc(Working_Set *working_set){
|
||||
Editing_File *result = 0;
|
||||
|
@ -448,7 +102,7 @@ working_set_alloc(Working_Set *working_set){
|
|||
|
||||
dll_remove(node);
|
||||
Buffer_Slot_ID id = result->id;
|
||||
*result = editing_file_zero();
|
||||
*result = null_editing_file;
|
||||
result->id = id;
|
||||
result->unique_buffer_id = ++working_set->unique_file_counter;
|
||||
dll_insert(&working_set->used_sentinel, node);
|
||||
|
@ -626,7 +280,7 @@ working_set_canon_contains(Working_Set *working_set, String name){
|
|||
|
||||
internal b32
|
||||
working_set_canon_add(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, String name){
|
||||
Editing_File *file, String name){
|
||||
b32 result = working_set_add_basic(system, general,working_set, &working_set->canon_table, file, name);
|
||||
return(result);
|
||||
}
|
||||
|
@ -674,7 +328,7 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
|||
if (node == used_nodes) file = 0;
|
||||
}
|
||||
|
||||
if (!file){
|
||||
if (!file){
|
||||
File_Node *node, *used_nodes;
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
for (dll_items(node, used_nodes)){
|
||||
|
@ -684,9 +338,9 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
|||
}
|
||||
}
|
||||
if (node == used_nodes) file = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (file);
|
||||
return (file);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -698,164 +352,10 @@ touch_file(Working_Set *working_set, Editing_File *file){
|
|||
}
|
||||
}
|
||||
|
||||
// Hot Directory
|
||||
|
||||
struct Hot_Directory{
|
||||
String string;
|
||||
File_List file_list;
|
||||
// TODO(allen): eliminate slash
|
||||
char slash;
|
||||
};
|
||||
|
||||
internal void
|
||||
hot_directory_clean_end(Hot_Directory *hot_directory){
|
||||
String *str = &hot_directory->string;
|
||||
if (str->size != 0 && str->str[str->size-1] != hot_directory->slash){
|
||||
str->size = reverse_seek_slash(*str) + 1;
|
||||
str->str[str->size] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal i32
|
||||
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
|
||||
File_Info *p = infos + pivot;
|
||||
File_Info *a = infos + start;
|
||||
for (i32 i = start; i < pivot; ++i, ++a){
|
||||
i32 comp = 0;
|
||||
comp = p->folder - a->folder;
|
||||
if (comp == 0){
|
||||
comp = compare_cc(a->filename, p->filename);
|
||||
}
|
||||
if (comp < 0){
|
||||
Swap(File_Info, *a, infos[start]);
|
||||
++start;
|
||||
}
|
||||
}
|
||||
Swap(File_Info, *p, infos[start]);
|
||||
return start;
|
||||
}
|
||||
|
||||
internal void
|
||||
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
|
||||
i32 mid = hot_directory_quick_partition(infos, start, pivot);
|
||||
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
|
||||
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
|
||||
}
|
||||
|
||||
inline void
|
||||
hot_directory_fixup(Hot_Directory *hot_directory, Working_Set *working_set){
|
||||
File_List *files = &hot_directory->file_list;
|
||||
if (files->count >= 2)
|
||||
hot_directory_quick_sort(files->infos, 0, files->count - 1);
|
||||
}
|
||||
|
||||
inline void
|
||||
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory,
|
||||
String str, Working_Set *working_set){
|
||||
b32 success = copy_checked_ss(&hot_directory->string, str);
|
||||
terminate_with_null(&hot_directory->string);
|
||||
if (success){
|
||||
if (str.size > 0){
|
||||
system->set_file_list(&hot_directory->file_list, str);
|
||||
}
|
||||
else{
|
||||
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0));
|
||||
}
|
||||
}
|
||||
hot_directory_fixup(hot_directory, working_set);
|
||||
}
|
||||
|
||||
inline void
|
||||
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory, Working_Set *working_set){
|
||||
system->set_file_list(&hot_directory->file_list, hot_directory->string);
|
||||
hot_directory_fixup(hot_directory, working_set);
|
||||
}
|
||||
|
||||
internal void
|
||||
hot_directory_init(Hot_Directory *hot_directory, String base, String dir, char slash){
|
||||
hot_directory->string = base;
|
||||
hot_directory->string.str[255] = 0;
|
||||
hot_directory->string.size = 0;
|
||||
copy_ss(&hot_directory->string, dir);
|
||||
append_s_char(&hot_directory->string, slash);
|
||||
hot_directory->slash = slash;
|
||||
}
|
||||
|
||||
struct Hot_Directory_Match{
|
||||
String filename;
|
||||
b32 is_folder;
|
||||
};
|
||||
|
||||
internal b32
|
||||
filename_match(String query, Absolutes *absolutes, String filename){
|
||||
b32 result;
|
||||
result = (query.size == 0);
|
||||
if (!result) result = wildcard_match_s(absolutes, filename, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline b32
|
||||
buffer_needs_save(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (!file->settings.unimportant){
|
||||
if (file->state.dirty == DirtyState_UnsavedChanges){
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline b32
|
||||
buffer_can_save(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (!file->settings.unimportant){
|
||||
if (file->state.dirty == DirtyState_UnsavedChanges ||
|
||||
file->state.dirty == DirtyState_UnloadedChanges){
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline b32
|
||||
file_is_ready(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (file && file->is_loading == 0){
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_to_loading(Editing_File *file){
|
||||
file->state = null_editing_file_state;
|
||||
file->settings = null_editing_file_settings;
|
||||
file->is_loading = 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_clean(Editing_File *file){
|
||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_dirty(Editing_File *file){
|
||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||
file->state.dirty = DirtyState_UnsavedChanges;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_behind_os(Editing_File *file){
|
||||
file->state.dirty = DirtyState_UnloadedChanges;
|
||||
}
|
||||
|
||||
inline Dirty_State
|
||||
file_get_sync(Editing_File *file){
|
||||
return (file->state.dirty);
|
||||
}
|
||||
//
|
||||
// Name Binding
|
||||
//
|
||||
|
||||
internal void
|
||||
editing_file_name_init(Editing_File_Name *name){
|
||||
|
@ -868,9 +368,7 @@ internal b32
|
|||
get_canon_name(System_Functions *system, Editing_File_Canon_Name *canon_name, String filename){
|
||||
canon_name->name = make_fixed_width_string(canon_name->name_);
|
||||
|
||||
canon_name->name.size =
|
||||
system->get_canonical(filename.str, filename.size,
|
||||
canon_name->name.str, canon_name->name.memory_size);
|
||||
canon_name->name.size = system->get_canonical(filename.str, filename.size, canon_name->name.str, canon_name->name.memory_size);
|
||||
terminate_with_null(&canon_name->name);
|
||||
|
||||
b32 result = (canon_name->name.size != 0);
|
||||
|
@ -928,8 +426,7 @@ buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *fil
|
|||
}
|
||||
|
||||
internal void
|
||||
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, String canon_filename){
|
||||
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String canon_filename){
|
||||
Assert(file->name.live_name.size == 0 &&
|
||||
file->name.source_path.size == 0 &&
|
||||
file->name.extension.size == 0);
|
||||
|
@ -956,8 +453,7 @@ buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_F
|
|||
}
|
||||
|
||||
internal void
|
||||
buffer_bind_name(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, String filename){
|
||||
buffer_bind_name(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String filename){
|
||||
Assert(file->name.live_name.size == 0 &&
|
||||
file->name.source_path.size == 0 &&
|
||||
file->name.extension.size == 0);
|
||||
|
@ -984,5 +480,6 @@ buffer_unbind_name(Working_Set *working_set, Editing_File *file){
|
|||
file->name.extension.size = 0;
|
||||
}
|
||||
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
@echo off
|
||||
|
||||
SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX
|
||||
SET OPTS=%OPTS% /GR- /EHa- /nologo /FC
|
||||
|
||||
pushd ..\build
|
||||
cl %OPTS% ..\code\file\4coder_file_tests.cpp /Zi /Fefile_test
|
||||
popd
|
||||
|
||||
if %ERRORLEVEL% eq 0 (..\build\file_test)
|
||||
|
|
@ -1903,102 +1903,110 @@ typedef struct Absolutes{
|
|||
|
||||
static void
|
||||
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
|
||||
int32_t count = 0;
|
||||
int32_t max = ArrayCount(absolutes->a) - 1;
|
||||
if (implicit_last) --max;
|
||||
if (name.size != 0){
|
||||
int32_t count = 0;
|
||||
int32_t max = ArrayCount(absolutes->a) - 1;
|
||||
if (implicit_last) --max;
|
||||
|
||||
String str;
|
||||
str.str = name.str;
|
||||
str.size = 0;
|
||||
str.memory_size = 0;
|
||||
fstr_bool prev_was_wild = 0;
|
||||
|
||||
if (implicit_first){
|
||||
absolutes->a[count++] = str;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < name.size; ++i){
|
||||
if (name.str[i] == '*' && count < max){
|
||||
if (!prev_was_wild){
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
str.size = 0;
|
||||
}
|
||||
str.str = name.str + i + 1;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
else{
|
||||
++str.size;
|
||||
prev_was_wild = 0;
|
||||
}
|
||||
}
|
||||
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
|
||||
if (implicit_last){
|
||||
String str;
|
||||
str.str = name.str;
|
||||
str.size = 0;
|
||||
str.memory_size = 0;
|
||||
absolutes->a[count++] = str;
|
||||
}
|
||||
fstr_bool prev_was_wild = 0;
|
||||
|
||||
absolutes->count = count;
|
||||
if (implicit_first){
|
||||
absolutes->a[count++] = str;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < name.size; ++i){
|
||||
if (name.str[i] == '*' && count < max){
|
||||
if (!prev_was_wild){
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
str.size = 0;
|
||||
}
|
||||
str.str = name.str + i + 1;
|
||||
prev_was_wild = 1;
|
||||
}
|
||||
else{
|
||||
++str.size;
|
||||
prev_was_wild = 0;
|
||||
}
|
||||
}
|
||||
|
||||
str.memory_size = str.size;
|
||||
absolutes->a[count++] = str;
|
||||
|
||||
if (implicit_last){
|
||||
str.size = 0;
|
||||
str.memory_size = 0;
|
||||
absolutes->a[count++] = str;
|
||||
}
|
||||
|
||||
absolutes->count = count;
|
||||
}
|
||||
else{
|
||||
absolutes->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static fstr_bool
|
||||
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
|
||||
fstr_bool r = 1;
|
||||
String *a = absolutes->a;
|
||||
|
||||
fstr_bool (*match_func)(char*, String);
|
||||
fstr_bool (*match_part_func)(char*, String);
|
||||
if (absolutes->count > 0){
|
||||
String *a = absolutes->a;
|
||||
|
||||
if (case_sensitive){
|
||||
match_func = match_cs;
|
||||
match_part_func = match_part_cs;
|
||||
}
|
||||
else{
|
||||
match_func = match_insensitive_cs;
|
||||
match_part_func = match_part_insensitive_cs;
|
||||
}
|
||||
fstr_bool (*match_func)(char*, String);
|
||||
fstr_bool (*match_part_func)(char*, String);
|
||||
|
||||
if (absolutes->count == 1){
|
||||
r = match_func(x, *a);
|
||||
}
|
||||
else{
|
||||
if (!match_part_func(x, *a)){
|
||||
r = 0;
|
||||
if (case_sensitive){
|
||||
match_func = match_cs;
|
||||
match_part_func = match_part_cs;
|
||||
}
|
||||
else{
|
||||
String *max = a + absolutes->count - 1;
|
||||
x += a->size;
|
||||
++a;
|
||||
while (a < max){
|
||||
if (*x == 0){
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
if (match_part_func(x, *a)){
|
||||
x += a->size;
|
||||
++a;
|
||||
}
|
||||
else{
|
||||
++x;
|
||||
}
|
||||
}
|
||||
if (r && a->size > 0){
|
||||
match_func = match_insensitive_cs;
|
||||
match_part_func = match_part_insensitive_cs;
|
||||
}
|
||||
|
||||
if (absolutes->count == 1){
|
||||
r = match_func(x, *a);
|
||||
}
|
||||
else{
|
||||
if (!match_part_func(x, *a)){
|
||||
r = 0;
|
||||
while (*x != 0){
|
||||
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
||||
r = 1;
|
||||
}
|
||||
else{
|
||||
String *max = a + absolutes->count - 1;
|
||||
x += a->size;
|
||||
++a;
|
||||
while (a < max){
|
||||
if (*x == 0){
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
if (match_part_func(x, *a)){
|
||||
x += a->size;
|
||||
++a;
|
||||
}
|
||||
else{
|
||||
++x;
|
||||
}
|
||||
}
|
||||
if (r && a->size > 0){
|
||||
r = 0;
|
||||
while (*x != 0){
|
||||
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
++x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
196
linux_4ed.cpp
196
linux_4ed.cpp
|
@ -116,15 +116,15 @@ struct Application_Links;
|
|||
#define LinuxGetMemory(size) LinuxGetMemory_(size, __LINE__, __FILE__)
|
||||
|
||||
#if FRED_INTERNAL
|
||||
#define LINUX_FN_DEBUG(fmt, ...) do { \
|
||||
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
#define LINUX_FN_DEBUG(fmt, ...) do { \
|
||||
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define LINUX_FN_DEBUG(fmt, ...)
|
||||
#define LINUX_FN_DEBUG(fmt, ...)
|
||||
#endif
|
||||
|
||||
#if (__cplusplus <= 199711L)
|
||||
#define static_assert(x, ...)
|
||||
#define static_assert(x, ...)
|
||||
#endif
|
||||
|
||||
#define SUPPORT_DPI 1
|
||||
|
@ -148,11 +148,11 @@ enum {
|
|||
};
|
||||
|
||||
struct Linux_Coroutine {
|
||||
Coroutine coroutine;
|
||||
Linux_Coroutine *next;
|
||||
ucontext_t ctx, yield_ctx;
|
||||
Coroutine coroutine;
|
||||
Linux_Coroutine *next;
|
||||
ucontext_t ctx, yield_ctx;
|
||||
stack_t stack;
|
||||
b32 done;
|
||||
b32 done;
|
||||
};
|
||||
|
||||
struct Thread_Context{
|
||||
|
@ -411,8 +411,8 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
rewinddir(d);
|
||||
info_ptr = file_list->infos;
|
||||
for (entry = readdir(d);
|
||||
entry != 0;
|
||||
entry = readdir(d)){
|
||||
entry != 0;
|
||||
entry = readdir(d)){
|
||||
fname = entry->d_name;
|
||||
if(fname[0] == '.' && (fname[1] == 0 || (fname[1] == '.' && fname[2] == 0))){
|
||||
continue;
|
||||
|
@ -787,9 +787,9 @@ internal Linux_Coroutine*
|
|||
LinuxAllocCoroutine(){
|
||||
Linux_Coroutine *result = linuxvars.coroutine_free;
|
||||
Assert(result != 0);
|
||||
if(getcontext(&result->ctx) == -1){
|
||||
perror("getcontext");
|
||||
}
|
||||
if(getcontext(&result->ctx) == -1){
|
||||
perror("getcontext");
|
||||
}
|
||||
result->ctx.uc_stack = result->stack;
|
||||
linuxvars.coroutine_free = result->next;
|
||||
return(result);
|
||||
|
@ -815,7 +815,7 @@ Sys_Create_Coroutine_Sig(system_create_coroutine){
|
|||
Linux_Coroutine *c = LinuxAllocCoroutine();
|
||||
c->done = 0;
|
||||
|
||||
makecontext(&c->ctx, (void (*)())LinuxCoroutineMain, 1, &c->coroutine);
|
||||
makecontext(&c->ctx, (void (*)())LinuxCoroutineMain, 1, &c->coroutine);
|
||||
|
||||
*(ucontext_t**)&c->coroutine.plat_handle = &c->ctx;
|
||||
c->coroutine.func = func;
|
||||
|
@ -832,7 +832,7 @@ Sys_Launch_Coroutine_Sig(system_launch_coroutine){
|
|||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
swapcontext(&c->yield_ctx, ctx);
|
||||
swapcontext(&c->yield_ctx, ctx);
|
||||
|
||||
if (c->done){
|
||||
LinuxFreeCoroutine(c);
|
||||
|
@ -867,7 +867,7 @@ Sys_Resume_Coroutine_Sig(system_resume_coroutine){
|
|||
|
||||
internal
|
||||
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
|
||||
swapcontext(*(ucontext_t**)&coroutine->plat_handle, (ucontext*)coroutine->yield_handle);
|
||||
swapcontext(*(ucontext_t**)&coroutine->plat_handle, (ucontext*)coroutine->yield_handle);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1035,8 +1035,8 @@ JobThreadProc(void* lpParameter){
|
|||
// Now it just wraps by the queue wrap.
|
||||
u32 next_read_index = (read_index + 1) % QUEUE_WRAP;
|
||||
u32 safe_read_index =
|
||||
InterlockedCompareExchange(&queue->read_position,
|
||||
next_read_index, read_index);
|
||||
InterlockedCompareExchange(&queue->read_position,
|
||||
next_read_index, read_index);
|
||||
|
||||
if (safe_read_index == read_index){
|
||||
Full_Job_Data *full_job = queue->jobs + safe_read_index;
|
||||
|
@ -1045,8 +1045,8 @@ JobThreadProc(void* lpParameter){
|
|||
// at the same time that we try to run it
|
||||
|
||||
i32 safe_running_thread =
|
||||
InterlockedCompareExchange(&full_job->running_thread,
|
||||
thread->id, THREAD_NOT_ASSIGNED);
|
||||
InterlockedCompareExchange(&full_job->running_thread,
|
||||
thread->id, THREAD_NOT_ASSIGNED);
|
||||
|
||||
if (safe_running_thread == THREAD_NOT_ASSIGNED){
|
||||
thread->job_id = full_job->id;
|
||||
|
@ -1188,7 +1188,7 @@ Sys_Post_Job_Sig(system_post_job){
|
|||
while (queue->count >= queue->max){
|
||||
i32 new_max = queue->max*2;
|
||||
Full_Job_Data *new_jobs = (Full_Job_Data*)
|
||||
system_get_memory(new_max*sizeof(Full_Job_Data));
|
||||
system_get_memory(new_max*sizeof(Full_Job_Data));
|
||||
|
||||
memcpy(new_jobs, queue->jobs, queue->count);
|
||||
|
||||
|
@ -1234,8 +1234,8 @@ Sys_Cancel_Job_Sig(system_cancel_job){
|
|||
Assert(job->id == job_id);
|
||||
|
||||
u32 thread_id =
|
||||
InterlockedCompareExchange(&job->running_thread,
|
||||
0, THREAD_NOT_ASSIGNED);
|
||||
InterlockedCompareExchange(&job->running_thread,
|
||||
0, THREAD_NOT_ASSIGNED);
|
||||
|
||||
if (thread_id != THREAD_NOT_ASSIGNED && thread_id != 0){
|
||||
i32 thread_index = thread_id - 1;
|
||||
|
@ -1380,7 +1380,7 @@ Font_Load_Sig(system_draw_font_load){
|
|||
tab_width,
|
||||
oversample,
|
||||
store_texture
|
||||
);
|
||||
);
|
||||
#endif
|
||||
|
||||
if(success){
|
||||
|
@ -1429,7 +1429,6 @@ LinuxLoadAppCode(String* base_dir){
|
|||
|
||||
internal void
|
||||
LinuxLoadSystemCode(){
|
||||
|
||||
// files
|
||||
linuxvars.system.set_file_list = system_set_file_list;
|
||||
linuxvars.system.get_canonical = system_get_canonical;
|
||||
|
@ -1484,9 +1483,6 @@ LinuxLoadSystemCode(){
|
|||
#if FRED_INTERNAL
|
||||
linuxvars.system.internal_get_thread_states = internal_get_thread_states;
|
||||
#endif
|
||||
|
||||
// non-function details
|
||||
linuxvars.system.slash = '/';
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -1541,13 +1537,13 @@ ctxErrorHandler( Display *dpy, XErrorEvent *ev )
|
|||
#if FRED_INTERNAL
|
||||
|
||||
static void LinuxGLDebugCallback(
|
||||
GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
const void* userParam
|
||||
GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
const void* userParam
|
||||
){
|
||||
fprintf(stderr, "GL DEBUG: %s\n", message);
|
||||
}
|
||||
|
@ -1568,7 +1564,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
|
|||
|
||||
const char *glxExts = glXQueryExtensionsString(XDisplay, DefaultScreen(XDisplay));
|
||||
|
||||
#define GLXLOAD(x) x ## Proc x = (x ## Proc) glXGetProcAddressARB( (const GLubyte*) #x);
|
||||
#define GLXLOAD(x) x ## Proc x = (x ## Proc) glXGetProcAddressARB( (const GLubyte*) #x);
|
||||
|
||||
GLXLOAD(glXCreateContextAttribsARB);
|
||||
|
||||
|
@ -1773,36 +1769,36 @@ ChooseGLXConfig(Display *XDisplay, int XScreenIndex)
|
|||
glx_config_result Result = {0};
|
||||
|
||||
int DesiredAttributes[] =
|
||||
{
|
||||
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,
|
||||
//GLX_SAMPLE_BUFFERS , 1,
|
||||
//GLX_SAMPLES , 4,
|
||||
None
|
||||
};
|
||||
{
|
||||
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,
|
||||
//GLX_SAMPLE_BUFFERS , 1,
|
||||
//GLX_SAMPLES , 4,
|
||||
None
|
||||
};
|
||||
|
||||
int ConfigCount = 0;
|
||||
GLXFBConfig *Configs = glXChooseFBConfig(XDisplay,
|
||||
XScreenIndex,
|
||||
DesiredAttributes,
|
||||
&ConfigCount);
|
||||
if(Configs && ConfigCount > 0)
|
||||
{
|
||||
int ConfigCount = 0;
|
||||
GLXFBConfig *Configs = glXChooseFBConfig(XDisplay,
|
||||
XScreenIndex,
|
||||
DesiredAttributes,
|
||||
&ConfigCount);
|
||||
if(Configs && ConfigCount > 0)
|
||||
{
|
||||
XVisualInfo* VI = glXGetVisualFromFBConfig(XDisplay, Configs[0]);
|
||||
if(VI)
|
||||
{
|
||||
Result.Found = true;
|
||||
Result.BestConfig = Configs[0];
|
||||
Result.BestInfo = *VI;
|
||||
Result.BestInfo = *VI;
|
||||
|
||||
int id = 0;
|
||||
glXGetFBConfigAttrib(XDisplay, Result.BestConfig, GLX_FBCONFIG_ID, &id);
|
||||
|
@ -1842,9 +1838,9 @@ LinuxInputInit(Display *dpy, Window XWindow)
|
|||
unsigned long xim_event_mask = 0;
|
||||
i32 i;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_ALL, "");
|
||||
XSetLocaleModifiers("");
|
||||
fprintf(stderr, "Supported locale?: %s.\n", XSupportsLocale() ? "Yes" : "No");
|
||||
fprintf(stderr, "Supported locale?: %s.\n", XSupportsLocale() ? "Yes" : "No");
|
||||
// TODO(inso): handle the case where it isn't supported somehow?
|
||||
|
||||
result.input_method = XOpenIM(dpy, 0, 0, 0);
|
||||
|
@ -1876,7 +1872,7 @@ LinuxInputInit(Display *dpy, Window XWindow)
|
|||
XNClientWindow, XWindow,
|
||||
XNFocusWindow, XWindow,
|
||||
NULL
|
||||
);
|
||||
);
|
||||
|
||||
if (XGetICValues(result.xic, XNFilterEvents, &xim_event_mask, NULL)){
|
||||
xim_event_mask = 0;
|
||||
|
@ -1906,7 +1902,7 @@ LinuxInputInit(Display *dpy, Window XWindow)
|
|||
ExposureMask |
|
||||
VisibilityChangeMask |
|
||||
xim_event_mask
|
||||
);
|
||||
);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
@ -1976,7 +1972,7 @@ LinuxKeycodeInit(Display* dpy){
|
|||
key_min,
|
||||
key_count,
|
||||
&syms_per_code
|
||||
);
|
||||
);
|
||||
|
||||
if(!syms) return;
|
||||
|
||||
|
@ -2008,15 +2004,15 @@ LinuxPushKey(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[MDFR_INDEX_COUNT], b32 i
|
|||
data = linuxvars.input.keys.press;
|
||||
}
|
||||
|
||||
if(*count < KEY_INPUT_BUFFER_SIZE){
|
||||
data[*count].keycode = code;
|
||||
data[*count].character = chr;
|
||||
data[*count].character_no_caps_lock = chr_nocaps;
|
||||
if(*count < KEY_INPUT_BUFFER_SIZE){
|
||||
data[*count].keycode = code;
|
||||
data[*count].character = chr;
|
||||
data[*count].character_no_caps_lock = chr_nocaps;
|
||||
|
||||
memcpy(data[*count].modifiers, *mods, sizeof(*mods));
|
||||
memcpy(data[*count].modifiers, *mods, sizeof(*mods));
|
||||
|
||||
++(*count);
|
||||
}
|
||||
++(*count);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2107,7 +2103,7 @@ LinuxSetWMState(Display* d, Window w, Atom one, Atom two, int mode)
|
|||
0,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&e
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -2141,7 +2137,7 @@ LinuxSetIcon(Display* d, Window w)
|
|||
PropModeReplace,
|
||||
(unsigned char*)linux_icon,
|
||||
sizeof(linux_icon) / sizeof(long)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -2437,7 +2433,7 @@ LinuxGetXSettingsDPI(Display* dpy, int screen)
|
|||
}
|
||||
}
|
||||
|
||||
out:
|
||||
out:
|
||||
if(prop){
|
||||
XFree(prop);
|
||||
}
|
||||
|
@ -2509,7 +2505,7 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
|||
PropModeReplace,
|
||||
(unsigned char*)&linuxvars.atom__NET_WM_WINDOW_TYPE_NORMAL,
|
||||
1
|
||||
);
|
||||
);
|
||||
|
||||
//NOTE(inso): window managers want the PID as a window property for some reason.
|
||||
pid_t pid = getpid();
|
||||
|
@ -2522,7 +2518,7 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
|||
PropModeReplace,
|
||||
(unsigned char*)&pid,
|
||||
1
|
||||
);
|
||||
);
|
||||
|
||||
#define WINDOW_NAME "4coder 4linux: " VERSION
|
||||
|
||||
|
@ -2540,10 +2536,10 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
|||
|
||||
sz_hints->max_width = sz_hints->max_height = (1UL << 16UL);
|
||||
|
||||
/* NOTE(inso): fluxbox thinks this is minimum, so don't set it
|
||||
sz_hints->base_width = BASE_W;
|
||||
sz_hints->base_height = BASE_H;
|
||||
*/
|
||||
/* NOTE(inso): fluxbox thinks this is minimum, so don't set it
|
||||
sz_hints->base_width = BASE_W;
|
||||
sz_hints->base_height = BASE_H;
|
||||
*/
|
||||
sz_hints->win_gravity = NorthWestGravity;
|
||||
|
||||
if (linuxvars.settings.set_window_pos){
|
||||
|
@ -2569,7 +2565,7 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
|||
&win_name, NULL,
|
||||
argv, argc,
|
||||
sz_hints, wm_hints, cl_hints
|
||||
);
|
||||
);
|
||||
|
||||
XFree(win_name.value);
|
||||
|
||||
|
@ -2594,7 +2590,7 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
|||
linuxvars.XWindow,
|
||||
linuxvars.settings.window_x,
|
||||
linuxvars.settings.window_y
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
if (linuxvars.settings.maximize_window){
|
||||
|
@ -2667,7 +2663,7 @@ LinuxHandleX11Events(void)
|
|||
sizeof(buff) - 1,
|
||||
&keysym,
|
||||
&status
|
||||
);
|
||||
);
|
||||
|
||||
if(status == XBufferOverflow){
|
||||
//TODO(inso): handle properly
|
||||
|
@ -2688,7 +2684,7 @@ LinuxHandleX11Events(void)
|
|||
sizeof(buff_no_caps) - 1,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
);
|
||||
|
||||
if(*buff_no_caps){
|
||||
key_no_caps = *buff_no_caps;
|
||||
|
@ -2813,11 +2809,11 @@ LinuxHandleX11Events(void)
|
|||
False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
&Event
|
||||
);
|
||||
);
|
||||
}
|
||||
}break;
|
||||
|
||||
// NOTE(inso): Someone wants us to give them the clipboard data.
|
||||
// NOTE(inso): Someone wants us to give them the clipboard data.
|
||||
case SelectionRequest: {
|
||||
XSelectionRequestEvent request = Event.xselectionrequest;
|
||||
|
||||
|
@ -2835,7 +2831,7 @@ LinuxHandleX11Events(void)
|
|||
request.property != None &&
|
||||
request.display &&
|
||||
request.requestor
|
||||
){
|
||||
){
|
||||
Atom atoms[] = {
|
||||
XA_STRING,
|
||||
linuxvars.atom_UTF8_STRING
|
||||
|
@ -2852,7 +2848,7 @@ LinuxHandleX11Events(void)
|
|||
PropModeReplace,
|
||||
(u8*)atoms,
|
||||
ArrayCount(atoms)
|
||||
);
|
||||
);
|
||||
|
||||
response.property = request.property;
|
||||
|
||||
|
@ -2875,7 +2871,7 @@ LinuxHandleX11Events(void)
|
|||
PropModeReplace,
|
||||
(u8*)linuxvars.clipboard_outgoing.str,
|
||||
linuxvars.clipboard_outgoing.size
|
||||
);
|
||||
);
|
||||
|
||||
response.property = request.property;
|
||||
}
|
||||
|
@ -2886,21 +2882,21 @@ LinuxHandleX11Events(void)
|
|||
|
||||
}break;
|
||||
|
||||
// NOTE(inso): Another program is now the clipboard owner.
|
||||
// NOTE(inso): Another program is now the clipboard owner.
|
||||
case SelectionClear: {
|
||||
if(Event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){
|
||||
linuxvars.clipboard_outgoing.size = 0;
|
||||
}
|
||||
}break;
|
||||
|
||||
// NOTE(inso): A program is giving us the clipboard data we asked for.
|
||||
// NOTE(inso): A program is giving us the clipboard data we asked for.
|
||||
case SelectionNotify: {
|
||||
XSelectionEvent* e = (XSelectionEvent*)&Event;
|
||||
if(
|
||||
e->selection == linuxvars.atom_CLIPBOARD &&
|
||||
e->target == linuxvars.atom_UTF8_STRING &&
|
||||
e->property != None
|
||||
){
|
||||
){
|
||||
Atom type;
|
||||
int fmt;
|
||||
unsigned long nitems, bytes_left;
|
||||
|
@ -2919,7 +2915,7 @@ LinuxHandleX11Events(void)
|
|||
&nitems,
|
||||
&bytes_left,
|
||||
&data
|
||||
);
|
||||
);
|
||||
|
||||
if(result == Success && fmt == 8){
|
||||
LinuxStringDup(&linuxvars.clipboard_contents, data, nitems);
|
||||
|
@ -2947,7 +2943,7 @@ LinuxHandleX11Events(void)
|
|||
linuxvars.atom_CLIPBOARD,
|
||||
linuxvars.XWindow,
|
||||
CurrentTime
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
@ -3223,7 +3219,7 @@ main(int argc, char **argv)
|
|||
&xfixes_version_unused,
|
||||
&linuxvars.xfixes_selection_event,
|
||||
&xfixes_err_unused
|
||||
) == True;
|
||||
) == True;
|
||||
|
||||
if(linuxvars.has_xfixes){
|
||||
XFixesSelectSelectionInput(
|
||||
|
@ -3231,7 +3227,7 @@ main(int argc, char **argv)
|
|||
linuxvars.XWindow,
|
||||
linuxvars.atom_CLIPBOARD,
|
||||
XFixesSetSelectionOwnerNotifyMask
|
||||
);
|
||||
);
|
||||
} else {
|
||||
fputs("Your X server doesn't support XFIXES, mention this fact if you report any clipboard-related issues.\n", stderr);
|
||||
}
|
||||
|
@ -3387,7 +3383,7 @@ main(int argc, char **argv)
|
|||
linuxvars.atom_CLIPBOARD,
|
||||
linuxvars.XWindow,
|
||||
CurrentTime
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
Application_Step_Result result = {};
|
||||
|
@ -3410,7 +3406,7 @@ main(int argc, char **argv)
|
|||
&linuxvars.input,
|
||||
&result,
|
||||
clparams
|
||||
);
|
||||
);
|
||||
|
||||
if(result.perform_kill){
|
||||
break;
|
||||
|
|
|
@ -4,7 +4,7 @@ extensions=".c.cpp.h.hpp.bat.sh";
|
|||
fkey_command_win[1] = {"build.bat", "*compilation*", true};
|
||||
fkey_command_win[2] = {"..\\misc\\run.bat", "*run*"};
|
||||
fkey_command_win[3] = {"site\\build.bat", "*compilation*", true};
|
||||
fkey_command_win[4] = {0, 0};
|
||||
fkey_command_win[4] = {"file\\run_tests.bat", "*tests*"};
|
||||
fkey_command_win[5] = {0, 0};
|
||||
fkey_command_win[6] = {0, 0};
|
||||
fkey_command_win[7] = {0, 0};
|
||||
|
|
|
@ -1047,19 +1047,19 @@ Win32ToggleFullscreen(void){
|
|||
|
||||
internal
|
||||
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
||||
if (OpenClipboard(win32vars.window_handle)){
|
||||
EmptyClipboard();
|
||||
HANDLE memory_handle;
|
||||
memory_handle = GlobalAlloc(GMEM_MOVEABLE, str.size+1);
|
||||
if (memory_handle){
|
||||
char *dest = (char*)GlobalLock(memory_handle);
|
||||
if (OpenClipboard(win32vars.window_handle)){
|
||||
EmptyClipboard();
|
||||
HANDLE memory_handle;
|
||||
memory_handle = GlobalAlloc(GMEM_MOVEABLE, str.size+1);
|
||||
if (memory_handle){
|
||||
char *dest = (char*)GlobalLock(memory_handle);
|
||||
copy_fast_unsafe_cs(dest, str);
|
||||
GlobalUnlock(memory_handle);
|
||||
SetClipboardData(CF_TEXT, memory_handle);
|
||||
win32vars.next_clipboard_is_self = 1;
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
GlobalUnlock(memory_handle);
|
||||
SetClipboardData(CF_TEXT, memory_handle);
|
||||
win32vars.next_clipboard_is_self = 1;
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
internal b32
|
||||
|
@ -1374,8 +1374,6 @@ Win32LoadSystemCode(){
|
|||
#if FRED_INTERNAL
|
||||
win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states;
|
||||
#endif
|
||||
|
||||
win32vars.system.slash = '/';
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -1973,7 +1971,7 @@ WinMain(HINSTANCE hInstance,
|
|||
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
|
||||
|
||||
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
|
||||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
||||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
||||
MessageBoxA(0,"Error: The application and custom version numbers don't match.\n", "Error",0);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -2052,8 +2050,7 @@ WinMain(HINSTANCE hInstance,
|
|||
}
|
||||
|
||||
win32vars.window_handle =
|
||||
CreateWindowA(window_class.lpszClassName,
|
||||
WINDOW_NAME, window_style,
|
||||
CreateWindowA(window_class.lpszClassName, WINDOW_NAME, window_style,
|
||||
window_x, window_y,
|
||||
window_rect.right - window_rect.left,
|
||||
window_rect.bottom - window_rect.top,
|
||||
|
@ -2371,6 +2368,6 @@ int main(int argc, char **argv){
|
|||
HINSTANCE hInstance = GetModuleHandle(0);
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
// BOTTOM
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue