extended ascii; improved file handling; assorted bug fixes
parent
9ef04f5dc5
commit
48bcb06893
|
@ -1,36 +1,36 @@
|
|||
enum{
|
||||
key_back = 1,
|
||||
key_up = 2,
|
||||
key_down = 3,
|
||||
key_left = 4,
|
||||
key_right = 5,
|
||||
key_del = 6,
|
||||
key_insert = 7,
|
||||
key_home = 8,
|
||||
key_end = 11,
|
||||
key_page_up = 12,
|
||||
key_page_down = 13,
|
||||
key_esc = 14,
|
||||
key_mouse_left = 15,
|
||||
key_mouse_right = 16,
|
||||
key_mouse_left_release = 17,
|
||||
key_mouse_right_release = 18,
|
||||
key_f1 = 127,
|
||||
key_f2 = 128,
|
||||
key_f3 = 129,
|
||||
key_f4 = 130,
|
||||
key_f5 = 131,
|
||||
key_f6 = 132,
|
||||
key_f7 = 133,
|
||||
key_f8 = 134,
|
||||
key_f9 = 135,
|
||||
key_f10 = 136,
|
||||
key_f11 = 137,
|
||||
key_f12 = 138,
|
||||
key_f13 = 139,
|
||||
key_f14 = 140,
|
||||
key_f15 = 141,
|
||||
key_f16 = 142,
|
||||
key_back = 57344,
|
||||
key_up = 57345,
|
||||
key_down = 57346,
|
||||
key_left = 57347,
|
||||
key_right = 57348,
|
||||
key_del = 57349,
|
||||
key_insert = 57350,
|
||||
key_home = 57351,
|
||||
key_end = 57352,
|
||||
key_page_up = 57353,
|
||||
key_page_down = 57354,
|
||||
key_esc = 57355,
|
||||
key_mouse_left = 57356,
|
||||
key_mouse_right = 57357,
|
||||
key_mouse_left_release = 57358,
|
||||
key_mouse_right_release = 57359,
|
||||
key_f1 = 57360,
|
||||
key_f2 = 57361,
|
||||
key_f3 = 57362,
|
||||
key_f4 = 57363,
|
||||
key_f5 = 57364,
|
||||
key_f6 = 57365,
|
||||
key_f7 = 57366,
|
||||
key_f8 = 57367,
|
||||
key_f9 = 57368,
|
||||
key_f10 = 57369,
|
||||
key_f11 = 57370,
|
||||
key_f12 = 57371,
|
||||
key_f13 = 57372,
|
||||
key_f14 = 57373,
|
||||
key_f15 = 57374,
|
||||
key_f16 = 57375,
|
||||
};
|
||||
static char*
|
||||
global_key_name(int32_t key_code, int32_t *size){
|
||||
|
|
|
@ -22,9 +22,6 @@ TYPEDEF int32_t bool32;
|
|||
/* DOC(int_color is an alias name to signal that an integer parameter or field is for a color value, colors are specified as 24 bit integers in 3 channels: 0xRRGGBB.) */
|
||||
TYPEDEF uint32_t int_color;
|
||||
|
||||
/* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */
|
||||
TYPEDEF unsigned char Key_Code;
|
||||
|
||||
/* DOC(Buffer_ID is used to name a 4coder buffer. Each buffer has a unique id but when a buffer is closed it's id may be recycled by future, different buffers.) */
|
||||
TYPEDEF int32_t Buffer_ID;
|
||||
|
||||
|
@ -174,14 +171,10 @@ ENUM(int32_t, Buffer_Setting_ID){
|
|||
A 1 indicates dos endings "\r\n" and a 0 indicates nix endings "\n".) */
|
||||
BufferSetting_Eol,
|
||||
|
||||
/* DOC(The BufferSetting_Unimportant setting marks a buffer so that it's dirty state will be completely
|
||||
ignored. This means the "dirty" star is hidden and the buffer can be closed without presenting an
|
||||
"are you sure" dialogue screen.) */
|
||||
/* DOC(The BufferSetting_Unimportant setting marks a buffer so that its dirty state will be forced to stay at DirtyState_UpToDate when the buffer is edited or when the buffer's paired file, if it has one, is edited.) */
|
||||
BufferSetting_Unimportant,
|
||||
|
||||
/* DOC(The BufferSetting_ReadOnly setting marks a buffer so that it can only be returned from buffer
|
||||
access calls that include an AccessProtected flag. By convention this means that edit commands that
|
||||
should not be applied to read only buffers will not edit this buffer.) */
|
||||
/* DOC(The BufferSetting_ReadOnly setting marks a buffer so that it can only be returned from buffer access calls that include an AccessProtected flag. By convention this means that edit commands that should not be applied to read only buffers will not edit this buffer.) */
|
||||
BufferSetting_ReadOnly,
|
||||
|
||||
/* DOC(The BufferSetting_VirtualWhitespace settings enables virtual whitespace on a buffer.
|
||||
|
@ -348,6 +341,9 @@ ENUM(int32_t, View_Split_Position){
|
|||
ViewSplit_Right
|
||||
};
|
||||
|
||||
/* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */
|
||||
TYPEDEF uint16_t Key_Code;
|
||||
|
||||
/* DOC(Key_Event_Data describes a key event, including the translation to a character, the translation to a character ignoring the state of caps lock, and an array of all the modifiers that were pressed at the time of the event.) */
|
||||
STRUCT Key_Event_Data{
|
||||
/* DOC(This field is the raw keycode which is always non-zero in valid key events.) */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define MAJOR 4
|
||||
#define MINOR 0
|
||||
#define PATCH 16
|
||||
#define PATCH 17
|
||||
|
||||
#define VN__(a,b,c) #a"."#b"."#c
|
||||
#define VN_(a,b,c) VN__(a,b,c)
|
||||
|
|
|
@ -22,15 +22,14 @@ CUSTOM_COMMAND_SIG(write_character){
|
|||
View_Summary view = get_active_view(app, access);
|
||||
|
||||
User_Input in = get_command_input(app);
|
||||
char character = 0;
|
||||
|
||||
char character = 0;
|
||||
if (in.type == UserInputKey){
|
||||
character = in.key.character;
|
||||
character = to_writable_char(in.key.character);
|
||||
}
|
||||
|
||||
if (character != 0){
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int32_t pos = view.cursor.pos;
|
||||
buffer_replace_range(app, &buffer, pos, pos, &character, 1);
|
||||
view_set_cursor(app, &view, seek_pos(view.cursor.pos + 1), true);
|
||||
|
@ -587,12 +586,13 @@ isearch(Application_Links *app, int32_t start_reversed){
|
|||
// only asked to intercept key events.
|
||||
Assert(in.type == UserInputKey);
|
||||
|
||||
char character = to_writable_char(in.key.character);
|
||||
int32_t made_change = 0;
|
||||
if (in.key.keycode == '\n' || in.key.keycode == '\t'){
|
||||
break;
|
||||
}
|
||||
else if (in.key.character && key_is_unmodified(&in.key)){
|
||||
append_s_char(&bar.string, in.key.character);
|
||||
else if (character && key_is_unmodified(&in.key)){
|
||||
append_s_char(&bar.string, character);
|
||||
made_change = 1;
|
||||
}
|
||||
else if (in.key.keycode == key_back){
|
||||
|
|
|
@ -30,11 +30,11 @@ static int32_t
|
|||
get_build_directory(Application_Links *app, Buffer_Summary *buffer, String *dir_out){
|
||||
int32_t result = BuildDir_None;
|
||||
|
||||
if (buffer && buffer->file_name){
|
||||
if (buffer != 0 && buffer->file_name != 0){
|
||||
if (!match_cc(buffer->file_name, buffer->buffer_name)){
|
||||
String dir = make_string_cap(buffer->file_name,
|
||||
buffer->file_name_len,
|
||||
buffer->file_name_len+1);
|
||||
char *file_name = buffer->file_name;
|
||||
int32_t file_name_len = buffer->file_name_len;
|
||||
String dir = make_string_cap(file_name, file_name_len, file_name_len+1);
|
||||
remove_last_folder(&dir);
|
||||
append_ss(dir_out, dir);
|
||||
result = BuildDir_AtFile;
|
||||
|
|
|
@ -122,6 +122,7 @@ default_keys(Bind_Helper *context){
|
|||
// value such as key_left or key_back then it is a vanilla key.
|
||||
// It is possible to override this binding for individual keys.
|
||||
bind_vanilla_keys(context, write_character);
|
||||
bind(context, 241, MDFR_NONE, write_character);
|
||||
|
||||
// NOTE(allen|a4.0.7): You can now bind left and right clicks.
|
||||
// They only trigger on mouse presses. Modifiers do work
|
||||
|
@ -199,7 +200,6 @@ default_keys(Bind_Helper *context){
|
|||
}
|
||||
|
||||
#ifndef NO_BINDING
|
||||
|
||||
extern "C" int32_t
|
||||
get_bindings(void *data, int32_t size){
|
||||
Bind_Helper context_ = begin_bind_helper(data, size);
|
||||
|
@ -211,7 +211,6 @@ get_bindings(void *data, int32_t size){
|
|||
int32_t result = end_bind_helper(context);
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif //NO_BINDING
|
||||
|
||||
#endif //FCODER_DEFAULT_BINDINGS
|
||||
|
|
|
@ -74,25 +74,24 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
|
|||
Buffer_Summary buffer = get_buffer(app, buffer_id, access);
|
||||
Assert(buffer.exists);
|
||||
|
||||
int32_t treat_as_code = 0;
|
||||
int32_t wrap_lines = 1;
|
||||
int32_t treat_as_code = false;
|
||||
int32_t wrap_lines = true;
|
||||
|
||||
if (buffer.file_name && buffer.size < (16 << 20)){
|
||||
if (buffer.file_name != 0 && buffer.size < (16 << 20)){
|
||||
String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
|
||||
if (match_ss(ext, make_lit_string("cpp")) ||
|
||||
match_ss(ext, make_lit_string("h")) ||
|
||||
match_ss(ext, make_lit_string("c")) ||
|
||||
match_ss(ext, make_lit_string("hpp"))){
|
||||
treat_as_code = 1;
|
||||
treat_as_code = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (treat_as_code){
|
||||
wrap_lines = 0;
|
||||
wrap_lines = false;
|
||||
}
|
||||
if (buffer.file_name[0] == '*'){
|
||||
wrap_lines = 0;
|
||||
if (buffer.file_name == 0){
|
||||
wrap_lines = false;
|
||||
}
|
||||
|
||||
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, default_wrap_width);
|
||||
|
@ -106,8 +105,8 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
|
|||
// Unfortunantely without tokens virtual whitespace doesn't really make sense.
|
||||
// So for now I have it automatically turning on lexing when virtual whitespace is turned on.
|
||||
// Cleaning some of that up is a goal for future versions.
|
||||
buffer_set_setting(app, &buffer, BufferSetting_WrapLine, 1);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, 1);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_WrapLine, true);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true);
|
||||
}
|
||||
else{
|
||||
buffer_set_setting(app, &buffer, BufferSetting_WrapLine, wrap_lines);
|
||||
|
|
|
@ -289,25 +289,24 @@ CUSTOM_COMMAND_SIG(write_zero_struct){
|
|||
// Open File In Quotes
|
||||
//
|
||||
|
||||
static int32_t
|
||||
static bool32
|
||||
file_name_in_quotes(Application_Links *app, String *file_name){
|
||||
int32_t result = false;
|
||||
bool32 result = false;
|
||||
uint32_t access = AccessProtected;
|
||||
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
char short_file_name[128];
|
||||
int32_t pos, start, end, size;
|
||||
View_Summary view = get_active_view(app, access);
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, access);
|
||||
|
||||
view = get_active_view(app, access);
|
||||
buffer = get_buffer(app, view.buffer_id, access);
|
||||
pos = view.cursor.pos;
|
||||
if (buffer.file_name != 0){
|
||||
int32_t pos = view.cursor.pos;
|
||||
int32_t start = 0, end = 0;
|
||||
buffer_seek_delimiter_forward(app, &buffer, pos, '"', &end);
|
||||
buffer_seek_delimiter_backward(app, &buffer, pos, '"', &start);
|
||||
|
||||
++start;
|
||||
size = end - start;
|
||||
|
||||
int32_t size = end - start;
|
||||
|
||||
char short_file_name[128];
|
||||
// NOTE(allen): This check is necessary because buffer_read_range
|
||||
// requiers that the output buffer you provide is at least (end - start) bytes long.
|
||||
if (size < sizeof(short_file_name)){
|
||||
|
@ -318,6 +317,7 @@ file_name_in_quotes(Application_Links *app, String *file_name){
|
|||
append_ss(file_name, make_string(short_file_name, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
@ -347,9 +347,9 @@ static bool32
|
|||
get_cpp_matching_file(Application_Links *app, Buffer_Summary buffer, Buffer_Summary *buffer_out){
|
||||
bool32 result = false;
|
||||
|
||||
if (buffer.file_name != 0){
|
||||
char space[512];
|
||||
String file_name = make_string_cap(space, 0, sizeof(space));
|
||||
|
||||
append(&file_name, make_string(buffer.file_name, buffer.file_name_len));
|
||||
|
||||
String extension = file_extension(file_name);
|
||||
|
@ -387,6 +387,7 @@ get_cpp_matching_file(Application_Links *app, Buffer_Summary buffer, Buffer_Summ
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ end_map(Bind_Helper *helper){
|
|||
}
|
||||
|
||||
inline void
|
||||
bind(Bind_Helper *helper, short code, unsigned char modifiers, int32_t cmdid){
|
||||
bind(Bind_Helper *helper, uint16_t code, uint8_t modifiers, int32_t cmdid){
|
||||
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
|
||||
if (!helper->error) ++helper->group->map_begin.bind_count;
|
||||
|
||||
|
@ -100,7 +100,7 @@ bind(Bind_Helper *helper, short code, unsigned char modifiers, int32_t cmdid){
|
|||
}
|
||||
|
||||
inline void
|
||||
bind(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){
|
||||
bind(Bind_Helper *helper, uint16_t code, uint8_t modifiers, Custom_Command_Function *func){
|
||||
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
|
||||
if (!helper->error) ++helper->group->map_begin.bind_count;
|
||||
|
||||
|
|
|
@ -52,11 +52,27 @@ key_is_unmodified(Key_Event_Data *key){
|
|||
return(unmodified);
|
||||
}
|
||||
|
||||
static char
|
||||
to_writable_char(Key_Code long_character){
|
||||
char character = 0;
|
||||
if (long_character < ' '){
|
||||
if (long_character == '\n'){
|
||||
character = '\n';
|
||||
}
|
||||
else if (long_character == '\t'){
|
||||
character = '\t';
|
||||
}
|
||||
}
|
||||
else if (long_character >= ' ' && long_character <= 255 && long_character != 127){
|
||||
character = (char)long_character;
|
||||
}
|
||||
return(character);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){
|
||||
User_Input in;
|
||||
int32_t success = 1;
|
||||
int32_t good_character = 0;
|
||||
|
||||
// NOTE(allen|a3.4.4): It will not cause an *error* if we continue on after failing to.
|
||||
// start a query bar, but it will be unusual behavior from the point of view of the
|
||||
|
@ -79,16 +95,19 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){
|
|||
break;
|
||||
}
|
||||
|
||||
good_character = 0;
|
||||
char character = 0;
|
||||
bool32 good_character = false;
|
||||
if (key_is_unmodified(&in.key)){
|
||||
if (force_number){
|
||||
if (in.key.character >= '0' && in.key.character <= '9'){
|
||||
good_character = 1;
|
||||
good_character = true;
|
||||
character = (char)(in.key.character);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (in.key.character != 0){
|
||||
good_character = 1;
|
||||
character = to_writable_char(in.key.character);
|
||||
if (character != 0){
|
||||
good_character = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +125,7 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){
|
|||
}
|
||||
}
|
||||
else if (good_character){
|
||||
append_s_char(&bar->string, in.key.character);
|
||||
append_s_char(&bar->string, character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,8 +67,9 @@ close_all_files_with_extension(Application_Links *app, Partition *scratch_part,
|
|||
|
||||
bool32 is_match = 1;
|
||||
if (extension_count > 0){
|
||||
String extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
is_match = 0;
|
||||
if (buffer.file_name != 0){
|
||||
String extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
for (int32_t i = 0; i < extension_count; ++i){
|
||||
if (match(extension, extension_list[i])){
|
||||
is_match = 1;
|
||||
|
@ -76,6 +77,7 @@ close_all_files_with_extension(Application_Links *app, Partition *scratch_part,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_match){
|
||||
if (buffers_to_close_count >= buffers_to_close_max){
|
||||
|
|
|
@ -582,7 +582,13 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part
|
|||
if (match.found_match){
|
||||
Partial_Cursor word_pos = {0};
|
||||
if (buffer_compute_cursor(app, &match.buffer, seek_pos(match.start), &word_pos)){
|
||||
char *file_name = match.buffer.file_name;
|
||||
int32_t file_len = match.buffer.file_name_len;
|
||||
if (file_name != 0){
|
||||
file_name = match.buffer.buffer_name;
|
||||
file_len = match.buffer.buffer_name_len;
|
||||
}
|
||||
|
||||
int32_t line_num_len = int_to_str_size(word_pos.line);
|
||||
int32_t column_num_len = int_to_str_size(word_pos.character);
|
||||
|
||||
|
@ -609,7 +615,7 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part
|
|||
part_size += str_len;
|
||||
|
||||
String out_line = make_string_cap(spare, 0, str_len);
|
||||
append_ss(&out_line, make_string(match.buffer.file_name, file_len));
|
||||
append_ss(&out_line, make_string(file_name, file_len));
|
||||
append_s_char(&out_line, ':');
|
||||
append_int_to_str(&out_line, word_pos.line);
|
||||
append_s_char(&out_line, ':');
|
||||
|
|
32
4ed.cpp
32
4ed.cpp
|
@ -321,15 +321,14 @@ COMMAND_DECL(interactive_open){
|
|||
}
|
||||
|
||||
// TODO(allen): Improvements to reopen
|
||||
// - Preserve existing token stack
|
||||
// - Keep current version open and do some sort of diff to keep
|
||||
// the cursor position correct
|
||||
// - Perform a diff
|
||||
// - If the diff is not tremendously big, apply the edits.
|
||||
COMMAND_DECL(reopen){
|
||||
USE_MODELS(models);
|
||||
USE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
||||
if (match_ss(file->name.source_path, file->name.live_name)) return;
|
||||
if (file->canon.name.str == 0) return;
|
||||
|
||||
if (file->canon.name.size != 0){
|
||||
Plat_Handle handle;
|
||||
|
@ -585,10 +584,9 @@ setup_ui_commands(Command_Map *commands, Partition *part, Command_Map *parent){
|
|||
// TODO(allen): This is hacky, when the new UI stuff happens, let's fix it,
|
||||
// and by that I mean actually fix it, don't just say you fixed it with
|
||||
// something stupid again.
|
||||
u8 mdfr;
|
||||
u8 mdfr_array[] = {MDFR_NONE, MDFR_SHIFT, MDFR_CTRL, MDFR_SHIFT | MDFR_CTRL};
|
||||
for (i32 i = 0; i < 4; ++i){
|
||||
mdfr = mdfr_array[i];
|
||||
u8 mdfr = mdfr_array[i];
|
||||
map_add(commands, key_left, mdfr, command_null);
|
||||
map_add(commands, key_right, mdfr, command_null);
|
||||
map_add(commands, key_up, mdfr, command_null);
|
||||
|
@ -629,7 +627,6 @@ setup_command_table(){
|
|||
SET(open_config);
|
||||
SET(open_menu);
|
||||
SET(open_debug);
|
||||
|
||||
#undef SET
|
||||
}
|
||||
|
||||
|
@ -1542,9 +1539,9 @@ App_Init_Sig(app_init){
|
|||
}break;
|
||||
}
|
||||
|
||||
file->settings.never_kill = 1;
|
||||
file->settings.unimportant = 1;
|
||||
file->settings.unwrapped_lines = 1;
|
||||
file->settings.never_kill = true;
|
||||
file->settings.unimportant = true;
|
||||
file->settings.unwrapped_lines = true;
|
||||
|
||||
if (init_files[i].ptr){
|
||||
*init_files[i].ptr = file;
|
||||
|
@ -1555,8 +1552,7 @@ App_Init_Sig(app_init){
|
|||
panel_make_empty(system, vars, p.panel);
|
||||
models->layout.active_panel = p.id;
|
||||
|
||||
String hdbase = make_fixed_width_string(models->hot_dir_base_);
|
||||
hot_directory_init(&models->hot_directory, hdbase, current_directory);
|
||||
hot_directory_init(&models->hot_directory, current_directory);
|
||||
|
||||
// NOTE(allen): child proc list setup
|
||||
i32 max_children = 16;
|
||||
|
@ -1648,15 +1644,14 @@ App_Step_Sig(app_step){
|
|||
Partition *part = &models->mem.part;
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
char *buffer = push_array(part, char, buffer_size);
|
||||
i32 unmark_top = 0;
|
||||
i32 unmark_max = (8 << 10);
|
||||
u32 unmark_top = 0;
|
||||
u32 unmark_max = (8 << 10);
|
||||
Editing_File **unmark = (Editing_File**)push_array(part, Editing_File*, unmark_max);
|
||||
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
for (;system->get_file_change(buffer, buffer_size, &mem_too_small, &size);){
|
||||
Assert(!mem_too_small);
|
||||
|
||||
Editing_File_Canon_Name canon;
|
||||
if (get_canon_name(system, &canon, make_string(buffer, size))){
|
||||
Editing_File *file = working_set_canon_contains(working_set, canon.name);
|
||||
|
@ -1665,18 +1660,17 @@ App_Step_Sig(app_step){
|
|||
file_mark_behind_os(file);
|
||||
}
|
||||
else if (file->state.ignore_behind_os == 1){
|
||||
// TODO(allen): I need the ability to put a file back on the list
|
||||
file->state.ignore_behind_os = 2;
|
||||
unmark[unmark_top++] = file;
|
||||
if (unmark_top == unmark_max){
|
||||
break;
|
||||
}
|
||||
file->state.ignore_behind_os = 2;
|
||||
unmark[unmark_top++] = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < unmark_top; ++i){
|
||||
for (u32 i = 0; i < unmark_top; ++i){
|
||||
unmark[i]->state.ignore_behind_os = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,10 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor
|
|||
buffer->size = buffer_size(&file->state.buffer);
|
||||
buffer->line_count = file->state.buffer.line_count;
|
||||
|
||||
buffer->file_name_len = file->name.source_path.size;
|
||||
buffer->file_name_len = file->canon.name.size;
|
||||
buffer->file_name = file->canon.name.str;
|
||||
|
||||
buffer->buffer_name_len = file->name.live_name.size;
|
||||
buffer->file_name = file->name.source_path.str;
|
||||
buffer->buffer_name = file->name.live_name.str;
|
||||
|
||||
buffer->dirty = file->state.dirty;
|
||||
|
@ -275,7 +276,7 @@ DOC_SEE(Command_Line_Interface_Flag)
|
|||
|
||||
if (file){
|
||||
file_clear(system, models, file);
|
||||
file->settings.unimportant = 1;
|
||||
file->settings.unimportant = true;
|
||||
|
||||
if (!(flags & CLI_AlwaysBindToView)){
|
||||
View_Iter iter = file_view_iter_init(&models->layout, file, 0);
|
||||
|
@ -840,10 +841,10 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
case BufferSetting_Unimportant:
|
||||
{
|
||||
if (value){
|
||||
file->settings.unimportant = 1;
|
||||
file->settings.unimportant = true;
|
||||
}
|
||||
else{
|
||||
file->settings.unimportant = 0;
|
||||
file->settings.unimportant = false;
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -2160,7 +2161,7 @@ DOC_RETURN(This call returns a File_List struct containing pointers to the names
|
|||
File_List result = {};
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
String str = make_string_terminated(part, dir, len);
|
||||
system->set_file_list(&result, str.str);
|
||||
system->set_file_list(&result, str.str, 0, 0, 0);
|
||||
end_temp_memory(temp);
|
||||
return(result);
|
||||
}
|
||||
|
@ -2173,7 +2174,7 @@ DOC(After this call the file list passed in should not be read or written to.)
|
|||
*/{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
system->set_file_list(&list, 0);
|
||||
system->set_file_list(&list, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
API_EXPORT void
|
||||
|
|
|
@ -86,7 +86,6 @@ struct Models{
|
|||
Editing_File *message_buffer;
|
||||
Editing_File *scratch_buffer;
|
||||
|
||||
char hot_dir_base_[256];
|
||||
Hot_Directory hot_directory;
|
||||
|
||||
Panel *prev_mouse_panel;
|
||||
|
@ -95,8 +94,8 @@ struct Models{
|
|||
|
||||
Debug_Data debug;
|
||||
|
||||
i16 user_up_key;
|
||||
i16 user_down_key;
|
||||
u16 user_up_key;
|
||||
u16 user_down_key;
|
||||
};
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#define Command_Function_Sig(name) void (name)( \
|
||||
System_Functions *system, \
|
||||
struct Command_Data *command, \
|
||||
struct Command_Binding binding)
|
||||
#define Command_Function_Sig(name) \
|
||||
void (name)(System_Functions *system, struct Command_Data *command, struct Command_Binding binding)
|
||||
|
||||
typedef Command_Function_Sig(*Command_Function);
|
||||
|
||||
|
@ -24,6 +22,7 @@ struct Command_Binding{
|
|||
};
|
||||
i64 hash;
|
||||
};
|
||||
static Command_Binding null_command_binding = {0};
|
||||
|
||||
struct Command_Map{
|
||||
Command_Map *parent;
|
||||
|
@ -41,8 +40,7 @@ map_hash(u16 event_code, u8 modifiers){
|
|||
}
|
||||
|
||||
internal b32
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Function function, Custom_Command_Function *custom = 0){
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0){
|
||||
Assert(map->count * 8 < map->max * 7);
|
||||
Command_Binding bind;
|
||||
bind.function = function;
|
||||
|
@ -64,14 +62,12 @@ map_add(Command_Map *map, u16 event_code, u8 modifiers,
|
|||
}
|
||||
|
||||
inline b32
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Function function, u64 custom_id){
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, u64 custom_id){
|
||||
return (map_add(map, event_code, modifiers, function, (Custom_Command_Function*)custom_id));
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
i32 *index_out){
|
||||
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers, i32 *index_out){
|
||||
i64 hash = map_hash(event_code, modifiers);
|
||||
i32 max = map->max;
|
||||
i32 index = hash % map->max;
|
||||
|
@ -87,8 +83,7 @@ map_find_entry(Command_Map *map, u16 event_code, u8 modifiers,
|
|||
}
|
||||
|
||||
internal b32
|
||||
map_find(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Binding *bind_out){
|
||||
map_find(Command_Map *map, u16 event_code, u8 modifiers, Command_Binding *bind_out){
|
||||
b32 result;
|
||||
i32 index;
|
||||
result = map_find_entry(map, event_code, modifiers, &index);
|
||||
|
@ -110,17 +105,11 @@ map_drop(Command_Map *map, u16 event_code, u8 modifiers){
|
|||
return result;
|
||||
}
|
||||
|
||||
inline Command_Binding
|
||||
command_binding_zero(){
|
||||
Command_Binding binding = {0};
|
||||
return(binding);
|
||||
}
|
||||
|
||||
internal void
|
||||
map_clear(Command_Map *commands){
|
||||
i32 max = commands->max;
|
||||
memset(commands->commands, 0, max*sizeof(*commands->commands));
|
||||
commands->vanilla_keyboard_default = command_binding_zero();
|
||||
commands->vanilla_keyboard_default = null_command_binding;
|
||||
commands->count = 0;
|
||||
}
|
||||
|
||||
|
@ -131,42 +120,31 @@ map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
|
|||
commands->parent = parent;
|
||||
commands->commands = push_array(part, Command_Binding, max);
|
||||
commands->max = max;
|
||||
|
||||
map_clear(commands);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
map_get_vanilla_keyboard_default(Command_Map *map, u8 command,
|
||||
Command_Binding *bind_out){
|
||||
map_get_vanilla_keyboard_default(Command_Map *map, u8 command, Command_Binding *bind_out){
|
||||
if (command == MDFR_NONE){
|
||||
*bind_out = map->vanilla_keyboard_default;
|
||||
}
|
||||
}
|
||||
|
||||
inline u8
|
||||
apply_shift_to_code(u8 keycode){
|
||||
return !(keycode >= 0x20 && keycode < 0x7F && keycode != ' ');
|
||||
}
|
||||
|
||||
internal Command_Binding
|
||||
map_extract(Command_Map *map, Key_Event_Data key){
|
||||
Command_Binding bind = {};
|
||||
Command_Binding bind = {0};
|
||||
|
||||
b32 ctrl = key.modifiers[MDFR_CONTROL_INDEX];
|
||||
b32 alt = key.modifiers[MDFR_ALT_INDEX];
|
||||
b32 shift = key.modifiers[MDFR_SHIFT_INDEX];
|
||||
u16 code;
|
||||
u8 command = MDFR_NONE;
|
||||
|
||||
//if (key.character_no_caps_lock != 0 &&
|
||||
// key.character_no_caps_lock != ' ') shift = 0;
|
||||
|
||||
if (shift) command |= MDFR_SHIFT;
|
||||
if (ctrl) command |= MDFR_CTRL;
|
||||
if (alt) command |= MDFR_ALT;
|
||||
|
||||
code = key.character_no_caps_lock;
|
||||
u16 code = key.character_no_caps_lock;
|
||||
if (code == 0){
|
||||
code = key.keycode;
|
||||
map_find(map, code, command, &bind);
|
||||
|
@ -175,7 +153,6 @@ map_extract(Command_Map *map, Key_Event_Data key){
|
|||
if (code != '\n' && code != '\t' && code != ' '){
|
||||
command &= ~(MDFR_SHIFT);
|
||||
}
|
||||
|
||||
map_find(map, code, command, &bind);
|
||||
if (bind.function == 0){
|
||||
map_get_vanilla_keyboard_default(map, command, &bind);
|
||||
|
|
|
@ -744,9 +744,6 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
|
|||
filename = file->canon.name.str;
|
||||
using_actual_filename = true;
|
||||
}
|
||||
else if (match(filename, file->canon.name)){
|
||||
using_actual_filename = true;
|
||||
}
|
||||
|
||||
if (filename){
|
||||
Mem_Options *mem = &models->mem;
|
||||
|
@ -774,13 +771,12 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
|
|||
}
|
||||
else{
|
||||
data = (char*)push_array(&mem->part, char, max);
|
||||
|
||||
if (!data){
|
||||
used_general = 1;
|
||||
data = (char*)general_memory_allocate(&mem->general, max);
|
||||
}
|
||||
}
|
||||
Assert(data);
|
||||
Assert(data != 0);
|
||||
|
||||
if (dos_write_mode){
|
||||
size = buffer_convert_out(buffer, data, max);
|
||||
|
@ -790,9 +786,21 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
|
|||
buffer_stringify(buffer, 0, size, data);
|
||||
}
|
||||
|
||||
if (!using_actual_filename && file->canon.name.str != 0){
|
||||
char space[512];
|
||||
u32 length = str_size(filename);
|
||||
system->get_canonical(filename, length, space, sizeof(space));
|
||||
|
||||
char *source_path = file->canon.name.str;
|
||||
if (match(space, source_path)){
|
||||
using_actual_filename = true;
|
||||
}
|
||||
}
|
||||
|
||||
result = system->save_file(filename, data, size);
|
||||
|
||||
if (result && using_actual_filename){
|
||||
file->state.ignore_behind_os = 1;
|
||||
file->state.ignore_behind_os = true;
|
||||
}
|
||||
|
||||
file_mark_clean(file);
|
||||
|
@ -2196,6 +2204,8 @@ file_first_lex_serial(Mem_Options *mem, Editing_File *file){
|
|||
|
||||
i32 chunk_index = 0;
|
||||
|
||||
Cpp_Token_Array *swap_array = &file->state.swap_array;
|
||||
|
||||
do{
|
||||
char *chunk = chunks[chunk_index];
|
||||
i32 chunk_size = chunk_sizes[chunk_index];
|
||||
|
@ -2204,40 +2214,50 @@ file_first_lex_serial(Mem_Options *mem, Editing_File *file){
|
|||
|
||||
switch (result){
|
||||
case LexResult_NeedChunk: ++chunk_index; break;
|
||||
case LexResult_NeedTokenMemory: InvalidCodePath;
|
||||
|
||||
|
||||
case LexResult_Finished:
|
||||
case LexResult_NeedTokenMemory:
|
||||
{
|
||||
u32 new_max = l_round_up_u32(tokens.count+1, KB(1));
|
||||
u32 new_mem_max = new_max*sizeof(Cpp_Token);
|
||||
u32 old_mem_max = swap_array->count*sizeof(Cpp_Token);
|
||||
if (swap_array->tokens == 0){
|
||||
swap_array->tokens = (Cpp_Token*)general_memory_allocate(general, new_mem_max);
|
||||
}
|
||||
else{
|
||||
swap_array->tokens = (Cpp_Token*)
|
||||
general_memory_reallocate(general, swap_array->tokens, old_mem_max, new_mem_max);
|
||||
}
|
||||
swap_array->max_count = new_max;
|
||||
|
||||
memcpy(swap_array->tokens + swap_array->count, tokens.tokens, tokens.count*sizeof(Cpp_Token));
|
||||
swap_array->count += tokens.count;
|
||||
tokens.count = 0;
|
||||
|
||||
if (result == LexResult_Finished){
|
||||
still_lexing = 0;
|
||||
}
|
||||
}break;
|
||||
|
||||
case LexResult_HitTokenLimit: InvalidCodePath;
|
||||
case LexResult_Finished: still_lexing = 0; break;
|
||||
}
|
||||
} while (still_lexing);
|
||||
|
||||
i32 new_max = l_round_up_i32(tokens.count+1, KB(1));
|
||||
|
||||
{
|
||||
Assert(file->state.swap_array.tokens == 0);
|
||||
file->state.swap_array.tokens = (Cpp_Token*)general_memory_allocate(general, new_max*sizeof(Cpp_Token));
|
||||
Cpp_Token_Array *token_array = &file->state.token_array;
|
||||
token_array->count = swap_array->count;
|
||||
token_array->max_count = swap_array->max_count;
|
||||
if (token_array->tokens != 0){
|
||||
general_memory_free(general, token_array->tokens);
|
||||
}
|
||||
token_array->tokens = swap_array->tokens;
|
||||
|
||||
u8 *dest = (u8*)file->state.swap_array.tokens;
|
||||
u8 *src = (u8*)tokens.tokens;
|
||||
swap_array->tokens = 0;
|
||||
swap_array->count = 0;
|
||||
swap_array->max_count = 0;
|
||||
|
||||
memcpy(dest, src, tokens.count*sizeof(Cpp_Token));
|
||||
|
||||
{
|
||||
Cpp_Token_Array *file_token_array = &file->state.token_array;
|
||||
file_token_array->count = tokens.count;
|
||||
file_token_array->max_count = new_max;
|
||||
if (file_token_array->tokens){
|
||||
general_memory_free(general, file_token_array->tokens);
|
||||
}
|
||||
file_token_array->tokens = file->state.swap_array.tokens;
|
||||
file->state.swap_array.tokens = 0;
|
||||
}
|
||||
|
||||
// NOTE(allen): These are outside the locked section because I don't
|
||||
// think getting these out of order will cause critical bugs, and I
|
||||
// want to minimize what's done in locked sections.
|
||||
file->state.tokens_complete = 1;
|
||||
file->state.still_lexing = 0;
|
||||
file->state.tokens_complete = true;
|
||||
file->state.still_lexing = false;
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
@ -4254,7 +4274,7 @@ begin_exhaustive_loop(Exhaustive_File_Loop *loop, Hot_Directory *hdir){
|
|||
|
||||
copy_ss(&loop->front_name, front_of_directory(hdir->string));
|
||||
get_absolutes(loop->front_name, &loop->absolutes, 1, 1);
|
||||
copy_ss(&loop->full_path, path_of_directory(hdir->string));
|
||||
copy_ss(&loop->full_path, hdir->canon_dir);
|
||||
loop->r = loop->full_path.size;
|
||||
}
|
||||
|
||||
|
@ -4265,18 +4285,23 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti
|
|||
local_persist String message_unsynced = make_lit_string(" LOADED !");
|
||||
|
||||
Exhaustive_File_Info result = {0};
|
||||
Editing_File *file = 0;
|
||||
|
||||
result.info = loop->infos + i;
|
||||
loop->full_path.size = loop->r;
|
||||
append_sc(&loop->full_path, result.info->filename);
|
||||
terminate_with_null(&loop->full_path);
|
||||
|
||||
Editing_File *file = working_set_canon_contains(working_set, loop->full_path);
|
||||
|
||||
#if 0
|
||||
if (file != 0){
|
||||
Editing_File_Canon_Name canon_name;
|
||||
|
||||
if (get_canon_name(system, &canon_name, loop->full_path)){
|
||||
file = working_set_canon_contains(working_set, canon_name.name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
String filename = make_string_cap(result.info->filename, result.info->filename_len, result.info->filename_len+1);
|
||||
|
||||
|
@ -5661,6 +5686,23 @@ struct Input_Process_Result{
|
|||
i32 max_y;
|
||||
};
|
||||
|
||||
static char
|
||||
to_writable_char(Key_Code long_character){
|
||||
char character = 0;
|
||||
if (long_character < ' '){
|
||||
if (long_character == '\n'){
|
||||
character = '\n';
|
||||
}
|
||||
else if (long_character == '\t'){
|
||||
character = '\t';
|
||||
}
|
||||
}
|
||||
else if (long_character >= ' ' && long_character <= 255 && long_character != 127){
|
||||
character = (char)long_character;
|
||||
}
|
||||
return(character);
|
||||
}
|
||||
|
||||
internal Input_Process_Result
|
||||
do_step_file_view(System_Functions *system,
|
||||
View *view, i32_Rect rect, b32 is_active,
|
||||
|
@ -5774,7 +5816,8 @@ do_step_file_view(System_Functions *system,
|
|||
i32 count = keys->count;
|
||||
for (i32 i = 0; i < count; ++i){
|
||||
Key_Event_Data key = get_single_key(keys, i);
|
||||
if (char_to_upper(key.character) == activation_key){
|
||||
char character = to_writable_char(key.character);
|
||||
if (char_to_upper(character) == activation_key){
|
||||
target->active = b->id;
|
||||
result.is_animating = 1;
|
||||
break;
|
||||
|
|
|
@ -27,9 +27,6 @@ struct Render_Font{
|
|||
String name;
|
||||
b32 loaded;
|
||||
|
||||
// TODO(allen): Have our own type here instead
|
||||
// of stbtt_packedchar, and have both stb fonts
|
||||
// and OS fonts go to our type.
|
||||
Glyph_Data glyphs[256];
|
||||
f32 advance_data[256];
|
||||
i32 height, ascent, descent, line_skip;
|
||||
|
@ -59,7 +56,8 @@ struct Render_Piece_Rectangle{
|
|||
|
||||
struct Render_Piece_Gradient{
|
||||
f32_Rect rect;
|
||||
u32 left_color, right_color;
|
||||
u32 left_color;
|
||||
u32 right_color;
|
||||
};
|
||||
|
||||
struct Render_Piece_Glyph{
|
||||
|
|
|
@ -148,7 +148,6 @@ font_draw_glyph(Render_Target *target, i16 font_id, u8 character, f32 x, f32 y,
|
|||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, char *str){
|
||||
f32 x = 0;
|
||||
|
@ -157,7 +156,7 @@ font_string_width(Render_Target *target, i16 font_id, char *str){
|
|||
|
||||
if (font){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i] % 128;
|
||||
u8 c = str[i];
|
||||
x += advance_data[c];
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +172,7 @@ font_string_width(Render_Target *target, i16 font_id, String str){
|
|||
|
||||
if (font){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i] % 128;
|
||||
u8 c = str.str[i];
|
||||
x += advance_data[c];
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +189,7 @@ draw_string(Render_Target *target, i16 font_id,
|
|||
|
||||
if (font){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i] % 128;
|
||||
u8 c = str[i];
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += advance_data[c];
|
||||
}
|
||||
|
@ -200,26 +199,25 @@ draw_string(Render_Target *target, i16 font_id,
|
|||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||
draw_string_mono(Render_Target *target, i16 font_id, char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i] % 128;
|
||||
u8 c = str[i];
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
String str, i32 x_, i32 y, u32 color){
|
||||
draw_string(Render_Target *target, i16 font_id, String str, i32 x_, i32 y, u32 color){
|
||||
f32 x = (f32)x_;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i] % 128;
|
||||
u8 c = str.str[i];
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += advance_data[c];
|
||||
}
|
||||
|
@ -229,13 +227,13 @@ draw_string(Render_Target *target, i16 font_id,
|
|||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
String str, f32 x, f32 y, f32 advance, u32 color){
|
||||
draw_string_mono(Render_Target *target, i16 font_id, String str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i] % 128;
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ handle_equal(Plat_Handle a, Plat_Handle b){
|
|||
return(result);
|
||||
}
|
||||
|
||||
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, char *directory)
|
||||
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, char *directory, char *canon_directory_out, u32 *canon_directory_size_out, u32 canon_directory_max)
|
||||
typedef Sys_Set_File_List_Sig(System_Set_File_List);
|
||||
|
||||
#define Sys_Get_Canonical_Sig(name) i32 name(char *filename, i32 len, char *buffer, i32 max)
|
||||
#define Sys_Get_Canonical_Sig(name) u32 name(char *filename, u32 len, char *buffer, u32 max)
|
||||
typedef Sys_Get_Canonical_Sig(System_Get_Canonical);
|
||||
|
||||
#define Sys_Add_Listener_Sig(name) b32 name(char *filename)
|
||||
|
@ -51,7 +51,6 @@ typedef Sys_Load_Close_Sig(System_Load_Close);
|
|||
#define Sys_Save_File_Sig(name) b32 name(char *filename, char *buffer, u32 size)
|
||||
typedef Sys_Save_File_Sig(System_Save_File);
|
||||
|
||||
|
||||
#define Sys_Now_Time_Sig(name) u64 name()
|
||||
typedef Sys_Now_Time_Sig(System_Now_Time);
|
||||
|
||||
|
|
|
@ -695,9 +695,7 @@ stb_font_load(Partition *part,
|
|||
return(result);
|
||||
}
|
||||
|
||||
// NOTE(allen): Thanks to insofaras.
|
||||
// This is copy-pasted from some work he
|
||||
// did to get free type working on Linux.
|
||||
// NOTE(allen): Thanks to insofaras. This is copy-pasted from some work he originally did to get free type working on Linux.
|
||||
|
||||
#undef internal
|
||||
#include <ft2build.h>
|
||||
|
@ -716,16 +714,11 @@ next_pow_of_2(u32 v){
|
|||
return ++v;
|
||||
}
|
||||
|
||||
#define NUM_GLYPHS 128
|
||||
#define NUM_GLYPHS 256
|
||||
#define ENABLE_LCD_FILTER 0
|
||||
|
||||
internal b32
|
||||
font_load_freetype(Partition *part,
|
||||
Render_Font *rf,
|
||||
char *filename,
|
||||
i32 pt_size,
|
||||
i32 tab_width,
|
||||
b32 use_hinting){
|
||||
font_load_freetype(Partition *part, Render_Font *rf, char *filename, i32 pt_size, i32 tab_width, b32 use_hinting){
|
||||
|
||||
memset(rf, 0, sizeof(*rf));
|
||||
|
||||
|
@ -877,7 +870,7 @@ font_load_freetype(Partition *part,
|
|||
// on the fly. Maybe later introduce a caching system or whatevs.
|
||||
f32 *adv = rf->advance_data;
|
||||
for (i32 i = 0; i < 256; ++i){
|
||||
if (i < ' ' || i > '~'){
|
||||
if (i < ' ' || i == 127){
|
||||
switch (i){
|
||||
case '\n':
|
||||
adv[i] = adv[' '];
|
||||
|
|
|
@ -1929,7 +1929,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32
|
|||
|
||||
default:
|
||||
if (S.write.item < item_end){
|
||||
if (S.ch >= ' ' && S.ch <= '~'){
|
||||
if (S.ch >= ' ' && S.ch <= 256 && S.ch != 127){
|
||||
S.write = write_render_item(S.write, S.i, S.ch, 0);
|
||||
}
|
||||
else{
|
||||
|
|
|
@ -119,10 +119,10 @@ static Editing_File_State null_editing_file_state = {0};
|
|||
|
||||
struct Editing_File_Name{
|
||||
char live_name_[256];
|
||||
char source_path_[256];
|
||||
//char source_path_[256];
|
||||
char extension_[16];
|
||||
String live_name;
|
||||
String source_path;
|
||||
//String source_path;
|
||||
String extension;
|
||||
};
|
||||
|
||||
|
@ -351,21 +351,36 @@ file_set_to_loading(Editing_File *file){
|
|||
|
||||
inline void
|
||||
file_mark_clean(Editing_File *file){
|
||||
if (file->settings.unimportant){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
else{
|
||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_dirty(Editing_File *file){
|
||||
if (file->settings.unimportant){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
else{
|
||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||
file->state.dirty = DirtyState_UnsavedChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_mark_behind_os(Editing_File *file){
|
||||
if (file->settings.unimportant){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
else{
|
||||
file->state.dirty = DirtyState_UnloadedChanges;
|
||||
}
|
||||
}
|
||||
|
||||
inline Dirty_State
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
// TOP
|
||||
|
||||
struct Hot_Directory{
|
||||
char string_space[256];
|
||||
char canon_dir_space[256];
|
||||
String string;
|
||||
String canon_dir;
|
||||
File_List file_list;
|
||||
};
|
||||
|
||||
|
@ -63,10 +66,23 @@ hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String
|
|||
b32 success = terminate_with_null(&hot_directory->string);
|
||||
if (success){
|
||||
if (str.size > 0){
|
||||
system->set_file_list(&hot_directory->file_list, hot_directory->string.str);
|
||||
u32 canon_max = hot_directory->canon_dir.memory_size;
|
||||
u32 canon_length = 0;
|
||||
char *canon_str = hot_directory->canon_dir.str;
|
||||
system->set_file_list(&hot_directory->file_list, hot_directory->string.str, canon_str, &canon_length, canon_max);
|
||||
if (canon_length > 0){
|
||||
hot_directory->canon_dir.size = canon_length;
|
||||
if (!char_is_slash(hot_directory->canon_dir.str[canon_length-1])){
|
||||
append_s_char(&hot_directory->canon_dir, '/');
|
||||
}
|
||||
}
|
||||
else{
|
||||
system->set_file_list(&hot_directory->file_list, 0);
|
||||
hot_directory->canon_dir.size = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
system->set_file_list(&hot_directory->file_list, 0, 0, 0, 0);
|
||||
hot_directory->canon_dir.size = 0;
|
||||
}
|
||||
}
|
||||
hot_directory_fixup(hot_directory);
|
||||
|
@ -78,8 +94,10 @@ hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){
|
|||
}
|
||||
|
||||
internal void
|
||||
hot_directory_init(Hot_Directory *hot_directory, String base, String dir){
|
||||
hot_directory->string = base;
|
||||
hot_directory_init(Hot_Directory *hot_directory, String dir){
|
||||
hot_directory->string = make_fixed_width_string(hot_directory->string_space);
|
||||
hot_directory->canon_dir = make_fixed_width_string(hot_directory->canon_dir_space);
|
||||
|
||||
hot_directory->string.str[255] = 0;
|
||||
hot_directory->string.size = 0;
|
||||
copy_ss(&hot_directory->string, dir);
|
||||
|
|
|
@ -358,7 +358,7 @@ touch_file(Working_Set *working_set, Editing_File *file){
|
|||
internal void
|
||||
editing_file_name_init(Editing_File_Name *name){
|
||||
name->live_name = make_fixed_width_string(name->live_name_);
|
||||
name->source_path = make_fixed_width_string(name->source_path_);
|
||||
//name->source_path = make_fixed_width_string(name->source_path_);
|
||||
name->extension = make_fixed_width_string(name->extension_);
|
||||
}
|
||||
|
||||
|
@ -377,9 +377,12 @@ internal void
|
|||
buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, String filename){
|
||||
Assert(name->live_name.str != 0);
|
||||
|
||||
copy_checked_ss(&name->source_path, filename);
|
||||
//copy_checked_ss(&name->source_path, filename);
|
||||
copy_ss(&name->live_name, front_of_directory(filename));
|
||||
|
||||
String ext = file_extension(filename);
|
||||
copy_ss(&name->extension, ext);
|
||||
#if 0
|
||||
if (name->source_path.size == name->live_name.size){
|
||||
name->extension.size = 0;
|
||||
}
|
||||
|
@ -387,6 +390,7 @@ buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, String fi
|
|||
String ext = file_extension(filename);
|
||||
copy_ss(&name->extension, ext);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
i32 original_len = name->live_name.size;
|
||||
|
@ -425,9 +429,8 @@ buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *fil
|
|||
|
||||
internal void
|
||||
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String canon_filename){
|
||||
Assert(file->name.live_name.size == 0 &&
|
||||
file->name.source_path.size == 0 &&
|
||||
file->name.extension.size == 0);
|
||||
Assert(file->name.live_name.size == 0 && file->name.extension.size == 0);
|
||||
//&& file->name.source_path.size == 0);
|
||||
Assert(file->canon.name.size == 0);
|
||||
|
||||
file->canon.name = make_fixed_width_string(file->canon.name_);
|
||||
|
@ -440,9 +443,8 @@ buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set
|
|||
|
||||
internal void
|
||||
buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_File *file){
|
||||
Assert(file->name.live_name.size == 0 &&
|
||||
file->name.source_path.size == 0 &&
|
||||
file->name.extension.size == 0);
|
||||
Assert(file->name.live_name.size == 0 && file->name.extension.size == 0);
|
||||
// && file->name.source_path.size == 0
|
||||
Assert(file->canon.name.size != 0);
|
||||
|
||||
system->remove_listener(file->canon.name_);
|
||||
|
@ -453,8 +455,8 @@ buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_F
|
|||
internal void
|
||||
buffer_bind_name(General_Memory *general, Working_Set *working_set, Editing_File *file, String filename){
|
||||
Assert(file->name.live_name.size == 0 &&
|
||||
file->name.source_path.size == 0 &&
|
||||
file->name.extension.size == 0);
|
||||
// && file->name.source_path.size == 0
|
||||
|
||||
Editing_File_Name new_name;
|
||||
editing_file_name_init(&new_name);
|
||||
|
@ -462,7 +464,7 @@ buffer_bind_name(General_Memory *general, Working_Set *working_set, Editing_File
|
|||
|
||||
editing_file_name_init(&file->name);
|
||||
copy_ss(&file->name.live_name, new_name.live_name);
|
||||
copy_ss(&file->name.source_path, new_name.source_path);
|
||||
//copy_ss(&file->name.source_path, new_name.source_path);
|
||||
copy_ss(&file->name.extension, new_name.extension);
|
||||
|
||||
b32 result = working_set_name_add(general, working_set, file, file->name.live_name);
|
||||
|
@ -474,7 +476,7 @@ buffer_unbind_name(Working_Set *working_set, Editing_File *file){
|
|||
Assert(file->name.live_name.size != 0);
|
||||
working_set_name_remove(working_set, file->name.live_name);
|
||||
file->name.live_name.size = 0;
|
||||
file->name.source_path.size = 0;
|
||||
//file->name.source_path.size = 0;
|
||||
file->name.extension.size = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,14 +140,7 @@ add_listener(File_Track_System *system, char *filename){
|
|||
char dir_name[1024];
|
||||
internal_get_parent_name(dir_name, sizeof(dir_name), filename);
|
||||
|
||||
HANDLE dir = CreateFile(
|
||||
dir_name,
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
|
||||
0);
|
||||
HANDLE dir = CreateFile(dir_name, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
|
||||
|
||||
if (dir != INVALID_HANDLE_VALUE){
|
||||
BY_HANDLE_FILE_INFORMATION dir_info = {0};
|
||||
|
|
|
@ -1892,7 +1892,7 @@ LinuxInputInit(Display *dpy, Window XWindow)
|
|||
// Keyboard handling funcs
|
||||
//
|
||||
|
||||
global u8 keycode_lookup_table[255];
|
||||
global Key_Code keycode_lookup_table[255];
|
||||
|
||||
internal void
|
||||
LinuxKeycodeInit(Display* dpy){
|
||||
|
|
|
@ -70,35 +70,25 @@ char *keys_that_need_codes[] = {
|
|||
"f16",
|
||||
};
|
||||
|
||||
void
|
||||
internal void
|
||||
generate_keycode_enum(){
|
||||
char *filename_keycodes = KEYCODES_FILE;
|
||||
Out_Context context = {0};
|
||||
int32_t i = 0, count = 0;
|
||||
unsigned char code = 1;
|
||||
|
||||
uint16_t code = 0xE000;
|
||||
|
||||
String out = make_out_string(10 << 20);
|
||||
|
||||
Out_Context context = {0};
|
||||
if (begin_file_out(&context, filename_keycodes, &out)){
|
||||
count = ArrayCount(keys_that_need_codes);
|
||||
int32_t count = ArrayCount(keys_that_need_codes);
|
||||
|
||||
append_sc(&out, "enum{\n");
|
||||
for (i = 0; i < count; i){
|
||||
if (strcmp(keys_that_need_codes[i], "f1") == 0 && code < 0x7F){
|
||||
code = 0x7F;
|
||||
}
|
||||
switch (code){
|
||||
case '\n': code++; break;
|
||||
case '\t': code++; break;
|
||||
case 0x20: code = 0x7F; break;
|
||||
default:
|
||||
for (int32_t i = 0; i < count;){
|
||||
append_sc(&out, "key_");
|
||||
append_sc(&out, keys_that_need_codes[i++]);
|
||||
append_sc(&out, " = ");
|
||||
append_int_to_str(&out, code++);
|
||||
append_sc(&out, ",\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
append_sc(&out, "};\n");
|
||||
|
||||
|
@ -108,7 +98,7 @@ generate_keycode_enum(){
|
|||
"char *result = 0;\n"
|
||||
"switch(key_code){\n");
|
||||
|
||||
for (i = 0; i < count; ++i){
|
||||
for (int32_t i = 0; i < count; ++i){
|
||||
append_sc(&out, "case key_");
|
||||
append_sc(&out, keys_that_need_codes[i]);
|
||||
append_sc(&out, ": result = \"");
|
||||
|
|
264
win32_4ed.cpp
264
win32_4ed.cpp
|
@ -739,19 +739,46 @@ Sys_File_Can_Be_Made_Sig(system_file_can_be_made){
|
|||
|
||||
internal
|
||||
Sys_Set_File_List_Sig(system_set_file_list){
|
||||
b32 clear_list = false;
|
||||
b32 clear_list = true;
|
||||
if (directory != 0){
|
||||
char dir_space[MAX_PATH + 32];
|
||||
String dir = make_string_cap(dir_space, 0, MAX_PATH + 32);
|
||||
append_sc(&dir, directory);
|
||||
append_ss(&dir, make_lit_string("\\*"));
|
||||
terminate_with_null(&dir);
|
||||
|
||||
char *c_str_dir = dir.str;
|
||||
HANDLE dir_handle = CreateFile(dir.str, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
|
||||
|
||||
if (dir_handle != INVALID_HANDLE_VALUE){
|
||||
DWORD final_length = GetFinalPathNameByHandleA(dir_handle, dir_space, sizeof(dir_space), 0);
|
||||
CloseHandle(dir_handle);
|
||||
|
||||
if (final_length < sizeof(dir_space)){
|
||||
char *c_str_dir = dir_space;
|
||||
|
||||
final_length -= 4;
|
||||
memmove(c_str_dir, c_str_dir+4, final_length);
|
||||
c_str_dir[final_length] = '\\';
|
||||
c_str_dir[final_length+1] = '*';
|
||||
c_str_dir[final_length+2] = 0;
|
||||
|
||||
if (canon_directory_out != 0){
|
||||
if (final_length+1 < canon_directory_max){
|
||||
memcpy(canon_directory_out, c_str_dir, final_length);
|
||||
if (char_is_slash(dir.str[dir.size-1]) && canon_directory_out[final_length-1] != '\\'){
|
||||
canon_directory_out[final_length++] = '\\';
|
||||
}
|
||||
canon_directory_out[final_length] = 0;
|
||||
*canon_directory_size_out = final_length;
|
||||
}
|
||||
else{
|
||||
u32 length = copy_fast_unsafe_cc(canon_directory_out, directory);
|
||||
canon_directory_out[length] = 0;
|
||||
*canon_directory_size_out = length;
|
||||
}
|
||||
}
|
||||
|
||||
WIN32_FIND_DATA find_data;
|
||||
HANDLE search;
|
||||
search = FindFirstFileA(c_str_dir, &find_data);
|
||||
HANDLE search = FindFirstFileA(c_str_dir, &find_data);
|
||||
|
||||
if (search != INVALID_HANDLE_VALUE){
|
||||
i32 character_count = 0;
|
||||
|
@ -804,17 +831,12 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
FindClose(search);
|
||||
|
||||
file_list->count = file_count;
|
||||
}else{
|
||||
clear_list = true;
|
||||
clear_list = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
clear_list = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
clear_list = true;
|
||||
}
|
||||
|
||||
if (clear_list){
|
||||
|
@ -826,13 +848,70 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This does not chase down symbolic links because doing so
|
||||
// would require a lot of heavy duty OS calls. I've decided to give up
|
||||
// a little ground on always recognizing files as equivalent in exchange
|
||||
// for the ability to handle them very quickly when nothing strange is
|
||||
// going on.
|
||||
internal int32_t
|
||||
win32_canonical_ascii_name(char *src, i32 len, char *dst, i32 max){
|
||||
#if 1
|
||||
internal u32
|
||||
win32_canonical_ascii_name(char *src, u32 len, char *dst, u32 max){
|
||||
u32 result = 0;
|
||||
|
||||
char src_space[MAX_PATH + 32];
|
||||
if (len < sizeof(src_space) && len >= 2 && ((src[0] >= 'a' && src[0] <= 'z') || (src[0] >= 'A' && src[0] <= 'Z')) && src[1] == ':'){
|
||||
memcpy(src_space, src, len);
|
||||
src_space[len] = 0;
|
||||
|
||||
HANDLE file = CreateFile(src_space, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if (file != INVALID_HANDLE_VALUE){
|
||||
DWORD final_length = GetFinalPathNameByHandleA(file, dst, max, 0);
|
||||
|
||||
if (final_length < max && final_length >= 4){
|
||||
if (dst[final_length-1] == 0){
|
||||
--final_length;
|
||||
}
|
||||
final_length -= 4;
|
||||
memmove(dst, dst+4, final_length);
|
||||
dst[final_length] = 0;
|
||||
result = final_length;
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
}
|
||||
else{
|
||||
String src_str = make_string(src, len);
|
||||
String path_str = path_of_directory(src_str);
|
||||
String front_str = front_of_directory(src_str);
|
||||
|
||||
memcpy(src_space, path_str.str, path_str.size);
|
||||
src_space[path_str.size] = 0;
|
||||
|
||||
HANDLE dir = CreateFile(src_space, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
|
||||
|
||||
if (dir != INVALID_HANDLE_VALUE){
|
||||
DWORD final_length = GetFinalPathNameByHandleA(dir, dst, max, 0);
|
||||
|
||||
if (final_length < max && final_length >= 4){
|
||||
if (dst[final_length-1] == 0){
|
||||
--final_length;
|
||||
}
|
||||
final_length -= 4;
|
||||
memmove(dst, dst+4, final_length);
|
||||
dst[final_length++] = '\\';
|
||||
memcpy(dst + final_length, front_str.str, front_str.size);
|
||||
final_length += front_str.size;
|
||||
dst[final_length] = 0;
|
||||
result = final_length;
|
||||
}
|
||||
|
||||
CloseHandle(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#else
|
||||
internal u32
|
||||
win32_canonical_ascii_name(char *src, u32 len, char *dst, u32 max){
|
||||
char *wrt = dst;
|
||||
char *wrt_stop = dst + max;
|
||||
char *src_stop = src + len;
|
||||
|
@ -890,9 +969,10 @@ win32_canonical_ascii_name(char *src, i32 len, char *dst, i32 max){
|
|||
wrt = dst;
|
||||
}
|
||||
|
||||
int32_t result = (int32_t)(wrt - dst);
|
||||
u32 result = (u32)(wrt - dst);
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
internal
|
||||
Sys_Get_Canonical_Sig(system_get_canonical){
|
||||
|
@ -903,13 +983,7 @@ Sys_Get_Canonical_Sig(system_get_canonical){
|
|||
internal
|
||||
Sys_Load_Handle_Sig(system_load_handle){
|
||||
b32 result = 0;
|
||||
HANDLE file = CreateFile(filename,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
HANDLE file = CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if (file != INVALID_HANDLE_VALUE){
|
||||
*(HANDLE*)handle_out = file;
|
||||
|
@ -941,11 +1015,7 @@ Sys_Load_File_Sig(system_load_file){
|
|||
|
||||
DWORD read_size = 0;
|
||||
|
||||
if (ReadFile(file,
|
||||
buffer,
|
||||
size,
|
||||
&read_size,
|
||||
0)){
|
||||
if (ReadFile(file, buffer, size, &read_size, 0)){
|
||||
if (read_size == size){
|
||||
result = 1;
|
||||
}
|
||||
|
@ -1521,7 +1591,7 @@ Win32LoadRenderCode(){
|
|||
// Helpers
|
||||
//
|
||||
|
||||
global u8 keycode_lookup_table[255];
|
||||
global Key_Code keycode_lookup_table[255];
|
||||
|
||||
internal void
|
||||
Win32KeycodeInit(){
|
||||
|
@ -1749,122 +1819,6 @@ Win32HighResolutionTime(){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32Foo(WPARAM wParam, LPARAM lParam){
|
||||
b8 previous_state = ((lParam & Bit_30)?(1):(0));
|
||||
b8 current_state = ((lParam & Bit_31)?(0):(1));
|
||||
|
||||
if (current_state){
|
||||
u8 key = keycode_lookup_table[(u8)wParam];
|
||||
|
||||
i32 *count = &win32vars.input_chunk.trans.key_data.count;
|
||||
Key_Event_Data *data = win32vars.input_chunk.trans.key_data.keys;
|
||||
b8 *control_keys = win32vars.input_chunk.pers.control_keys;
|
||||
i32 control_keys_size = sizeof(win32vars.input_chunk.pers.control_keys);
|
||||
|
||||
if (*count < KEY_INPUT_BUFFER_SIZE){
|
||||
if (!key){
|
||||
UINT vk = (UINT)wParam;
|
||||
UINT scan = (UINT)((lParam >> 16) & 0x7F);
|
||||
BYTE state[256];
|
||||
BYTE control_state = 0;
|
||||
WORD x1 = 0, x2 = 0, x = 0, junk_x;
|
||||
i32 result1 = 0, result2 = 0, result = 0;
|
||||
|
||||
GetKeyboardState(state);
|
||||
x1 = 0;
|
||||
result1 = ToAscii(vk, scan, state, &x1, 0);
|
||||
if (result1 < 0){
|
||||
ToAscii(vk, scan, state, &junk_x, 0);
|
||||
}
|
||||
result1 = (result1 == 1);
|
||||
if (!usable_ascii((char)x1)){
|
||||
result1 = 0;
|
||||
}
|
||||
|
||||
control_state = state[VK_CONTROL];
|
||||
state[VK_CONTROL] = 0;
|
||||
x2 = 0;
|
||||
result2 = ToAscii(vk, scan, state, &x2, 0);
|
||||
if (result2 < 0){
|
||||
ToAscii(vk, scan, state, &junk_x, 0);
|
||||
}
|
||||
result2 = (result2 == 1);
|
||||
if (!usable_ascii((char)x2)){
|
||||
result2 = 0;
|
||||
}
|
||||
|
||||
// TODO(allen): This is becoming a really major issue.
|
||||
// Apparently control + i outputs a '\t' which is VALID ascii
|
||||
// according to this system. So it reports the key as '\t'.
|
||||
// This wasn't an issue before because we were ignoring control
|
||||
// when computing character_no_caps_lock which is what is used
|
||||
// for commands. But that is incorrect for some keyboard layouts
|
||||
// where control+alt is used to signal AltGr for important keys.
|
||||
if (result1 && result2){
|
||||
char c1 = char_to_upper((char)x1);
|
||||
char cParam = char_to_upper((char)wParam);
|
||||
|
||||
if ((c1 == '\n' || c1 == '\r') && cParam != VK_RETURN){
|
||||
result1 = 0;
|
||||
}
|
||||
if (c1 == '\t' && cParam != VK_TAB){
|
||||
result1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (result1){
|
||||
x = x1;
|
||||
state[VK_CONTROL] = control_state;
|
||||
result = 1;
|
||||
}
|
||||
else if (result2){
|
||||
x = x2;
|
||||
result = 1;
|
||||
}
|
||||
|
||||
if (result == 1 && x < 128){
|
||||
key = (u8)x;
|
||||
if (key == '\r') key = '\n';
|
||||
data[*count].character = key;
|
||||
|
||||
state[VK_CAPITAL] = 0;
|
||||
x = 0;
|
||||
result = ToAscii(vk, scan, state, &x, 0);
|
||||
if (result < 0){
|
||||
ToAscii(vk, scan, state, &junk_x, 0);
|
||||
}
|
||||
result = (result == 1);
|
||||
if (!usable_ascii((char)x)){
|
||||
result = 0;
|
||||
}
|
||||
|
||||
if (result){
|
||||
key = (u8)x;
|
||||
if (key == '\r') key = '\n';
|
||||
data[*count].character_no_caps_lock = key;
|
||||
data[*count].keycode = key;
|
||||
}
|
||||
}
|
||||
if (result != 1 || x >= 128){
|
||||
data[*count].character = 0;
|
||||
data[*count].character_no_caps_lock = 0;
|
||||
data[*count].keycode = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
data[*count].character = 0;
|
||||
data[*count].character_no_caps_lock = 0;
|
||||
data[*count].keycode = key;
|
||||
}
|
||||
memcpy(data[*count].modifiers, control_keys, control_keys_size);
|
||||
data[*count].modifiers[MDFR_HOLD_INDEX] = previous_state;
|
||||
++(*count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal LRESULT
|
||||
Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
||||
LRESULT result = 0;
|
||||
|
@ -1928,7 +1882,7 @@ Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
|||
b8 current_state = ((lParam & Bit_31)?(0):(1));
|
||||
|
||||
if (current_state){
|
||||
u8 key = keycode_lookup_table[(u8)wParam];
|
||||
Key_Code key = keycode_lookup_table[(u8)wParam];
|
||||
|
||||
if (key != 0){
|
||||
i32 *count = &win32vars.input_chunk.trans.key_data.count;
|
||||
|
@ -1952,16 +1906,19 @@ Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
|||
|
||||
case WM_CHAR: case WM_SYSCHAR: case WM_UNICHAR:
|
||||
{
|
||||
u8 character = wParam & 0x7F;
|
||||
u16 character = (u16)wParam;
|
||||
|
||||
if (character == '\r'){
|
||||
character = '\n';
|
||||
}
|
||||
else if ((character < 32 && character != '\t') || character == 127){
|
||||
else if (character == '\t'){
|
||||
character = '\t';
|
||||
}
|
||||
else if (character < 32 || character == 127){
|
||||
break;
|
||||
}
|
||||
|
||||
u8 character_no_caps_lock = character;
|
||||
u16 character_no_caps_lock = character;
|
||||
|
||||
i32 *count = &win32vars.input_chunk.trans.key_data.count;
|
||||
Key_Event_Data *data = win32vars.input_chunk.trans.key_data.keys;
|
||||
|
@ -1972,7 +1929,7 @@ Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
|||
GetKeyboardState(state);
|
||||
if (state[VK_CAPITAL]){
|
||||
if (character_no_caps_lock >= 'a' && character_no_caps_lock <= 'z'){
|
||||
character_no_caps_lock += (u8)('A' - 'a');
|
||||
character_no_caps_lock -= (u8)('a' - 'A');
|
||||
}
|
||||
else if (character_no_caps_lock >= 'A' && character_no_caps_lock <= 'Z'){
|
||||
character_no_caps_lock += (u8)('a' - 'A');
|
||||
|
@ -1986,7 +1943,6 @@ Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
|||
memcpy(data[*count].modifiers, control_keys, control_keys_size);
|
||||
++(*count);
|
||||
|
||||
//result = DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
win32vars.got_useful_event = 1;
|
||||
}break;
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
// portable FT rendering.
|
||||
|
||||
internal b32
|
||||
win32_ft_font_load(Partition *part, Render_Font *rf, char *name,
|
||||
i32 pt_size, i32 tab_width, b32 use_hinting){
|
||||
win32_ft_font_load(Partition *part, Render_Font *rf, char *name, i32 pt_size, i32 tab_width, b32 use_hinting){
|
||||
|
||||
b32 result = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue