From 64a2a75300a8598e28128ecfeb542b7420130d01 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 17 Feb 2017 17:03:19 -0500 Subject: [PATCH] fixed issue with expansion binding built in command maps --- 4coder_API/types.h | 22 ++---- 4coder_helper/4coder_bind_helper.h | 4 +- 4ed.cpp | 25 +++---- 4ed_app_models.h | 4 +- 4ed_command.cpp | 105 ++++++++++++++++------------- 4ed_file_view.cpp | 14 ++-- 4ed_gui.cpp | 4 +- 4ed_math.h | 19 ++++++ 4ed_utf8_conversions.h | 45 +++++++++++++ linux_4ed.cpp | 30 +-------- meta/4ed_metagen.cpp | 2 +- 11 files changed, 152 insertions(+), 122 deletions(-) create mode 100644 4ed_utf8_conversions.h diff --git a/4coder_API/types.h b/4coder_API/types.h index 169f97b1..adfe80e0 100644 --- a/4coder_API/types.h +++ b/4coder_API/types.h @@ -342,7 +342,7 @@ ENUM(int32_t, View_Split_Position){ }; /* 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; +TYPEDEF uint32_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{ @@ -355,7 +355,7 @@ STRUCT Key_Event_Data{ /* DOC(This field is like the field character, except that the state of caps lock is ignored in the translation.) */ Key_Code character_no_caps_lock; - /* DOC(This field is an array indicating the state of modifiers at the time of the key press. The array is indexed using the values of Key_Modifier. A 1 indicates that the corresponding modifier was held, and a 0 indicates that it was not held.) + /* DOC(This field is an array indicating the state of modifiers at the time of the key press. The array is indexed using the values of Key_Modifier. 1 indicates that the corresponding modifier was held, and a 0 indicates that it was not held.) DOC_SEE(Key_Modifier) */ @@ -826,23 +826,11 @@ STRUCT Binding_Unit{ Binding_Unit_Type type; UNION{ STRUCT{ int32_t total_size; int32_t user_map_count; int32_t error; } header; - STRUCT{ int32_t mapid; int32_t replace; int32_t bind_count; } map_begin; STRUCT{ int32_t mapid; } map_inherit; - STRUCT{ - int16_t code; - uint8_t modifiers; - int32_t command_id; - } binding; - STRUCT{ - int16_t code; - uint8_t modifiers; - Custom_Command_Function *func; - } callback; - STRUCT{ - int32_t hook_id; - void *func; - } hook; + STRUCT{ Key_Code code; uint8_t modifiers; int32_t command_id; } binding; + STRUCT{ Key_Code code; uint8_t modifiers; Custom_Command_Function *func; } callback; + STRUCT{ int32_t hook_id; void *func; } hook; }; }; diff --git a/4coder_helper/4coder_bind_helper.h b/4coder_helper/4coder_bind_helper.h index 71976b0d..3232008e 100644 --- a/4coder_helper/4coder_bind_helper.h +++ b/4coder_helper/4coder_bind_helper.h @@ -86,7 +86,7 @@ end_map(Bind_Helper *helper){ } inline void -bind(Bind_Helper *helper, uint16_t code, uint8_t modifiers, int32_t cmdid){ +bind(Bind_Helper *helper, Key_Code 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, uint16_t code, uint8_t modifiers, int32_t cmdid){ } inline void -bind(Bind_Helper *helper, uint16_t code, uint8_t modifiers, Custom_Command_Function *func){ +bind(Bind_Helper *helper, Key_Code 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; diff --git a/4ed.cpp b/4ed.cpp index 7a9192f5..89af34d2 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -164,6 +164,7 @@ struct App_Vars{ Available_Input available_input; }; +global_const App_Vars null_app_vars = {0}; typedef enum Coroutine_Type{ Co_View, @@ -1112,18 +1113,12 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, } } -inline App_Vars -app_vars_zero(){ - App_Vars vars={0}; - return(vars); -} - internal App_Vars* app_setup_memory(System_Functions *system, Application_Memory *memory){ Partition _partition = make_part(memory->vars_memory, memory->vars_memory_size); App_Vars *vars = push_struct(&_partition, App_Vars); - Assert(vars); - *vars = app_vars_zero(); + Assert(vars != 0); + *vars = null_app_vars; vars->models.mem.part = _partition; #if defined(USE_DEBUG_MEMORY) @@ -1261,21 +1256,17 @@ App_Init_Sig(app_init){ b32 did_file = false; if (wanted_size <= models->app_links.memory_size){ Command_Map *map_ptr = 0; - Binding_Unit *unit, *end; - i32 user_map_count; - unit = (Binding_Unit*)models->app_links.memory; + Binding_Unit *unit = (Binding_Unit*)models->app_links.memory; if (unit->type == unit_header && unit->header.error == 0){ - end = unit + unit->header.total_size; + Binding_Unit *end = unit + unit->header.total_size; - user_map_count = unit->header.user_map_count; + i32 user_map_count = unit->header.user_map_count; - models->map_id_table = push_array( - &models->mem.part, i32, user_map_count); + models->map_id_table = push_array(&models->mem.part, i32, user_map_count); memset(models->map_id_table, -1, user_map_count*sizeof(i32)); - models->user_maps = push_array( - &models->mem.part, Command_Map, user_map_count); + models->user_maps = push_array(&models->mem.part, Command_Map, user_map_count); models->user_map_count = user_map_count; diff --git a/4ed_app_models.h b/4ed_app_models.h index 32730f8b..d63fe79f 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -94,8 +94,8 @@ struct Models{ Debug_Data debug; - u16 user_up_key; - u16 user_down_key; + Key_Code user_up_key; + Key_Code user_down_key; }; // BOTTOM diff --git a/4ed_command.cpp b/4ed_command.cpp index c7a8283f..a4a38ad3 100644 --- a/4ed_command.cpp +++ b/4ed_command.cpp @@ -20,7 +20,7 @@ struct Command_Binding{ Custom_Command_Function *custom; u64 custom_id; }; - i64 hash; + u64 hash; }; static Command_Binding null_command_binding = {0}; @@ -28,103 +28,110 @@ struct Command_Map{ Command_Map *parent; Command_Binding vanilla_keyboard_default; Command_Binding *commands; - i32 count, max; + u32 count, max; }; +#define COMMAND_HASH_EMPTY 0 +#define COMMAND_HASH_ERASED max_u64 + internal void command_null(Command_Data *command); -internal i64 -map_hash(u16 event_code, u8 modifiers){ - i64 result = (event_code << 8) | modifiers; - return result; +internal u64 +map_hash(Key_Code event_code, u8 modifiers){ + u64 result = (event_code << 8) | modifiers; + return(result); } internal b32 -map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0, b32 override_original = true){ +map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0, b32 override_original = true){ b32 result = false; Assert(map->count * 8 < map->max * 7); - Command_Binding bind; - bind.function = function; - bind.custom = custom; - bind.hash = map_hash(event_code, modifiers); + u64 hash = map_hash(event_code, modifiers); - i32 max = map->max; - i32 index = bind.hash % max; - Command_Binding entry; - while ((entry = map->commands[index]).function && entry.hash != -1){ - if (entry.hash == bind.hash){ - result = 1; + u32 max = map->max; + u32 index = hash % max; + Command_Binding entry = map->commands[index]; + while (entry.function != 0 && entry.hash != COMMAND_HASH_ERASED){ + if (entry.hash == hash){ + result = true; break; } index = (index + 1) % max; + entry = map->commands[index]; } + if (override_original || !result){ + Command_Binding bind; + bind.function = function; + bind.custom = custom; + bind.hash = hash; map->commands[index] = bind; ++map->count; } + return(result); } inline b32 -map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, u64 custom_id, b32 override_original = true){ - return (map_add(map, event_code, modifiers, function, (Custom_Command_Function*)custom_id), override_original); +map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function function, u64 custom_id, b32 override_original = true){ + return (map_add(map, event_code, modifiers, function, (Custom_Command_Function*)custom_id, override_original)); } internal b32 -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; - Command_Binding entry; - while ((entry = map->commands[index]).function){ +map_find_entry(Command_Map *map, Key_Code event_code, u8 modifiers, u32 *index_out){ + u64 hash = map_hash(event_code, modifiers); + u32 max = map->max; + u32 index = hash % max; + b32 result = false; + Command_Binding entry = map->commands[index]; + while (entry.function != 0){ if (entry.hash == hash){ *index_out = index; - return 1; + result = true; + break; } index = (index + 1) % max; + entry = map->commands[index]; } - return 0; + return(result); } internal b32 -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); +map_find(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Binding *bind_out){ + u32 index = 0; + b32 result = map_find_entry(map, event_code, modifiers, &index); if (result){ *bind_out = map->commands[index]; } - return result; + return(result); } internal b32 -map_drop(Command_Map *map, u16 event_code, u8 modifiers){ - b32 result; - i32 index; - result = map_find_entry(map, event_code, modifiers, &index); +map_drop(Command_Map *map, Key_Code event_code, u8 modifiers){ + u32 index = 0; + b32 result = map_find_entry(map, event_code, modifiers, &index); if (result){ map->commands[index].function = 0; - map->commands[index].hash = -1; + map->commands[index].hash = COMMAND_HASH_ERASED; } - return result; + return(result); } internal void map_clear(Command_Map *commands){ - i32 max = commands->max; + u32 max = commands->max; memset(commands->commands, 0, max*sizeof(*commands->commands)); commands->vanilla_keyboard_default = null_command_binding; commands->count = 0; } internal void -map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){ +map_init(Command_Map *commands, Partition *part, u32 max, Command_Map *parent){ if (commands->commands == 0){ - max = ((max < 6)?(6):(max)); + max = clamp_bottom((u32)6, max); commands->parent = parent; commands->commands = push_array(part, Command_Binding, max); commands->max = max; - map_clear(commands); } } @@ -148,7 +155,7 @@ map_extract(Command_Map *map, Key_Event_Data key){ if (ctrl) command |= MDFR_CTRL; if (alt) command |= MDFR_ALT; - u16 code = key.character_no_caps_lock; + Key_Code code = key.character_no_caps_lock; if (code == 0){ code = key.keycode; map_find(map, code, command, &bind); @@ -168,8 +175,8 @@ map_extract(Command_Map *map, Key_Event_Data key){ internal Command_Binding map_extract_recursive(Command_Map *map, Key_Event_Data key){ - Command_Binding cmd_bind = {}; - Command_Map *visited_maps[16] = {}; + Command_Binding cmd_bind = {0}; + Command_Map *visited_maps[16] = {0}; i32 visited_top = 0; while (map){ @@ -185,9 +192,13 @@ map_extract_recursive(Command_Map *map, Key_Event_Data key){ } } } - else map = 0; + else{ + map = 0; + } + } + else{ + map = 0; } - else map = 0; } return(cmd_bind); diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index fabea16e..9329aba6 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -79,7 +79,7 @@ get_map(Models *models, i32 mapid){ } internal void -map_set_count(Models *models, i32 mapid, i32 count){ +map_set_count(Models *models, i32 mapid, u32 count){ Command_Map *map = get_or_add_map(models, mapid); Assert(map->commands == 0); map->count = count; @@ -88,18 +88,18 @@ map_set_count(Models *models, i32 mapid, i32 count){ } } -internal i32 +internal u32 map_get_count(Models *models, i32 mapid){ Command_Map *map = get_or_add_map(models, mapid); - i32 count = map->count; + u32 count = map->count; Assert(map->commands == 0); return(count); } -internal i32 +internal u32 map_get_max_count(Models *models, i32 mapid){ Command_Map *map = get_or_add_map(models, mapid); - i32 count = map->max; + u32 count = map->max; return(count); } @@ -4951,8 +4951,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su GUI_id scroll_context = {0}; scroll_context.id[1] = VUI_Interactive + ((u64)view->interaction << 32); - i16 user_up_key = models->user_up_key; - i16 user_down_key = models->user_down_key; + Key_Code user_up_key = models->user_up_key; + Key_Code user_down_key = models->user_down_key; switch (view->interaction){ case IInt_Sys_File_List: diff --git a/4ed_gui.cpp b/4ed_gui.cpp index 8e9764f4..15719c2c 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -1254,7 +1254,7 @@ gui_do_jump(GUI_Target *target, GUI_View_Jump jump, GUI_Scroll_Vars vars){ } internal void -gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, i16 user_up_key, i16 user_down_key){ +gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, Key_Code user_up_key, Key_Code user_down_key){ if (update->has_adjustment){ *list_i = update->adjustment_value; @@ -1270,7 +1270,7 @@ gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect b32 indirectly_activate = 0; for (i32 j = 0; j < keys->count; ++j){ - i16 key = keys->keys[j].keycode; + Key_Code key = keys->keys[j].keycode; if (key == user_up_key){ --*list_i; diff --git a/4ed_math.h b/4ed_math.h index 468972be..129ae6a7 100644 --- a/4ed_math.h +++ b/4ed_math.h @@ -469,6 +469,25 @@ clamp(i32 a, i32 n, i32 z){ return (n); } +inline u32 +clamp_bottom(u32 a, u32 n){ + if (n < a) n = a; + return (n); +} + +inline u32 +clamp_top(u32 n, u32 z){ + if (n > z) n = z; + return (n); +} + +inline u32 +clamp(u32 a, u32 n, u32 z){ + if (n < a) n = a; + else if (n > z) n = z; + return (n); +} + /* * Color */ diff --git a/4ed_utf8_conversions.h b/4ed_utf8_conversions.h new file mode 100644 index 00000000..2026b2b8 --- /dev/null +++ b/4ed_utf8_conversions.h @@ -0,0 +1,45 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 17.02.2017 + * + * File for reading and writing utf8. + * + */ + +// TOP + +#if !defined(FED_UTF8_CONVERSION_H) +#define FED_UTF8_CONVERSION_H + +internal u32 +utf8_to_u32_unchecked(u8 *buffer){ + u32 result = 0; + + if (buffer[0] <= 0x7F){ + result = (u32)buffer[0]; + } + else if (buffer[0] <= 0xE0){ + result = ((u32)((buffer[0])&0x1F)) << 6; + result |= ((u32)((buffer[1])&0x3F)); + } + else if (buffer[0] <= 0xF0){ + result = ((u32)((buffer[0])&0x0F)) << 12; + result |= ((u32)((buffer[1])&0x3F)) << 6; + result |= ((u32)((buffer[2])&0x3F)); + } + else{ + result = ((u32)((buffer[0])&0x07)) << 18; + result |= ((u32)((buffer[1])&0x3F)) << 12; + result |= ((u32)((buffer[2])&0x3F)) << 6; + result |= ((u32)((buffer[3])&0x3F)); + } + + return(result); +} + + +#endif + +// BOTTOM + diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 19ea6d9f..1df86b2c 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -37,6 +37,8 @@ #include "4ed_rendering.h" #include "4ed.h" +#include "4ed_utf8_conversions.h" + #include #include #include @@ -2598,32 +2600,6 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight) return true; } -internal u16 -utf8_to_u16_unchecked(u8 *buffer){ - u16 result = 0; - - if (buffer[0] <= 0x7F){ - result = (u16)buffer[0]; - } - else if (buffer[0] <= 0xE0){ - result = ((u16)((buffer[0])&0x1F)) << 6; - result |= ((u16)((buffer[1])&0x3F)); - } - else if (buffer[0] <= 0xF0){ - result = ((u16)((buffer[0])&0x0F)) << 12; - result |= ((u16)((buffer[1])&0x3F)) << 6; - result |= ((u16)((buffer[2])&0x3F)); - } - else{ - result = ((u16)((buffer[0])&0x07)) << 18; - result |= ((u16)((buffer[1])&0x3F)) << 12; - result |= ((u16)((buffer[2])&0x3F)) << 6; - result |= ((u16)((buffer[3])&0x3F)); - } - - return(result); -} - internal void LinuxHandleX11Events(void) { @@ -2677,7 +2653,7 @@ LinuxHandleX11Events(void) fputs("FIXME: XBufferOverflow from LookupString.\n", stderr); } - u16 key = utf8_to_u16_unchecked(buff); + u16 key = utf8_to_u32_unchecked(buff); u16 key_no_caps = key; if(mods[MDFR_CAPS_INDEX] && status == XLookupBoth && Event.xkey.keycode){ diff --git a/meta/4ed_metagen.cpp b/meta/4ed_metagen.cpp index a9b3a43f..4fac97b0 100644 --- a/meta/4ed_metagen.cpp +++ b/meta/4ed_metagen.cpp @@ -94,7 +94,7 @@ generate_keycode_enum(){ append_sc(&out, "static char*\n" - "global_key_name(int32_t key_code, int32_t *size){\n" + "global_key_name(uint32_t key_code, int32_t *size){\n" "char *result = 0;\n" "switch(key_code){\n");