word complete v1 again
This commit is contained in:
parent
5619527d37
commit
770c48f95b
|
@ -174,6 +174,16 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){
|
|||
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){
|
||||
Bind_Helper context_actual = begin_bind_helper(data, size);
|
||||
Bind_Helper *context = &context_actual;
|
||||
|
|
|
@ -36,6 +36,11 @@ struct String{
|
|||
int size;
|
||||
int memory_size;
|
||||
};
|
||||
|
||||
struct Offset_String{
|
||||
int offset;
|
||||
int size;
|
||||
};
|
||||
#endif
|
||||
|
||||
inline bool char_not_slash(char c) { return (c != '\\' && c != '/'); }
|
||||
|
|
124
4ed.cpp
124
4ed.cpp
|
@ -38,6 +38,14 @@ struct Sys_App_Binding{
|
|||
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{
|
||||
Mem_Options mem;
|
||||
|
||||
|
@ -52,6 +60,7 @@ struct App_Vars{
|
|||
Command_Map *user_maps;
|
||||
i32 *map_id_table;
|
||||
i32 user_map_count;
|
||||
Command_Binding prev_command;
|
||||
|
||||
Sys_App_Binding *sys_app_bindings;
|
||||
i32 sys_app_count, sys_app_max;
|
||||
|
@ -84,6 +93,7 @@ struct App_Vars{
|
|||
|
||||
App_State state;
|
||||
App_State_Resizing resizing;
|
||||
Complete_State complete_state;
|
||||
Panel *prev_mouse_panel;
|
||||
|
||||
Custom_API config_api;
|
||||
|
@ -442,25 +452,43 @@ COMMAND_DECL(word_complete){
|
|||
REQ_FILE(file, view);
|
||||
USE_LAYOUT(layout);
|
||||
USE_MEM(mem);
|
||||
USE_VARS(vars);
|
||||
USE_WORKING_SET(working_set);
|
||||
|
||||
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_Backify_Type loop;
|
||||
char *data;
|
||||
i32 end;
|
||||
i32 size_of_buffer;
|
||||
|
||||
i32 cursor_pos, word_start, word_end;
|
||||
char c;
|
||||
|
||||
char *str, *spare;
|
||||
char *spare;
|
||||
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;
|
||||
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_start = word_end;
|
||||
cursor_pos = word_end - 1;
|
||||
|
@ -486,26 +514,81 @@ COMMAND_DECL(word_complete){
|
|||
|
||||
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){
|
||||
temp1 = begin_temp_memory(part);
|
||||
for (;;){
|
||||
match = search_next_match(part, &complete_state->set, &complete_state->iter);
|
||||
|
||||
str = (char*)push_array(part, char, size);
|
||||
buffer_stringify(buffer, word_start, word_end, str);
|
||||
|
||||
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;
|
||||
if (match.found_match){
|
||||
temp = begin_temp_memory(part);
|
||||
match_size = match.end - match.start;
|
||||
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);
|
||||
|
||||
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, '?', MDFR_CTRL, command_toggle_show_whitespace);
|
||||
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_lowercase);
|
||||
map_add(commands, 'u', MDFR_CTRL, command_to_uppercase);
|
||||
map_add(commands, 'j', MDFR_CTRL, command_to_lowercase);
|
||||
map_add(commands, '~', MDFR_CTRL, command_clean_all_lines);
|
||||
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, 'g', MDFR_CTRL, command_goto_line);
|
||||
|
@ -3462,6 +3545,7 @@ App_Step_Sig(app_step){
|
|||
app_result.redraw = 1;
|
||||
}
|
||||
}
|
||||
vars->prev_command = cmd;
|
||||
}break;
|
||||
|
||||
case APP_STATE_RESIZING:
|
||||
|
|
31
4ed.h
31
4ed.h
|
@ -90,37 +90,6 @@ struct Clipboard_Contents{
|
|||
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{
|
||||
char **argv;
|
||||
int argc;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "4ed_internal.h"
|
||||
|
||||
#include "4tech_table.cpp"
|
||||
|
||||
#define FCPP_LEXER_IMPLEMENTATION
|
||||
#include "4cpp_lexer.h"
|
||||
|
||||
|
|
|
@ -4613,13 +4613,13 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
|
|||
}
|
||||
|
||||
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);
|
||||
if (pos < size){
|
||||
if (step_forward){
|
||||
file_view->isearch.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);
|
||||
if (pos == size) pos = start_pos;
|
||||
}
|
||||
|
@ -4765,5 +4765,200 @@ file_view_iter_good(File_View_Iter iter){
|
|||
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
|
||||
|
||||
|
|
|
@ -249,5 +249,7 @@ end_temp_memory(Temp_Memory temp){
|
|||
((Partition*)temp.handle)->pos = temp.pos;
|
||||
}
|
||||
|
||||
#define reset_temp_memory end_temp_memory
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
31
4ed_system.h
31
4ed_system.h
|
@ -187,5 +187,36 @@ struct System_Functions{
|
|||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
buffer_convert_out(Buffer_Type *buffer, char *dest, int max){
|
||||
Buffer_Stringify_Type loop;
|
||||
|
@ -463,17 +472,14 @@ buffer_find_hard_start_end:
|
|||
}
|
||||
|
||||
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;
|
||||
char *data;
|
||||
int size, end;
|
||||
int pos;
|
||||
|
||||
size = buffer_size(buffer);
|
||||
int end, pos;
|
||||
|
||||
pos = start_pos;
|
||||
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_next(&loop)){
|
||||
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:
|
||||
if (pos >= size - len + 1) pos = size;
|
||||
if (pos >= end_pos - len + 1) pos = end_pos;
|
||||
return(pos);
|
||||
}
|
||||
|
||||
|
|
376
linux_4ed.cpp
376
linux_4ed.cpp
|
@ -40,7 +40,8 @@
|
|||
#include <GL/glx.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <linux/fs.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
//#include <X11/extensions/XInput2.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <linux/input.h>
|
||||
#include <time.h>
|
||||
#include <dlfcn.h>
|
||||
|
@ -53,6 +54,17 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
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 *custom;
|
||||
|
||||
|
@ -65,6 +77,8 @@ struct Linux_Vars{
|
|||
#if FRED_INTERNAL
|
||||
Sys_Bubble internal_bubble;
|
||||
#endif
|
||||
|
||||
Font_Load_System fnt;
|
||||
};
|
||||
|
||||
globalvar Linux_Vars linuxvars;
|
||||
|
@ -76,7 +90,8 @@ Sys_Get_Memory_Sig(system_get_memory_){
|
|||
// TODO(allen): Implement without stdlib.h
|
||||
void *result = 0;
|
||||
|
||||
if (size != 0){
|
||||
Assert(size != 0);
|
||||
|
||||
#if FRED_INTERNAL
|
||||
Sys_Bubble *bubble;
|
||||
|
||||
|
@ -94,7 +109,6 @@ Sys_Get_Memory_Sig(system_get_memory_){
|
|||
#else
|
||||
result = malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
@ -348,6 +362,16 @@ Sys_Save_File_Sig(system_save_file){
|
|||
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
|
||||
LinuxLoadAppCode(){
|
||||
b32 result = 0;
|
||||
|
@ -397,6 +421,40 @@ LinuxLoadSystemCode(){
|
|||
#include "system_shared.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.
|
||||
static bool ctxErrorOccurred = false;
|
||||
static int XInput2OpCode = 0;
|
||||
|
@ -439,7 +497,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
|
|||
None
|
||||
};
|
||||
|
||||
printf("\nAttribs: %d %d %d %d %d\n",
|
||||
printf("Attribs: %d %d %d %d %d\n",
|
||||
context_attribs[0],
|
||||
context_attribs[1],
|
||||
context_attribs[2],
|
||||
|
@ -636,16 +694,23 @@ ChooseGLXConfig(Display *XDisplay, int XScreenIndex)
|
|||
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)
|
||||
{
|
||||
#if 0
|
||||
int event, error;
|
||||
if(XQueryExtension(dpy, "XInputExtension", &XInput2OpCode, &event, &error))
|
||||
{
|
||||
int major = 2, minor = 0;
|
||||
if(XIQueryVersion(dpy, &major, &minor) != BadRequest)
|
||||
{
|
||||
printf("XInput initialized");
|
||||
printf("XInput initialized version %d.%d\n", major, minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -723,11 +788,61 @@ InitializeXInput(Display *dpy, Window XWindow)
|
|||
XISetMask(Mask.mask, XI_RawMotion);
|
||||
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
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
i32 COUNTER = 0;
|
||||
linuxvars = {};
|
||||
exchange_vars = {};
|
||||
|
||||
|
@ -765,7 +880,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (curdir_req >= (1 << 13)){
|
||||
// TODO(allen): fuckin' bullshit string APIs makin' me pissed
|
||||
// TODO(allen): bullshit string APIs makin' me pissed
|
||||
return 57;
|
||||
}
|
||||
|
||||
|
@ -795,70 +910,162 @@ main(int argc, char **argv)
|
|||
}
|
||||
if (output_size != 0) return 0;
|
||||
|
||||
system_filter_real_files(files, file_count);
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
|
||||
Display *XDisplay = XOpenDisplay(0);
|
||||
if(XDisplay && GLXSupportsModernContexts(XDisplay))
|
||||
keycode_init(&linuxvars.key_codes);
|
||||
|
||||
#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;
|
||||
XScreenIndex < XScreenCount;
|
||||
++XScreenIndex)
|
||||
{
|
||||
Screen *XScreen = ScreenOfDisplay(XDisplay, XScreenIndex);
|
||||
Screen *XScreen = ScreenOfDisplay(linuxvars.XDisplay, XScreenIndex);
|
||||
|
||||
int WinWidth = WidthOfScreen(XScreen);
|
||||
int WinHeight = HeightOfScreen(XScreen);
|
||||
i32 ScrnWidth, ScrnHeight;
|
||||
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)
|
||||
{
|
||||
Colormap cmap;
|
||||
XSetWindowAttributes swa;
|
||||
swa.colormap = cmap = XCreateColormap(XDisplay,
|
||||
RootWindow(XDisplay, Config.BestInfo.screen ),
|
||||
swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay,
|
||||
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen ),
|
||||
Config.BestInfo.visual, AllocNone);
|
||||
swa.background_pixmap = None;
|
||||
swa.border_pixel = 0;
|
||||
swa.event_mask = StructureNotifyMask;
|
||||
|
||||
Window XWindow = XCreateWindow(XDisplay,
|
||||
RootWindow(XDisplay, Config.BestInfo.screen),
|
||||
linuxvars.XWindow =
|
||||
XCreateWindow(linuxvars.XDisplay,
|
||||
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen),
|
||||
0, 0, WinWidth, WinHeight,
|
||||
0, Config.BestInfo.depth, InputOutput,
|
||||
Config.BestInfo.visual,
|
||||
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;
|
||||
GLXContext GLContext =
|
||||
InitializeOpenGLContext(XDisplay, XWindow, Config.BestConfig, IsLegacy);
|
||||
InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy);
|
||||
|
||||
XWindowAttributes WinAttribs;
|
||||
if(XGetWindowAttributes(XDisplay, XWindow, &WinAttribs))
|
||||
if(XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs))
|
||||
{
|
||||
WinWidth = WinAttribs.width;
|
||||
WinHeight = WinAttribs.height;
|
||||
}
|
||||
|
||||
XRaiseWindow(XDisplay, XWindow);
|
||||
XSync(XDisplay, False);
|
||||
XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
||||
XSync(linuxvars.XDisplay, False);
|
||||
|
||||
window_setup_success = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XSetICFocus(linuxvars.xic);
|
||||
|
||||
if (window_setup_success){
|
||||
LinuxResizeTarget(WinWidth, WinHeight);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
while(XPending(XDisplay))
|
||||
while(XPending(linuxvars.XDisplay))
|
||||
{
|
||||
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) &&
|
||||
(Event.xcookie.extension == XInput2OpCode) &&
|
||||
XGetEventData(XDisplay, &Event.xcookie))
|
||||
XGetEventData(linuxvars.XDisplay, &Event.xcookie))
|
||||
{
|
||||
switch(Event.xcookie.evtype)
|
||||
{
|
||||
|
@ -868,8 +1075,8 @@ main(int argc, char **argv)
|
|||
int root_x_return, root_y_return;
|
||||
int MouseX, MouseY;
|
||||
unsigned int mask_return;
|
||||
XQueryPointer(XDisplay,
|
||||
XWindow,
|
||||
XQueryPointer(linuxvars.XDisplay,
|
||||
linuxvars.XWindow,
|
||||
&root_return, &child_return,
|
||||
&root_x_return, &root_y_return,
|
||||
&MouseX, &MouseY,
|
||||
|
@ -889,20 +1096,109 @@ main(int argc, char **argv)
|
|||
{
|
||||
b32 Down = (Event.xcookie.evtype == XI_KeyPress);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// TOP
|
||||
|
||||
internal void
|
||||
system_filter_real_files(char **files, i32 *file_count){
|
||||
sysshared_filter_real_files(char **files, i32 *file_count){
|
||||
i32 i, j;
|
||||
i32 end;
|
||||
|
||||
|
@ -24,5 +24,115 @@ system_filter_real_files(char **files, i32 *file_count){
|
|||
*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
|
||||
|
||||
|
|
|
@ -14,6 +14,24 @@
|
|||
// the application code, but system_shared.cpp and 4ed_rendering.cpp
|
||||
// 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_Free_Memory_Sig(name) void name(void *block)
|
||||
#define Sys_File_Can_Be_Made(name) b32 name(char *filename)
|
||||
|
|
189
win32_4ed.cpp
189
win32_4ed.cpp
|
@ -94,17 +94,6 @@ struct Win32_Input_Chunk{
|
|||
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{
|
||||
HWND window_handle;
|
||||
HDC window_hdc;
|
||||
|
@ -154,10 +143,7 @@ struct Win32_Vars{
|
|||
Sys_Bubble internal_bubble;
|
||||
#endif
|
||||
|
||||
Win32_Font_Load_Parameters fnt_params[8];
|
||||
Win32_Font_Load_Parameters used_font_param;
|
||||
Win32_Font_Load_Parameters free_font_param;
|
||||
Partition fnt_part;
|
||||
Font_Load_System fnt;
|
||||
};
|
||||
|
||||
globalvar Win32_Vars win32vars;
|
||||
|
@ -861,41 +847,6 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){
|
|||
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
|
||||
Win32LoadAppCode(){
|
||||
b32 result = 0;
|
||||
|
@ -985,6 +936,38 @@ Win32LoadSystemCode(){
|
|||
#include "system_shared.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
|
||||
Win32RedrawScreen(HDC hdc){
|
||||
system_acquire_lock(RENDER_LOCK);
|
||||
|
@ -994,45 +977,6 @@ Win32RedrawScreen(HDC 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
|
||||
Win32Callback(HWND hwnd, UINT uMsg,
|
||||
WPARAM wParam, LPARAM lParam){
|
||||
|
@ -1298,29 +1242,29 @@ Win32Callback(HWND hwnd, UINT uMsg,
|
|||
|
||||
case WM_4coder_LOAD_FONT:
|
||||
{
|
||||
if (win32vars.fnt_part.base == 0){
|
||||
win32vars.fnt_part = Win32ScratchPartition(Mbytes(8));
|
||||
if (win32vars.fnt.part.base == 0){
|
||||
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;){
|
||||
|
||||
success = draw_font_load(win32vars.fnt_part.base,
|
||||
win32vars.fnt_part.max,
|
||||
success = draw_font_load(win32vars.fnt.part.base,
|
||||
win32vars.fnt.part.max,
|
||||
params->font_out,
|
||||
params->filename,
|
||||
params->pt_size,
|
||||
params->tab_width);
|
||||
|
||||
if (!success){
|
||||
Win32ScratchPartitionDouble(&win32vars.fnt_part);
|
||||
Win32ScratchPartitionDouble(&win32vars.fnt.part);
|
||||
}
|
||||
}
|
||||
|
||||
system_acquire_lock(FONT_LOCK);
|
||||
fnt__remove(params);
|
||||
fnt__insert(&win32vars.free_font_param, params);
|
||||
fnt__insert(&win32vars.fnt.free_param, params);
|
||||
system_release_lock(FONT_LOCK);
|
||||
}break;
|
||||
|
||||
|
@ -1598,7 +1542,7 @@ main(int argc, char **argv){
|
|||
if (output_size != 0) return 0;
|
||||
FreeConsole();
|
||||
|
||||
system_filter_real_files(files, file_count);
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
|
||||
LARGE_INTEGER lpf;
|
||||
QueryPerformanceFrequency(&lpf);
|
||||
|
@ -1664,6 +1608,10 @@ main(int argc, char **argv){
|
|||
}
|
||||
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_arrow = LoadCursor(NULL, IDC_ARROW);
|
||||
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];
|
||||
exchange_vars.file.max = sizeof(file_slots) / sizeof(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;
|
||||
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
|
||||
|
||||
exchange_vars.file.active = {};
|
||||
exchange_vars.file.active.next = &exchange_vars.file.active;
|
||||
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);
|
||||
}
|
||||
Font_Load_Parameters params[32];
|
||||
sysshared_init_font_params(&win32vars.fnt, params, ArrayCount(params));
|
||||
|
||||
win32vars.app.init(win32vars.system, &win32vars.target,
|
||||
&memory_vars, &exchange_vars, &win32vars.key_codes,
|
||||
|
|
Loading…
Reference in New Issue