new linux shit

This commit is contained in:
Allen Webster 2016-02-01 00:03:42 -05:00
parent 951b992b2f
commit 8195020bfd
16 changed files with 4959 additions and 4688 deletions

View File

@ -1,318 +1,317 @@
/* /*
* Example use of customization API * Example use of customization API
*/ */
#define FCPP_STRING_IMPLEMENTATION #define FCPP_STRING_IMPLEMENTATION
#include "4coder_string.h" #include "4coder_string.h"
#include "4coder_custom.h" #include "4coder_custom.h"
#include "4coder_helper.h" #include "4coder_helper.h"
#ifndef literal #ifndef literal
#define literal(s) s, (sizeof(s)-1) #define literal(s) s, (sizeof(s)-1)
#endif #endif
// NOTE(allen|a3.1): All of your custom ids should be >= mapid_user_custom. // NOTE(allen|a3.3): All of your custom ids should be enumerated
// I recommend enumerating your own map ids as shown here. // as shown here, they may start at 0, and you can only have
enum My_Maps{ // 2^24 of them so don't be wasteful!
my_code_map = mapid_user_custom, enum My_Maps{
my_html_map my_code_map,
}; my_html_map
};
HOOK_SIG(my_start){
exec_command(cmd_context, cmdid_open_panel_vsplit); HOOK_SIG(my_start){
exec_command(cmd_context, cmdid_change_active_panel); exec_command(cmd_context, cmdid_open_panel_vsplit);
} exec_command(cmd_context, cmdid_change_active_panel);
}
char *get_extension(const char *filename, int len, int *extension_len){
char *c = (char*)(filename + len - 1); char *get_extension(const char *filename, int len, int *extension_len){
char *end = c; char *c = (char*)(filename + len - 1);
while (*c != '.' && c > filename) --c; char *end = c;
*extension_len = (int)(end - c); while (*c != '.' && c > filename) --c;
return c+1; *extension_len = (int)(end - c);
} return c+1;
}
bool str_match(const char *a, int len_a, const char *b, int len_b){
bool result = 0; bool str_match(const char *a, int len_a, const char *b, int len_b){
if (len_a == len_b){ bool result = 0;
char *end = (char*)(a + len_a); if (len_a == len_b){
while (a < end && *a == *b){ char *end = (char*)(a + len_a);
++a; ++b; while (a < end && *a == *b){
} ++a; ++b;
if (a == end) result = 1; }
} if (a == end) result = 1;
return result; }
} return result;
}
HOOK_SIG(my_file_settings){
Buffer_Summary buffer = get_active_buffer(cmd_context); HOOK_SIG(my_file_settings){
Buffer_Summary buffer = get_active_buffer(cmd_context);
int treat_as_code = 0;
int treat_as_code = 0;
// NOTE(allen|a3.1): This checks buffer.file_name just in case get_active_buffer returns back
// a null buffer (where every member is 0). // NOTE(allen|a3.1): This checks buffer.file_name just in case get_active_buffer returns back
if (buffer.file_name && buffer.size < (16 << 20)){ // a null buffer (where every member is 0).
int extension_len; if (buffer.file_name && buffer.size < (16 << 20)){
char *extension = get_extension(buffer.file_name, buffer.file_name_len, &extension_len); int extension_len;
if (str_match(extension, extension_len, literal("cpp"))) treat_as_code = 1; char *extension = get_extension(buffer.file_name, buffer.file_name_len, &extension_len);
else if (str_match(extension, extension_len, literal("h"))) treat_as_code = 1; if (str_match(extension, extension_len, literal("cpp"))) treat_as_code = 1;
else if (str_match(extension, extension_len, literal("c"))) treat_as_code = 1; else if (str_match(extension, extension_len, literal("h"))) treat_as_code = 1;
else if (str_match(extension, extension_len, literal("hpp"))) treat_as_code = 1; else if (str_match(extension, extension_len, literal("c"))) treat_as_code = 1;
} else if (str_match(extension, extension_len, literal("hpp"))) treat_as_code = 1;
}
push_parameter(app, cmd_context, par_lex_as_cpp_file, treat_as_code);
push_parameter(app, cmd_context, par_wrap_lines, !treat_as_code); push_parameter(app, cmd_context, par_lex_as_cpp_file, treat_as_code);
push_parameter(app, cmd_context, par_key_mapid, (treat_as_code)?(my_code_map):(mapid_file)); push_parameter(app, cmd_context, par_wrap_lines, !treat_as_code);
exec_command(cmd_context, cmdid_set_settings); push_parameter(app, cmd_context, par_key_mapid, (treat_as_code)?(my_code_map):(mapid_file));
} exec_command(cmd_context, cmdid_set_settings);
}
CUSTOM_COMMAND_SIG(open_in_other){
exec_command(cmd_context, cmdid_change_active_panel); CUSTOM_COMMAND_SIG(open_in_other){
exec_command(cmd_context, cmdid_interactive_open); exec_command(cmd_context, cmdid_change_active_panel);
} exec_command(cmd_context, cmdid_interactive_open);
}
CUSTOM_COMMAND_SIG(open_my_files){
// NOTE(allen|a3.1): The command cmdid_interactive_open can now open CUSTOM_COMMAND_SIG(open_my_files){
// a file specified on the parameter stack. If the file does not // NOTE(allen|a3.1): The command cmdid_interactive_open can now open
// exist cmdid_interactive_open behaves as usual. // a file specified on the parameter stack. If the file does not exist
push_parameter(app, cmd_context, par_name, literal("w:/4ed/data/test/basic.cpp")); // cmdid_interactive_open behaves as usual.
exec_command(cmd_context, cmdid_interactive_open); push_parameter(app, cmd_context, par_name, literal("w:/4ed/data/test/basic.cpp"));
exec_command(cmd_context, cmdid_interactive_open);
exec_command(cmd_context, cmdid_change_active_panel);
exec_command(cmd_context, cmdid_change_active_panel);
char my_file[256];
int my_file_len; char my_file[256];
int my_file_len;
my_file_len = sizeof("w:/4ed/data/test/basic.txt") - 1;
for (int i = 0; i < my_file_len; ++i){ my_file_len = sizeof("w:/4ed/data/test/basic.txt") - 1;
my_file[i] = ("w:/4ed/data/test/basic.txt")[i]; for (int i = 0; i < my_file_len; ++i){
} my_file[i] = ("w:/4ed/data/test/basic.txt")[i];
}
// NOTE(allen|a3.1): null terminators are not needed for strings.
push_parameter(app, cmd_context, par_name, my_file, my_file_len); // NOTE(allen|a3.1): null terminators are not needed for strings.
exec_command(cmd_context, cmdid_interactive_open); push_parameter(app, cmd_context, par_name, my_file, my_file_len);
exec_command(cmd_context, cmdid_interactive_open);
exec_command(cmd_context, cmdid_change_active_panel);
} exec_command(cmd_context, cmdid_change_active_panel);
}
CUSTOM_COMMAND_SIG(build_at_launch_location){
// NOTE(allen|a3.3): An example of calling build by setting all CUSTOM_COMMAND_SIG(build_at_launch_location){
// parameters directly. This only works if build.bat can be called // NOTE(allen|a3.3): An example of calling build by setting all
// from the starting directory // parameters directly. This only works if build.bat can be called
push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 1); // from the starting directory
push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*")); push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 1);
push_parameter(app, cmd_context, par_cli_path, literal(".")); push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*"));
push_parameter(app, cmd_context, par_cli_command, literal("build")); push_parameter(app, cmd_context, par_cli_path, literal("."));
exec_command(cmd_context, cmdid_build); push_parameter(app, cmd_context, par_cli_command, literal("build"));
} exec_command(cmd_context, cmdid_build);
}
CUSTOM_COMMAND_SIG(build_search){
// NOTE(allen|a3.3): An example of traversing the filesystem through parent CUSTOM_COMMAND_SIG(build_search){
// directories looking for a file, in this case a batch file to execute. // NOTE(allen|a3.3): An example of traversing the filesystem through parent
// // directories looking for a file, in this case a batch file to execute.
// //
// Step 1: push_directory returns a String containing the current "hot" directory //
// (whatever directory you most recently visited in the 4coder file browsing interface) // Step 1: push_directory returns a String containing the current "hot" directory
// // (whatever directory you most recently visited in the 4coder file browsing interface)
// Step 2: app->directory_has_file queries the file system to see if "build.bat" exists //
// If it does exist several parameters are pushed: // Step 2: app->directory_has_file queries the file system to see if "build.bat" exists
// - par_cli_overlap_with_conflict: whether to launch this process if an existing process // If it does exist several parameters are pushed:
// is already being used for output on the same buffer // - par_cli_overlap_with_conflict: whether to launch this process if an existing process
// // is already being used for output on the same buffer
// - par_target_buffer_name: the name of the buffer to fill with the output from the process //
// // - par_target_buffer_name: the name of the buffer to fill with the output from the process
// - par_cli_path: sets the path from which the command is executed //
// // - par_cli_path: sets the path from which the command is executed
// - par_cli_command: sets the actual command to be executed, this can be almost any command //
// that you could execute through a command line interface // - par_cli_command: sets the actual command to be executed, this can be almost any command
// // that you could execute through a command line interface
// //
// To set par_cli_path: push_parameter makes a copy of the dir string on the stack //
// because the string allocated by push_directory is going to change again // To set par_cli_path: push_parameter makes a copy of the dir string on the stack
// To set par_cli_command: app->push_parameter does not make a copy of the dir because // because the string allocated by push_directory is going to change again
// dir isn't going to change again. // To set par_cli_command: app->push_parameter does not make a copy of the dir because
// // dir isn't going to change again.
// Step 3: If the batch file did not exist try to move to the parent directory using //
// app->directory_cd. The cd function can also be used to navigate to subdirectories. // Step 3: If the batch file did not exist try to move to the parent directory using
// It returns true if it can actually move in the specified direction, and false otherwise. // app->directory_cd. The cd function can also be used to navigate to subdirectories.
// It returns true if it can actually move in the specified direction, and false otherwise.
int keep_going = 1;
String dir = push_directory(app, cmd_context); int keep_going = 1;
while (keep_going){ String dir = push_directory(app, cmd_context);
if (app->directory_has_file(dir, "build.bat")){ while (keep_going){
push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 0); if (app->directory_has_file(dir, "build.bat")){
push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*")); push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 0);
push_parameter(app, cmd_context, par_cli_path, dir.str, dir.size); push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*"));
push_parameter(app, cmd_context, par_cli_path, dir.str, dir.size);
if (append(&dir, "build")){
app->push_parameter(cmd_context, if (append(&dir, "build")){
dynamic_int(par_cli_command), app->push_parameter(cmd_context,
dynamic_string(dir.str, dir.size)); dynamic_int(par_cli_command),
exec_command(cmd_context, cmdid_build); dynamic_string(dir.str, dir.size));
} exec_command(cmd_context, cmdid_build);
else{ }
clear_parameters(cmd_context); else{
} clear_parameters(cmd_context);
}
return;
} return;
}
if (app->directory_cd(&dir, "..") == 0){
keep_going = 0; if (app->directory_cd(&dir, "..") == 0){
} keep_going = 0;
} }
}
// TODO(allen): feedback message - couldn't find build.bat
} // TODO(allen): feedback message - couldn't find build.bat
}
CUSTOM_COMMAND_SIG(write_and_auto_tab){
exec_command(cmd_context, cmdid_write_character); CUSTOM_COMMAND_SIG(write_and_auto_tab){
exec_command(cmd_context, cmdid_auto_tab_line_at_cursor); exec_command(cmd_context, cmdid_write_character);
} exec_command(cmd_context, cmdid_auto_tab_line_at_cursor);
}
extern "C" GET_BINDING_DATA(get_bindings){
Bind_Helper context_actual = begin_bind_helper(data, size); extern "C" GET_BINDING_DATA(get_bindings){
Bind_Helper *context = &context_actual; Bind_Helper context_actual = begin_bind_helper(data, size);
Bind_Helper *context = &context_actual;
// NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are
// global and once set they always apply, regardless of what map is active. // NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are
set_hook(context, hook_start, my_start); // global and once set they always apply, regardless of what map is active.
set_hook(context, hook_open_file, my_file_settings); set_hook(context, hook_start, my_start);
set_hook(context, hook_open_file, my_file_settings);
begin_map(context, mapid_global);
begin_map(context, mapid_global);
bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit);
bind(context, '-', MDFR_CTRL, cmdid_open_panel_hsplit); bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit);
bind(context, 'P', MDFR_CTRL, cmdid_close_panel); bind(context, '-', MDFR_CTRL, cmdid_open_panel_hsplit);
bind(context, 'n', MDFR_CTRL, cmdid_interactive_new); bind(context, 'P', MDFR_CTRL, cmdid_close_panel);
bind(context, 'o', MDFR_CTRL, cmdid_interactive_open); bind(context, 'n', MDFR_CTRL, cmdid_interactive_new);
bind(context, ',', MDFR_CTRL, cmdid_change_active_panel); bind(context, 'o', MDFR_CTRL, cmdid_interactive_open);
bind(context, 'k', MDFR_CTRL, cmdid_interactive_kill_buffer); bind(context, ',', MDFR_CTRL, cmdid_change_active_panel);
bind(context, 'i', MDFR_CTRL, cmdid_interactive_switch_buffer); bind(context, 'k', MDFR_CTRL, cmdid_interactive_kill_buffer);
bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker); bind(context, 'i', MDFR_CTRL, cmdid_interactive_switch_buffer);
bind(context, 'x', MDFR_ALT, cmdid_open_menu); bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker);
bind_me(context, 'o', MDFR_ALT, open_in_other); bind(context, 'x', MDFR_ALT, cmdid_open_menu);
bind_me(context, 'o', MDFR_ALT, open_in_other);
// NOTE(allen): These callbacks may not actually be useful to you, but
// go look at them and see what they do. // NOTE(allen): These callbacks may not actually be useful to you, but
bind_me(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files); // go look at them and see what they do.
bind_me(context, 'M', MDFR_ALT, build_at_launch_location); bind_me(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
bind_me(context, 'm', MDFR_ALT, build_search); bind_me(context, 'M', MDFR_ALT, build_at_launch_location);
bind_me(context, 'm', MDFR_ALT, build_search);
end_map(context);
end_map(context);
begin_map(context, my_code_map);
begin_map(context, my_code_map);
// NOTE(allen|a3.1): Set this map (my_code_map == mapid_user_custom) to
// inherit from mapid_file. When searching if a key is bound // NOTE(allen|a3.1): Set this map (my_code_map == mapid_user_custom) to
// in this map, if it is not found here it will then search mapid_file. // inherit from mapid_file. When searching if a key is bound
// // in this map, if it is not found here it will then search mapid_file.
// If this is not set, it defaults to mapid_global. //
inherit_map(context, mapid_file); // If this is not set, it defaults to mapid_global.
inherit_map(context, mapid_file);
// NOTE(allen|a3.1): Children can override parent's bindings.
bind(context, codes->right, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_right); // NOTE(allen|a3.1): Children can override parent's bindings.
bind(context, codes->left, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_left); bind(context, codes->right, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_right);
bind(context, codes->left, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_left);
// NOTE(allen|a3.2): Specific keys can override vanilla keys,
// and write character writes whichever character corresponds // NOTE(allen|a3.2): Specific keys can override vanilla keys,
// to the key that triggered the command. // and write character writes whichever character corresponds
bind_me(context, '\n', MDFR_NONE, write_and_auto_tab); // to the key that triggered the command.
bind_me(context, '}', MDFR_NONE, write_and_auto_tab); bind_me(context, '\n', MDFR_NONE, write_and_auto_tab);
bind_me(context, ')', MDFR_NONE, write_and_auto_tab); bind_me(context, '}', MDFR_NONE, write_and_auto_tab);
bind_me(context, ']', MDFR_NONE, write_and_auto_tab); bind_me(context, ')', MDFR_NONE, write_and_auto_tab);
bind_me(context, ';', MDFR_NONE, write_and_auto_tab); bind_me(context, ']', MDFR_NONE, write_and_auto_tab);
bind_me(context, ';', MDFR_NONE, write_and_auto_tab);
#if 0
bind(context, '\t', MDFR_NONE, cmdid_auto_tab_line_at_cursor); bind(context, '\t', MDFR_NONE, cmdid_auto_tab_line_at_cursor);
bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range); bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
bind(context, '\t', MDFR_CTRL | MDFR_SHIFT, cmdid_write_character); bind(context, '\t', MDFR_CTRL | MDFR_SHIFT, cmdid_write_character);
#endif
end_map(context);
end_map(context);
begin_map(context, mapid_file);
begin_map(context, mapid_file);
// NOTE(allen|a3.1): Binding this essentially binds all key combos that
// NOTE(allen|a3.1): Binding this essentially binds all key combos that // would normally insert a character into a buffer.
// would normally insert a character into a buffer. // Or apply this rule (which always works): if the code for the key
// Or apply this rule (which always works): if the code for the key // is not in the codes struct, it is a vanilla key.
// is not in the codes struct, it is a vanilla key. // It is possible to override this binding for individual keys.
// It is possible to override this binding for individual keys. bind_vanilla_keys(context, cmdid_write_character);
bind_vanilla_keys(context, cmdid_write_character);
bind(context, codes->left, MDFR_NONE, cmdid_move_left);
bind(context, codes->left, MDFR_NONE, cmdid_move_left); bind(context, codes->right, MDFR_NONE, cmdid_move_right);
bind(context, codes->right, MDFR_NONE, cmdid_move_right); bind(context, codes->del, MDFR_NONE, cmdid_delete);
bind(context, codes->del, MDFR_NONE, cmdid_delete); bind(context, codes->back, MDFR_NONE, cmdid_backspace);
bind(context, codes->back, MDFR_NONE, cmdid_backspace); bind(context, codes->up, MDFR_NONE, cmdid_move_up);
bind(context, codes->up, MDFR_NONE, cmdid_move_up); bind(context, codes->down, MDFR_NONE, cmdid_move_down);
bind(context, codes->down, MDFR_NONE, cmdid_move_down); bind(context, codes->end, MDFR_NONE, cmdid_seek_end_of_line);
bind(context, codes->end, MDFR_NONE, cmdid_seek_end_of_line); bind(context, codes->home, MDFR_NONE, cmdid_seek_beginning_of_line);
bind(context, codes->home, MDFR_NONE, cmdid_seek_beginning_of_line); bind(context, codes->page_up, MDFR_NONE, cmdid_page_up);
bind(context, codes->page_up, MDFR_NONE, cmdid_page_up); bind(context, codes->page_down, MDFR_NONE, cmdid_page_down);
bind(context, codes->page_down, MDFR_NONE, cmdid_page_down);
bind(context, codes->right, MDFR_CTRL, cmdid_seek_whitespace_right);
bind(context, codes->right, MDFR_CTRL, cmdid_seek_whitespace_right); bind(context, codes->left, MDFR_CTRL, cmdid_seek_whitespace_left);
bind(context, codes->left, MDFR_CTRL, cmdid_seek_whitespace_left); bind(context, codes->up, MDFR_CTRL, cmdid_seek_whitespace_up);
bind(context, codes->up, MDFR_CTRL, cmdid_seek_whitespace_up); bind(context, codes->down, MDFR_CTRL, cmdid_seek_whitespace_down);
bind(context, codes->down, MDFR_CTRL, cmdid_seek_whitespace_down);
bind(context, ' ', MDFR_CTRL, cmdid_set_mark);
bind(context, ' ', MDFR_CTRL, cmdid_set_mark); bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap);
bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap); bind(context, 'c', MDFR_CTRL, cmdid_copy);
bind(context, 'c', MDFR_CTRL, cmdid_copy); bind(context, 'x', MDFR_CTRL, cmdid_cut);
bind(context, 'x', MDFR_CTRL, cmdid_cut); bind(context, 'v', MDFR_CTRL, cmdid_paste);
bind(context, 'v', MDFR_CTRL, cmdid_paste); bind(context, 'V', MDFR_CTRL, cmdid_paste_next);
bind(context, 'V', MDFR_CTRL, cmdid_paste_next); bind(context, 'Z', MDFR_CTRL, cmdid_timeline_scrub);
bind(context, 'Z', MDFR_CTRL, cmdid_timeline_scrub); bind(context, 'z', MDFR_CTRL, cmdid_undo);
bind(context, 'z', MDFR_CTRL, cmdid_undo); bind(context, 'y', MDFR_CTRL, cmdid_redo);
bind(context, 'y', MDFR_CTRL, cmdid_redo); bind(context, codes->left, MDFR_ALT, cmdid_increase_rewind_speed);
bind(context, codes->left, MDFR_ALT, cmdid_increase_rewind_speed); bind(context, codes->right, MDFR_ALT, cmdid_increase_fastforward_speed);
bind(context, codes->right, MDFR_ALT, cmdid_increase_fastforward_speed); bind(context, codes->down, MDFR_ALT, cmdid_stop_rewind_fastforward);
bind(context, codes->down, MDFR_ALT, cmdid_stop_rewind_fastforward); bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward); bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward); bind(context, 'd', MDFR_CTRL, cmdid_delete_range);
bind(context, 'd', MDFR_CTRL, cmdid_delete_range); bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap);
bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap); bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode);
bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode); bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase);
bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase); bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase);
bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase); bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace);
bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines);
bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); // NOTE(allen|a3.2): These now only set the mode of the file for writing to disk
// NOTE(allen|a3.2): These now only set the mode of the file for writing to disk // they do no longer effect the internal representation.
// they do no longer effect the internal representation. bind(context, '1', MDFR_CTRL, cmdid_eol_dosify);
bind(context, '1', MDFR_CTRL, cmdid_eol_dosify); bind(context, '!', MDFR_CTRL, cmdid_eol_nixify);
bind(context, '!', MDFR_CTRL, cmdid_eol_nixify);
bind(context, 'f', MDFR_CTRL, cmdid_search);
bind(context, 'f', MDFR_CTRL, cmdid_search); bind(context, 'r', MDFR_CTRL, cmdid_rsearch);
bind(context, 'r', MDFR_CTRL, cmdid_rsearch); bind(context, 'g', MDFR_CTRL, cmdid_goto_line);
bind(context, 'g', MDFR_CTRL, cmdid_goto_line);
bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer);
bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); bind(context, 'O', MDFR_CTRL, cmdid_reopen);
bind(context, 'O', MDFR_CTRL, cmdid_reopen); bind(context, 'w', MDFR_CTRL, cmdid_interactive_save_as);
bind(context, 'w', MDFR_CTRL, cmdid_interactive_save_as); bind(context, 's', MDFR_CTRL, cmdid_save);
bind(context, 's', MDFR_CTRL, cmdid_save);
end_map(context);
end_map(context); end_bind_helper(context);
end_bind_helper(context);
return context->write_total;
return context->write_total; }
}
inline void
inline void strset_(char *dst, char *src){
strset_(char *dst, char *src){ do{
do{ *dst++ = *src++;
*dst++ = *src++; }while (*src);
}while (*src); }
}
#define strset(d,s) if (sizeof(s) <= sizeof(d)) strset_(d,s)
#define strset(d,s) if (sizeof(s) <= sizeof(d)) strset_(d,s)
extern "C" SET_EXTRA_FONT_SIG(set_extra_font){
extern "C" SET_EXTRA_FONT_SIG(set_extra_font){ strset(font_out->file_name, "liberation-mono.ttf");
strset(font_out->file_name, "liberation-mono.ttf"); strset(font_out->font_name, "BIG");
strset(font_out->font_name, "BIG"); font_out->size = 25;
font_out->size = 25; }
}

View File

@ -1,337 +1,336 @@
#define MDFR_NONE 0 #define MDFR_NONE 0
#define MDFR_CTRL 1 #define MDFR_CTRL 1
#define MDFR_ALT 2 #define MDFR_ALT 2
#define MDFR_SHIFT 4 #define MDFR_SHIFT 4
#define MDFR_NUMPAD 8 #define MDFR_NUMPAD 8
typedef unsigned char Code; typedef unsigned char Code;
struct Key_Codes{ struct Key_Codes{
Code back; Code back;
Code up; Code up;
Code down; Code down;
Code left; Code left;
Code right; Code right;
Code del; Code del;
Code insert; Code insert;
Code home; Code home;
Code end; Code end;
Code page_up; Code page_up;
Code page_down; Code page_down;
Code esc; Code esc;
#if 0 // TODO(allen): Get these working sometime #if 0 // TODO(allen): Get these working sometime
union{ union{
struct{ struct{
Code f1; Code f1;
Code f2; Code f2;
Code f3; Code f3;
Code f4; Code f4;
Code f5; Code f5;
Code f6; Code f6;
Code f7; Code f7;
Code f8; Code f8;
Code f9; Code f9;
Code f10; Code f10;
Code f11; Code f11;
Code f12; Code f12;
Code f13; Code f13;
Code f14; Code f14;
Code f15; Code f15;
Code f16; Code f16;
}; };
Code f[16]; Code f[16];
}; };
#endif #endif
}; };
enum Command_ID{ enum Command_ID{
cmdid_null, cmdid_null,
cmdid_write_character, cmdid_write_character,
cmdid_seek_whitespace_right, cmdid_seek_whitespace_right,
cmdid_seek_whitespace_left, cmdid_seek_whitespace_left,
cmdid_seek_whitespace_up, cmdid_seek_whitespace_up,
cmdid_seek_whitespace_down, cmdid_seek_whitespace_down,
cmdid_seek_token_left, cmdid_seek_token_left,
cmdid_seek_token_right, cmdid_seek_token_right,
cmdid_seek_white_or_token_left, cmdid_seek_white_or_token_left,
cmdid_seek_white_or_token_right, cmdid_seek_white_or_token_right,
cmdid_seek_alphanumeric_left, cmdid_seek_alphanumeric_left,
cmdid_seek_alphanumeric_right, cmdid_seek_alphanumeric_right,
cmdid_seek_alphanumeric_or_camel_left, cmdid_seek_alphanumeric_or_camel_left,
cmdid_seek_alphanumeric_or_camel_right, cmdid_seek_alphanumeric_or_camel_right,
cmdid_search, cmdid_search,
cmdid_rsearch, cmdid_rsearch,
cmdid_goto_line, cmdid_goto_line,
cmdid_set_mark, cmdid_set_mark,
cmdid_copy, cmdid_copy,
cmdid_cut, cmdid_cut,
cmdid_paste, cmdid_paste,
cmdid_paste_next, cmdid_paste_next,
cmdid_delete_range, cmdid_delete_range,
cmdid_timeline_scrub, cmdid_timeline_scrub,
cmdid_undo, cmdid_undo,
cmdid_redo, cmdid_redo,
cmdid_increase_rewind_speed, cmdid_increase_rewind_speed,
cmdid_increase_fastforward_speed, cmdid_increase_fastforward_speed,
cmdid_stop_rewind_fastforward, cmdid_stop_rewind_fastforward,
cmdid_history_backward, cmdid_history_backward,
cmdid_history_forward, cmdid_history_forward,
cmdid_interactive_new, cmdid_interactive_new,
cmdid_interactive_open, cmdid_interactive_open,
cmdid_reopen, cmdid_reopen,
cmdid_save, cmdid_save,
cmdid_interactive_save_as, cmdid_interactive_save_as,
cmdid_change_active_panel, cmdid_change_active_panel,
cmdid_interactive_switch_buffer, cmdid_interactive_switch_buffer,
cmdid_interactive_kill_buffer, cmdid_interactive_kill_buffer,
cmdid_kill_buffer, cmdid_kill_buffer,
cmdid_toggle_line_wrap, cmdid_toggle_line_wrap,
cmdid_toggle_endline_mode, cmdid_toggle_endline_mode,
cmdid_to_uppercase, cmdid_to_uppercase,
cmdid_to_lowercase, cmdid_to_lowercase,
cmdid_toggle_show_whitespace, cmdid_toggle_show_whitespace,
cmdid_clean_all_lines, cmdid_clean_all_lines,
cmdid_eol_dosify, cmdid_eol_dosify,
cmdid_eol_nixify, cmdid_eol_nixify,
cmdid_auto_tab, cmdid_auto_tab,
cmdid_auto_tab_range, cmdid_auto_tab_range,
cmdid_auto_tab_line_at_cursor, cmdid_auto_tab_line_at_cursor,
cmdid_auto_tab_whole_file, cmdid_auto_tab_whole_file,
cmdid_open_panel_vsplit, cmdid_open_panel_vsplit,
cmdid_open_panel_hsplit, cmdid_open_panel_hsplit,
cmdid_close_panel, cmdid_close_panel,
cmdid_move_left, cmdid_move_left,
cmdid_move_right, cmdid_move_right,
cmdid_delete, cmdid_delete,
cmdid_backspace, cmdid_backspace,
cmdid_move_up, cmdid_move_up,
cmdid_move_down, cmdid_move_down,
cmdid_seek_end_of_line, cmdid_seek_end_of_line,
cmdid_seek_beginning_of_line, cmdid_seek_beginning_of_line,
cmdid_page_up, cmdid_page_up,
cmdid_page_down, cmdid_page_down,
cmdid_open_color_tweaker, cmdid_open_color_tweaker,
cmdid_close_minor_view, cmdid_close_minor_view,
cmdid_cursor_mark_swap, cmdid_cursor_mark_swap,
cmdid_open_menu, cmdid_open_menu,
cmdid_set_settings, cmdid_set_settings,
cmdid_build, cmdid_build,
// //
cmdid_count cmdid_count
}; };
enum Param_ID{ enum Param_ID{
par_name, par_name,
par_lex_as_cpp_file, par_lex_as_cpp_file,
par_wrap_lines, par_wrap_lines,
par_key_mapid, par_key_mapid,
par_target_buffer_name, par_target_buffer_name,
par_cli_path, par_cli_path,
par_cli_command, par_cli_command,
par_cli_overlap_with_conflict, par_cli_overlap_with_conflict,
par_cli_always_bind_to_view, par_cli_always_bind_to_view,
// never below this // never below this
par_type_count par_type_count
}; };
enum Hook_ID{ enum Hook_ID{
hook_start, hook_start,
hook_open_file, hook_open_file,
// never below this // never below this
hook_type_count hook_type_count
}; };
enum Dynamic_Type{ enum Dynamic_Type{
dynamic_type_int, dynamic_type_int,
dynamic_type_string, dynamic_type_string,
// never below this // never below this
dynamic_type_count dynamic_type_count
}; };
struct Dynamic{ struct Dynamic{
int type; int type;
union{ union{
struct{ struct{
int str_len; int str_len;
char *str_value; char *str_value;
}; };
int int_value; int int_value;
}; };
}; };
inline Dynamic inline Dynamic
dynamic_int(int x){ dynamic_int(int x){
Dynamic result; Dynamic result;
result.type = dynamic_type_int; result.type = dynamic_type_int;
result.int_value = x; result.int_value = x;
return result; return result;
} }
inline Dynamic inline Dynamic
dynamic_string(const char *string, int len){ dynamic_string(const char *string, int len){
Dynamic result; Dynamic result;
result.type = dynamic_type_string; result.type = dynamic_type_string;
result.str_len = len; result.str_len = len;
result.str_value = (char*)(string); result.str_value = (char*)(string);
return result; return result;
} }
inline int inline int
dynamic_to_int(Dynamic *dynamic){ dynamic_to_int(Dynamic *dynamic){
int result = 0; int result = 0;
if (dynamic->type == dynamic_type_int){ if (dynamic->type == dynamic_type_int){
result = dynamic->int_value; result = dynamic->int_value;
} }
return result; return result;
} }
inline char* inline char*
dynamic_to_string(Dynamic *dynamic, int *len){ dynamic_to_string(Dynamic *dynamic, int *len){
char *result = 0; char *result = 0;
if (dynamic->type == dynamic_type_string){ if (dynamic->type == dynamic_type_string){
result = dynamic->str_value; result = dynamic->str_value;
*len = dynamic->str_len; *len = dynamic->str_len;
} }
return result; return result;
} }
inline int inline int
dynamic_to_bool(Dynamic *dynamic){ dynamic_to_bool(Dynamic *dynamic){
int result = 0; int result = 0;
if (dynamic->type == dynamic_type_int){ if (dynamic->type == dynamic_type_int){
result = (dynamic->int_value != 0); result = (dynamic->int_value != 0);
} }
else{ else{
result = 1; result = 1;
} }
return result; return result;
} }
struct Extra_Font{ struct Extra_Font{
char file_name[256]; char file_name[256];
char font_name[24]; char font_name[24];
int size; int size;
}; };
struct Buffer_Summary{ struct Buffer_Summary{
// NOTE(allen): None of these members nor any of the data pointed to // NOTE(allen): None of these members nor any of the data pointed to
// by these members should be modified. // by these members should be modified.
int file_id; int file_id;
int size; int size;
int file_name_len; int file_name_len;
int buffer_name_len; int buffer_name_len;
const char *file_name; const char *file_name;
const char *buffer_name; const char *buffer_name;
int file_cursor_pos; int file_cursor_pos;
int is_lexed; int is_lexed;
int map_id; int map_id;
}; };
#ifndef FRED_STRING_STRUCT #ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT #define FRED_STRING_STRUCT
struct String{ struct String{
char *str; char *str;
int size; int size;
int memory_size; int memory_size;
}; };
#endif #endif
#define GET_BINDING_DATA(name) int name(void *data, int size, Key_Codes *codes) #define GET_BINDING_DATA(name) int name(void *data, int size, Key_Codes *codes)
#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out) #define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out)
#define CUSTOM_COMMAND_SIG(name) void name(void *cmd_context, struct Application_Links *app) #define CUSTOM_COMMAND_SIG(name) void name(void *cmd_context, struct Application_Links *app)
#define HOOK_SIG(name) void name(void *cmd_context, struct Application_Links *app) #define HOOK_SIG(name) void name(void *cmd_context, struct Application_Links *app)
extern "C"{ extern "C"{
typedef CUSTOM_COMMAND_SIG(Custom_Command_Function); typedef CUSTOM_COMMAND_SIG(Custom_Command_Function);
typedef GET_BINDING_DATA(Get_Binding_Data_Function); typedef GET_BINDING_DATA(Get_Binding_Data_Function);
typedef SET_EXTRA_FONT_SIG(Set_Extra_Font_Function); typedef SET_EXTRA_FONT_SIG(Set_Extra_Font_Function);
typedef HOOK_SIG(Hook_Function); typedef HOOK_SIG(Hook_Function);
} }
#define PUSH_PARAMETER_SIG(name) void name(void *cmd_context, Dynamic param, Dynamic value) #define PUSH_PARAMETER_SIG(name) void name(void *cmd_context, Dynamic param, Dynamic value)
#define PUSH_MEMORY_SIG(name) char* name(void *cmd_context, int len) #define PUSH_MEMORY_SIG(name) char* name(void *cmd_context, int len)
#define EXECUTE_COMMAND_SIG(name) void name(void *cmd_context, int command_id) #define EXECUTE_COMMAND_SIG(name) void name(void *cmd_context, int command_id)
#define CLEAR_PARAMETERS_SIG(name) void name(void *cmd_context) #define CLEAR_PARAMETERS_SIG(name) void name(void *cmd_context)
#define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(void *cmd_context) #define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(void *cmd_context)
#define DIRECTORY_GET_HOT_SIG(name) int name(void *cmd_context, char *buffer, int max) #define DIRECTORY_GET_HOT_SIG(name) int name(void *cmd_context, char *buffer, int max)
#define DIRECTORY_HAS_FILE_SIG(name) int name(String dir, char *filename) #define DIRECTORY_HAS_FILE_SIG(name) int name(String dir, char *filename)
#define DIRECTORY_CD_SIG(name) int name(String *dir, char *rel_path) #define DIRECTORY_CD_SIG(name) int name(String *dir, char *rel_path)
extern "C"{ extern "C"{
typedef EXECUTE_COMMAND_SIG(Exec_Command_Function); typedef EXECUTE_COMMAND_SIG(Exec_Command_Function);
typedef PUSH_PARAMETER_SIG(Push_Parameter_Function); typedef PUSH_PARAMETER_SIG(Push_Parameter_Function);
typedef PUSH_MEMORY_SIG(Push_Memory_Function); typedef PUSH_MEMORY_SIG(Push_Memory_Function);
typedef CLEAR_PARAMETERS_SIG(Clear_Parameters_Function); typedef CLEAR_PARAMETERS_SIG(Clear_Parameters_Function);
typedef GET_ACTIVE_BUFFER_SIG(Get_Active_Buffer_Function); typedef GET_ACTIVE_BUFFER_SIG(Get_Active_Buffer_Function);
typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot); typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot);
typedef DIRECTORY_HAS_FILE_SIG(Directory_Has_File); typedef DIRECTORY_HAS_FILE_SIG(Directory_Has_File);
typedef DIRECTORY_CD_SIG(Directory_CD); typedef DIRECTORY_CD_SIG(Directory_CD);
} }
struct Application_Links{ struct Application_Links{
Exec_Command_Function *exec_command_keep_stack; Exec_Command_Function *exec_command_keep_stack;
Push_Parameter_Function *push_parameter; Push_Parameter_Function *push_parameter;
Push_Memory_Function *push_memory; Push_Memory_Function *push_memory;
Clear_Parameters_Function *clear_parameters; Clear_Parameters_Function *clear_parameters;
Get_Active_Buffer_Function *get_active_buffer; Get_Active_Buffer_Function *get_active_buffer;
Directory_Get_Hot *directory_get_hot; Directory_Get_Hot *directory_get_hot;
Directory_Has_File *directory_has_file; Directory_Has_File *directory_has_file;
Directory_CD *directory_cd; Directory_CD *directory_cd;
}; };
struct Custom_API{ struct Custom_API{
Get_Binding_Data_Function *get_bindings; Get_Binding_Data_Function *get_bindings;
Set_Extra_Font_Function *set_extra_font; };
};
// NOTE(allen): definitions for the buffer that communicates to 4ed.exe
// NOTE(allen): definitions for the buffer that communicates to 4ed.exe
enum Binding_Unit_Type{
enum Binding_Unit_Type{ unit_header,
unit_header, unit_map_begin,
unit_map_begin, unit_binding,
unit_binding, unit_callback,
unit_callback, unit_inherit,
unit_inherit, unit_hook
unit_hook };
};
enum Map_ID{
enum Map_ID{ mapid_global = (1 << 24),
mapid_global, mapid_file,
mapid_file, // NOTE(allen): mapid_nomap will remain empty even if you attempt to fill it
// NOTE(allen): mapid_nomap will remain empty even if you attempt to fill it // it is for setting a map's parent to nothing, in cases where you don't want
// it is for setting a map's parent to nothing // to inherit from global (which is the default).
mapid_nomap, mapid_nomap
mapid_user_custom = 100 };
};
struct Binding_Unit{
struct Binding_Unit{ Binding_Unit_Type type;
Binding_Unit_Type type; union{
union{ struct{ int total_size; int user_map_count; int error; } header;
struct{ int total_size; int user_map_count; int error; } header;
struct{ int mapid; int bind_count; } map_begin;
struct{ int mapid; int bind_count; } map_begin; struct{ int mapid; } map_inherit;
struct{ int mapid; } map_inherit; struct{
struct{ short code;
short code; unsigned char modifiers;
unsigned char modifiers; int command_id;
int command_id; } binding;
} binding; struct{
struct{ short code;
short code; unsigned char modifiers;
unsigned char modifiers; Custom_Command_Function *func;
Custom_Command_Function *func; } callback;
} callback; struct{
struct{ int hook_id;
int hook_id; Custom_Command_Function *func;
Custom_Command_Function *func; } hook;
} hook; };
}; };
};

View File

@ -1,252 +1,252 @@
/* /*
* Bind helper struct and functions * Bind helper struct and functions
*/ */
struct Bind_Helper{ struct Bind_Helper{
Binding_Unit *cursor, *start, *end; Binding_Unit *cursor, *start, *end;
Binding_Unit *header, *group; Binding_Unit *header, *group;
int write_total; int write_total;
int error; int error;
}; };
#define BH_ERR_NONE 0 #define BH_ERR_NONE 0
#define BH_ERR_MISSING_END 1 #define BH_ERR_MISSING_END 1
#define BH_ERR_MISSING_BEGIN 2 #define BH_ERR_MISSING_BEGIN 2
#define BH_ERR_OUT_OF_MEMORY 3 #define BH_ERR_OUT_OF_MEMORY 3
inline void inline void
copy(char *dest, const char *src, int len){ copy(char *dest, const char *src, int len){
for (int i = 0; i < len; ++i){ for (int i = 0; i < len; ++i){
*dest++ = *src++; *dest++ = *src++;
} }
} }
inline Binding_Unit* inline Binding_Unit*
write_unit(Bind_Helper *helper, Binding_Unit unit){ write_unit(Bind_Helper *helper, Binding_Unit unit){
Binding_Unit *p = 0; Binding_Unit *p = 0;
helper->write_total += sizeof(*p); helper->write_total += sizeof(*p);
if (helper->error == 0 && helper->cursor != helper->end){ if (helper->error == 0 && helper->cursor != helper->end){
p = helper->cursor++; p = helper->cursor++;
*p = unit; *p = unit;
} }
return p; return p;
} }
inline char* inline char*
write_inline_string(Bind_Helper *helper, char *value, int len){ write_inline_string(Bind_Helper *helper, char *value, int len){
char *dest = 0; char *dest = 0;
helper->write_total += len; helper->write_total += len;
if (helper->error == 0){ if (helper->error == 0){
dest = (char*)helper->cursor; dest = (char*)helper->cursor;
int cursor_advance = len + sizeof(*helper->cursor) - 1; int cursor_advance = len + sizeof(*helper->cursor) - 1;
cursor_advance /= sizeof(*helper->cursor); cursor_advance /= sizeof(*helper->cursor);
cursor_advance *= sizeof(*helper->cursor); cursor_advance *= sizeof(*helper->cursor);
helper->cursor += cursor_advance; helper->cursor += cursor_advance;
if (helper->cursor < helper->end){ if (helper->cursor < helper->end){
copy(dest, value, len); copy(dest, value, len);
} }
else{ else{
helper->error = BH_ERR_OUT_OF_MEMORY; helper->error = BH_ERR_OUT_OF_MEMORY;
} }
} }
return dest; return dest;
} }
inline Bind_Helper inline Bind_Helper
begin_bind_helper(void *data, int size){ begin_bind_helper(void *data, int size){
Bind_Helper result; Bind_Helper result;
result.header = 0; result.header = 0;
result.group = 0; result.group = 0;
result.write_total = 0; result.write_total = 0;
result.error = 0; result.error = 0;
result.cursor = (Binding_Unit*)data; result.cursor = (Binding_Unit*)data;
result.start = result.cursor; result.start = result.cursor;
result.end = result.start + size / sizeof(*result.cursor); result.end = result.start + size / sizeof(*result.cursor);
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_header; unit.type = unit_header;
unit.header.total_size = sizeof(*result.header); unit.header.total_size = sizeof(*result.header);
result.header = write_unit(&result, unit); result.header = write_unit(&result, unit);
result.header->header.user_map_count = 0; result.header->header.user_map_count = 0;
return result; return result;
} }
inline void inline void
begin_map(Bind_Helper *helper, int mapid){ begin_map(Bind_Helper *helper, int mapid){
if (helper->group != 0 && helper->error == 0) helper->error = BH_ERR_MISSING_END; if (helper->group != 0 && helper->error == 0) helper->error = BH_ERR_MISSING_END;
if (!helper->error && mapid >= mapid_user_custom) ++helper->header->header.user_map_count; if (!helper->error && mapid < mapid_global) ++helper->header->header.user_map_count;
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_map_begin; unit.type = unit_map_begin;
unit.map_begin.mapid = mapid; unit.map_begin.mapid = mapid;
helper->group = write_unit(helper, unit); helper->group = write_unit(helper, unit);
helper->group->map_begin.bind_count = 0; helper->group->map_begin.bind_count = 0;
} }
inline void inline void
end_map(Bind_Helper *helper){ end_map(Bind_Helper *helper){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
helper->group = 0; helper->group = 0;
} }
struct Bind_Target{ struct Bind_Target{
short code; short code;
unsigned char modifiers; unsigned char modifiers;
}; };
inline Bind_Target inline Bind_Target
tkey(short code, unsigned char modifiers){ tkey(short code, unsigned char modifiers){
Bind_Target target; Bind_Target target;
target.code = code; target.code = code;
target.modifiers = modifiers; target.modifiers = modifiers;
return target; return target;
} }
inline void inline void
bind(Bind_Helper *helper, Bind_Target target, int cmdid){ bind(Bind_Helper *helper, Bind_Target target, int cmdid){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
if (!helper->error) ++helper->group->map_begin.bind_count; if (!helper->error) ++helper->group->map_begin.bind_count;
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_binding; unit.type = unit_binding;
unit.binding.command_id = cmdid; unit.binding.command_id = cmdid;
unit.binding.code = target.code; unit.binding.code = target.code;
unit.binding.modifiers = target.modifiers; unit.binding.modifiers = target.modifiers;
write_unit(helper, unit); write_unit(helper, unit);
} }
inline void inline void
bind_me(Bind_Helper *helper, Bind_Target target, Custom_Command_Function *func){ bind_me(Bind_Helper *helper, Bind_Target target, Custom_Command_Function *func){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
if (!helper->error) ++helper->group->map_begin.bind_count; if (!helper->error) ++helper->group->map_begin.bind_count;
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_callback; unit.type = unit_callback;
unit.callback.func = func; unit.callback.func = func;
unit.callback.code = target.code; unit.callback.code = target.code;
unit.callback.modifiers = target.modifiers; unit.callback.modifiers = target.modifiers;
write_unit(helper, unit); write_unit(helper, unit);
} }
inline void inline void
bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){ bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){
Bind_Target target; Bind_Target target;
target = tkey(code, modifiers); target = tkey(code, modifiers);
bind(helper, target, cmdid); bind(helper, target, cmdid);
} }
inline void inline void
bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){ bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){
Bind_Target target; Bind_Target target;
target = tkey(code, modifiers); target = tkey(code, modifiers);
bind_me(helper, target, func); bind_me(helper, target, func);
} }
inline void inline void
bind_vanilla_keys(Bind_Helper *helper, int cmdid){ bind_vanilla_keys(Bind_Helper *helper, int cmdid){
bind(helper, 0, 0, cmdid); bind(helper, 0, 0, cmdid);
} }
inline void inline void
bind_me_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){ bind_me_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){
bind_me(helper, 0, 0, func); bind_me(helper, 0, 0, func);
} }
inline void inline void
bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int cmdid){ bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int cmdid){
bind(helper, 0, modifiers, cmdid); bind(helper, 0, modifiers, cmdid);
} }
inline void inline void
bind_me_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){ bind_me_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){
bind_me(helper, 0, modifiers, func); bind_me(helper, 0, modifiers, func);
} }
inline void inline void
inherit_map(Bind_Helper *helper, int mapid){ inherit_map(Bind_Helper *helper, int mapid){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
if (!helper->error && mapid >= mapid_user_custom) ++helper->header->header.user_map_count; if (!helper->error && mapid < mapid_global) ++helper->header->header.user_map_count;
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_inherit; unit.type = unit_inherit;
unit.map_inherit.mapid = mapid; unit.map_inherit.mapid = mapid;
write_unit(helper, unit); write_unit(helper, unit);
} }
inline void inline void
set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){ set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_hook; unit.type = unit_hook;
unit.hook.hook_id = hook_id; unit.hook.hook_id = hook_id;
unit.hook.func = func; unit.hook.func = func;
write_unit(helper, unit); write_unit(helper, unit);
} }
inline void inline void
end_bind_helper(Bind_Helper *helper){ end_bind_helper(Bind_Helper *helper){
if (helper->header){ if (helper->header){
helper->header->header.total_size = (int)(helper->cursor - helper->start); helper->header->header.total_size = (int)(helper->cursor - helper->start);
helper->header->header.error = helper->error; helper->header->header.error = helper->error;
} }
} }
// NOTE(allen): Useful functions and overloads on app links // NOTE(allen): Useful functions and overloads on app links
inline void inline void
push_parameter(Application_Links *app, void *cmd_context, int param, int value){ push_parameter(Application_Links *app, void *cmd_context, int param, int value){
app->push_parameter(cmd_context, dynamic_int(param), dynamic_int(value)); app->push_parameter(cmd_context, dynamic_int(param), dynamic_int(value));
} }
inline void inline void
push_parameter(Application_Links *app, void *cmd_context, int param, const char *value, int value_len){ push_parameter(Application_Links *app, void *cmd_context, int param, const char *value, int value_len){
char *value_copy = app->push_memory(cmd_context, value_len+1); char *value_copy = app->push_memory(cmd_context, value_len+1);
copy(value_copy, value, value_len); copy(value_copy, value, value_len);
value_copy[value_len] = 0; value_copy[value_len] = 0;
app->push_parameter(cmd_context, dynamic_int(param), dynamic_string(value_copy, value_len)); app->push_parameter(cmd_context, dynamic_int(param), dynamic_string(value_copy, value_len));
} }
inline void inline void
push_parameter(Application_Links *app, void *cmd_context, const char *param, int param_len, int value){ push_parameter(Application_Links *app, void *cmd_context, const char *param, int param_len, int value){
char *param_copy = app->push_memory(cmd_context, param_len+1); char *param_copy = app->push_memory(cmd_context, param_len+1);
copy(param_copy, param, param_len); copy(param_copy, param, param_len);
param_copy[param_len] = 0; param_copy[param_len] = 0;
app->push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_int(value)); app->push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_int(value));
} }
inline void inline void
push_parameter(Application_Links *app, void *cmd_context, const char *param, int param_len, const char *value, int value_len){ push_parameter(Application_Links *app, void *cmd_context, const char *param, int param_len, const char *value, int value_len){
char *param_copy = app->push_memory(cmd_context, param_len+1); char *param_copy = app->push_memory(cmd_context, param_len+1);
char *value_copy = app->push_memory(cmd_context, value_len+1); char *value_copy = app->push_memory(cmd_context, value_len+1);
copy(param_copy, param, param_len); copy(param_copy, param, param_len);
copy(value_copy, value, value_len); copy(value_copy, value, value_len);
value_copy[value_len] = 0; value_copy[value_len] = 0;
param_copy[param_len] = 0; param_copy[param_len] = 0;
app->push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_string(value_copy, value_len)); app->push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_string(value_copy, value_len));
} }
inline String inline String
push_directory(Application_Links *app, void *cmd_context){ push_directory(Application_Links *app, void *cmd_context){
String result; String result;
result.memory_size = 512; result.memory_size = 512;
result.str = app->push_memory(cmd_context, result.memory_size); result.str = app->push_memory(cmd_context, result.memory_size);
result.size = app->directory_get_hot(cmd_context, result.str, result.memory_size); result.size = app->directory_get_hot(cmd_context, result.str, result.memory_size);
return(result); return(result);
} }
#define dir_string(d) ((d).str), ((d).size) #define dir_string(d) ((d).str), ((d).size)
#define exec_command_keep_stack app->exec_command_keep_stack #define exec_command_keep_stack app->exec_command_keep_stack
#define clear_parameters app->clear_parameters #define clear_parameters app->clear_parameters
#define get_active_buffer app->get_active_buffer #define get_active_buffer app->get_active_buffer
#define exec_command(cmd_context, id) \ #define exec_command(cmd_context, id) \
exec_command_keep_stack(cmd_context, id); \ exec_command_keep_stack(cmd_context, id); \
clear_parameters(cmd_context) clear_parameters(cmd_context)

File diff suppressed because it is too large Load Diff

View File

@ -220,6 +220,7 @@ enum Cpp_Token_Type{
CPP_PP_UNKNOWN, CPP_PP_UNKNOWN,
CPP_TOKEN_DEFINED, CPP_TOKEN_DEFINED,
CPP_TOKEN_INCLUDE_FILE, CPP_TOKEN_INCLUDE_FILE,
CPP_TOKEN_ERROR_MESSAGE,
// NOTE(allen): used in the parser // NOTE(allen): used in the parser
CPP_TOKEN_EOF CPP_TOKEN_EOF
@ -256,6 +257,7 @@ enum Cpp_Preprocessor_State{
CPP_LEX_PP_BODY, CPP_LEX_PP_BODY,
CPP_LEX_PP_BODY_IF, CPP_LEX_PP_BODY_IF,
CPP_LEX_PP_NUMBER, CPP_LEX_PP_NUMBER,
CPP_LEX_PP_ERROR,
CPP_LEX_PP_JUNK, CPP_LEX_PP_JUNK,
// NEVER ADD BELOW THIS // NEVER ADD BELOW THIS
CPP_LEX_PP_COUNT CPP_LEX_PP_COUNT
@ -450,6 +452,7 @@ FCPP_GLOBAL String_And_Flag keyword_strings[] = {
{"long", CPP_TOKEN_KEY_MODIFIER}, {"long", CPP_TOKEN_KEY_MODIFIER},
{"short", CPP_TOKEN_KEY_MODIFIER}, {"short", CPP_TOKEN_KEY_MODIFIER},
{"unsigned", CPP_TOKEN_KEY_MODIFIER},
{"const", CPP_TOKEN_KEY_QUALIFIER}, {"const", CPP_TOKEN_KEY_QUALIFIER},
{"volatile", CPP_TOKEN_KEY_QUALIFIER}, {"volatile", CPP_TOKEN_KEY_QUALIFIER},
@ -766,7 +769,7 @@ cpp_read_junk_line(Cpp_File file, int pos){
--pos; --pos;
} }
result.pos = pos; result.pos = pos;
result.token.size = pos - result.token.start - 1; result.token.size = pos - result.token.start;
} }
return result; return result;
@ -1348,6 +1351,9 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
lex.pp_state = CPP_LEX_PP_NUMBER; lex.pp_state = CPP_LEX_PP_NUMBER;
break; break;
case CPP_PP_ERROR: case CPP_PP_ERROR:
lex.pp_state = CPP_LEX_PP_ERROR;
break;
case CPP_PP_UNKNOWN: case CPP_PP_UNKNOWN:
case CPP_PP_ELSE: case CPP_PP_ELSE:
case CPP_PP_ENDIF: case CPP_PP_ENDIF:
@ -1383,7 +1389,8 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
} }
else{ else{
if (lex.pp_state == CPP_LEX_PP_IDENTIFIER){ switch (lex.pp_state){
case CPP_LEX_PP_IDENTIFIER:
if (!char_is_alpha_numeric(current)){ if (!char_is_alpha_numeric(current)){
has_result = 0; has_result = 0;
lex.pp_state = CPP_LEX_PP_JUNK; lex.pp_state = CPP_LEX_PP_JUNK;
@ -1394,8 +1401,9 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
lex.pos = result.pos; lex.pos = result.pos;
lex.pp_state = CPP_LEX_PP_JUNK; lex.pp_state = CPP_LEX_PP_JUNK;
} }
} break;
else if (lex.pp_state == CPP_LEX_PP_MACRO_IDENTIFIER){
case CPP_LEX_PP_MACRO_IDENTIFIER:
if (!char_is_alpha_numeric(current)){ if (!char_is_alpha_numeric(current)){
has_result = 0; has_result = 0;
lex.pp_state = CPP_LEX_PP_JUNK; lex.pp_state = CPP_LEX_PP_JUNK;
@ -1406,9 +1414,9 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
lex.pos = result.pos; lex.pos = result.pos;
lex.pp_state = CPP_LEX_PP_BODY; lex.pp_state = CPP_LEX_PP_BODY;
} }
} break;
else if (lex.pp_state == CPP_LEX_PP_INCLUDE){ case CPP_LEX_PP_INCLUDE:
if (current != '"' && current != '<'){ if (current != '"' && current != '<'){
has_result = 0; has_result = 0;
lex.pp_state = CPP_LEX_PP_JUNK; lex.pp_state = CPP_LEX_PP_JUNK;
@ -1418,8 +1426,9 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
lex.pos = result.pos; lex.pos = result.pos;
lex.pp_state = CPP_LEX_PP_JUNK; lex.pp_state = CPP_LEX_PP_JUNK;
} }
} break;
else if (lex.pp_state == CPP_LEX_PP_BODY){
case CPP_LEX_PP_BODY:
if (current == '#'){ if (current == '#'){
result = cpp_read_pp_operator(file, lex.pos); result = cpp_read_pp_operator(file, lex.pos);
} }
@ -1428,8 +1437,9 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
} }
lex.pos = result.pos; lex.pos = result.pos;
result.token.flags |= CPP_TFLAG_PP_BODY; result.token.flags |= CPP_TFLAG_PP_BODY;
} break;
else if (lex.pp_state == CPP_LEX_PP_BODY_IF){
case CPP_LEX_PP_BODY_IF:
if (current == '#'){ if (current == '#'){
result = cpp_read_pp_operator(file, lex.pos); result = cpp_read_pp_operator(file, lex.pos);
} }
@ -1438,9 +1448,9 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
} }
lex.pos = result.pos; lex.pos = result.pos;
result.token.flags |= CPP_TFLAG_PP_BODY; result.token.flags |= CPP_TFLAG_PP_BODY;
} break;
else if (lex.pp_state == CPP_LEX_PP_NUMBER){ case CPP_LEX_PP_NUMBER:
if (!char_is_numeric(current)){ if (!char_is_numeric(current)){
has_result = 0; has_result = 0;
lex.pp_state = CPP_LEX_PP_JUNK; lex.pp_state = CPP_LEX_PP_JUNK;
@ -1451,8 +1461,17 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
result.token.flags |= CPP_TFLAG_PP_BODY; result.token.flags |= CPP_TFLAG_PP_BODY;
lex.pp_state = CPP_LEX_PP_INCLUDE; lex.pp_state = CPP_LEX_PP_INCLUDE;
} }
} break;
else{
case CPP_LEX_PP_ERROR:
result = cpp_read_junk_line(file, lex.pos);
lex.pos = result.pos;
result.token.type = CPP_TOKEN_ERROR_MESSAGE;
result.token.flags |= CPP_TFLAG_PP_BODY;
break;
default:
{
bool took_comment = 0; bool took_comment = 0;
if (current == '/' && lex.pos + 1 < file.size){ if (current == '/' && lex.pos + 1 < file.size){
if (file.data[lex.pos + 1] == '/'){ if (file.data[lex.pos + 1] == '/'){
@ -1472,6 +1491,8 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){
lex.pos = result.pos; lex.pos = result.pos;
result.token.flags |= CPP_TFLAG_PP_BODY; result.token.flags |= CPP_TFLAG_PP_BODY;
} }
}break;
} }
} }
} }

209
4ed.cpp
View File

@ -122,7 +122,7 @@ app_get_map_index(App_Vars *vars, i32 mapid){
internal Command_Map* internal Command_Map*
app_get_map(App_Vars *vars, i32 mapid){ app_get_map(App_Vars *vars, i32 mapid){
Command_Map *map = 0; Command_Map *map = 0;
if (mapid >= mapid_user_custom) map = vars->user_maps + mapid - mapid_user_custom; if (mapid < mapid_global) map = vars->user_maps + mapid;
else if (mapid == mapid_global) map = &vars->map_top; else if (mapid == mapid_global) map = &vars->map_top;
else if (mapid == mapid_file) map = &vars->map_file; else if (mapid == mapid_file) map = &vars->map_file;
return map; return map;
@ -1065,10 +1065,12 @@ COMMAND_DECL(kill_buffer){
COMMAND_DECL(toggle_line_wrap){ COMMAND_DECL(toggle_line_wrap){
ProfileMomentFunction(); ProfileMomentFunction();
REQ_FILE_VIEW(view); REQ_FILE_VIEW(view);
REQ_FILE(file, view);
Relative_Scrolling scrolling = view_get_relative_scrolling(view); Relative_Scrolling scrolling = view_get_relative_scrolling(view);
if (view->unwrapped_lines){ if (view->unwrapped_lines){
view->unwrapped_lines = 0; view->unwrapped_lines = 0;
file->settings.unwrapped_lines = 0;
view->target_x = 0; view->target_x = 0;
view->cursor = view->cursor =
view_compute_cursor_from_pos(view, view->cursor.pos); view_compute_cursor_from_pos(view, view->cursor.pos);
@ -1076,6 +1078,7 @@ COMMAND_DECL(toggle_line_wrap){
} }
else{ else{
view->unwrapped_lines = 1; view->unwrapped_lines = 1;
file->settings.unwrapped_lines = 1;
view->cursor = view->cursor =
view_compute_cursor_from_pos(view, view->cursor.pos); view_compute_cursor_from_pos(view, view->cursor.pos);
view->preferred_x = view->cursor.unwrapped_x; view->preferred_x = view->cursor.unwrapped_x;
@ -1660,6 +1663,8 @@ COMMAND_DECL(set_settings){
if (view->unwrapped_lines){ if (view->unwrapped_lines){
if (v){ if (v){
view->unwrapped_lines = 0; view->unwrapped_lines = 0;
file->settings.unwrapped_lines = 0;
if (!file->state.is_loading){ if (!file->state.is_loading){
Relative_Scrolling scrolling = view_get_relative_scrolling(view); Relative_Scrolling scrolling = view_get_relative_scrolling(view);
view->target_x = 0; view->target_x = 0;
@ -1672,6 +1677,7 @@ COMMAND_DECL(set_settings){
else{ else{
if (!v){ if (!v){
view->unwrapped_lines = 1; view->unwrapped_lines = 1;
file->settings.unwrapped_lines = 1;
if (!file->state.is_loading){ if (!file->state.is_loading){
Relative_Scrolling scrolling = view_get_relative_scrolling(view); Relative_Scrolling scrolling = view_get_relative_scrolling(view);
@ -1688,7 +1694,7 @@ COMMAND_DECL(set_settings){
int v = dynamic_to_int(&param->param.value); int v = dynamic_to_int(&param->param.value);
if (v == mapid_global) file->settings.base_map_id = mapid_global; if (v == mapid_global) file->settings.base_map_id = mapid_global;
else if (v == mapid_file) file->settings.base_map_id = mapid_file; else if (v == mapid_file) file->settings.base_map_id = mapid_file;
else if (v >= mapid_user_custom){ else if (v < mapid_global){
int index = app_get_map_index(vars, v); int index = app_get_map_index(vars, v);
if (index < vars->user_map_count) file->settings.base_map_id = v; if (index < vars->user_map_count) file->settings.base_map_id = v;
else file->settings.base_map_id = mapid_file; else file->settings.base_map_id = mapid_file;
@ -2047,16 +2053,23 @@ setup_debug_commands(Command_Map *commands, Partition *part, Key_Codes *codes, C
internal void internal void
setup_ui_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Command_Map *parent){ setup_ui_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Command_Map *parent){
map_init(commands, part, 12, parent); map_init(commands, part, 32, parent);
commands->vanilla_keyboard_default.function = command_null; commands->vanilla_keyboard_default.function = command_null;
map_add(commands, codes->left, MDFR_NONE, command_null); // TODO(allen): This is hacky, when the new UI stuff happens, let's fix it, and by that
map_add(commands, codes->right, MDFR_NONE, command_null); // I mean actually fix it, don't just say you fixed it with something stupid again.
map_add(commands, codes->up, MDFR_NONE, command_null); u8 mdfr;
map_add(commands, codes->down, MDFR_NONE, command_null); u8 mdfr_array[] = {MDFR_NONE, MDFR_SHIFT, MDFR_CTRL, MDFR_SHIFT | MDFR_CTRL};
map_add(commands, codes->back, MDFR_NONE, command_null); for (i32 i = 0; i < 4; ++i){
map_add(commands, codes->esc, MDFR_NONE, command_close_minor_view); mdfr = mdfr_array[i];
map_add(commands, codes->left, mdfr, command_null);
map_add(commands, codes->right, mdfr, command_null);
map_add(commands, codes->up, mdfr, command_null);
map_add(commands, codes->down, mdfr, command_null);
map_add(commands, codes->back, mdfr, command_null);
map_add(commands, codes->esc, mdfr, command_close_minor_view);
}
} }
internal void internal void
@ -2492,86 +2505,134 @@ HOOK_SIG(default_open_file_hook){
} }
enum Command_Line_Action{ enum Command_Line_Action{
CLAct_Nothing,
CLAct_Ignore, CLAct_Ignore,
CLAct_UserFile, CLAct_UserFile,
CLAct_CustomDLL, CLAct_CustomDLL,
CLAct_InitialFilePosition, CLAct_InitialFilePosition,
CLAct_WindowSize, CLAct_WindowSize,
CLAct_WindowMaximize,
CLAct_WindowPosition, CLAct_WindowPosition,
CLAct_Count CLAct_Count
}; };
void void
init_command_line_settings(App_Settings *settings, App_Plat_Settings *plat_settings, init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
Command_Line_Parameters clparams){ Command_Line_Parameters clparams){
char *arg; char *arg;
Command_Line_Action action; Command_Line_Action action = CLAct_Nothing;
i32 i,index; i32 i,index;
b32 strict = 0; b32 strict = 0;
settings->init_files_max = ArrayCount(settings->init_files); settings->init_files_max = ArrayCount(settings->init_files);
for (i = 1; i < clparams.argc; ++i){ for (i = 1; i <= clparams.argc; ++i){
arg = clparams.argv[i]; if (i == clparams.argc) arg = "";
if (arg[0] == '-'){ else arg = clparams.argv[i];
action = CLAct_Ignore; switch (action){
switch (arg[1]){ case CLAct_Nothing:
case 'u': action = CLAct_UserFile; strict = 0; break; {
case 'U': action = CLAct_UserFile; strict = 1; break; if (arg[0] == '-'){
action = CLAct_Ignore;
case 'd': action = CLAct_CustomDLL; strict = 0; break; switch (arg[1]){
case 'D': action = CLAct_CustomDLL; strict = 1; break; case 'u': action = CLAct_UserFile; strict = 0; break;
case 'U': action = CLAct_UserFile; strict = 1; break;
case 'l': action = CLAct_InitialFilePosition; break;
case 'd': action = CLAct_CustomDLL; strict = 0; break;
case 'w': action = CLAct_WindowSize; break; case 'D': action = CLAct_CustomDLL; strict = 1; break;
case 'p': action = CLAct_WindowPosition; break;
} case 'l': action = CLAct_InitialFilePosition; break;
switch (action){ case 'w': action = CLAct_WindowSize; break;
case 'W': action = CLAct_WindowMaximize; break;
case 'p': action = CLAct_WindowPosition; break;
}
}
else if (arg[0] != 0){
if (settings->init_files_count < settings->init_files_max){
index = settings->init_files_count++;
settings->init_files[index] = arg;
}
}
}break;
case CLAct_UserFile: case CLAct_UserFile:
{
settings->user_file_is_strict = strict; settings->user_file_is_strict = strict;
++i;
if (i < clparams.argc){ if (i < clparams.argc){
settings->user_file = clparams.argv[i]; settings->user_file = clparams.argv[i];
} }
break; action = CLAct_Nothing;
}break;
case CLAct_CustomDLL: case CLAct_CustomDLL:
{
plat_settings->custom_dll_is_strict = strict; plat_settings->custom_dll_is_strict = strict;
++i;
if (i < clparams.argc){ if (i < clparams.argc){
plat_settings->custom_dll = clparams.argv[i]; plat_settings->custom_dll = clparams.argv[i];
} }
break; action = CLAct_Nothing;
}break;
case CLAct_InitialFilePosition: case CLAct_InitialFilePosition:
++i; {
if (i < clparams.argc){ if (i < clparams.argc){
settings->initial_line = str_to_int(clparams.argv[i]); settings->initial_line = str_to_int(clparams.argv[i]);
} }
break; action = CLAct_Nothing;
}break;
case CLAct_WindowSize: case CLAct_WindowSize:
break; {
if (i + 1 < clparams.argc){
case CLAct_WindowPosition: plat_settings->set_window_size = 1;
break; plat_settings->window_w = str_to_int(clparams.argv[i]);
} plat_settings->window_h = str_to_int(clparams.argv[i+1]);
++i;
}
action = CLAct_Nothing;
}break;
case CLAct_WindowMaximize:
{
--i;
plat_settings->maximize_window = 1;
action = CLAct_Nothing;
}break;
} case CLAct_WindowPosition:
else{ {
if (settings->init_files_count < settings->init_files_max){ if (i + 1 < clparams.argc){
index = settings->init_files_count++; plat_settings->set_window_pos = 1;
settings->init_files[index] = arg; plat_settings->window_x = str_to_int(clparams.argv[i]);
} plat_settings->window_y = str_to_int(clparams.argv[i+1]);
++i;
}
action = CLAct_Nothing;
}break;
} }
} }
} }
internal App_Vars*
app_setup_memory(Application_Memory *memory){
Partition _partition = partition_open(memory->vars_memory, memory->vars_memory_size);
App_Vars *vars = push_struct(&_partition, App_Vars);
Assert(vars);
*vars = {};
vars->mem.part = _partition;
general_memory_open(&vars->mem.general, memory->target_memory, memory->target_memory_size);
return(vars);
}
App_Read_Command_Line_Sig(app_read_command_line){ App_Read_Command_Line_Sig(app_read_command_line){
i32 output_size = 0; i32 output_size = 0;
//init_command_line_settings(); App_Vars *vars = app_setup_memory(memory);
init_command_line_settings(&vars->settings, plat_settings, clparams);
return(output_size); return(output_size);
} }
@ -2579,17 +2640,11 @@ App_Read_Command_Line_Sig(app_read_command_line){
App_Init_Sig(app_init){ App_Init_Sig(app_init){
app_links_init(system); app_links_init(system);
Partition _partition = partition_open(memory->vars_memory, memory->vars_memory_size); App_Vars *vars = (App_Vars*)memory->vars_memory;
App_Vars *vars = push_struct(&_partition, App_Vars);
Assert(vars);
*vars = {};
vars->config_api = api; vars->config_api = api;
vars->mem.part = _partition;
Partition *partition = &vars->mem.part; Partition *partition = &vars->mem.part;
target->partition = partition; target->partition = partition;
general_memory_open(&vars->mem.general, memory->target_memory, memory->target_memory_size);
i32 panel_max_count = vars->layout.panel_max_count = 16; i32 panel_max_count = vars->layout.panel_max_count = 16;
i32 divider_max_count = panel_max_count - 1; i32 divider_max_count = panel_max_count - 1;
vars->layout.panel_count = 1; vars->layout.panel_count = 1;
@ -2687,7 +2742,7 @@ App_Init_Sig(app_init){
map_init(mapptr, &vars->mem.part, table_max, global); map_init(mapptr, &vars->mem.part, table_max, global);
did_file = 1; did_file = 1;
} }
else if (mapid >= mapid_user_custom){ else if (mapid < mapid_global){
i32 index = app_get_or_add_map_index(vars, mapid); i32 index = app_get_or_add_map_index(vars, mapid);
Assert(index < user_map_count); Assert(index < user_map_count);
mapptr = vars->user_maps + index; mapptr = vars->user_maps + index;
@ -2702,7 +2757,7 @@ App_Init_Sig(app_init){
int mapid = unit->map_inherit.mapid; int mapid = unit->map_inherit.mapid;
if (mapid == mapid_global) parent = &vars->map_top; if (mapid == mapid_global) parent = &vars->map_top;
else if (mapid == mapid_file) parent = &vars->map_file; else if (mapid == mapid_file) parent = &vars->map_file;
else if (mapid >= mapid_user_custom){ else if (mapid < mapid_global){
i32 index = app_get_or_add_map_index(vars, mapid); i32 index = app_get_or_add_map_index(vars, mapid);
if (index < user_map_count) parent = vars->user_maps + index; if (index < user_map_count) parent = vars->user_maps + index;
else parent = 0; else parent = 0;
@ -2819,27 +2874,6 @@ App_Init_Sig(app_init){
font_set_add(partition, vars->font_set, file_name, name, pt_size); font_set_add(partition, vars->font_set, file_name, name, pt_size);
} }
#if 0
if (vars->config_api.set_extra_font){
Extra_Font extra;
extra.size = 17;
vars->config_api.set_extra_font(&extra);
memory_used = 0;
if (app_load_font(target,
vars->fonts.fonts + font_count, extra.file_name, extra.size,
partition_current(partition),
&memory_used, 4, make_string_slowly(extra.font_name))){
++font_count;
}
else{
vars->fonts.fonts[font_count] = {};
}
push_block(partition, memory_used);
}
vars->fonts.count = font_count;
#endif
} }
// NOTE(allen): file setup // NOTE(allen): file setup
@ -2918,6 +2952,7 @@ App_Step_Sig(app_step){
copy(dest, make_string((char*)clipboard.str, clipboard.size)); copy(dest, make_string((char*)clipboard.str, clipboard.size));
} }
// TODO(allen): profile this make sure it's not costing me too much power.
// NOTE(allen): check files are up to date // NOTE(allen): check files are up to date
for (i32 i = 0; i < vars->working_set.file_index_count; ++i){ for (i32 i = 0; i < vars->working_set.file_index_count; ++i){
Editing_File *file = vars->working_set.files + i; Editing_File *file = vars->working_set.files + i;
@ -3277,9 +3312,19 @@ App_Step_Sig(app_step){
Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part); Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part);
command_data.part = partition_sub_part(&vars->mem.part, 16 << 10); command_data.part = partition_sub_part(&vars->mem.part, 16 << 10);
if (first_step && vars->hooks[hook_start]){ if (first_step){
vars->hooks[hook_start](&command_data, &app_links); if (vars->hooks[hook_start]){
command_data.part.pos = 0; vars->hooks[hook_start](&command_data, &app_links);
command_data.part.pos = 0;
}
char *file_name;
i32 i;
for (i = 0; i < vars->settings.init_file_count; ++i){
file_name = vars->settings.init_files[i];
// TODO(allen): open files, do not attach to view
//app_open_file(system, vars, exchange,live_set, working_set, panel,command, string.str, string.size);
}
} }
// NOTE(allen): command input to active view // NOTE(allen): command input to active view
@ -3366,7 +3411,7 @@ App_Step_Sig(app_step){
Assert(view_->do_view); Assert(view_->do_view);
b32 active = (panel == active_panel); b32 active = (panel == active_panel);
Input_Summary input = (active)?(active_input):(dead_input); Input_Summary input = (active)?(active_input):(dead_input);
if (panel == mouse_panel){ if (panel == mouse_panel && !mouse_data.out_of_window){
input.mouse = mouse_data; input.mouse = mouse_data;
} }
if (view_->do_view(system, exchange, view_, panel->inner, active_view, if (view_->do_view(system, exchange, view_, panel->inner, active_view,

416
4ed.h
View File

@ -1,205 +1,211 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 12.12.2014 * 12.12.2014
* *
* Application Layer for 4coder * Application Layer for 4coder
* *
*/ */
// TOP // TOP
#ifndef FRED_H #ifndef FRED_H
#define FRED_H #define FRED_H
struct Application_Memory{ struct Application_Memory{
void *vars_memory; void *vars_memory;
i32 vars_memory_size; i32 vars_memory_size;
void *target_memory; void *target_memory;
i32 target_memory_size; i32 target_memory_size;
}; };
#define KEY_INPUT_BUFFER_SIZE 4 #define KEY_INPUT_BUFFER_SIZE 4
#define KEY_INPUT_BUFFER_DSIZE (KEY_INPUT_BUFFER_SIZE << 1) #define KEY_INPUT_BUFFER_DSIZE (KEY_INPUT_BUFFER_SIZE << 1)
enum Key_Control{ enum Key_Control{
CONTROL_KEY_SHIFT, CONTROL_KEY_SHIFT,
CONTROL_KEY_CONTROL, CONTROL_KEY_CONTROL,
CONTROL_KEY_ALT, CONTROL_KEY_ALT,
CONTROL_KEY_CAPS, CONTROL_KEY_CAPS,
// always last // always last
CONTROL_KEY_COUNT CONTROL_KEY_COUNT
}; };
struct Key_Event_Data{ struct Key_Event_Data{
u8 keycode; u8 keycode;
u8 character; u8 character;
u8 character_no_caps_lock; u8 character_no_caps_lock;
b8 modifiers[CONTROL_KEY_COUNT]; b8 modifiers[CONTROL_KEY_COUNT];
}; };
struct Key_Input_Data{ struct Key_Input_Data{
Key_Event_Data press[KEY_INPUT_BUFFER_SIZE]; Key_Event_Data press[KEY_INPUT_BUFFER_SIZE];
Key_Event_Data hold[KEY_INPUT_BUFFER_SIZE]; Key_Event_Data hold[KEY_INPUT_BUFFER_SIZE];
i32 press_count; i32 press_count;
i32 hold_count; i32 hold_count;
}; };
struct Key_Summary{ struct Key_Summary{
i32 count; i32 count;
Key_Event_Data keys[KEY_INPUT_BUFFER_DSIZE]; Key_Event_Data keys[KEY_INPUT_BUFFER_DSIZE];
}; };
inline Key_Event_Data inline Key_Event_Data
get_single_key(Key_Summary *summary, i32 index){ get_single_key(Key_Summary *summary, i32 index){
Assert(index >= 0 && index < summary->count); Assert(index >= 0 && index < summary->count);
Key_Event_Data key; Key_Event_Data key;
key = summary->keys[index]; key = summary->keys[index];
return key; return key;
} }
struct Mouse_State{ struct Mouse_State{
b32 out_of_window; b32 out_of_window;
b8 left_button, right_button; b8 left_button, right_button;
b8 left_button_pressed, right_button_pressed; b8 left_button_pressed, right_button_pressed;
b8 left_button_released, right_button_released; b8 left_button_released, right_button_released;
i16 wheel; i16 wheel;
i32 x, y; i32 x, y;
}; };
struct Mouse_Summary{ struct Mouse_Summary{
i32 mx, my; i32 mx, my;
b32 l, r; b32 l, r;
b32 press_l, press_r; b32 press_l, press_r;
b32 release_l, release_r; b32 release_l, release_r;
b32 out_of_window; b32 out_of_window;
b32 wheel_used; b32 wheel_used;
i16 wheel_amount; i16 wheel_amount;
}; };
struct Input_Summary{ struct Input_Summary{
Mouse_Summary mouse; Mouse_Summary mouse;
Key_Summary keys; Key_Summary keys;
Key_Codes *codes; Key_Codes *codes;
}; };
// TODO(allen): This can go, and we can just use a String for it. // TODO(allen): This can go, and we can just use a String for it.
struct Clipboard_Contents{ struct Clipboard_Contents{
u8 *str; u8 *str;
i32 size; i32 size;
}; };
#define FileNameMax (1 << 9) #define FileNameMax (1 << 9)
struct File_Slot{ struct File_Slot{
File_Slot *next, *prev; File_Slot *next, *prev;
byte *data; byte *data;
i32 size, max; i32 size, max;
char *filename; char *filename;
i32 filename_len; i32 filename_len;
u32 flags; u32 flags;
}; };
enum File_Exchange_Flag{ enum File_Exchange_Flag{
FEx_Request = 0x1, FEx_Request = 0x1,
FEx_Ready = 0x2, FEx_Ready = 0x2,
FEx_Not_Exist = 0x4, FEx_Not_Exist = 0x4,
FEx_Save = 0x8, FEx_Save = 0x8,
FEx_Save_Complete = 0x10 FEx_Save_Complete = 0x10
}; };
struct File_Exchange{ struct File_Exchange{
File_Slot available, active, free_list; File_Slot available, active, free_list;
File_Slot *files; File_Slot *files;
i32 num_active, max; i32 num_active, max;
}; };
struct Exchange{ struct Exchange{
Thread_Exchange thread; Thread_Exchange thread;
File_Exchange file; File_Exchange file;
}; };
struct Command_Line_Parameters{ struct Command_Line_Parameters{
char **argv; char **argv;
int argc; int argc;
}; };
struct App_Plat_Settings{ struct Plat_Settings{
char *custom_dll; char *custom_dll;
b32 custom_dll_is_strict; b32 custom_dll_is_strict;
};
i32 window_w, window_h;
#define App_Read_Command_Line_Sig(name) \ i32 window_x, window_y;
i32 name(System_Functions *system, \ b8 set_window_pos, set_window_size;
Application_Memory *memory, \ b8 maximize_window;
String current_directory, \ };
Command_Line_Parameters clparams \
) #define App_Read_Command_Line_Sig(name) \
i32 name(System_Functions *system, \
typedef App_Read_Command_Line_Sig(App_Read_Command_Line); Application_Memory *memory, \
String current_directory, \
#define App_Init_Sig(name) void \ Plat_Settings *plat_settings, \
name(System_Functions *system, \ Command_Line_Parameters clparams \
Render_Target *target, \ )
Application_Memory *memory, \
Exchange *exchange, \ typedef App_Read_Command_Line_Sig(App_Read_Command_Line);
Key_Codes *codes, \
Clipboard_Contents clipboard, \ #define App_Init_Sig(name) void \
String current_directory, \ name(System_Functions *system, \
Custom_API api) Render_Target *target, \
Application_Memory *memory, \
typedef App_Init_Sig(App_Init); Exchange *exchange, \
Key_Codes *codes, \
enum Application_Mouse_Cursor{ Clipboard_Contents clipboard, \
APP_MOUSE_CURSOR_DEFAULT, String current_directory, \
APP_MOUSE_CURSOR_ARROW, Custom_API api)
APP_MOUSE_CURSOR_IBEAM,
APP_MOUSE_CURSOR_LEFTRIGHT, typedef App_Init_Sig(App_Init);
APP_MOUSE_CURSOR_UPDOWN,
// never below this enum Application_Mouse_Cursor{
APP_MOUSE_CURSOR_COUNT APP_MOUSE_CURSOR_DEFAULT,
}; APP_MOUSE_CURSOR_ARROW,
APP_MOUSE_CURSOR_IBEAM,
struct Application_Step_Result{ APP_MOUSE_CURSOR_LEFTRIGHT,
Application_Mouse_Cursor mouse_cursor_type; APP_MOUSE_CURSOR_UPDOWN,
b32 redraw; // never below this
b32 lctrl_lalt_is_altgr; APP_MOUSE_CURSOR_COUNT
}; };
#define App_Step_Sig(name) void \ struct Application_Step_Result{
name(System_Functions *system, \ Application_Mouse_Cursor mouse_cursor_type;
Key_Codes *codes, \ b32 redraw;
Key_Input_Data *input, \ b32 lctrl_lalt_is_altgr;
Mouse_State *mouse, \ };
Render_Target *target, \
Application_Memory *memory, \ #define App_Step_Sig(name) void \
Exchange *exchange, \ name(System_Functions *system, \
Clipboard_Contents clipboard, \ Key_Codes *codes, \
b32 time_step, b32 first_step, b32 force_redraw, \ Key_Input_Data *input, \
Application_Step_Result *result) Mouse_State *mouse, \
Render_Target *target, \
typedef App_Step_Sig(App_Step); Application_Memory *memory, \
Exchange *exchange, \
#define App_Alloc_Sig(name) void *name(void *handle, i32 size) Clipboard_Contents clipboard, \
typedef App_Alloc_Sig(App_Alloc); b32 time_step, b32 first_step, b32 force_redraw, \
Application_Step_Result *result)
#define App_Free_Sig(name) void name(void *handle, void *block)
typedef App_Free_Sig(App_Free); typedef App_Step_Sig(App_Step);
struct App_Functions{ #define App_Alloc_Sig(name) void *name(void *handle, i32 size)
App_Read_Command_Line *read_command_line; typedef App_Alloc_Sig(App_Alloc);
App_Init *init;
App_Step *step; #define App_Free_Sig(name) void name(void *handle, void *block)
typedef App_Free_Sig(App_Free);
App_Alloc *alloc;
App_Free *free; struct App_Functions{
}; App_Read_Command_Line *read_command_line;
App_Init *init;
#define App_Get_Functions_Sig(name) App_Functions name() App_Step *step;
typedef App_Get_Functions_Sig(App_Get_Functions);
App_Alloc *alloc;
#endif App_Free *free;
};
// BOTTOM
#define App_Get_Functions_Sig(name) App_Functions name()
typedef App_Get_Functions_Sig(App_Get_Functions);
#endif
// BOTTOM

View File

@ -1,25 +1,25 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 27.01.2016 * 27.01.2016
* *
* Global app level settings definition * Global app level settings definition
* *
*/ */
// TOP // TOP
struct App_Settings{ struct App_Settings{
char *user_file; char *user_file;
b32 user_file_is_strict; b32 user_file_is_strict;
char *init_files[4]; char *init_files[8];
i32 init_files_count; i32 init_files_count;
i32 init_files_max; i32 init_files_max;
i32 initial_line; i32 initial_line;
b32 lctrl_lalt_is_altgr; b32 lctrl_lalt_is_altgr;
}; };
// BOTTOM // BOTTOM

View File

@ -99,6 +99,7 @@ struct Editing_File_Settings{
Font_Set *set; Font_Set *set;
i32 base_map_id; i32 base_map_id;
i32 dos_write_mode; i32 dos_write_mode;
b32 unwrapped_lines;
b8 tokens_exist; b8 tokens_exist;
b8 super_locked; b8 super_locked;
b8 is_initialized; b8 is_initialized;
@ -1111,7 +1112,8 @@ struct File_View{
f32 scroll_y, target_y, vel_y; f32 scroll_y, target_y, vel_y;
f32 scroll_x, target_x, vel_x; f32 scroll_x, target_x, vel_x;
f32 preferred_x; f32 preferred_x;
Full_Cursor scroll_y_cursor; i32 scroll_i;
union{ union{
Incremental_Search isearch; Incremental_Search isearch;
struct{ struct{
@ -1220,21 +1222,26 @@ file_save(System_Functions *system, Exchange *exchange, Mem_Options *mem,
i32 result = 0; i32 result = 0;
#if BUFFER_EXPERIMENT_SCALPEL <= 3 #if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 max = buffer_size(&file->state.buffer) + file->state.buffer.line_count; i32 max, size;
byte *data = (byte*)general_memory_allocate(&mem->general, max, 0); byte *data;
Assert(data); b32 dos_write_mode = file->settings.dos_write_mode;
i32 size;
if (file->settings.dos_write_mode){
size = buffer_convert_out(&file->state.buffer, (char*)data, max);
}
else{
size = buffer_size(&file->state.buffer);
buffer_stringify(&file->state.buffer, 0, size, (char*)data);
}
if (dos_write_mode)
max = buffer_size(&file->state.buffer) + file->state.buffer.line_count + 1;
else
max = buffer_size(&file->state.buffer);
data = (byte*)general_memory_allocate(&mem->general, max, 0);
Assert(data);
if (dos_write_mode)
size = buffer_convert_out(&file->state.buffer, (char*)data, max);
else
buffer_stringify(&file->state.buffer, 0, size = max, (char*)data);
i32 filename_len = str_size(filename); i32 filename_len = str_size(filename);
result = exchange_save_file(exchange, filename, filename_len, result = exchange_save_file(exchange, filename, filename_len,
data, size, max); data, size, max);
if (result == 0){ if (result == 0){
general_memory_free(&mem->general, data); general_memory_free(&mem->general, data);
@ -2293,6 +2300,7 @@ view_set_file(System_Functions *system, File_View *view,
view->font_advance = info->advance; view->font_advance = info->advance;
view->font_height = info->height; view->font_height = info->height;
view->font_set = set; view->font_set = set;
view->unwrapped_lines = file->settings.unwrapped_lines;
file->settings.set = set; file->settings.set = set;
view->cursor = {}; view->cursor = {};
@ -2647,6 +2655,83 @@ file_pre_edit_maintenance(System_Functions *system,
file->state.last_4ed_edit_time = system->time(); file->state.last_4ed_edit_time = system->time();
} }
struct Cursor_Fix_Descriptor{
b32 is_batch;
union{
struct{
Buffer_Edit *batch;
i32 batch_size;
};
struct{
i32 start, end;
i32 shift_amount;
};
};
};
internal void
file_edit_cursor_fix(System_Functions *system,
Partition *part, General_Memory *general,
Editing_File *file, Editing_Layout *layout,
Cursor_Fix_Descriptor desc){
Full_Cursor temp_cursor;
Temp_Memory cursor_temp = begin_temp_memory(part);
i32 cursor_max = layout->panel_max_count * 2;
Cursor_With_Index *cursors = push_array(part, Cursor_With_Index, cursor_max);
i32 panel_count = layout->panel_count;
i32 cursor_count = 0;
Panel *current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_measure_wraps(system, general, current_view);
write_cursor_with_index(cursors, &cursor_count, current_view->cursor.pos);
write_cursor_with_index(cursors, &cursor_count, current_view->mark);
write_cursor_with_index(cursors, &cursor_count, current_view->scroll_i);
}
}
if (cursor_count > 0){
buffer_sort_cursors(cursors, cursor_count);
if (desc.is_batch){
buffer_batch_edit_update_cursors(cursors, cursor_count,
desc.batch, desc.batch_size);
}
else{
buffer_update_cursors(cursors, cursor_count,
desc.start, desc.end,
desc.shift_amount + (desc.end - desc.start));
}
buffer_unsort_cursors(cursors, cursor_count);
cursor_count = 0;
current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_cursor_move(current_view, cursors[cursor_count++].pos);
current_view->preferred_x = view_get_cursor_x(current_view);
current_view->mark = cursors[cursor_count++].pos;
current_view->scroll_i = cursors[cursor_count++].pos;
temp_cursor = view_compute_cursor_from_pos(current_view, current_view->scroll_i);
if (current_view->unwrapped_lines){
current_view->target_y += (temp_cursor.unwrapped_y - current_view->scroll_y);
current_view->scroll_y = temp_cursor.unwrapped_y;
}
else{
current_view->target_y += (temp_cursor.wrapped_y - current_view->scroll_y);
current_view->scroll_y = temp_cursor.wrapped_y;
}
}
}
}
end_temp_memory(cursor_temp);
}
internal void internal void
file_do_single_edit(System_Functions *system, file_do_single_edit(System_Functions *system,
Mem_Options *mem, Editing_File *file, Mem_Options *mem, Editing_File *file,
@ -2722,40 +2807,14 @@ file_do_single_edit(System_Functions *system,
#endif #endif
#if BUFFER_EXPERIMENT_SCALPEL <= 3 #if BUFFER_EXPERIMENT_SCALPEL <= 3
Temp_Memory cursor_temp = begin_temp_memory(&mem->part); Cursor_Fix_Descriptor desc = {};
i32 cursor_max = layout->panel_max_count * 2; desc.start = start;
Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max); desc.end = end;
desc.shift_amount = shift_amount;
i32 cursor_count = 0; file_edit_cursor_fix(system, part, general,
current_panel = layout->panels; file, layout, desc);
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_measure_wraps(system, general, current_view);
write_cursor_with_index(cursors, &cursor_count, current_view->cursor.pos);
write_cursor_with_index(cursors, &cursor_count, current_view->mark);
}
}
if (cursor_count > 0){
buffer_sort_cursors(cursors, cursor_count);
buffer_update_cursors(cursors, cursor_count,
start, end, shift_amount + (end - start));
buffer_unsort_cursors(cursors, cursor_count);
}
cursor_count = 0;
current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_cursor_move(current_view, cursors[cursor_count++].pos);
current_view->mark = cursors[cursor_count++].pos;
current_view->preferred_x = view_get_cursor_x(current_view);
}
}
end_temp_memory(cursor_temp);
#endif #endif
} }
@ -2834,41 +2893,14 @@ view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, File_View *
} }
// NOTE(allen): cursor fixing // NOTE(allen): cursor fixing
{ Cursor_Fix_Descriptor desc = {};
Temp_Memory cursor_temp = begin_temp_memory(part); desc.is_batch = 1;
i32 cursor_max = layout->panel_max_count * 2; desc.batch = batch;
Cursor_With_Index *cursors = push_array(part, Cursor_With_Index, cursor_max); desc.batch_size = batch_size;
i32 panel_count = layout->panel_count; file_edit_cursor_fix(system, part, general,
i32 cursor_count = 0; file, layout, desc);
Panel *current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_measure_wraps(system, general, current_view);
write_cursor_with_index(cursors, &cursor_count, current_view->cursor.pos);
write_cursor_with_index(cursors, &cursor_count, current_view->mark);
}
}
if (cursor_count > 0){
buffer_sort_cursors(cursors, cursor_count);
buffer_batch_edit_update_cursors(cursors, cursor_count, batch, batch_size);
buffer_unsort_cursors(cursors, cursor_count);
}
cursor_count = 0;
current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_cursor_move(current_view, cursors[cursor_count++].pos);
current_view->mark = cursors[cursor_count++].pos;
current_view->preferred_x = view_get_cursor_x(current_view);
}
}
end_temp_memory(cursor_temp);
}
#endif #endif
} }
@ -4168,10 +4200,27 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
if (font) advance_data = font->advance_data; if (font) advance_data = font->advance_data;
i32 count; i32 count;
Full_Cursor render_cursor;
Buffer_Render_Options opts = {}; Buffer_Render_Options opts = {};
buffer_get_render_data(&file->state.buffer, view->line_wrap_y, items, max, &count,
(f32)rect.x0, (f32)rect.y0, view->scroll_x, view->scroll_y, !view->unwrapped_lines, f32 *wraps = view->line_wrap_y;
(f32)max_x, (f32)max_y, advance_data, (f32)line_height, opts); f32 scroll_x = view->scroll_x;
f32 scroll_y = view->scroll_y;
{
render_cursor = buffer_get_start_cursor(&file->state.buffer, wraps, scroll_y,
!view->unwrapped_lines, (f32)max_x, advance_data, (f32)line_height);
view->scroll_i = render_cursor.pos;
buffer_get_render_data(&file->state.buffer, items, max, &count,
(f32)rect.x0, (f32)rect.y0,
scroll_x, scroll_y, render_cursor,
!view->unwrapped_lines,
(f32)max_x, (f32)max_y,
advance_data, (f32)line_height,
opts);
}
Assert(count > 0); Assert(count > 0);
@ -4212,9 +4261,11 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
Buffer_Render_Item *item = items; Buffer_Render_Item *item = items;
i32 prev_ind = -1; i32 prev_ind = -1;
u32 highlight_color = 0; u32 highlight_color = 0;
u32 highlight_this_color = 0;
for (i32 i = 0; i < count; ++i, ++item){ for (i32 i = 0; i < count; ++i, ++item){
i32 ind = item->index; i32 ind = item->index;
highlight_this_color = 0;
if (tokens_use && ind != prev_ind){ if (tokens_use && ind != prev_ind){
Cpp_Token current_token = token_stack.tokens[token_i-1]; Cpp_Token current_token = token_stack.tokens[token_i-1];
@ -4231,23 +4282,39 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
} }
if (current_token.type == CPP_TOKEN_JUNK && if (current_token.type == CPP_TOKEN_JUNK &&
i >= current_token.start && i <= current_token.start + current_token.size){ i >= current_token.start && i < current_token.start + current_token.size){
highlight_color = style->main.highlight_junk_color; highlight_color = style->main.highlight_junk_color;
} }
else{
highlight_color = 0;
}
} }
u32 char_color = main_color;
u32 char_color = main_color;
if (item->flags & BRFlag_Special_Character) char_color = special_color; if (item->flags & BRFlag_Special_Character) char_color = special_color;
f32_Rect char_rect = f32R(item->x0, item->y0, item->x1, item->y1);
if (view->show_whitespace && highlight_color == 0 &&
char_is_whitespace((char)item->glyphid)){
highlight_this_color = style->main.highlight_white_color;
}
else{
highlight_this_color = highlight_color;
}
if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){ if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
if (is_active){ if (is_active){
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color); draw_rectangle(target, char_rect, cursor_color);
char_color = at_cursor_color; char_color = at_cursor_color;
} }
else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color); else{
if (!view->show_temp_highlight){
draw_rectangle_outline(target, char_rect, cursor_color);
}
}
} }
else if (highlight_color){ else if (highlight_this_color){
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), highlight_color); draw_rectangle(target, char_rect, highlight_this_color);
} }
u32 fade_color = 0xFFFF00FF; u32 fade_color = 0xFFFF00FF;
@ -4263,7 +4330,7 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
char_color = color_blend(char_color, fade_amount, fade_color); char_color = color_blend(char_color, fade_amount, fade_color);
if (ind == view->mark && prev_ind != ind){ if (ind == view->mark && prev_ind != ind){
draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), mark_color); draw_rectangle_outline(target, char_rect, mark_color);
} }
if (item->glyphid != 0){ if (item->glyphid != 0){
font_draw_glyph(target, font_id, (u8)item->glyphid, font_draw_glyph(target, font_id, (u8)item->glyphid,

View File

@ -14,28 +14,19 @@
internal void internal void
keycode_init(Key_Codes *codes){ keycode_init(Key_Codes *codes){
set_dynamic_key_names(codes); set_dynamic_key_names(codes);
u16 code, loose; keycode_lookup_table[KEY_BACKSPACE] = codes->back;
for (u16 i = 0; i < 255; ++i){ keycode_lookup_table[KEY_DELETE] = codes->del;
if (i >= 'a' && i <= 'z'){ keycode_lookup_table[KEY_UP] = codes->up;
keycode_lookup_table[i] = i + ('A' - 'a'); keycode_lookup_table[KEY_DOWN] = codes->down;
loose_keycode_lookup_table[i] = 0; keycode_lookup_table[KEY_LEFT] = codes->left;
} keycode_lookup_table[KEY_RIGHT] = codes->right;
keycode_lookup_table[KEY_INSERT] = codes->insert;
else if (i >= '0' && i <= '9'){ keycode_lookup_table[KEY_HOME] = codes->home;
keycode_lookup_table[i] = i; keycode_lookup_table[KEY_END] = codes->end;
loose_keycode_lookup_table[i] = 0; keycode_lookup_table[KEY_PAGEUP] = codes->page_up;
} keycode_lookup_table[KEY_PAGEDOWN] = codes->page_down;
keycode_lookup_table[KEY_ESC] = codes->esc;
else{
loose = 0;
switch (i){
}
keycode_lookup_table[i] = code;
loose_keycode_lookup_table[i] = loose;
}
}
} }
// BOTTOM // BOTTOM

View File

@ -112,7 +112,7 @@ _OutDbgStr(u8*);
TMax(u8, 255); TMax(u8, 255);
TMax(u16, 65535); TMax(u16, 65535);
TMax(u32, 4294967295); TMax(u32, 4294967295);
TMax(u64, 18446744073709551615); TMax(u64, 18446744073709551615U);
TMax(i8, 127); TMax(i8, 127);
TMax(i16, 32767); TMax(i16, 32767);

View File

@ -1145,13 +1145,33 @@ struct Buffer_Render_Options{
b8 show_slash_t; b8 show_slash_t;
}; };
internal_4tech Full_Cursor
buffer_get_start_cursor(Buffer_Type *buffer, float *wraps, float scroll_y,
int wrapped, float width, float *advance_data, float font_height){
Full_Cursor result;
if (wrapped){
result = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data);
}
else{
result = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data);
}
return(result);
}
internal_4tech void internal_4tech void
buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *items, int max, int *count, buffer_get_render_data(Buffer_Type *buffer, Buffer_Render_Item *items, int max, int *count,
float port_x, float port_y, float scroll_x, float scroll_y, int wrapped, float port_x, float port_y,
float width, float height, float *advance_data, float font_height, float scroll_x, float scroll_y, Full_Cursor start_cursor,
int wrapped,
float width, float height,
float *advance_data, float font_height,
Buffer_Render_Options opts){ Buffer_Render_Options opts){
Buffer_Stringify_Type loop; Buffer_Stringify_Type loop;
Full_Cursor start_cursor;
Buffer_Render_Item *item; Buffer_Render_Item *item;
char *data; char *data;
int size, end; int size, end;
@ -1160,21 +1180,13 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
int i, item_i; int i, item_i;
float ch_width, ch_width_sub; float ch_width, ch_width_sub;
char ch; char ch;
size = buffer_size(buffer); size = buffer_size(buffer);
shift_x = port_x - scroll_x; shift_x = port_x - scroll_x;
shift_y = port_y - scroll_y; shift_y = port_y - scroll_y;
if (wrapped){ if (wrapped) shift_y += start_cursor.wrapped_y;
start_cursor = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0, wraps, else shift_y += start_cursor.unwrapped_y;
width, font_height, advance_data);
shift_y += start_cursor.wrapped_y;
}
else{
start_cursor = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data);
shift_y += start_cursor.unwrapped_y;
}
x = shift_x; x = shift_x;
y = shift_y; y = shift_y;

View File

@ -1,3 +1,3 @@
@echo off @echo off
call "w:\4ed\code\buildsuper.bat" call "w:\4ed\misc\builddbg.bat"

View File

@ -9,50 +9,7 @@
// TOP // TOP
#ifdef FRED_NOT_PACKAGE #include "4ed_config.h"
#define FRED_INTERNAL 1
#define FRED_SLOW 1
#define FRED_PRINT_DEBUG 1
#define FRED_PRINT_DEBUG_FILE_LINE 0
#define FRED_PROFILING 1
#define FRED_PROFILING_OS 0
#define FRED_FULL_ERRORS 0
#else
#define FRED_SLOW 0
#define FRED_INTERNAL 0
#define FRED_PRINT_DEBUG 0
#define FRED_PRINT_DEBUG_FILE_LINE 0
#define FRED_PROFILING 0
#define FRED_PROFILING_OS 0
#define FRED_FULL_ERRORS 0
#endif
#define SOFTWARE_RENDER 0
#if FRED_INTERNAL == 0
# undef FRED_PRINT_DEBUG
# define FRED_PRINT_DEBUG 0
# undef FRED_PROFILING
# define FRED_PROFILING 0
# undef FRED_PROFILING_OS
# define FRED_PROFILING_OS 0
#endif
#if FRED_PRINT_DEBUG == 0
# undef FRED_PRINT_DEBUG_FILE_LINE
# define FRED_PRINT_DEBUG_FILE_LINE 0
# undef FRED_PRINT_DEBUG_FILE_LINE
# define FRED_PROFILING_OS 0
#endif
#define FPS 30
#define frame_useconds (1000000 / FPS)
#include "4ed_meta.h" #include "4ed_meta.h"
@ -60,334 +17,480 @@
#include "4cpp_types.h" #include "4cpp_types.h"
#define FCPP_STRING_IMPLEMENTATION #define FCPP_STRING_IMPLEMENTATION
#include "4cpp_string.h" #include "4coder_string.h"
#include "4ed_mem.cpp" #include "4ed_mem.cpp"
#include "4ed_math.cpp" #include "4ed_math.cpp"
#include "4coder_custom.h" #include "4coder_custom.h"
#include "4ed_system.h" #include "4ed_system.h"
#include "4ed.h"
#include "4ed_rendering.h" #include "4ed_rendering.h"
#include "4ed.h"
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <stdio.h> #include <stdio.h>
#include <memory.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <xmmintrin.h>
#include <linux/fs.h>
#include <X11/extensions/XInput2.h>
#include <linux/input.h>
#include "4ed_internal.h" #include "4ed_internal.h"
#include "4ed_linux_keyboard.cpp" #include "4ed_linux_keyboard.cpp"
#define printe(m) printf("%s:%d: %s\n", __FILE__, __LINE__, #m) // NOTE(allen): Thanks to Casey for providing the linux OpenGL launcher.
/* TODO(allen):
struct Linux_Vars{ 1. get 4coder rendering it's blank self
Key_Codes codes; 2. get input working
Key_Input_Data input; (release linux version)
Mouse_State mouse; 3. add in extra stuff as it is completed in windows
Render_Target target;
Application_Memory mem; */
b32 keep_going;
b32 force_redraw;
Clipboard_Contents clipboard;
void *app_code, *custom; static bool ctxErrorOccurred = false;
static int XInput2OpCode = 0;
System_Functions *system; internal int
App_Functions app; ctxErrorHandler( Display *dpy, XErrorEvent *ev )
Config_API config_api; {
ctxErrorOccurred = true;
}; return 0;
Linux_Vars linuxvars;
internal
Sys_Get_Memory_Sig(system_get_memory_){
void *ptr = 0;
i32 prot = PROT_READ | PROT_WRITE;
i32 flags = MAP_PRIVATE | MAP_ANON;
#if FRED_INTERNAL
ptr = mmap(0, size + sizeof(Sys_Bubble), prot, flags, -1, 0);
Sys_Bubble *bubble = (Sys_Bubble*)ptr;
bubble->flags = MEM_BUBBLE_SYS_DEBUG;
bubble->line_number = line_number;
bubble->file_name = file_name;
bubble->size = size;
//WaitForSingleObject(win32vars.DEBUG_sysmem_lock, INFINITE);
insert_bubble(&win32vars.internal_bubble, bubble);
//ReleaseSemaphore(win32vars.DEBUG_sysmem_lock, 1, 0);
ptr = bubble + 1;
#else
ptr = mmap(0, size + sizeof(i32), prot, flags, -1, 0);
i32 *size_ptr = (i32*)ptr;
*size_ptr = size;
ptr = size_ptr + 1;
#endif
return ptr;
} }
#define system_get_memory(size) system_get_memory_(size, __LINE__, __FILE__) internal GLXContext
InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, b32 &IsLegacy)
internal {
Sys_Free_Memory_Sig(system_free_memory){ IsLegacy = false;
if (block){
#if FRED_INTERNAL
Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1;
Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG);
//WaitForSingleObject(win32vars.DEBUG_sysmem_lock, INFINITE);
remove_bubble(bubble);
//ReleaseSemaphore(win32vars.DEBUG_sysmem_lock, 1, 0);
munmap(bubble, bubble->size);
#else
i32 *size_ptr = (i32*)block - 1;
munmap(size_ptr, *size_ptr);
#endif
}
}
internal
Sys_Time_Sig(system_time){
i64 result = 0;
struct timespec tp;
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0){
result = tp.tv_sec*1000000 + tp.tv_nsec/1000;
}
return result;
}
internal
Sys_Load_File_Sig(system_load_file){
File_Data result = {};
i32 prot = PROT_READ;
i32 flags = MAP_PRIVATE | MAP_ANON;
struct stat sb; typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
if (stat(filename, &sb) == 0){ const char *glxExts = glXQueryExtensionsString(XDisplay, DefaultScreen(XDisplay));
result.size = sb.st_size;
result.data = system_get_memory(result.size); glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
if (result.data){ glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
i32 file = open(filename, O_RDONLY); glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
i32 result_size = read(file, result.data, result.size);
Assert(result_size == result.size); GLXContext ctx = 0;
close(file); ctxErrorOccurred = false;
int (*oldHandler)(Display*, XErrorEvent*) =
XSetErrorHandler(&ctxErrorHandler);
if (!glXCreateContextAttribsARB)
{
printf( "glXCreateContextAttribsARB() not found"
" ... using old-style GLX context\n" );
ctx = glXCreateNewContext( XDisplay, bestFbc, GLX_RGBA_TYPE, 0, True );
}
else
{
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
printf("\nAttribs: %d %d %d %d %d\n",
context_attribs[0],
context_attribs[1],
context_attribs[2],
context_attribs[3],
context_attribs[4]);
printf( "Creating context\n" );
ctx = glXCreateContextAttribsARB( XDisplay, bestFbc, 0,
True, context_attribs );
XSync( XDisplay, False );
if ( !ctxErrorOccurred && ctx )
{
printf( "Created GL 4.3 context\n" );
}
else
{
ctxErrorOccurred = false;
context_attribs[1] = 4;
context_attribs[3] = 0;
printf( "Creating context\n" );
ctx = glXCreateContextAttribsARB( XDisplay, bestFbc, 0,
True, context_attribs );
XSync( XDisplay, False );
if ( !ctxErrorOccurred && ctx )
{
printf( "Created GL 4.0 context\n" );
}
else
{
context_attribs[1] = 1;
context_attribs[3] = 0;
ctxErrorOccurred = false;
printf( "Failed to create GL 4.0 context"
" ... using old-style GLX context\n" );
ctx = glXCreateContextAttribsARB( XDisplay, bestFbc, 0,
True, context_attribs );
IsLegacy = true;
}
} }
} }
return result; XSync( XDisplay, False );
} XSetErrorHandler( oldHandler );
if ( ctxErrorOccurred || !ctx )
{
printf( "Failed to create an OpenGL context\n" );
exit(1);
}
if ( ! glXIsDirect ( XDisplay, ctx ) )
{
printf( "Indirect GLX rendering context obtained\n" );
}
else
{
printf( "Direct GLX rendering context obtained\n" );
}
printf( "Making context current\n" );
glXMakeCurrent( XDisplay, XWindow, ctx );
internal GLint n;
Sys_Save_File_Sig(system_save_file){ char *Vendor = (char *)glGetString(GL_VENDOR);
i32 file = open(filename, O_CREAT | O_WRONLY); char *Renderer = (char *)glGetString(GL_RENDERER);
if (!file) return 0; char *Version = (char *)glGetString(GL_VERSION);
char *Extensions = (char *)glGetString(GL_EXTENSIONS);
i32 result_size = write(file, data, size); printf("GL_VENDOR: %s\n", Vendor);
Assert(result_size == size); printf("GL_RENDERER: %s\n", Renderer);
printf("GL_VERSION: %s\n", Version);
printf("GL_EXTENSIONS: %s\n", Extensions);
close(file); return(ctx);
return 1;
} }
internal b32 internal b32
LinuxLoadAppCode(){ GLXSupportsModernContexts(Display *XDisplay)
b32 result = 0; {
b32 Result = false;
char app_code_file[] = "4ed_app.so"; int GLXMajor, GLXMinor;
i32 app_code_file_len = sizeof(app_code_file) - 1;
char path[1024];
i32 size = readlink("/proc/self/exe", path,
1024 - app_code_file_len - 1);
for (--size;
path[size] != '/' && size > 0;
--size);
memcpy(path + size + 1, app_code_file, app_code_file_len + 1);
linuxvars.app_code = 0;
if (linuxvars.app_code){
result = 1;
linuxvars.app.init = (App_Init*)0;
linuxvars.app.step = (App_Step*)0;
}
else{
// TODO(allen): initialization failure
printe(app_code);
}
return result;
}
internal char *XVendor = ServerVendor(XDisplay);
Sys_Acquire_Lock_Sig(system_acquire_lock){ printf("XWindows vendor: %s\n", XVendor);
AllowLocal(id); if(glXQueryVersion(XDisplay, &GLXMajor, &GLXMinor))
}
internal
Sys_Release_Lock_Sig(system_release_lock){
AllowLocal(id);
}
internal
Sys_Force_Redraw_Sig(system_force_redraw){
linuxvars.force_redraw = 1;
}
internal void
LinuxLoadSystemCode(){
linuxvars.system->get_memory_full = system_get_memory_;
linuxvars.system->free_memory = system_free_memory;
linuxvars.system->load_file = system_load_file;
linuxvars.system->save_file = system_save_file;
#if 0
linuxvars.system->file_time_stamp = system_file_time_stamp;
linuxvars.system->time_stamp_now = system_time_stamp_now;
linuxvars.system->free_file = system_free_file;
linuxvars.system->get_current_directory = system_get_current_directory;
linuxvars.system->get_easy_directory = system_get_easy_directory;
linuxvars.system->get_file_list = system_get_file_list;
linuxvars.system->free_file_list = system_free_file_list;
linuxvars.system->post_clipboard = system_post_clipboard;
linuxvars.system->time = system_time;
linuxvars.system->cli_call = system_cli_call;
linuxvars.system->cli_begin_update = system_cli_begin_update;
linuxvars.system->cli_update_step = system_cli_update_step;
linuxvars.system->cli_end_update = system_cli_end_update;
linuxvars.system->thread_get_id = system_thread_get_id;
linuxvars.system->thread_current_job_id = system_thread_current_job_id;
linuxvars.system->post_job = system_post_job;
linuxvars.system->cancel_job = system_cancel_job;
linuxvars.system->job_is_pending = system_job_is_pending;
linuxvars.system->grow_thread_memory = system_grow_thread_memory;
linuxvars.system->acquire_lock = system_acquire_lock;
linuxvars.system->release_lock = system_release_lock;
linuxvars.system->force_redraw = system_force_redraw;
linuxvars.system->internal_sentinel = INTERNAL_system_sentinel;
linuxvars.system->internal_get_thread_states = INTERNAL_get_thread_states;
#endif
}
internal void
LinuxShowScreen(){
}
int main(){
linuxvars = {};
if (!LinuxLoadAppCode()){
return(1);
}
System_Functions system_;
System_Functions *system = &system_;
linuxvars.system = system;
LinuxLoadSystemCode();
{ {
void *base; printf("GLX version %d.%d\n", GLXMajor, GLXMinor);
#if FRED_INTERNAL if(((GLXMajor == 1 ) && (GLXMinor >= 3)) ||
base = (void*)Mbytes(128); (GLXMajor > 1))
#else {
base = (void*)0; Result = true;
#endif
i32 prot = PROT_READ | PROT_WRITE;
i32 flags = MAP_PRIVATE | MAP_ANON;
linuxvars.mem.vars_memory_size = Mbytes(2);
linuxvars.mem.vars_memory = mmap(base, linuxvars.mem.vars_memory_size,
prot, flags, -1, 0);
#if FRED_INTERNAL
base = (void*)Mbytes(160);
#else
base = (void*)0;
#endif
linuxvars.mem.target_memory_size = Mbytes(64);
linuxvars.mem.target_memory = mmap(base, linuxvars.mem.target_memory_size,
prot, flags, -1, 0);
}
i32 width = 800;
i32 height = 600;
i32 bpp = 24;
linuxvars.target.width = width;
linuxvars.target.height = height;
keycode_init(&linuxvars.codes);
system_acquire_lock(FRAME_LOCK);
b32 first = 1;
linuxvars.keep_going = 1;
i64 timer_start = system_time();
for (;linuxvars.keep_going;){
linuxvars.input = {};
linuxvars.clipboard = {};
linuxvars.mouse.wheel = 0;
linuxvars.force_redraw = 0;
for (;0;){
} }
}
linuxvars.mouse.left_button_prev = linuxvars.mouse.left_button;
linuxvars.mouse.right_button_prev = linuxvars.mouse.right_button; return(Result);
}
typedef struct glx_config_result{
b32 Found;
GLXFBConfig BestConfig;
XVisualInfo BestInfo;
} glx_config_result;
internal glx_config_result
ChooseGLXConfig(Display *XDisplay, int XScreenIndex)
{
glx_config_result Result = {0};
int DesiredAttributes[] =
{
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_ALPHA_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , True,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};
{
int ConfigCount;
GLXFBConfig *Configs = glXChooseFBConfig(XDisplay,
XScreenIndex,
DesiredAttributes,
&ConfigCount);
#if 0 #if 0
Application_Step_Result app_result = int DiffValues[GLXValueCount];
linuxvars.app.step(linuxvars.system,
&linuxvars.codes,
&linuxvars.input,
&linuxvars.mouse,
&linuxvars.target,
&linuxvars.mem,
linuxvars.clipboard,
1, first, linuxvars.force_redraw);
#else
Application_Step_Result app_result = {};
#endif #endif
{for(int ConfigIndex = 0;
if (1 || linuxvars.force_redraw){ ConfigIndex < ConfigCount;
//glClearColor(1.f, 1.f, 0.f, 1.f); ++ConfigIndex)
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); {
LinuxShowScreen(); GLXFBConfig &Config = Configs[ConfigIndex];
linuxvars.force_redraw = 0; XVisualInfo *VisualInfo = glXGetVisualFromFBConfig(XDisplay, Config);
}
#if 0
i64 timer_target = timer_start + frame_useconds; printf(" Option %d:\n", ConfigIndex);
i64 timer_end = system_time(); printf(" Depth: %d\n", VisualInfo->depth);
for (;timer_end < timer_target;){ printf(" Bits per channel: %d\n", VisualInfo->bits_per_rgb);
i64 samount = timer_target - timer_end; printf(" Mask: R%06x G%06x B%06x\n",
usleep(samount); (uint32)VisualInfo->red_mask,
timer_end = system_time(); (uint32)VisualInfo->green_mask,
} (uint32)VisualInfo->blue_mask);
timer_start = system_time(); printf(" Class: %d\n", VisualInfo->c_class);
#endif
#if 0
{for(int ValueIndex = 0;
ValueIndex < GLXValueCount;
++ValueIndex)
{
glx_value_info &ValueInfo = GLXValues[ValueIndex];
int Value;
glXGetFBConfigAttrib(XDisplay, Config, ValueInfo.ID, &Value);
if(DiffValues[ValueIndex] != Value)
{
printf(" %s: %d\n", ValueInfo.Name, Value);
DiffValues[ValueIndex] = Value;
}
}}
#endif
// TODO(casey): How the hell are you supposed to pick a config here??
if(ConfigIndex == 0)
{
Result.Found = true;
Result.BestConfig = Config;
Result.BestInfo = *VisualInfo;
}
XFree(VisualInfo);
}}
XFree(Configs);
} }
return(Result);
}
internal void
InitializeXInput(Display *dpy, Window XWindow)
{
int event, error;
if(XQueryExtension(dpy, "XInputExtension", &XInput2OpCode, &event, &error))
{
int major = 2, minor = 0;
if(XIQueryVersion(dpy, &major, &minor) != BadRequest)
{
printf("XInput initialized");
}
else
{
printf("XI2 not available. Server supports %d.%d\n", major, minor);
}
}
else
{
printf("X Input extension not available.\n");
}
/*
TODO(casey): So, this is all one big clusterfuck I guess.
The problem here is that you want to be able to get input
from all possible devices that could be a mouse or keyboard
(or gamepad, or whatever). So you'd like to be able to
register events for XIAllDevices, so that when a new
input device is connected, you will start receiving
input from it automatically, without having to periodically
poll XIQueryDevice to see if a new device has appeared.
UNFORTUNATELY, this is not actually possible in Linux because
there was a bug in Xorg (as of early 2013, it is still not
fixed in most distributions people are using, AFAICT) which
makes the XServer return an error if you actually try to
do this :(
But EVENTUALLY, if that shit gets fixed, then that is
the way this should work.
*/
#if 0
int DeviceCount;
XIDeviceInfo *DeviceInfo = XIQueryDevice(dpy, XIAllDevices, &DeviceCount);
{for(int32x DeviceIndex = 0;
DeviceIndex < DeviceCount;
++DeviceIndex)
{
XIDeviceInfo *Device = DeviceInfo + DeviceIndex;
printf("Device %d: %s\n", Device->deviceid, Device->name);
}}
XIFreeDeviceInfo(DeviceInfo);
#endif
return(0); XIEventMask Mask = {0};
Mask.deviceid = XIAllDevices;
Mask.mask_len = XIMaskLen(XI_RawMotion);
size_t MaskSize = Mask.mask_len * sizeof(char unsigned);
Mask.mask = (char unsigned *)alloca(MaskSize);
memset(Mask.mask, 0, MaskSize);
if(Mask.mask)
{
XISetMask(Mask.mask, XI_ButtonPress);
XISetMask(Mask.mask, XI_ButtonRelease);
XISetMask(Mask.mask, XI_KeyPress);
XISetMask(Mask.mask, XI_KeyRelease);
XISetMask(Mask.mask, XI_Motion);
XISetMask(Mask.mask, XI_DeviceChanged);
XISetMask(Mask.mask, XI_Enter);
XISetMask(Mask.mask, XI_Leave);
XISetMask(Mask.mask, XI_FocusIn);
XISetMask(Mask.mask, XI_FocusOut);
XISetMask(Mask.mask, XI_HierarchyChanged);
XISetMask(Mask.mask, XI_PropertyEvent);
XISelectEvents(dpy, XWindow, &Mask, 1);
XSync(dpy, False);
Mask.deviceid = XIAllMasterDevices;
memset(Mask.mask, 0, MaskSize);
XISetMask(Mask.mask, XI_RawKeyPress);
XISetMask(Mask.mask, XI_RawKeyRelease);
XISetMask(Mask.mask, XI_RawButtonPress);
XISetMask(Mask.mask, XI_RawButtonRelease);
XISetMask(Mask.mask, XI_RawMotion);
XISelectEvents(dpy, DefaultRootWindow(dpy), &Mask, 1);
}
}
int
main(int ArgCount, char **Args)
{
Display *XDisplay = XOpenDisplay(0);
if(XDisplay && GLXSupportsModernContexts(XDisplay))
{
int XScreenCount = ScreenCount(XDisplay);
for(int XScreenIndex = 0;
XScreenIndex < XScreenCount;
++XScreenIndex)
{
Screen *XScreen = ScreenOfDisplay(XDisplay, XScreenIndex);
int WinWidth = WidthOfScreen(XScreen);
int WinHeight = HeightOfScreen(XScreen);
glx_config_result Config = ChooseGLXConfig(XDisplay, XScreenIndex);
if(Config.Found)
{
Colormap cmap;
XSetWindowAttributes swa;
swa.colormap = cmap = XCreateColormap(XDisplay,
RootWindow(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),
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);
b32 IsLegacy = false;
GLXContext GLContext =
InitializeOpenGLContext(XDisplay, XWindow, Config.BestConfig, IsLegacy);
XWindowAttributes WinAttribs;
if(XGetWindowAttributes(XDisplay, XWindow, &WinAttribs))
{
WinWidth = WinAttribs.width;
WinHeight = WinAttribs.height;
}
XRaiseWindow(XDisplay, XWindow);
XSync(XDisplay, False);
for(;;)
{
while(XPending(XDisplay))
{
XEvent Event;
XNextEvent(XDisplay, &Event);
if((Event.xcookie.type == GenericEvent) &&
(Event.xcookie.extension == XInput2OpCode) &&
XGetEventData(XDisplay, &Event.xcookie))
{
switch(Event.xcookie.evtype)
{
case XI_Motion:
{
Window root_return, child_return;
int root_x_return, root_y_return;
int MouseX, MouseY;
unsigned int mask_return;
XQueryPointer(XDisplay,
XWindow,
&root_return, &child_return,
&root_x_return, &root_y_return,
&MouseX, &MouseY,
&mask_return);
} break;
case XI_ButtonPress:
case XI_ButtonRelease:
{
b32 Down = (Event.xcookie.evtype == XI_ButtonPress);
XIDeviceEvent *DevEvent = (XIDeviceEvent *)Event.xcookie.data;
int Button = DevEvent->detail;
} break;
case XI_KeyPress:
case XI_KeyRelease:
{
b32 Down = (Event.xcookie.evtype == XI_KeyPress);
XIDeviceEvent *DevEvent = (XIDeviceEvent *)Event.xcookie.data;
int VK = DevEvent->detail;
} break;
}
XFreeEventData(XDisplay, &Event.xcookie);
}
}
// Draw some stuff here?
glXSwapBuffers(XDisplay, XWindow);
}
}
}
}
}
} }
// BOTTOM // BOTTOM

BIN
vc120.pdb

Binary file not shown.

File diff suppressed because it is too large Load Diff