word complete v1 again

This commit is contained in:
Allen Webster 2016-02-20 13:23:46 -05:00
parent 5619527d37
commit 770c48f95b
15 changed files with 3204 additions and 2334 deletions

View File

@ -174,6 +174,16 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){
exec_command(cmd_context, cmdid_auto_tab_line_at_cursor); exec_command(cmd_context, cmdid_auto_tab_line_at_cursor);
} }
// NOTE(allen|a3.4): How one might go about writing things like cut_line
// same idea works for cut word and other such composite commands.
CUSTOM_COMMAND_SIG(cut_line){
exec_command(cmd_context, cmdid_seek_beginning_of_line);
exec_command(cmd_context, cmdid_set_mark);
exec_command(cmd_context, cmdid_seek_end_of_line);
exec_command(cmd_context, cmdid_cut);
exec_command(cmd_context, cmdid_delete);
}
extern "C" GET_BINDING_DATA(get_bindings){ extern "C" GET_BINDING_DATA(get_bindings){
Bind_Helper context_actual = begin_bind_helper(data, size); Bind_Helper context_actual = begin_bind_helper(data, size);
Bind_Helper *context = &context_actual; Bind_Helper *context = &context_actual;

View File

@ -36,6 +36,11 @@ struct String{
int size; int size;
int memory_size; int memory_size;
}; };
struct Offset_String{
int offset;
int size;
};
#endif #endif
inline bool char_not_slash(char c) { return (c != '\\' && c != '/'); } inline bool char_not_slash(char c) { return (c != '\\' && c != '/'); }

124
4ed.cpp
View File

@ -38,6 +38,14 @@ struct Sys_App_Binding{
i32 app_id; i32 app_id;
}; };
struct Complete_State{
Search_Set set;
Search_Iter iter;
Table hits;
String_Space str;
i32 word_start, word_end;
};
struct App_Vars{ struct App_Vars{
Mem_Options mem; Mem_Options mem;
@ -52,6 +60,7 @@ struct App_Vars{
Command_Map *user_maps; Command_Map *user_maps;
i32 *map_id_table; i32 *map_id_table;
i32 user_map_count; i32 user_map_count;
Command_Binding prev_command;
Sys_App_Binding *sys_app_bindings; Sys_App_Binding *sys_app_bindings;
i32 sys_app_count, sys_app_max; i32 sys_app_count, sys_app_max;
@ -84,6 +93,7 @@ struct App_Vars{
App_State state; App_State state;
App_State_Resizing resizing; App_State_Resizing resizing;
Complete_State complete_state;
Panel *prev_mouse_panel; Panel *prev_mouse_panel;
Custom_API config_api; Custom_API config_api;
@ -442,25 +452,43 @@ COMMAND_DECL(word_complete){
REQ_FILE(file, view); REQ_FILE(file, view);
USE_LAYOUT(layout); USE_LAYOUT(layout);
USE_MEM(mem); USE_MEM(mem);
USE_VARS(vars);
USE_WORKING_SET(working_set);
Partition *part = &mem->part; Partition *part = &mem->part;
General_Memory *general = &mem->general;
Complete_State *complete_state = &vars->complete_state;
Search_Range *ranges;
Search_Match match;
Temp_Memory temp1, temp2; Temp_Memory temp;
Buffer_Type *buffer; Buffer_Type *buffer;
Buffer_Backify_Type loop; Buffer_Backify_Type loop;
char *data; char *data;
i32 end; i32 end;
i32 size_of_buffer;
i32 cursor_pos, word_start, word_end; i32 cursor_pos, word_start, word_end;
char c; char c;
char *str, *spare; char *spare;
i32 size; i32 size;
i32 match_start, match_end, match_size; i32 buffer_count, i, j;
Editing_File *file_ptr;
i32 match_size;
b32 do_init = 0;
buffer = &file->state.buffer; buffer = &file->state.buffer;
size_of_buffer = buffer_size(buffer);
if (vars->prev_command.function != command_word_complete){
do_init = 1;
}
if (do_init){
word_end = view->cursor.pos; word_end = view->cursor.pos;
word_start = word_end; word_start = word_end;
cursor_pos = word_end - 1; cursor_pos = word_end - 1;
@ -486,26 +514,81 @@ COMMAND_DECL(word_complete){
size = word_end - word_start; size = word_end - word_start;
search_iter_init(general, &complete_state->iter, size);
buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str);
complete_state->iter.word.size = size;
buffer_count = working_set->file_index_count;
search_set_init(general, &complete_state->set, buffer_count + 1);
ranges = complete_state->set.ranges;
ranges[0].buffer = buffer;
ranges[0].start = 0;
ranges[0].size = word_start;
ranges[1].buffer = buffer;
ranges[1].start = word_end;
ranges[1].size = size_of_buffer - word_end;
file_ptr = working_set->files;
for (i = 0, j = 2; i < buffer_count; ++i, ++file_ptr){
if (file_ptr != file && !file_ptr->state.is_dummy && file_is_ready(file_ptr)){
ranges[j].buffer = &file_ptr->state.buffer;
ranges[j].start = 0;
ranges[j].size = buffer_size(ranges[j].buffer);
++j;
}
}
complete_state->set.count = j;
search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
search_hit_add(general, &complete_state->hits, &complete_state->str,
complete_state->iter.word.str, complete_state->iter.word.size);
complete_state->word_start = word_start;
complete_state->word_end = word_end;
}
else{
word_start = complete_state->word_start;
word_end = complete_state->word_end;
size = complete_state->iter.word.size;
}
if (size > 0){ if (size > 0){
temp1 = begin_temp_memory(part); for (;;){
match = search_next_match(part, &complete_state->set, &complete_state->iter);
str = (char*)push_array(part, char, size); if (match.found_match){
buffer_stringify(buffer, word_start, word_end, str); temp = begin_temp_memory(part);
match_size = match.end - match.start;
temp2 = begin_temp_memory(part);
spare = (char*)push_array(part, char, size);
end_temp_memory(temp2);
// TODO(allen): find string needs explicit end position
match_start = buffer_find_string(buffer, word_end, str, size, spare);
match_end = buffer_seek_word_right_assume_on_word(buffer, match_start);
match_size = match_end - match_start;
spare = (char*)push_array(part, char, match_size); spare = (char*)push_array(part, char, match_size);
buffer_stringify(buffer, match_start, match_end, spare); buffer_stringify(match.buffer, match.start, match.end, spare);
if (search_hit_add(general, &complete_state->hits, &complete_state->str, spare, match_size)){
view_replace_range(system, mem, view, layout, word_start, word_end, spare, match_size, word_end); view_replace_range(system, mem, view, layout, word_start, word_end, spare, match_size, word_end);
end_temp_memory(temp1); complete_state->word_end = word_start + match_size;
complete_state->set.ranges[1].start = word_start + match_size;
break;
}
end_temp_memory(temp);
}
else{
complete_state->iter.pos = 0;
complete_state->iter.i = 0;
search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
search_hit_add(general, &complete_state->hits, &complete_state->str,
complete_state->iter.word.str, complete_state->iter.word.size);
match_size = complete_state->iter.word.size;
view_replace_range(system, mem, view, layout, word_start, word_end,
complete_state->iter.word.str, match_size, word_end);
complete_state->word_end = word_start + match_size;
complete_state->set.ranges[1].start = word_start + match_size;
break;
}
}
} }
} }
@ -2159,11 +2242,11 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap); map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap);
map_add(commands, '?', MDFR_CTRL, command_toggle_show_whitespace); map_add(commands, '?', MDFR_CTRL, command_toggle_show_whitespace);
map_add(commands, '|', MDFR_CTRL, command_toggle_tokens); map_add(commands, '|', MDFR_CTRL, command_toggle_tokens);
map_add(commands, 'U', MDFR_CTRL, command_to_uppercase); map_add(commands, 'u', MDFR_CTRL, command_to_uppercase);
map_add(commands, 'u', MDFR_CTRL, command_to_lowercase); map_add(commands, 'j', MDFR_CTRL, command_to_lowercase);
map_add(commands, '~', MDFR_CTRL, command_clean_all_lines); map_add(commands, '~', MDFR_CTRL, command_clean_all_lines);
map_add(commands, 'f', MDFR_CTRL, command_search); map_add(commands, 'f', MDFR_CTRL, command_search);
map_add(commands, 'j', MDFR_CTRL, command_word_complete); map_add(commands, 't', MDFR_CTRL, command_word_complete);
map_add(commands, 'r', MDFR_CTRL, command_rsearch); map_add(commands, 'r', MDFR_CTRL, command_rsearch);
map_add(commands, 'g', MDFR_CTRL, command_goto_line); map_add(commands, 'g', MDFR_CTRL, command_goto_line);
@ -3462,6 +3545,7 @@ App_Step_Sig(app_step){
app_result.redraw = 1; app_result.redraw = 1;
} }
} }
vars->prev_command = cmd;
}break; }break;
case APP_STATE_RESIZING: case APP_STATE_RESIZING:

31
4ed.h
View File

@ -90,37 +90,6 @@ struct Clipboard_Contents{
i32 size; i32 size;
}; };
#define FileNameMax (1 << 9)
struct File_Slot{
File_Slot *next, *prev;
byte *data;
i32 size, max;
char *filename;
i32 filename_len;
u32 flags;
};
enum File_Exchange_Flag{
FEx_Request = 0x1,
FEx_Ready = 0x2,
FEx_Not_Exist = 0x4,
FEx_Save = 0x8,
FEx_Save_Complete = 0x10,
FEx_Save_Failed = 0x20
};
struct File_Exchange{
File_Slot available, active, free_list;
File_Slot *files;
i32 num_active, max;
};
struct Exchange{
Thread_Exchange thread;
File_Exchange file;
};
struct Command_Line_Parameters{ struct Command_Line_Parameters{
char **argv; char **argv;
int argc; int argc;

View File

@ -29,6 +29,8 @@
#include "4ed_internal.h" #include "4ed_internal.h"
#include "4tech_table.cpp"
#define FCPP_LEXER_IMPLEMENTATION #define FCPP_LEXER_IMPLEMENTATION
#include "4cpp_lexer.h" #include "4cpp_lexer.h"

View File

@ -4613,13 +4613,13 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
} }
else{ else{
pos = buffer_find_string(&file->state.buffer, start_pos + 1, pos = buffer_find_string(&file->state.buffer, start_pos + 1, size,
string->str, string->size, spare); string->str, string->size, spare);
if (pos < size){ if (pos < size){
if (step_forward){ if (step_forward){
file_view->isearch.pos = pos; file_view->isearch.pos = pos;
start_pos = pos; start_pos = pos;
pos = buffer_find_string(&file->state.buffer, start_pos + 1, pos = buffer_find_string(&file->state.buffer, start_pos + 1, size,
string->str, string->size, spare); string->str, string->size, spare);
if (pos == size) pos = start_pos; if (pos == size) pos = start_pos;
} }
@ -4765,5 +4765,200 @@ file_view_iter_good(File_View_Iter iter){
return(result); return(result);
} }
struct Search_Range{
Buffer_Type *buffer;
i32 start, size;
};
struct Search_Set{
Search_Range *ranges;
i32 count, max;
};
struct Search_Iter{
String word;
i32 pos;
i32 i;
};
struct Search_Match{
Buffer_Type *buffer;
i32 start, end;
b32 found_match;
};
internal void
search_iter_init(General_Memory *general, Search_Iter *iter, i32 size){
i32 str_max;
if (iter->word.str == 0){
str_max = size*2;
iter->word.str = (char*)general_memory_allocate(general, str_max, 0);
iter->word.memory_size = str_max;
}
else if (iter->word.memory_size < size){
str_max = size*2;
iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max, 0);
iter->word.memory_size = str_max;
}
iter->i = 0;
iter->pos = 0;
}
internal void
search_set_init(General_Memory *general, Search_Set *set, i32 set_count){
i32 max;
if (set->ranges == 0){
max = set_count*2;
set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max, 0);
set->max = max;
}
else if (set->max < set_count){
max = set_count*2;
set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
general, set->ranges, sizeof(Search_Range)*max, 0);
set->max = max;
}
set->count = set_count;
}
internal void
search_hits_table_alloc(General_Memory *general, Table *hits, i32 table_size){
i32 hash_size, mem_size;
hash_size = table_size * sizeof(u32);
hash_size = (hash_size + 7) & ~7;
mem_size = hash_size + table_size * sizeof(Offset_String);
hits->hash_array = (u32*)general_memory_allocate(general, mem_size, 0);
hits->data_array = (u8*)hits->hash_array + hash_size;
hits->max = table_size;
hits->item_size = sizeof(Offset_String);
}
internal void
search_hits_init(General_Memory *general, Table *hits, String_Space *str, i32 table_size, i32 str_size){
i32 hash_size, mem_size;
if (hits->hash_array == 0){
search_hits_table_alloc(general, hits, table_size);
}
else if (hits->max < table_size){
hash_size = table_size * sizeof(u32);
hash_size = (hash_size + 7) & ~7;
mem_size = hash_size + table_size * sizeof(Offset_String);
hits->hash_array = (u32*)general_memory_reallocate_nocopy(
general, hits->hash_array, mem_size, 0);
hits->data_array = (u8*)hits->hash_array + hash_size;
hits->max = table_size;
hits->item_size = sizeof(Offset_String);
}
if (str->space == 0){
str->space = (char*)general_memory_allocate(general, str_size, 0);
str->max = str_size;
}
else if (str->max < str_size){
str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size, 0);
str->max = str_size;
}
str->pos = str->new_pos = 0;
table_clear(hits);
}
internal b32
search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *str, i32 len){
b32 result;
i32 new_size;
Offset_String ostring;
Table new_hits;
Assert(len != 0);
ostring = strspace_append(space, str, len);
if (ostring.size == 0){
new_size = Max(space->max*2, space->max + len);
space->space = (char*)general_memory_reallocate(general, space->space, space->new_pos, new_size, 0);
ostring = strspace_append(space, str, len);
}
Assert(ostring.size != 0);
if (table_at_capacity(hits)){
search_hits_table_alloc(general, &new_hits, hits->max*2);
table_clear(&new_hits);
table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
general_memory_free(general, hits->hash_array);
*hits = new_hits;
}
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
result = 1;
strspace_keep_prev(space);
}
else{
result = 0;
strspace_discard_prev(space);
}
return(result);
}
internal Search_Match
search_next_match(Partition *part, Search_Set *set, Search_Iter *iter_){
Search_Match result = {};
Search_Iter iter = *iter_;
Search_Range *range;
Temp_Memory temp;
char *spare;
i32 start_pos, end_pos, count;
temp = begin_temp_memory(part);
spare = push_array(part, char, iter.word.size);
count = set->count;
for (; iter.i < count;){
range = set->ranges + iter.i;
end_pos = range->start + range->size;
if (iter.pos + iter.word.size < end_pos){
start_pos = Max(iter.pos, range->start);
result.start = buffer_find_string(range->buffer, start_pos, end_pos, iter.word.str, iter.word.size, spare);
if (result.start < end_pos){
iter.pos = result.start + 1;
if (result.start == 0 || !char_is_alpha_numeric(buffer_get_char(range->buffer, result.start - 1))){
result.end = buffer_seek_word_right_assume_on_word(range->buffer, result.start);
if (result.end < end_pos){
result.found_match = 1;
result.buffer = range->buffer;
iter.pos = result.end;
break;
}
}
}
else{
++iter.i, iter.pos = 0;
}
}
else{
++iter.i, iter.pos = 0;
}
}
end_temp_memory(temp);
*iter_ = iter;
return(result);
}
// BOTTOM // BOTTOM

View File

@ -249,5 +249,7 @@ end_temp_memory(Temp_Memory temp){
((Partition*)temp.handle)->pos = temp.pos; ((Partition*)temp.handle)->pos = temp.pos;
} }
#define reset_temp_memory end_temp_memory
// BOTTOM // BOTTOM

View File

@ -187,5 +187,36 @@ struct System_Functions{
INTERNAL_System_Debug_Message *internal_debug_message; INTERNAL_System_Debug_Message *internal_debug_message;
}; };
#define FileNameMax (1 << 9)
struct File_Slot{
File_Slot *next, *prev;
byte *data;
i32 size, max;
char *filename;
i32 filename_len;
u32 flags;
};
enum File_Exchange_Flag{
FEx_Request = 0x1,
FEx_Ready = 0x2,
FEx_Not_Exist = 0x4,
FEx_Save = 0x8,
FEx_Save_Complete = 0x10,
FEx_Save_Failed = 0x20
};
struct File_Exchange{
File_Slot available, active, free_list;
File_Slot *files;
i32 num_active, max;
};
struct Exchange{
Thread_Exchange thread;
File_Exchange file;
};
// BOTTOM // BOTTOM

235
4tech_table.cpp Normal file
View File

@ -0,0 +1,235 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 14.02.2016
*
* 4tech C style genereic hash table
*
*/
// TOP
#define TableHashEmpty 0
#define TableHashDeleted 1
#define TableHashMin 0x10000000
typedef u32 Hash_Function(void *item, void *arg);
typedef i32 Compare_Function(void *key, void *item, void *arg);
struct Table{
u32 *hash_array;
u8 *data_array;
i32 count, max;
i32 item_size;
};
internal b32
table_at_capacity(Table *table){
b32 result = 1;
if (table->count * 8 < table->max * 7){
result = 0;
}
return(result);
}
internal b32
table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
u32 hash, *inspect;
i32 i;
Assert(table->count * 8 < table->max * 7);
hash = (hash_func(item, arg) | TableHashMin);
i = hash % table->max;
inspect = table->hash_array + i;
while (*inspect >= TableHashMin){
if (*inspect == hash){
if (comp_func(item, table->data_array + i*table->item_size, arg) == 0){
return(1);
}
}
++i;
++inspect;
if (i == table->max){
i = 0;
inspect = table->hash_array;
}
}
*inspect = hash;
memcpy(table->data_array + i*table->item_size, item, table->item_size);
++table->count;
return(0);
}
internal b32
table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, Hash_Function *hash_func, Compare_Function *comp_func){
u32 hash, *inspect;
i32 i;
hash = (hash_func(search_key, arg) | TableHashMin);
i = hash % table->max;
inspect = table->hash_array + i;
while (*inspect != TableHashEmpty){
if (*inspect == hash){
if (comp_func(search_key, table->data_array + i*table->item_size, arg) == 0){
if (pos) *pos = i*table->item_size;
if (index) *index = i;
return(1);
}
}
++i;
++inspect;
if (i == table->max){
i = 0;
inspect = table->hash_array;
}
}
return(0);
}
internal void*
table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 pos;
void *result = 0;
if (table_find_pos(table, search_key, arg, &pos, 0, hash_func, comp_func)){
result = table->data_array + pos;
}
return(result);
}
internal void
table_remove_index(Table *table, i32 index){
table->hash_array[index] = TableHashDeleted;
--table->count;
}
internal b32
table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 index;
b32 result = 0;
if (table_find_pos(table, search_key, arg, 0, &index, hash_func, comp_func)){
table_remove_index(table, index);
result = 1;
}
return(result);
}
internal void
table_clear(Table *table){
table->count = 0;
memset(table->hash_array, 0, table->max*sizeof(*table->hash_array));
}
internal void
table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 i, c, count, item_size;
u32 *hash_item;
u8 *data_item;
Assert((dst->count + src->count - 1) * 7 < dst->max * 8);
Assert(dst->item_size == src->item_size);
count = src->count;
hash_item = src->hash_array;
data_item = src->data_array;
item_size = src->item_size;
for (i = 0, c = 0; c < count; ++i, ++hash_item, data_item += item_size){
if (*hash_item >= TableHashMin){
++c;
table_add(dst, data_item, arg, hash_func, comp_func);
}
}
}
internal u32
tbl_string_hash(void *item, void *arg){
String *string = (String*)item;
char *str;
i32 i,len;
u32 x = 5381;
char c;
(void)arg;
str = string->str;
len = string->size;
i = 0;
while (i < len){
c = str[i++];
x = ((x << 5) + x) + c;
}
return(x);
}
internal i32
tbl_string_compare(void *a, void *b, void *arg){
String *stra = (String*)a;
String *strb = (String*)b;
i32 result = !match(*stra, *strb);
return(result);
}
internal u32
tbl_offset_string_hash(void *item, void *arg){
Offset_String *string = (Offset_String*)item;
char *str;
i32 i,len;
u32 x = 5381;
char c;
str = ((char*)arg) + string->offset;
len = string->size;
i = 0;
while (i < len){
c = str[i++];
x = ((x << 5) + x) + c;
}
return(x);
}
internal i32
tbl_offset_string_compare(void *a, void *b, void *arg){
Offset_String *ostra = (Offset_String*)a;
Offset_String *ostrb = (Offset_String*)b;
String stra = make_string((char*)arg + ostra->offset, ostra->size);
String strb = make_string((char*)arg + ostrb->offset, ostrb->size);
i32 result = !match(stra, strb);
return(result);
}
struct String_Space{
char *space;
i32 pos, new_pos, max;
};
internal Offset_String
strspace_append(String_Space *space, char *str, i32 len){
Offset_String result = {};
if (space->new_pos + len <= space->max){
result.offset = space->new_pos;
result.size = len;
memcpy(space->space + space->new_pos, str, len);
space->new_pos = space->pos + len;
}
return(result);
}
internal void
strspace_keep_prev(String_Space *space){
space->pos = space->new_pos;
}
internal void
strspace_discard_prev(String_Space *space){
space->new_pos = space->pos;
}
// BOTTOM

View File

@ -37,6 +37,15 @@ buffer_backify(Buffer_Type *buffer, int start, int end, char *out){
} }
} }
internal_4tech char
buffer_get_char(Buffer_Type *buffer, int i){
char out = 0;
if (i >= 0 && i < buffer_size(buffer)){
buffer_stringify(buffer, i, i+1, &out);
}
return(out);
}
internal_4tech int internal_4tech int
buffer_convert_out(Buffer_Type *buffer, char *dest, int max){ buffer_convert_out(Buffer_Type *buffer, char *dest, int max){
Buffer_Stringify_Type loop; Buffer_Stringify_Type loop;
@ -463,17 +472,14 @@ buffer_find_hard_start_end:
} }
internal_4tech int internal_4tech int
buffer_find_string(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){ buffer_find_string(Buffer_Type *buffer, int start_pos, int end_pos, char *str, int len, char *spare){
Buffer_Stringify_Type loop; Buffer_Stringify_Type loop;
char *data; char *data;
int size, end; int end, pos;
int pos;
size = buffer_size(buffer);
pos = start_pos; pos = start_pos;
if (len > 0){ if (len > 0){
for (loop = buffer_stringify_loop(buffer, start_pos, size - len + 1); for (loop = buffer_stringify_loop(buffer, start_pos, end_pos - len + 1);
buffer_stringify_good(&loop); buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){ buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos; end = loop.size + loop.absolute_pos;
@ -489,7 +495,7 @@ buffer_find_string(Buffer_Type *buffer, int start_pos, char *str, int len, char
} }
buffer_find_string_end: buffer_find_string_end:
if (pos >= size - len + 1) pos = size; if (pos >= end_pos - len + 1) pos = end_pos;
return(pos); return(pos);
} }

View File

@ -40,7 +40,8 @@
#include <GL/glx.h> #include <GL/glx.h>
#include <xmmintrin.h> #include <xmmintrin.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <X11/extensions/XInput2.h> //#include <X11/extensions/XInput2.h>
#include <X11/XKBlib.h>
#include <linux/input.h> #include <linux/input.h>
#include <time.h> #include <time.h>
#include <dlfcn.h> #include <dlfcn.h>
@ -53,6 +54,17 @@
#include <stdlib.h> #include <stdlib.h>
struct Linux_Vars{ struct Linux_Vars{
Display *XDisplay;
Window XWindow;
Render_Target target;
XIM input_method;
XIMStyle input_style;
XIC xic;
Key_Codes key_codes;
Clipboard_Contents clipboard_contents;
void *app_code; void *app_code;
void *custom; void *custom;
@ -65,6 +77,8 @@ struct Linux_Vars{
#if FRED_INTERNAL #if FRED_INTERNAL
Sys_Bubble internal_bubble; Sys_Bubble internal_bubble;
#endif #endif
Font_Load_System fnt;
}; };
globalvar Linux_Vars linuxvars; globalvar Linux_Vars linuxvars;
@ -76,7 +90,8 @@ Sys_Get_Memory_Sig(system_get_memory_){
// TODO(allen): Implement without stdlib.h // TODO(allen): Implement without stdlib.h
void *result = 0; void *result = 0;
if (size != 0){ Assert(size != 0);
#if FRED_INTERNAL #if FRED_INTERNAL
Sys_Bubble *bubble; Sys_Bubble *bubble;
@ -94,7 +109,6 @@ Sys_Get_Memory_Sig(system_get_memory_){
#else #else
result = malloc(size); result = malloc(size);
#endif #endif
}
return(result); return(result);
} }
@ -348,6 +362,16 @@ Sys_Save_File_Sig(system_save_file){
return(result); return(result);
} }
// TODO(allen): Implement this. Also where is this
// macro define? Let's try to organize these functions
// a little better now that they're starting to settle
// into their places.
internal
Font_Load_Sig(system_draw_font_load){
return(0);
}
internal b32 internal b32
LinuxLoadAppCode(){ LinuxLoadAppCode(){
b32 result = 0; b32 result = 0;
@ -397,6 +421,40 @@ LinuxLoadSystemCode(){
#include "system_shared.cpp" #include "system_shared.cpp"
#include "4ed_rendering.cpp" #include "4ed_rendering.cpp"
internal void
LinuxLoadRenderCode(){
linuxvars.target.push_clip = draw_push_clip;
linuxvars.target.pop_clip = draw_pop_clip;
linuxvars.target.push_piece = draw_push_piece;
linuxvars.target.font_set.font_info_load = draw_font_info_load;
linuxvars.target.font_set.font_load = system_draw_font_load;
linuxvars.target.font_set.release_font = draw_release_font;
}
internal void
LinuxRedrawTarget(){
system_acquire_lock(RENDER_LOCK);
launch_rendering(&linuxvars.target);
system_release_lock(RENDER_LOCK);
glFlush();
glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow);
}
internal void
LinuxResizeTarget(i32 width, i32 height){
if (width > 0 && height > 0){
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, -1, 1);
glScissor(0, 0, width, height);
linuxvars.target.width = width;
linuxvars.target.height = height;
}
}
// NOTE(allen): Thanks to Casey for providing the linux OpenGL launcher. // NOTE(allen): Thanks to Casey for providing the linux OpenGL launcher.
static bool ctxErrorOccurred = false; static bool ctxErrorOccurred = false;
static int XInput2OpCode = 0; static int XInput2OpCode = 0;
@ -439,7 +497,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
None None
}; };
printf("\nAttribs: %d %d %d %d %d\n", printf("Attribs: %d %d %d %d %d\n",
context_attribs[0], context_attribs[0],
context_attribs[1], context_attribs[1],
context_attribs[2], context_attribs[2],
@ -636,16 +694,23 @@ ChooseGLXConfig(Display *XDisplay, int XScreenIndex)
return(Result); return(Result);
} }
internal void struct Init_Input_Result{
XIM input_method;
XIMStyle best_style;
XIC xic;
};
internal Init_Input_Result
InitializeXInput(Display *dpy, Window XWindow) InitializeXInput(Display *dpy, Window XWindow)
{ {
#if 0
int event, error; int event, error;
if(XQueryExtension(dpy, "XInputExtension", &XInput2OpCode, &event, &error)) if(XQueryExtension(dpy, "XInputExtension", &XInput2OpCode, &event, &error))
{ {
int major = 2, minor = 0; int major = 2, minor = 0;
if(XIQueryVersion(dpy, &major, &minor) != BadRequest) if(XIQueryVersion(dpy, &major, &minor) != BadRequest)
{ {
printf("XInput initialized"); printf("XInput initialized version %d.%d\n", major, minor);
} }
else else
{ {
@ -723,11 +788,61 @@ InitializeXInput(Display *dpy, Window XWindow)
XISetMask(Mask.mask, XI_RawMotion); XISetMask(Mask.mask, XI_RawMotion);
XISelectEvents(dpy, DefaultRootWindow(dpy), &Mask, 1); XISelectEvents(dpy, DefaultRootWindow(dpy), &Mask, 1);
} }
#endif
// NOTE(allen): Annnndddd... here goes some guess work of my own.
Init_Input_Result result = {};
XIMStyle style;
XIMStyles *styles = 0;
i32 i, count;
XSetLocaleModifiers("");
printf("supported locales: %d\n", XSupportsLocale());
XSelectInput(linuxvars.XDisplay, linuxvars.XWindow, ExposureMask | KeyPressMask);
result.input_method = XOpenIM(dpy, 0, 0, 0);
if (result.input_method){
if (!XGetIMValues(result.input_method, XNQueryInputStyle, &styles, NULL) &&
styles){
result.best_style = 0;
count = styles->count_styles;
for (i = 0; i < count; ++i){
style = styles->supported_styles[i];
if (style == (XIMPreeditNothing | XIMStatusNothing)){
result.best_style = style;
break;
}
}
if (result.best_style){
XFree(styles);
result.xic =
XCreateIC(result.input_method, XNInputStyle, result.best_style,
XNClientWindow, XWindow,
XNFocusWindow, XWindow,
0, 0,
NULL);
}
else{
result = {};
printf("Could not get minimum required input style");
}
}
}
else{
result = {};
printf("Could not open X Input Method\n");
}
return(result);
} }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
i32 COUNTER = 0;
linuxvars = {}; linuxvars = {};
exchange_vars = {}; exchange_vars = {};
@ -765,7 +880,7 @@ main(int argc, char **argv)
} }
if (curdir_req >= (1 << 13)){ if (curdir_req >= (1 << 13)){
// TODO(allen): fuckin' bullshit string APIs makin' me pissed // TODO(allen): bullshit string APIs makin' me pissed
return 57; return 57;
} }
@ -795,70 +910,162 @@ main(int argc, char **argv)
} }
if (output_size != 0) return 0; if (output_size != 0) return 0;
system_filter_real_files(files, file_count); sysshared_filter_real_files(files, file_count);
Display *XDisplay = XOpenDisplay(0); keycode_init(&linuxvars.key_codes);
if(XDisplay && GLXSupportsModernContexts(XDisplay))
#ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.so";
char *custom_file;
if (linuxvars.settings.custom_dll) custom_file = linuxvars.settings.custom_dll;
else custom_file = custom_file_default;
linuxvars.custom = dlopen(custom_file, RTLD_LAZY);
if (!linuxvars.custom && custom_file != custom_file_default){
if (!linuxvars.settings.custom_dll_is_strict){
linuxvars.custom = dlopen(custom_file_default, RTLD_LAZY);
}
}
if (linuxvars.custom){
linuxvars.custom_api.get_bindings = (Get_Binding_Data_Function*)
dlsym(linuxvars.custom, "get_bindings");
}
#endif
// TODO(allen): Setup background threads and locks
LinuxLoadRenderCode();
linuxvars.target.max = Mbytes(1);
linuxvars.target.push_buffer = (byte*)system_get_memory(linuxvars.target.max);
File_Slot file_slots[32];
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
Font_Load_Parameters params[8];
sysshared_init_font_params(&linuxvars.fnt, params, ArrayCount(params));
linuxvars.app.init(linuxvars.system, &linuxvars.target,
&memory_vars, &exchange_vars, &linuxvars.key_codes,
linuxvars.clipboard_contents, current_directory,
linuxvars.custom_api);
// NOTE(allen): Here begins the linux screen setup stuff.
// Behold the true nature of this wonderful OS:
// (thanks again to Casey for providing this stuff)
Colormap cmap;
XSetWindowAttributes swa;
int WinWidth, WinHeight;
b32 window_setup_success = 0;
WinWidth = 800;
WinHeight = 600;
i32 xkb_ev_code = 0, xkb_err_code = 0;
linuxvars.XDisplay = XkbOpenDisplay(0, &xkb_ev_code, &xkb_err_code, 0, 0, 0);
if(linuxvars.XDisplay && GLXSupportsModernContexts(linuxvars.XDisplay))
{ {
int XScreenCount = ScreenCount(XDisplay); int XScreenCount = ScreenCount(linuxvars.XDisplay);
for(int XScreenIndex = 0; for(int XScreenIndex = 0;
XScreenIndex < XScreenCount; XScreenIndex < XScreenCount;
++XScreenIndex) ++XScreenIndex)
{ {
Screen *XScreen = ScreenOfDisplay(XDisplay, XScreenIndex); Screen *XScreen = ScreenOfDisplay(linuxvars.XDisplay, XScreenIndex);
int WinWidth = WidthOfScreen(XScreen); i32 ScrnWidth, ScrnHeight;
int WinHeight = HeightOfScreen(XScreen); ScrnWidth = WidthOfScreen(XScreen);
ScrnHeight = HeightOfScreen(XScreen);
glx_config_result Config = ChooseGLXConfig(XDisplay, XScreenIndex); if (ScrnWidth + 50 < WinWidth) WinWidth = ScrnWidth + 50;
if (ScrnHeight + 50 < WinHeight) WinHeight = ScrnHeight + 50;
glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex);
if(Config.Found) if(Config.Found)
{ {
Colormap cmap; swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay,
XSetWindowAttributes swa; RootWindow(linuxvars.XDisplay, Config.BestInfo.screen ),
swa.colormap = cmap = XCreateColormap(XDisplay,
RootWindow(XDisplay, Config.BestInfo.screen ),
Config.BestInfo.visual, AllocNone); Config.BestInfo.visual, AllocNone);
swa.background_pixmap = None; swa.background_pixmap = None;
swa.border_pixel = 0; swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask; swa.event_mask = StructureNotifyMask;
Window XWindow = XCreateWindow(XDisplay, linuxvars.XWindow =
RootWindow(XDisplay, Config.BestInfo.screen), XCreateWindow(linuxvars.XDisplay,
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen),
0, 0, WinWidth, WinHeight, 0, 0, WinWidth, WinHeight,
0, Config.BestInfo.depth, InputOutput, 0, Config.BestInfo.depth, InputOutput,
Config.BestInfo.visual, Config.BestInfo.visual,
CWBorderPixel|CWColormap|CWEventMask, &swa ); CWBorderPixel|CWColormap|CWEventMask, &swa );
if(XWindow)
{
XStoreName(XDisplay, XWindow, "4coder");
XMapWindow(XDisplay, XWindow);
InitializeXInput(XDisplay, XWindow); if(linuxvars.XWindow)
{
XStoreName(linuxvars.XDisplay, linuxvars.XWindow, "4coder-window");
XMapWindow(linuxvars.XDisplay, linuxvars.XWindow);
Init_Input_Result input_result =
InitializeXInput(linuxvars.XDisplay, linuxvars.XWindow);
linuxvars.input_method = input_result.input_method;
linuxvars.input_style = input_result.best_style;
linuxvars.xic = input_result.xic;
b32 IsLegacy = false; b32 IsLegacy = false;
GLXContext GLContext = GLXContext GLContext =
InitializeOpenGLContext(XDisplay, XWindow, Config.BestConfig, IsLegacy); InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy);
XWindowAttributes WinAttribs; XWindowAttributes WinAttribs;
if(XGetWindowAttributes(XDisplay, XWindow, &WinAttribs)) if(XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs))
{ {
WinWidth = WinAttribs.width; WinWidth = WinAttribs.width;
WinHeight = WinAttribs.height; WinHeight = WinAttribs.height;
} }
XRaiseWindow(XDisplay, XWindow); XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
XSync(XDisplay, False); XSync(linuxvars.XDisplay, False);
window_setup_success = 1;
}
}
}
}
XSetICFocus(linuxvars.xic);
if (window_setup_success){
LinuxResizeTarget(WinWidth, WinHeight);
for(;;) for(;;)
{ {
while(XPending(XDisplay)) while(XPending(linuxvars.XDisplay))
{ {
XEvent Event; XEvent Event;
XNextEvent(XDisplay, &Event); XNextEvent(linuxvars.XDisplay, &Event);
if (XFilterEvent(&Event, None) == True){
continue;
}
switch (Event.type){
case KeyPress:
{
KeySym ks = NoSymbol;
XkbLookupKeySym(linuxvars.XDisplay, Event.xkey.keycode, Event.xkey.state, NULL, &ks);
printf("keysym: %s\n", XKeysymToString(ks));
Status st;
char buff[256];
memset(buff, 0, sizeof(buff));
XmbLookupString(linuxvars.xic, &Event.xkey, buff, sizeof(buff), &ks, &st);
printf("IC status: %d, code: %u, sym: %s, str: %s\n", st, Event.xkey.keycode, XKeysymToString(ks), buff);
}break;
}
#if 0
if((Event.xcookie.type == GenericEvent) && if((Event.xcookie.type == GenericEvent) &&
(Event.xcookie.extension == XInput2OpCode) && (Event.xcookie.extension == XInput2OpCode) &&
XGetEventData(XDisplay, &Event.xcookie)) XGetEventData(linuxvars.XDisplay, &Event.xcookie))
{ {
switch(Event.xcookie.evtype) switch(Event.xcookie.evtype)
{ {
@ -868,8 +1075,8 @@ main(int argc, char **argv)
int root_x_return, root_y_return; int root_x_return, root_y_return;
int MouseX, MouseY; int MouseX, MouseY;
unsigned int mask_return; unsigned int mask_return;
XQueryPointer(XDisplay, XQueryPointer(linuxvars.XDisplay,
XWindow, linuxvars.XWindow,
&root_return, &child_return, &root_return, &child_return,
&root_x_return, &root_y_return, &root_x_return, &root_y_return,
&MouseX, &MouseY, &MouseX, &MouseY,
@ -889,20 +1096,109 @@ main(int argc, char **argv)
{ {
b32 Down = (Event.xcookie.evtype == XI_KeyPress); b32 Down = (Event.xcookie.evtype == XI_KeyPress);
XIDeviceEvent *DevEvent = (XIDeviceEvent *)Event.xcookie.data; XIDeviceEvent *DevEvent = (XIDeviceEvent *)Event.xcookie.data;
int VK = DevEvent->detail; int keycode = DevEvent->detail;
if (Down){
printf("Keycode %d\n", keycode);
// NOTE(allen): Thanks to eisbehr for providing the code
// for initializing an XKeyPressedEvent struct for use in
// Xmb8LookupString
XKeyPressedEvent eventBase = {};
eventBase.type = KeyPress;
eventBase.serial = 0xF00D;
eventBase.send_event = 1; // at least admit that this isn't a genuine event
eventBase.display = DevEvent->display;
eventBase.window = DevEvent->event;
eventBase.root = DevEvent->root;
eventBase.subwindow = 0;
eventBase.time = {}; // Let's hope we don't need a real time.
eventBase.x = 0;
eventBase.y = 0;
eventBase.x_root = 0;
eventBase.y_root = 0;
eventBase.state = 0; // state of modifiers
// Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask,
// ShiftMask, LockMask, ControlMask,
// Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask.
//eventBase.keycode = 10;//minKeyCode;
eventBase.same_screen = 1;
eventBase.keycode = keycode;
char lookup_buffer[32];
Status status;
i32 size;
KeySym keysym;
size = XmbLookupString(linuxvars.xic, &eventBase,
lookup_buffer, sizeof(lookup_buffer),
&keysym, &status);
if (status == XBufferOverflow){
printf("Buffer overflow %d\n", size);
}
else if (status == XLookupNone){
printf("nothing branch\n");
}
else if (status == XLookupChars || status == XLookupBoth){
printf("keysym %lu translation: %.*s\n", keysym, size, lookup_buffer);
}
else{
printf("unknown branch %d\n", status);
}
break;
}
} break; } break;
} }
XFreeEventData(XDisplay, &Event.xcookie); XFreeEventData(linuxvars.XDisplay, &Event.xcookie);
} }
#endif
} }
// Draw some stuff here? b32 redraw = 1;
glXSwapBuffers(XDisplay, XWindow); Key_Input_Data input_data;
} Mouse_State mouse;
Application_Step_Result result;
input_data = {};
mouse = {};
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.redraw = redraw;
result.lctrl_lalt_is_altgr = 0;
linuxvars.app.step(linuxvars.system,
&linuxvars.key_codes,
&input_data,
&mouse,
&linuxvars.target,
&memory_vars,
&exchange_vars,
linuxvars.clipboard_contents,
1, linuxvars.first, redraw,
&result);
if (result.redraw){
LinuxRedrawTarget();
} }
glBegin(GL_QUADS);
{
glVertex2f(.5f, .5f);
glVertex2f(1.f, .5f);
glVertex2f(1.f, 1.f);
glVertex2f(.5f, 1.f);
glVertex2f(0.f, 0.f);
glVertex2f(.2f, 0.f);
glVertex2f(.2f, .2f);
glVertex2f(0.f, .2f);
} }
glEnd();
glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow);
} }
} }
} }

View File

@ -10,7 +10,7 @@
// TOP // TOP
internal void internal void
system_filter_real_files(char **files, i32 *file_count){ sysshared_filter_real_files(char **files, i32 *file_count){
i32 i, j; i32 i, j;
i32 end; i32 end;
@ -24,5 +24,115 @@ system_filter_real_files(char **files, i32 *file_count){
*file_count = j; *file_count = j;
} }
void
ex__file_insert(File_Slot *pos, File_Slot *file){
file->next = pos->next;
file->next->prev = file;
file->prev = pos;
pos->next = file;
}
void
ex__insert_range(File_Slot *start, File_Slot *end, File_Slot *pos){
end->next->prev = start->prev;
start->prev->next = end->next;
end->next = pos->next;
start->prev = pos;
pos->next->prev = end;
pos->next = start;
}
internal void
ex__check_file(File_Slot *pos){
File_Slot *file = pos;
Assert(pos == pos->next->prev);
for (pos = pos->next;
file != pos;
pos = pos->next){
Assert(pos == pos->next->prev);
}
}
internal void
ex__check(File_Exchange *file_exchange){
ex__check_file(&file_exchange->available);
ex__check_file(&file_exchange->active);
ex__check_file(&file_exchange->free_list);
}
internal void
sysshared_init_file_exchange(
Exchange *exchange, File_Slot *slots, i32 max,
char **filename_space_out){
char *filename_space;
i32 i;
exchange->file.max = max;
exchange->file.available = {};
exchange->file.available.next = &exchange->file.available;
exchange->file.available.prev = &exchange->file.available;
exchange->file.active = {};
exchange->file.active.next = &exchange->file.active;
exchange->file.active.prev = &exchange->file.active;
exchange->file.free_list = {};
exchange->file.free_list.next = &exchange->file.free_list;
exchange->file.free_list.prev = &exchange->file.free_list;
exchange->file.files = slots;
memset(slots, 0, sizeof(File_Slot)*max);
filename_space = (char*)
system_get_memory(FileNameMax*exchange->file.max);
File_Slot *slot = slots;
for (i = 0; i < exchange->file.max; ++i, ++slot){
ex__file_insert(&exchange->file.available, slot);
slot->filename = filename_space;
filename_space += FileNameMax;
}
if (filename_space_out) *filename_space_out = filename_space;
}
internal void
fnt__remove(Font_Load_Parameters *params){
params->next->prev = params->prev;
params->prev->next = params->next;
}
internal void
fnt__insert(Font_Load_Parameters *pos, Font_Load_Parameters *params){
params->next = pos->next;
pos->next->prev = params;
pos->next = params;
params->prev = pos;
}
internal void
sysshared_init_font_params(
Font_Load_System *fnt, Font_Load_Parameters *params, i32 max){
Font_Load_Parameters *param;
i32 i;
fnt->params = params;
fnt->max = max;
fnt->free_param.next = &fnt->free_param;
fnt->free_param.prev = &fnt->free_param;
fnt->used_param.next = &fnt->free_param;
fnt->used_param.prev = &fnt->free_param;
param = params;
for (i = 0; i < max; ++i, ++param){
fnt__insert(&fnt->free_param, param);
}
}
// BOTTOM // BOTTOM

View File

@ -14,6 +14,24 @@
// the application code, but system_shared.cpp and 4ed_rendering.cpp // the application code, but system_shared.cpp and 4ed_rendering.cpp
// rely on the functions listed here. // rely on the functions listed here.
struct Font_Load_Parameters{
Font_Load_Parameters *next;
Font_Load_Parameters *prev;
Render_Font *font_out;
char *filename;
i32 pt_size;
i32 tab_width;
};
struct Font_Load_System{
Font_Load_Parameters *params;
Font_Load_Parameters used_param;
Font_Load_Parameters free_param;
Partition part;
i32 max;
};
#define Sys_Get_Memory_Sig(name) void* name(i32 size, i32 line_number, char *file_name) #define Sys_Get_Memory_Sig(name) void* name(i32 size, i32 line_number, char *file_name)
#define Sys_Free_Memory_Sig(name) void name(void *block) #define Sys_Free_Memory_Sig(name) void name(void *block)
#define Sys_File_Can_Be_Made(name) b32 name(char *filename) #define Sys_File_Can_Be_Made(name) b32 name(char *filename)

BIN
vc120.pdb

Binary file not shown.

View File

@ -94,17 +94,6 @@ struct Win32_Input_Chunk{
Win32_Input_Chunk_Persistent pers; Win32_Input_Chunk_Persistent pers;
}; };
struct Win32_Font_Load_Parameters{
Win32_Font_Load_Parameters *next;
Win32_Font_Load_Parameters *prev;
Render_Font *font_out;
char *filename;
i32 pt_size;
i32 tab_width;
};
struct Win32_Vars{ struct Win32_Vars{
HWND window_handle; HWND window_handle;
HDC window_hdc; HDC window_hdc;
@ -154,10 +143,7 @@ struct Win32_Vars{
Sys_Bubble internal_bubble; Sys_Bubble internal_bubble;
#endif #endif
Win32_Font_Load_Parameters fnt_params[8]; Font_Load_System fnt;
Win32_Font_Load_Parameters used_font_param;
Win32_Font_Load_Parameters free_font_param;
Partition fnt_part;
}; };
globalvar Win32_Vars win32vars; globalvar Win32_Vars win32vars;
@ -861,41 +847,6 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){
return close_me; return close_me;
} }
internal void
fnt__remove(Win32_Font_Load_Parameters *params){
params->next->prev = params->prev;
params->prev->next = params->next;
}
internal void
fnt__insert(Win32_Font_Load_Parameters *pos, Win32_Font_Load_Parameters *params){
params->next = pos->next;
pos->next->prev = params;
pos->next = params;
params->prev = pos;
}
internal
Font_Load_Sig(system_draw_font_load){
Win32_Font_Load_Parameters *params;
system_acquire_lock(FONT_LOCK);
params = win32vars.free_font_param.next;
fnt__remove(params);
fnt__insert(&win32vars.used_font_param, params);
system_release_lock(FONT_LOCK);
params->font_out = font_out;
params->filename = filename;
params->pt_size = pt_size;
params->tab_width = tab_width;
SendMessage(win32vars.window_handle,
WM_4coder_LOAD_FONT,
0, (i32)(params - win32vars.fnt_params));
return(1);
}
internal b32 internal b32
Win32LoadAppCode(){ Win32LoadAppCode(){
b32 result = 0; b32 result = 0;
@ -985,6 +936,38 @@ Win32LoadSystemCode(){
#include "system_shared.cpp" #include "system_shared.cpp"
#include "4ed_rendering.cpp" #include "4ed_rendering.cpp"
internal
Font_Load_Sig(system_draw_font_load){
Font_Load_Parameters *params;
system_acquire_lock(FONT_LOCK);
params = win32vars.fnt.free_param.next;
fnt__remove(params);
fnt__insert(&win32vars.fnt.used_param, params);
system_release_lock(FONT_LOCK);
params->font_out = font_out;
params->filename = filename;
params->pt_size = pt_size;
params->tab_width = tab_width;
SendMessage(win32vars.window_handle,
WM_4coder_LOAD_FONT,
0, (i32)(params - win32vars.fnt.params));
return(1);
}
internal void
Win32LoadRenderCode(){
win32vars.target.push_clip = draw_push_clip;
win32vars.target.pop_clip = draw_pop_clip;
win32vars.target.push_piece = draw_push_piece;
win32vars.target.font_set.font_info_load = draw_font_info_load;
win32vars.target.font_set.font_load = system_draw_font_load;
win32vars.target.font_set.release_font = draw_release_font;
}
internal void internal void
Win32RedrawScreen(HDC hdc){ Win32RedrawScreen(HDC hdc){
system_acquire_lock(RENDER_LOCK); system_acquire_lock(RENDER_LOCK);
@ -994,45 +977,6 @@ Win32RedrawScreen(HDC hdc){
SwapBuffers(hdc); SwapBuffers(hdc);
} }
void
ex__file_insert(File_Slot *pos, File_Slot *file){
file->next = pos->next;
file->next->prev = file;
file->prev = pos;
pos->next = file;
}
void
ex__insert_range(File_Slot *start, File_Slot *end, File_Slot *pos){
end->next->prev = start->prev;
start->prev->next = end->next;
end->next = pos->next;
start->prev = pos;
pos->next->prev = end;
pos->next = start;
}
internal void
ex__check_file(File_Slot *pos){
File_Slot *file = pos;
Assert(pos == pos->next->prev);
for (pos = pos->next;
file != pos;
pos = pos->next){
Assert(pos == pos->next->prev);
}
}
internal void
ex__check(File_Exchange *file_exchange){
ex__check_file(&file_exchange->available);
ex__check_file(&file_exchange->active);
ex__check_file(&file_exchange->free_list);
}
internal LRESULT internal LRESULT
Win32Callback(HWND hwnd, UINT uMsg, Win32Callback(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam){ WPARAM wParam, LPARAM lParam){
@ -1298,29 +1242,29 @@ Win32Callback(HWND hwnd, UINT uMsg,
case WM_4coder_LOAD_FONT: case WM_4coder_LOAD_FONT:
{ {
if (win32vars.fnt_part.base == 0){ if (win32vars.fnt.part.base == 0){
win32vars.fnt_part = Win32ScratchPartition(Mbytes(8)); win32vars.fnt.part = Win32ScratchPartition(Mbytes(8));
} }
Win32_Font_Load_Parameters *params = win32vars.fnt_params + lParam; Font_Load_Parameters *params = win32vars.fnt.params + lParam;
for (b32 success = 0; success == 0;){ for (b32 success = 0; success == 0;){
success = draw_font_load(win32vars.fnt_part.base, success = draw_font_load(win32vars.fnt.part.base,
win32vars.fnt_part.max, win32vars.fnt.part.max,
params->font_out, params->font_out,
params->filename, params->filename,
params->pt_size, params->pt_size,
params->tab_width); params->tab_width);
if (!success){ if (!success){
Win32ScratchPartitionDouble(&win32vars.fnt_part); Win32ScratchPartitionDouble(&win32vars.fnt.part);
} }
} }
system_acquire_lock(FONT_LOCK); system_acquire_lock(FONT_LOCK);
fnt__remove(params); fnt__remove(params);
fnt__insert(&win32vars.free_font_param, params); fnt__insert(&win32vars.fnt.free_param, params);
system_release_lock(FONT_LOCK); system_release_lock(FONT_LOCK);
}break; }break;
@ -1598,7 +1542,7 @@ main(int argc, char **argv){
if (output_size != 0) return 0; if (output_size != 0) return 0;
FreeConsole(); FreeConsole();
system_filter_real_files(files, file_count); sysshared_filter_real_files(files, file_count);
LARGE_INTEGER lpf; LARGE_INTEGER lpf;
QueryPerformanceFrequency(&lpf); QueryPerformanceFrequency(&lpf);
@ -1664,6 +1608,10 @@ main(int argc, char **argv){
} }
win32vars.DEBUG_sysmem_lock = CreateSemaphore(0, 1, 1, 0); win32vars.DEBUG_sysmem_lock = CreateSemaphore(0, 1, 1, 0);
Win32LoadRenderCode();
win32vars.target.max = Mbytes(1);
win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max);
win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM); win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM);
win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW); win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW);
win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE); win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE);
@ -1798,53 +1746,12 @@ main(int argc, char **argv){
} }
} }
win32vars.target.push_clip = draw_push_clip;
win32vars.target.pop_clip = draw_pop_clip;
win32vars.target.push_piece = draw_push_piece;
win32vars.target.font_set.font_info_load = draw_font_info_load;
win32vars.target.font_set.font_load = system_draw_font_load;
win32vars.target.font_set.release_font = draw_release_font;
win32vars.target.max = Mbytes(1);
win32vars.target.push_buffer = (byte*)Win32GetMemory(win32vars.target.max);
File_Slot file_slots[32]; File_Slot file_slots[32];
exchange_vars.file.max = sizeof(file_slots) / sizeof(file_slots[0]); sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
exchange_vars.file.available = {};
exchange_vars.file.available.next = &exchange_vars.file.available;
exchange_vars.file.available.prev = &exchange_vars.file.available;
exchange_vars.file.active = {}; Font_Load_Parameters params[32];
exchange_vars.file.active.next = &exchange_vars.file.active; sysshared_init_font_params(&win32vars.fnt, params, ArrayCount(params));
exchange_vars.file.active.prev = &exchange_vars.file.active;
exchange_vars.file.free_list = {};
exchange_vars.file.free_list.next = &exchange_vars.file.free_list;
exchange_vars.file.free_list.prev = &exchange_vars.file.free_list;
exchange_vars.file.files = file_slots;
memset(file_slots, 0, sizeof(file_slots));
char *filename_space = (char*)
Win32GetMemory(FileNameMax*exchange_vars.file.max);
for (int i = 0; i < exchange_vars.file.max; ++i){
File_Slot *slot = file_slots + i;
ex__file_insert(&exchange_vars.file.available, slot);
slot->filename = filename_space;
filename_space += FileNameMax;
}
win32vars.free_font_param.next = &win32vars.free_font_param;
win32vars.free_font_param.prev = &win32vars.free_font_param;
win32vars.used_font_param.next = &win32vars.used_font_param;
win32vars.used_font_param.prev = &win32vars.used_font_param;
for (i32 i = 0; i < ArrayCount(win32vars.fnt_params); ++i){
fnt__insert(&win32vars.free_font_param, win32vars.fnt_params + i);
}
win32vars.app.init(win32vars.system, &win32vars.target, win32vars.app.init(win32vars.system, &win32vars.target,
&memory_vars, &exchange_vars, &win32vars.key_codes, &memory_vars, &exchange_vars, &win32vars.key_codes,