new protection API
parent
e7b67f8236
commit
e9c5f89575
|
@ -203,6 +203,7 @@ struct Buffer_Summary{
|
|||
int exists;
|
||||
int ready;
|
||||
int buffer_id;
|
||||
unsigned int lock_flags;
|
||||
|
||||
int size;
|
||||
|
||||
|
@ -225,8 +226,7 @@ struct View_Summary{
|
|||
int exists;
|
||||
int view_id;
|
||||
int buffer_id;
|
||||
int locked_buffer_id;
|
||||
int hidden_buffer_id;
|
||||
unsigned int lock_flags;
|
||||
|
||||
Full_Cursor cursor;
|
||||
Full_Cursor mark;
|
||||
|
@ -281,6 +281,13 @@ struct Theme_Color{
|
|||
unsigned int color;
|
||||
};
|
||||
|
||||
enum Access_Types{
|
||||
AccessOpen = 0x0,
|
||||
AccessProtected = 0x1,
|
||||
AccessHidden = 0x2,
|
||||
AccessAll = 0xFF
|
||||
};
|
||||
|
||||
|
||||
#define VIEW_ROUTINE_SIG(name) void name(struct Application_Links *app, int view_id)
|
||||
#define GET_BINDING_DATA(name) int name(void *data, int size)
|
||||
|
|
|
@ -9,23 +9,23 @@
|
|||
#define CLIPBOARD_POST_SIG(n) int n(Application_Links *app, char *str, int len)
|
||||
#define CLIPBOARD_COUNT_SIG(n) int n(Application_Links *app)
|
||||
#define CLIPBOARD_INDEX_SIG(n) int n(Application_Links *app, int index, char *out, int len)
|
||||
#define GET_BUFFER_FIRST_SIG(n) Buffer_Summary n(Application_Links *app)
|
||||
#define GET_BUFFER_NEXT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer)
|
||||
#define GET_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int index)
|
||||
#define GET_PARAMETER_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int param_index)
|
||||
#define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int len)
|
||||
#define GET_BUFFER_FIRST_SIG(n) Buffer_Summary n(Application_Links *app, unsigned int access)
|
||||
#define GET_BUFFER_NEXT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer, unsigned int access)
|
||||
#define GET_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int index, unsigned int access)
|
||||
#define GET_PARAMETER_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int param_index, unsigned int access)
|
||||
#define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int len, unsigned int access)
|
||||
#define REFRESH_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer)
|
||||
#define BUFFER_READ_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out)
|
||||
#define BUFFER_REPLACE_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len)
|
||||
#define BUFFER_SEEK_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start_pos, int seek_forward, unsigned int flags)
|
||||
#define BUFFER_REPLACE_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len)
|
||||
#define BUFFER_SET_SETTING_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int setting, int value)
|
||||
#define CREATE_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int filename_len, int do_in_background)
|
||||
#define SAVE_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, char *filename, int filename_len)
|
||||
#define KILL_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Identifier buffer, int always_kill, int view_id)
|
||||
#define GET_VIEW_FIRST_SIG(n) View_Summary n(Application_Links *app)
|
||||
#define GET_VIEW_NEXT_SIG(n) void n(Application_Links *app, View_Summary *view)
|
||||
#define GET_VIEW_SIG(n) View_Summary n(Application_Links *app, int index)
|
||||
#define GET_ACTIVE_VIEW_SIG(n) View_Summary n(Application_Links *app)
|
||||
#define GET_VIEW_FIRST_SIG(n) View_Summary n(Application_Links *app, unsigned int access)
|
||||
#define GET_VIEW_NEXT_SIG(n) void n(Application_Links *app, View_Summary *view, unsigned int access)
|
||||
#define GET_VIEW_SIG(n) View_Summary n(Application_Links *app, int index, unsigned int access)
|
||||
#define GET_ACTIVE_VIEW_SIG(n) View_Summary n(Application_Links *app, unsigned int access)
|
||||
#define REFRESH_VIEW_SIG(n) int n(Application_Links *app, View_Summary *view)
|
||||
#define VIEW_AUTO_TAB_SIG(n) int n(Application_Links *app, View_Summary *view, int start, int end, int tab_width, unsigned int flags)
|
||||
#define VIEW_COMPUTE_CURSOR_SIG(n) Full_Cursor n(Application_Links *app, View_Summary *view, Buffer_Seek seek)
|
||||
|
@ -66,8 +66,8 @@ extern "C"{
|
|||
typedef GET_BUFFER_BY_NAME_SIG(Get_Buffer_By_Name_Function);
|
||||
typedef REFRESH_BUFFER_SIG(Refresh_Buffer_Function);
|
||||
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
|
||||
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
||||
typedef BUFFER_SEEK_SIG(Buffer_Seek_Function);
|
||||
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
||||
typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_Function);
|
||||
typedef CREATE_BUFFER_SIG(Create_Buffer_Function);
|
||||
typedef SAVE_BUFFER_SIG(Save_Buffer_Function);
|
||||
|
@ -119,8 +119,8 @@ struct Application_Links{
|
|||
Get_Buffer_By_Name_Function *get_buffer_by_name;
|
||||
Refresh_Buffer_Function *refresh_buffer;
|
||||
Buffer_Read_Range_Function *buffer_read_range;
|
||||
Buffer_Replace_Range_Function *buffer_replace_range;
|
||||
Buffer_Seek_Function *buffer_seek;
|
||||
Buffer_Replace_Range_Function *buffer_replace_range;
|
||||
Buffer_Set_Setting_Function *buffer_set_setting;
|
||||
Create_Buffer_Function *create_buffer;
|
||||
Save_Buffer_Function *save_buffer;
|
||||
|
@ -174,8 +174,8 @@ app_links->get_parameter_buffer = external_get_parameter_buffer;\
|
|||
app_links->get_buffer_by_name = external_get_buffer_by_name;\
|
||||
app_links->refresh_buffer = external_refresh_buffer;\
|
||||
app_links->buffer_read_range = external_buffer_read_range;\
|
||||
app_links->buffer_replace_range = external_buffer_replace_range;\
|
||||
app_links->buffer_seek = external_buffer_seek;\
|
||||
app_links->buffer_replace_range = external_buffer_replace_range;\
|
||||
app_links->buffer_set_setting = external_buffer_set_setting;\
|
||||
app_links->create_buffer = external_create_buffer;\
|
||||
app_links->save_buffer = external_save_buffer;\
|
||||
|
|
|
@ -43,8 +43,9 @@ CUSTOM_COMMAND_SIG(switch_to_compilation){
|
|||
char name[] = "*compilation*";
|
||||
int name_size = sizeof(name)-1;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer_by_name(app, name, name_size);
|
||||
unsigned int access = AccessOpen;
|
||||
view = app->get_active_view(app, access);
|
||||
buffer = app->get_buffer_by_name(app, name, name_size, access);
|
||||
|
||||
app->view_set_buffer(app, &view, buffer.buffer_id);
|
||||
}
|
||||
|
@ -57,7 +58,8 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
String string;
|
||||
int is_first, i;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
view = app->get_active_view(app, access);
|
||||
cursor = view.cursor;
|
||||
|
||||
exec_command(app, seek_token_left);
|
||||
|
@ -72,7 +74,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
string.size = range.max - range.min;
|
||||
assert(string.size < app->memory_size);
|
||||
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
app->buffer_read_range(app, &buffer, range.min, range.max, string.str);
|
||||
|
||||
is_first = 1;
|
||||
|
@ -95,13 +97,15 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
|
||||
CUSTOM_COMMAND_SIG(open_my_files){
|
||||
// TODO(allen|a4.0.8): comment
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
view_open_file(app, &view, literal("w:/4ed/data/test/basic.cpp"), false);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(build_at_launch_location){
|
||||
// TODO(allen|a4.0.8): comment
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
app->exec_system_command(app, &view,
|
||||
buffer_identifier(literal("*compilation*")),
|
||||
literal("."),
|
||||
|
@ -139,7 +143,8 @@ HOOK_SIG(my_file_settings){
|
|||
// opened hook. The file created hook is guaranteed to have only
|
||||
// and exactly one buffer parameter. In normal command callbacks
|
||||
// there are no parameter buffers.
|
||||
Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
Buffer_Summary buffer = app->get_parameter_buffer(app, 0, access);
|
||||
assert(buffer.exists);
|
||||
|
||||
int treat_as_code = 0;
|
||||
|
|
|
@ -37,7 +37,8 @@ get_view_x(View_Summary view){
|
|||
//
|
||||
|
||||
CUSTOM_COMMAND_SIG(write_character){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
User_Input in = app->get_command_input(app);
|
||||
char character = 0;
|
||||
|
@ -47,7 +48,8 @@ CUSTOM_COMMAND_SIG(write_character){
|
|||
}
|
||||
|
||||
if (character != 0){
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int pos = view.cursor.pos;
|
||||
int next_pos = pos + 1;
|
||||
app->buffer_replace_range(app, &buffer,
|
||||
|
@ -57,8 +59,9 @@ CUSTOM_COMMAND_SIG(write_character){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(delete_char){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int pos = view.cursor.pos;
|
||||
if (0 < buffer.size && pos < buffer.size){
|
||||
|
@ -68,8 +71,9 @@ CUSTOM_COMMAND_SIG(delete_char){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(backspace_char){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int pos = view.cursor.pos;
|
||||
if (0 < pos && pos <= buffer.size){
|
||||
|
@ -81,7 +85,8 @@ CUSTOM_COMMAND_SIG(backspace_char){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(set_mark){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
app->view_set_mark(app, &view, seek_pos(view.cursor.pos));
|
||||
// TODO(allen): Just expose the preferred_x seperately
|
||||
|
@ -89,7 +94,8 @@ CUSTOM_COMMAND_SIG(set_mark){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(cursor_mark_swap){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
int cursor = view.cursor.pos;
|
||||
int mark = view.mark.pos;
|
||||
|
@ -99,8 +105,9 @@ CUSTOM_COMMAND_SIG(cursor_mark_swap){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(delete_range){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
Range range = get_range(&view);
|
||||
|
||||
|
@ -139,11 +146,9 @@ get_relative_xy(View_Summary *view, int x, int y, float *x_out, float *y_out){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(click_set_cursor){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
// TODO(allen): Need a better system for
|
||||
// weeding out views in a hidden state.
|
||||
if (view.locked_buffer_id != 0){
|
||||
Mouse_State mouse = app->get_mouse_state(app);
|
||||
float rx = 0, ry = 0;
|
||||
if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){
|
||||
|
@ -153,12 +158,11 @@ CUSTOM_COMMAND_SIG(click_set_cursor){
|
|||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(click_set_mark){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
if (view.locked_buffer_id != 0){
|
||||
Mouse_State mouse = app->get_mouse_state(app);
|
||||
float rx = 0, ry = 0;
|
||||
if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){
|
||||
|
@ -168,11 +172,11 @@ CUSTOM_COMMAND_SIG(click_set_mark){
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
move_vertical(Application_Links *app, float line_multiplier){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
float new_y = get_view_y(view) + line_multiplier*view.line_height;
|
||||
float x = view.preferred_x;
|
||||
|
@ -200,7 +204,8 @@ CUSTOM_COMMAND_SIG(move_down_10){
|
|||
|
||||
|
||||
CUSTOM_COMMAND_SIG(move_left){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
int new_pos = view.cursor.pos - 1;
|
||||
app->view_set_cursor(app, &view,
|
||||
seek_pos(new_pos),
|
||||
|
@ -208,7 +213,8 @@ CUSTOM_COMMAND_SIG(move_left){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(move_right){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
int new_pos = view.cursor.pos + 1;
|
||||
app->view_set_cursor(app, &view,
|
||||
seek_pos(new_pos),
|
||||
|
@ -221,9 +227,10 @@ CUSTOM_COMMAND_SIG(move_right){
|
|||
//
|
||||
|
||||
static int
|
||||
clipboard_copy(Application_Links *app, int start, int end, Buffer_Summary *buffer_out){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
clipboard_copy(Application_Links *app, int start, int end, Buffer_Summary *buffer_out,
|
||||
unsigned int access){
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
int result = false;
|
||||
|
||||
if (0 <= start && start <= end && end <= buffer.size){
|
||||
|
@ -242,11 +249,12 @@ clipboard_copy(Application_Links *app, int start, int end, Buffer_Summary *buffe
|
|||
}
|
||||
|
||||
static int
|
||||
clipboard_cut(Application_Links *app, int start, int end, Buffer_Summary *buffer_out){
|
||||
clipboard_cut(Application_Links *app, int start, int end, Buffer_Summary *buffer_out,
|
||||
unsigned int access){
|
||||
Buffer_Summary buffer = {0};
|
||||
int result = false;
|
||||
|
||||
if (clipboard_copy(app, start, end, &buffer)){
|
||||
if (clipboard_copy(app, start, end, &buffer, access)){
|
||||
app->buffer_replace_range(app, &buffer, start, end, 0, 0);
|
||||
if (buffer_out){*buffer_out = buffer;}
|
||||
}
|
||||
|
@ -255,15 +263,17 @@ clipboard_cut(Application_Links *app, int start, int end, Buffer_Summary *buffer
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(copy){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Range range = get_range(&view);
|
||||
clipboard_copy(app, range.min, range.max, 0);
|
||||
clipboard_copy(app, range.min, range.max, 0, access);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(cut){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Range range = get_range(&view);
|
||||
clipboard_cut(app, range.min, range.max, 0);
|
||||
clipboard_cut(app, range.min, range.max, 0, access);
|
||||
}
|
||||
|
||||
struct View_Paste_Index{
|
||||
|
@ -274,9 +284,10 @@ View_Paste_Index view_paste_index_[16];
|
|||
View_Paste_Index *view_paste_index = view_paste_index_ - 1;
|
||||
|
||||
CUSTOM_COMMAND_SIG(paste){
|
||||
unsigned int access = AccessOpen;
|
||||
int count = app->clipboard_count(app);
|
||||
if (count > 0){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
// NOTE(allen): THIS is a very temporary poop-sauce
|
||||
// system that I just threw in to get this working.
|
||||
|
@ -296,7 +307,7 @@ CUSTOM_COMMAND_SIG(paste){
|
|||
if (str){
|
||||
app->clipboard_index(app, paste_index, str, len);
|
||||
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
int pos = view.cursor.pos;
|
||||
app->buffer_replace_range(app, &buffer, pos, pos, str, len);
|
||||
app->view_set_mark(app, &view, seek_pos(pos));
|
||||
|
@ -312,9 +323,10 @@ CUSTOM_COMMAND_SIG(paste){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(paste_next){
|
||||
unsigned int access = AccessOpen;
|
||||
int count = app->clipboard_count(app);
|
||||
if (count > 0){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
// NOTE(allen): THIS is a very temporary poop-sauce
|
||||
// system that I just threw in to get this working.
|
||||
|
@ -335,7 +347,7 @@ CUSTOM_COMMAND_SIG(paste_next){
|
|||
if (str){
|
||||
app->clipboard_index(app, paste_index, str, len);
|
||||
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
Range range = get_range(&view);
|
||||
int pos = range.min;
|
||||
|
||||
|
@ -483,8 +495,9 @@ buffer_seek_whitespace_down(Application_Links *app, Buffer_Summary *buffer, int
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(seek_whitespace_up){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int new_pos = buffer_seek_whitespace_up(app, &buffer, view.cursor.pos);
|
||||
app->view_set_cursor(app, &view,
|
||||
|
@ -493,8 +506,9 @@ CUSTOM_COMMAND_SIG(seek_whitespace_up){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(seek_whitespace_down){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int new_pos = buffer_seek_whitespace_down(app, &buffer, view.cursor.pos);
|
||||
app->view_set_cursor(app, &view,
|
||||
|
@ -567,16 +581,18 @@ seek_line_beginning(Application_Links *app, Buffer_Summary *buffer, int pos){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(seek_end_of_line){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int new_pos = seek_line_end(app, &buffer, view.cursor.pos);
|
||||
app->view_set_cursor(app, &view, seek_pos(new_pos), true);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(seek_beginning_of_line){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int new_pos = seek_line_beginning(app, &buffer, view.cursor.pos);
|
||||
app->view_set_cursor(app, &view, seek_pos(new_pos), true);
|
||||
|
@ -584,8 +600,9 @@ CUSTOM_COMMAND_SIG(seek_beginning_of_line){
|
|||
|
||||
static void
|
||||
basic_seek(Application_Links *app, int seek_type, unsigned int flags){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
int pos = app->buffer_seek(app, &buffer, view.cursor.pos, seek_type, flags);
|
||||
app->view_set_cursor(app, &view, seek_pos(pos), true);
|
||||
}
|
||||
|
@ -617,7 +634,8 @@ SEEK_COMMAND(alphanumeric_or_camel, left, BoundryAlphanumeric | BoundryCamelCas
|
|||
|
||||
static void
|
||||
write_string(Application_Links *app, String string){
|
||||
Buffer_Summary buffer = get_active_buffer(app);
|
||||
unsigned int access = AccessOpen;
|
||||
Buffer_Summary buffer = get_active_buffer(app, access);
|
||||
app->buffer_replace_range(app, &buffer,
|
||||
buffer.buffer_cursor_pos, buffer.buffer_cursor_pos,
|
||||
string.str, string.size);
|
||||
|
@ -633,13 +651,11 @@ CUSTOM_COMMAND_SIG(write_increment){
|
|||
|
||||
static void
|
||||
long_braces(Application_Links *app, char *text, int size){
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
int pos;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
|
||||
pos = view.cursor.pos;
|
||||
app->buffer_replace_range(app, &buffer, pos, pos, text, size);
|
||||
app->view_set_cursor(app, &view, seek_pos(pos + 2), true);
|
||||
|
@ -671,6 +687,8 @@ CUSTOM_COMMAND_SIG(open_long_braces_break){
|
|||
// TODO(allen): Have this thing check if it is on
|
||||
// a blank line and insert newlines as needed.
|
||||
CUSTOM_COMMAND_SIG(if0_off){
|
||||
unsigned int access = AccessOpen;
|
||||
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
|
||||
|
@ -683,8 +701,8 @@ CUSTOM_COMMAND_SIG(if0_off){
|
|||
Range range;
|
||||
int pos;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
view = app->get_active_view(app, access);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
range = get_range(&view);
|
||||
pos = range.min;
|
||||
|
@ -709,44 +727,50 @@ CUSTOM_COMMAND_SIG(if0_off){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(backspace_word){
|
||||
unsigned int access = AccessOpen;
|
||||
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
int pos2, pos1;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
view = app->get_active_view(app, access);
|
||||
|
||||
pos2 = view.cursor.pos;
|
||||
exec_command(app, seek_alphanumeric_left);
|
||||
app->refresh_view(app, &view);
|
||||
pos1 = view.cursor.pos;
|
||||
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(delete_word){
|
||||
unsigned int access = AccessOpen;
|
||||
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
int pos2, pos1;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
view = app->get_active_view(app, access);
|
||||
|
||||
pos1 = view.cursor.pos;
|
||||
exec_command(app, seek_alphanumeric_right);
|
||||
app->refresh_view(app, &view);
|
||||
pos2 = view.cursor.pos;
|
||||
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(snipe_token_or_word){
|
||||
unsigned int access = AccessOpen;
|
||||
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
int pos1, pos2;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
view = app->get_active_view(app, access);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
pos1 = app->buffer_seek(app, &buffer, view.cursor.pos, false, BoundryToken | BoundryWhitespace);
|
||||
|
||||
|
@ -757,13 +781,15 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(open_file_in_quotes){
|
||||
unsigned int access = AccessProtected;
|
||||
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
char short_file_name[128];
|
||||
int pos, start, end, size;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
view = app->get_active_view(app, access);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
pos = view.cursor.pos;
|
||||
buffer_seek_delimiter_forward(app, &buffer, pos, '"', &end);
|
||||
buffer_seek_delimiter_backward(app, &buffer, pos, '"', &start);
|
||||
|
@ -793,6 +819,8 @@ CUSTOM_COMMAND_SIG(save_as){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(goto_line){
|
||||
unsigned int access = AccessProtected;
|
||||
|
||||
int line_number;
|
||||
Query_Bar bar;
|
||||
char string_space[256];
|
||||
|
@ -802,7 +830,7 @@ CUSTOM_COMMAND_SIG(goto_line){
|
|||
|
||||
if (query_user_number(app, &bar)){
|
||||
line_number = str_to_int(bar.string);
|
||||
active_view_to_line(app, line_number);
|
||||
active_view_to_line(app, access, line_number);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,14 +839,13 @@ CUSTOM_COMMAND_SIG(reverse_search);
|
|||
|
||||
static void
|
||||
isearch(Application_Links *app, int start_reversed){
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
unsigned int access = AccessProtected;
|
||||
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
User_Input in;
|
||||
Query_Bar bar;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.locked_buffer_id);
|
||||
|
||||
if (!buffer.exists) return;
|
||||
|
||||
if (app->start_query_bar(app, &bar, 0) == 0) return;
|
||||
|
@ -960,11 +987,9 @@ CUSTOM_COMMAND_SIG(replace_in_range){
|
|||
r = replace.string;
|
||||
w = with.string;
|
||||
|
||||
Buffer_Summary buffer;
|
||||
View_Summary view;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
Range range = get_range(&view);
|
||||
|
||||
|
@ -1011,8 +1036,9 @@ CUSTOM_COMMAND_SIG(query_replace){
|
|||
|
||||
app->start_query_bar(app, &bar, 0);
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
view = app->get_active_view(app, access);
|
||||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
pos = view.cursor.pos;
|
||||
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
|
||||
|
@ -1051,9 +1077,10 @@ CUSTOM_COMMAND_SIG(close_all_code){
|
|||
int buffers_to_close[2048];
|
||||
int buffers_to_close_count = 0;
|
||||
|
||||
for (buffer = app->get_buffer_first(app);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
for (buffer = app->get_buffer_first(app, access);
|
||||
buffer.exists;
|
||||
app->get_buffer_next(app, &buffer)){
|
||||
app->get_buffer_next(app, &buffer, access)){
|
||||
|
||||
extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
if (match(extension, make_lit_string("cpp")) ||
|
||||
|
@ -1123,8 +1150,8 @@ CUSTOM_COMMAND_SIG(execute_any_cli){
|
|||
hot_directory = make_fixed_width_string(hot_directory_space);
|
||||
hot_directory.size = app->directory_get_hot(app, hot_directory.str, hot_directory.memory_size);
|
||||
|
||||
// TODO(allen): provide command line call
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
// TODO(allen): Make this work without null terminators
|
||||
terminate_with_null(&bar_out.string);
|
||||
|
@ -1147,7 +1174,8 @@ CUSTOM_COMMAND_SIG(execute_previous_cli){
|
|||
hot_directory = make_string_slowly(hot_directory_space);
|
||||
|
||||
if (out_buffer.size > 0 && cmd.size > 0 && hot_directory.size > 0){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
app->exec_system_command(app, &view,
|
||||
buffer_identifier(out_buffer.str, out_buffer.size),
|
||||
|
@ -1257,7 +1285,8 @@ CUSTOM_COMMAND_SIG(build_search){
|
|||
append(&command, "build");
|
||||
append(&command, '"');
|
||||
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
terminate_with_null(&dir);
|
||||
terminate_with_null(&command);
|
||||
|
@ -1281,7 +1310,8 @@ CUSTOM_COMMAND_SIG(build_search){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
app->view_auto_tab(app, &view,
|
||||
view.cursor.pos, view.cursor.pos,
|
||||
|
@ -1290,8 +1320,9 @@ CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_tab_whole_file){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
app->view_auto_tab(app, &view,
|
||||
0, buffer.size,
|
||||
|
@ -1300,7 +1331,8 @@ CUSTOM_COMMAND_SIG(auto_tab_whole_file){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_tab_range){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Range range = get_range(&view);
|
||||
|
||||
app->view_auto_tab(app, &view,
|
||||
|
|
|
@ -241,9 +241,9 @@ exec_command(Application_Links *app, Custom_Command_Function *func){
|
|||
}
|
||||
|
||||
inline void
|
||||
active_view_to_line(Application_Links *app, int line_number){
|
||||
active_view_to_line(Application_Links *app, unsigned int access, int line_number){
|
||||
View_Summary view;
|
||||
view = app->get_active_view(app);
|
||||
view = app->get_active_view(app, access);
|
||||
|
||||
// NOTE(allen|a3.4.4): We don't have to worry about whether this is a valid line number.
|
||||
// When it's not possible to place a cursor at the position for whatever reason it will set the
|
||||
|
@ -256,10 +256,14 @@ get_first_view_with_buffer(Application_Links *app, int buffer_id){
|
|||
View_Summary result = {};
|
||||
View_Summary test = {};
|
||||
|
||||
for(test = app->get_view_first(app);
|
||||
unsigned int access = AccessProtected|AccessHidden;
|
||||
for(test = app->get_view_first(app, access);
|
||||
test.exists;
|
||||
app->get_view_next(app, &test)){
|
||||
if(test.locked_buffer_id == buffer_id){
|
||||
app->get_view_next(app, &test, access)){
|
||||
|
||||
Buffer_Summary buffer = app->get_buffer(app, test.buffer_id, access);
|
||||
|
||||
if(buffer.buffer_id == buffer_id){
|
||||
result = test;
|
||||
break;
|
||||
}
|
||||
|
@ -352,9 +356,9 @@ query_user_number(Application_Links *app, Query_Bar *bar){
|
|||
inline String empty_string() {String Result = {}; return(Result);}
|
||||
|
||||
inline Buffer_Summary
|
||||
get_active_buffer(Application_Links *app){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
get_active_buffer(Application_Links *app, unsigned int access){
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
return(buffer);
|
||||
}
|
||||
|
||||
|
@ -729,7 +733,7 @@ static int
|
|||
view_open_file(Application_Links *app, View_Summary *view,
|
||||
char *filename, int filename_len, int do_in_background){
|
||||
int result = false;
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, filename, filename_len);
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, filename, filename_len, AccessProtected|AccessHidden);
|
||||
if (buffer.exists){
|
||||
app->view_set_buffer(app, view, buffer.buffer_id);
|
||||
result = true;
|
||||
|
|
2
4ed.cpp
2
4ed.cpp
|
@ -260,7 +260,7 @@ do_feedback_message(System_Functions *system, Models *models, String value){
|
|||
#define USE_FILE(n,v) Editing_File *n = (v)->file_data.file
|
||||
|
||||
#define REQ_OPEN_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_Open) return
|
||||
#define REQ_READABLE_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_NoWrite) return
|
||||
#define REQ_READABLE_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_Protected) return
|
||||
|
||||
#define REQ_FILE(n,v) Editing_File *n = (v)->file_data.file; if (!n) return
|
||||
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file_data.file; if (!n || !n->state.undo.undo.edits) return
|
||||
|
|
|
@ -4,6 +4,17 @@ The implementation for the custom API
|
|||
|
||||
// TOP
|
||||
|
||||
inline b32
|
||||
access_test(u32 lock_flags, u32 access_flags){
|
||||
b32 result = 0;
|
||||
|
||||
if ((lock_flags & ~access_flags) == 0){
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *working_set){
|
||||
*buffer = buffer_summary_zero();
|
||||
|
@ -22,6 +33,11 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor
|
|||
buffer->buffer_name = file->name.live_name.str;
|
||||
|
||||
buffer->map_id = file->settings.base_map_id;
|
||||
|
||||
buffer->lock_flags = 0;
|
||||
if (file->settings.read_only){
|
||||
buffer->lock_flags |= AccessProtected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,8 +49,9 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Command_Data *cm
|
|||
|
||||
internal void
|
||||
fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){
|
||||
i32 lock_level;
|
||||
int buffer_id;
|
||||
File_Viewing_Data *data = &vptr->file_data;
|
||||
|
||||
*view = view_summary_zero();
|
||||
|
||||
if (vptr->in_use){
|
||||
|
@ -43,32 +60,12 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_
|
|||
view->line_height = (float)(vptr->line_height);
|
||||
view->unwrapped_lines = vptr->file_data.unwrapped_lines;
|
||||
view->show_whitespace = vptr->file_data.show_whitespace;
|
||||
view->lock_flags = view_lock_flags(vptr);
|
||||
|
||||
|
||||
if (vptr->file_data.file){
|
||||
lock_level = view_lock_level(vptr);
|
||||
if (data->file){
|
||||
buffer_id = vptr->file_data.file->id.id;
|
||||
|
||||
if (lock_level <= 0){
|
||||
view->buffer_id = buffer_id;
|
||||
}
|
||||
else{
|
||||
view->buffer_id = 0;
|
||||
}
|
||||
|
||||
if (lock_level <= 1){
|
||||
view->locked_buffer_id = buffer_id;
|
||||
}
|
||||
else{
|
||||
view->locked_buffer_id = 0;
|
||||
}
|
||||
|
||||
if (lock_level <= 2){
|
||||
view->hidden_buffer_id = buffer_id;
|
||||
}
|
||||
else{
|
||||
view->hidden_buffer_id = 0;
|
||||
}
|
||||
|
||||
view->mark = view_compute_cursor_from_pos(vptr, vptr->recent->mark);
|
||||
view->cursor = vptr->recent->cursor;
|
||||
|
@ -384,19 +381,15 @@ CLIPBOARD_INDEX_SIG(external_clipboard_index){
|
|||
return(size);
|
||||
}
|
||||
|
||||
GET_BUFFER_FIRST_SIG(external_get_buffer_first){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
Buffer_Summary result = {};
|
||||
internal void
|
||||
internal_get_buffer_first(Working_Set *working_set, Buffer_Summary *buffer){
|
||||
if (working_set->file_count > 0){
|
||||
fill_buffer_summary(&result, (Editing_File*)working_set->used_sentinel.next, working_set);
|
||||
fill_buffer_summary(buffer, (Editing_File*)working_set->used_sentinel.next, working_set);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
GET_BUFFER_NEXT_SIG(external_get_buffer_next){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
internal void
|
||||
internal_get_buffer_next(Working_Set *working_set, Buffer_Summary *buffer){
|
||||
Editing_File *file;
|
||||
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
|
@ -409,6 +402,29 @@ GET_BUFFER_NEXT_SIG(external_get_buffer_next){
|
|||
}
|
||||
}
|
||||
|
||||
GET_BUFFER_FIRST_SIG(external_get_buffer_first){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
Buffer_Summary result = {};
|
||||
|
||||
internal_get_buffer_first(working_set, &result);
|
||||
while (result.exists && !access_test(result.lock_flags, access)){
|
||||
internal_get_buffer_next(working_set, &result);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
GET_BUFFER_NEXT_SIG(external_get_buffer_next){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
|
||||
internal_get_buffer_next(working_set, buffer);
|
||||
while (buffer->exists && !access_test(buffer->lock_flags, access)){
|
||||
internal_get_buffer_next(working_set, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
GET_BUFFER_SIG(external_get_buffer){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
|
@ -418,6 +434,9 @@ GET_BUFFER_SIG(external_get_buffer){
|
|||
file = working_set_get_active_file(working_set, index);
|
||||
if (file){
|
||||
fill_buffer_summary(&buffer, file, working_set);
|
||||
if (!access_test(buffer.lock_flags, access)){
|
||||
buffer = buffer_summary_zero();
|
||||
}
|
||||
}
|
||||
|
||||
return(buffer);
|
||||
|
@ -429,7 +448,7 @@ GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){
|
|||
Buffer_Summary buffer = {};
|
||||
|
||||
if (param_index >= 0 && param_index < models->buffer_param_count){
|
||||
buffer = external_get_buffer(app, models->buffer_param_indices[param_index]);
|
||||
buffer = external_get_buffer(app, models->buffer_param_indices[param_index], access);
|
||||
}
|
||||
|
||||
return(buffer);
|
||||
|
@ -444,6 +463,9 @@ GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name){
|
|||
file = working_set_contains(cmd->system, working_set, make_string(filename, len));
|
||||
if (file && !file->is_dummy){
|
||||
fill_buffer_summary(&buffer, file, working_set);
|
||||
if (!access_test(buffer.lock_flags, access)){
|
||||
buffer = buffer_summary_zero();
|
||||
}
|
||||
}
|
||||
|
||||
return(buffer);
|
||||
|
@ -451,7 +473,7 @@ GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name){
|
|||
|
||||
REFRESH_BUFFER_SIG(external_refresh_buffer){
|
||||
int result;
|
||||
*buffer = external_get_buffer(app, buffer->buffer_id);
|
||||
*buffer = external_get_buffer(app, buffer->buffer_id, AccessAll);
|
||||
result = buffer->exists;
|
||||
return(result);
|
||||
}
|
||||
|
@ -465,7 +487,6 @@ BUFFER_SEEK_SIG(external_buffer_seek){
|
|||
|
||||
if (file){
|
||||
// TODO(allen): reduce duplication?
|
||||
{
|
||||
i32 size = buffer_size(&file->state.buffer);
|
||||
i32 pos[4] = {0};
|
||||
i32 new_pos = 0;
|
||||
|
@ -542,7 +563,6 @@ BUFFER_SEEK_SIG(external_buffer_seek){
|
|||
}
|
||||
}
|
||||
result = new_pos;
|
||||
}
|
||||
|
||||
fill_buffer_summary(buffer, file, cmd);
|
||||
}
|
||||
|
@ -766,31 +786,29 @@ KILL_BUFFER_SIG(external_kill_buffer){
|
|||
return(result);
|
||||
}
|
||||
|
||||
GET_VIEW_FIRST_SIG(external_get_view_first){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
internal void
|
||||
internal_get_view_first(Command_Data *cmd, View_Summary *view){
|
||||
Editing_Layout *layout = &cmd->models->layout;
|
||||
View_Summary view = {};
|
||||
|
||||
Panel *panel = layout->used_sentinel.next;
|
||||
|
||||
Assert(panel != &layout->used_sentinel);
|
||||
fill_view_summary(&view, panel->view, cmd);
|
||||
|
||||
return(view);
|
||||
fill_view_summary(view, panel->view, cmd);
|
||||
}
|
||||
|
||||
GET_VIEW_NEXT_SIG(external_get_view_next){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
internal void
|
||||
internal_get_view_next(Command_Data *cmd, View_Summary *view){
|
||||
Editing_Layout *layout = &cmd->models->layout;
|
||||
Live_Views *live_set = &cmd->vars->live_set;
|
||||
View *vptr;
|
||||
Panel *panel;
|
||||
int index = view->view_id - 1;
|
||||
View *vptr = 0;
|
||||
Panel *panel = 0;
|
||||
|
||||
if (index >= 0 && index < live_set->max){
|
||||
vptr = live_set->views + index;
|
||||
panel = vptr->panel;
|
||||
if (panel) panel = panel->next;
|
||||
if (panel){
|
||||
panel = panel->next;
|
||||
}
|
||||
if (panel && panel != &layout->used_sentinel){
|
||||
fill_view_summary(view, panel->view, &cmd->vars->live_set, &cmd->models->working_set);
|
||||
}
|
||||
|
@ -803,17 +821,41 @@ GET_VIEW_NEXT_SIG(external_get_view_next){
|
|||
}
|
||||
}
|
||||
|
||||
GET_VIEW_FIRST_SIG(external_get_view_first){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
View_Summary view = {};
|
||||
|
||||
internal_get_view_first(cmd, &view);
|
||||
while (view.exists && !access_test(view.lock_flags, access)){
|
||||
internal_get_view_next(cmd, &view);
|
||||
}
|
||||
|
||||
return(view);
|
||||
}
|
||||
|
||||
GET_VIEW_NEXT_SIG(external_get_view_next){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
|
||||
internal_get_view_next(cmd, view);
|
||||
while (view->exists && !access_test(view->lock_flags, access)){
|
||||
internal_get_view_next(cmd, view);
|
||||
}
|
||||
}
|
||||
|
||||
GET_VIEW_SIG(external_get_view){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
View_Summary view = {};
|
||||
Live_Views *live_set = cmd->live_set;
|
||||
int max = live_set->max;
|
||||
View *vptr;
|
||||
View *vptr = 0;
|
||||
|
||||
index -= 1;
|
||||
if (index >= 0 && index < max){
|
||||
vptr = live_set->views + index;
|
||||
fill_view_summary(&view, vptr, live_set, &cmd->models->working_set);
|
||||
if (!access_test(view.lock_flags, access)){
|
||||
view = view_summary_zero();
|
||||
}
|
||||
}
|
||||
|
||||
return(view);
|
||||
|
@ -823,12 +865,15 @@ GET_ACTIVE_VIEW_SIG(external_get_active_view){
|
|||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
View_Summary view = {};
|
||||
fill_view_summary(&view, cmd->view, &cmd->vars->live_set, &cmd->models->working_set);
|
||||
if (!access_test(view.lock_flags, access)){
|
||||
view = view_summary_zero();
|
||||
}
|
||||
return(view);
|
||||
}
|
||||
|
||||
REFRESH_VIEW_SIG(external_refresh_view){
|
||||
int result;
|
||||
*view = external_get_view(app, view->view_id);
|
||||
*view = external_get_view(app, view->view_id, AccessAll);
|
||||
result = view->exists;
|
||||
return(result);
|
||||
}
|
||||
|
|
|
@ -300,16 +300,36 @@ struct Live_Views{
|
|||
i32 count, max;
|
||||
};
|
||||
|
||||
#define LockLevel_Open 0
|
||||
#define LockLevel_NoWrite 1
|
||||
#define LockLevel_NoUpdate 2
|
||||
enum Lock_Level{
|
||||
LockLevel_Open = 0,
|
||||
LockLevel_Protected = 1,
|
||||
LockLevel_Hidden = 2
|
||||
};
|
||||
|
||||
inline u32
|
||||
view_lock_flags(View *view){
|
||||
u32 result = AccessOpen;
|
||||
File_Viewing_Data *data = &view->file_data;
|
||||
if (view->showing_ui != VUI_None){
|
||||
result |= AccessHidden;
|
||||
}
|
||||
if (data->file_locked ||
|
||||
(data->file && data->file->settings.read_only)){
|
||||
result |= AccessProtected;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline i32
|
||||
view_lock_level(View *view){
|
||||
i32 result = LockLevel_Open;
|
||||
File_Viewing_Data *data = &view->file_data;
|
||||
if (view->showing_ui != VUI_None) result = LockLevel_NoUpdate;
|
||||
else if (data->file_locked || (data->file && data->file->settings.read_only)) result = LockLevel_NoWrite;
|
||||
u32 flags = view_lock_flags(view);
|
||||
if (flags & AccessHidden){
|
||||
result = LockLevel_Hidden;
|
||||
}
|
||||
else if (flags & AccessProtected){
|
||||
result = LockLevel_Protected;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -434,6 +434,7 @@ generate_custom_headers(){
|
|||
if (parse.size > 0){
|
||||
pos = find(parse, 0, '(');
|
||||
sig->name = substr(parse, 0, pos);
|
||||
sig->name = chop_whitespace(sig->name);
|
||||
parse = substr(parse, pos);
|
||||
|
||||
if (parse.size > 0){
|
||||
|
|
|
@ -362,7 +362,7 @@ part_free(void *ptr, void *context){
|
|||
// of this function (and other functions implementing
|
||||
// the same interface).
|
||||
internal i32
|
||||
draw_font_load(Partition *part,
|
||||
font_load(Partition *part,
|
||||
Render_Font *font_out,
|
||||
char *filename_untranslated,
|
||||
i32 pt_size,
|
||||
|
|
|
@ -17,18 +17,19 @@ int Clipboard_Count(Application_Links *app);
|
|||
int Clipboard_Index(Application_Links *app, int index, char *out, int len);
|
||||
|
||||
// Direct buffer manipulation
|
||||
Buffer_Summary Get_Buffer_First(Application_Links *app);
|
||||
void Get_Buffer_Next(Application_Links *app, Buffer_Summary *buffer);
|
||||
Buffer_Summary Get_Buffer_First(Application_Links *app, unsigned int access);
|
||||
void Get_Buffer_Next(Application_Links *app, Buffer_Summary *buffer, unsigned int access);
|
||||
|
||||
Buffer_Summary Get_Buffer(Application_Links *app, int index);
|
||||
Buffer_Summary Get_Parameter_Buffer(Application_Links *app, int param_index);
|
||||
Buffer_Summary Get_Buffer_By_Name(Application_Links *app, char *filename, int len);
|
||||
Buffer_Summary Get_Buffer(Application_Links *app, int index, unsigned int access);
|
||||
Buffer_Summary Get_Parameter_Buffer(Application_Links *app, int param_index, unsigned int access);
|
||||
Buffer_Summary Get_Buffer_By_Name(Application_Links *app, char *filename, int len, unsigned int access);
|
||||
|
||||
int Refresh_Buffer(Application_Links *app, Buffer_Summary *buffer);
|
||||
int Buffer_Read_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out);
|
||||
int Buffer_Replace_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len);
|
||||
|
||||
int Buffer_Read_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out);
|
||||
int Buffer_Seek(Application_Links *app, Buffer_Summary *buffer, int start_pos, int seek_forward, unsigned int flags);
|
||||
|
||||
int Buffer_Replace_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len);
|
||||
int Buffer_Set_Setting(Application_Links *app, Buffer_Summary *buffer, int setting, int value);
|
||||
|
||||
Buffer_Summary Create_Buffer(Application_Links *app, char *filename, int filename_len, int do_in_background);
|
||||
|
@ -36,11 +37,11 @@ int Save_Buffer(Application_Links *app, Buffer_Summary *buffer, char *filename,
|
|||
int Kill_Buffer(Application_Links *app, Buffer_Identifier buffer, int always_kill, int view_id);
|
||||
|
||||
// View manipulation
|
||||
View_Summary Get_View_First(Application_Links *app);
|
||||
void Get_View_Next(Application_Links *app, View_Summary *view);
|
||||
View_Summary Get_View_First(Application_Links *app, unsigned int access);
|
||||
void Get_View_Next(Application_Links *app, View_Summary *view, unsigned int access);
|
||||
|
||||
View_Summary Get_View(Application_Links *app, int index);
|
||||
View_Summary Get_Active_View(Application_Links *app);
|
||||
View_Summary Get_View(Application_Links *app, int index, unsigned int access);
|
||||
View_Summary Get_Active_View(Application_Links *app, unsigned int access);
|
||||
|
||||
int Refresh_View(Application_Links *app, View_Summary *view);
|
||||
|
||||
|
@ -50,7 +51,6 @@ int View_Set_Cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek
|
|||
int View_Set_Mark (Application_Links *app, View_Summary *view, Buffer_Seek seek);
|
||||
int View_Set_Highlight (Application_Links *app, View_Summary *view, int start, int end, int turn_on);
|
||||
int View_Set_Buffer (Application_Links *app, View_Summary *view, int buffer_id);
|
||||
|
||||
// TODO(allen): Switch from ticks to seconds.
|
||||
int View_Post_Fade (Application_Links *app, View_Summary *view, int ticks, int start, int end, unsigned int color);
|
||||
|
||||
|
|
|
@ -1162,7 +1162,7 @@ Font_Load_Sig(system_draw_font_load){
|
|||
#if LINUX_FONTS
|
||||
success = linux_font_load(font_out, filename, pt_size, tab_width);
|
||||
#else
|
||||
success = draw_font_load(
|
||||
success = font_load(
|
||||
&linuxvars.font_part,
|
||||
font_out,
|
||||
filename,
|
||||
|
|
|
@ -402,7 +402,8 @@ CUSTOM_COMMAND_SIG(casey_switch_buffer_other_window)
|
|||
internal void
|
||||
DeleteAfterCommand(struct Application_Links *app, unsigned long long CommandID)
|
||||
{
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
int pos2 = view.cursor.pos;
|
||||
if (CommandID < cmdid_count){
|
||||
|
@ -416,7 +417,7 @@ DeleteAfterCommand(struct Application_Links *app, unsigned long long CommandID)
|
|||
|
||||
Range range = make_range(pos1, pos2);
|
||||
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
app->buffer_replace_range(app, &buffer, range.min, range.max, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -432,7 +433,8 @@ CUSTOM_COMMAND_SIG(casey_delete_token_right)
|
|||
|
||||
CUSTOM_COMMAND_SIG(casey_kill_to_end_of_line)
|
||||
{
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
int pos2 = view.cursor.pos;
|
||||
exec_command(app, seek_end_of_line);
|
||||
|
@ -445,7 +447,7 @@ CUSTOM_COMMAND_SIG(casey_kill_to_end_of_line)
|
|||
range.max += 1;
|
||||
}
|
||||
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
app->buffer_replace_range(app, &buffer, range.min, range.max, 0, 0);
|
||||
exec_command(app, auto_tab_line_at_cursor);
|
||||
}
|
||||
|
@ -497,8 +499,9 @@ SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIf
|
|||
|
||||
SanitizeSlashes(FileName);
|
||||
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, FileName.str, FileName.size);
|
||||
unsigned int access = AccessAll;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, FileName.str, FileName.size, access);
|
||||
|
||||
Result.view = view;
|
||||
Result.buffer = buffer;
|
||||
|
@ -523,7 +526,7 @@ SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIf
|
|||
// This returns false if the open fails.
|
||||
view_open_file(app, &view, expand_str(FileName), false);
|
||||
|
||||
Result.buffer = app->get_buffer_by_name(app, FileName.str, FileName.size);
|
||||
Result.buffer = app->get_buffer_by_name(app, FileName.str, FileName.size, access);
|
||||
|
||||
Result.Loaded = true;
|
||||
Result.Switched = true;
|
||||
|
@ -575,8 +578,9 @@ CUSTOM_COMMAND_SIG(casey_build_search)
|
|||
|
||||
CUSTOM_COMMAND_SIG(casey_find_corresponding_file)
|
||||
{
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
String extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
if (extension.str)
|
||||
|
@ -630,11 +634,12 @@ CUSTOM_COMMAND_SIG(casey_find_corresponding_file)
|
|||
|
||||
CUSTOM_COMMAND_SIG(casey_find_corresponding_file_other_window)
|
||||
{
|
||||
View_Summary old_view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, old_view.buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary old_view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, old_view.buffer_id, access);
|
||||
|
||||
exec_command(app, cmdid_change_active_panel);
|
||||
View_Summary new_view = app->get_active_view(app);
|
||||
View_Summary new_view = app->get_active_view(app, AccessAll);
|
||||
app->view_set_buffer(app, &new_view, buffer.buffer_id);
|
||||
|
||||
// exec_command(app, casey_find_corresponding_file);
|
||||
|
@ -646,9 +651,10 @@ CUSTOM_COMMAND_SIG(casey_save_and_make_without_asking)
|
|||
|
||||
Buffer_Summary buffer = {};
|
||||
|
||||
for(buffer = app->get_buffer_first(app);
|
||||
unsigned int access = AccessAll;
|
||||
for(buffer = app->get_buffer_first(app, access);
|
||||
buffer.exists;
|
||||
app->get_buffer_next(app, &buffer))
|
||||
app->get_buffer_next(app, &buffer, access))
|
||||
{
|
||||
#if 0
|
||||
push_parameter(app, par_name, buffer.file_name, buffer.file_name_len);
|
||||
|
@ -712,7 +718,8 @@ CUSTOM_COMMAND_SIG(casey_save_and_make_without_asking)
|
|||
|
||||
if(append(&command, "build.bat"))
|
||||
{
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessAll;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
app->exec_system_command(app, &view,
|
||||
buffer_identifier(GlobalCompilationBufferName, (int)strlen(GlobalCompilationBufferName)),
|
||||
dir.str, dir.size,
|
||||
|
@ -843,7 +850,7 @@ casey_parse_error(Application_Links *app, Buffer_Summary buffer, View_Summary vi
|
|||
internal void
|
||||
casey_seek_error_dy(Application_Links *app, int dy)
|
||||
{
|
||||
Buffer_Summary Buffer = app->get_buffer_by_name(app, GlobalCompilationBufferName, (int)strlen(GlobalCompilationBufferName));
|
||||
Buffer_Summary Buffer = app->get_buffer_by_name(app, GlobalCompilationBufferName, (int)strlen(GlobalCompilationBufferName), AccessAll);
|
||||
View_Summary compilation_view = get_first_view_with_buffer(app, Buffer.buffer_id);
|
||||
|
||||
// NOTE(casey): First get the current error (which may be none, if we've never parsed before)
|
||||
|
@ -1068,7 +1075,8 @@ ParseCalc(tokenizer *Tokenizer)
|
|||
|
||||
CUSTOM_COMMAND_SIG(casey_quick_calc)
|
||||
{
|
||||
View_Summary view = app->get_active_view(app);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
Range range = get_range(&view);
|
||||
|
||||
|
@ -1076,7 +1084,7 @@ CUSTOM_COMMAND_SIG(casey_quick_calc)
|
|||
char *Stuff = (char *)malloc(Size + 1);
|
||||
Stuff[Size] = 0;
|
||||
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
app->buffer_read_range(app, &buffer, range.min, range.max, Stuff);
|
||||
|
||||
tokenizer Tokenizer = {Stuff};
|
||||
|
@ -1331,7 +1339,8 @@ HOOK_SIG(casey_file_settings)
|
|||
// received through functions like this app->get_parameter_buffer.
|
||||
// This is different from the past where this hook got a buffer
|
||||
// from app->get_active_buffer.
|
||||
Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
|
||||
unsigned int access = AccessAll;
|
||||
Buffer_Summary buffer = app->get_parameter_buffer(app, 0, access);
|
||||
|
||||
int treat_as_code = 0;
|
||||
int treat_as_project = 0;
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include <string.h>
|
||||
|
||||
CUSTOM_COMMAND_SIG(kill_rect){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
Full_Cursor cursor;
|
||||
|
||||
Buffer_Rect rect = get_rect(&view);
|
||||
|
@ -30,8 +31,9 @@ CUSTOM_COMMAND_SIG(kill_rect){
|
|||
// TODO(allen): Both of these brace related commands would work better
|
||||
// if the API exposed access to the tokens in a code file.
|
||||
CUSTOM_COMMAND_SIG(mark_matching_brace){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int start_pos = view.cursor.pos;
|
||||
|
||||
|
@ -110,8 +112,9 @@ CUSTOM_COMMAND_SIG(mark_matching_brace){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(cursor_to_surrounding_scope){
|
||||
View_Summary view = app->get_active_view(app);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id);
|
||||
unsigned int access = AccessProtected;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
int start_pos = view.cursor.pos - 1;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#define SUPPORT_DPI 1
|
||||
#define USE_WIN32_FONTS 0
|
||||
#define USE_FT_FONTS 0
|
||||
|
||||
#define FPS 60
|
||||
#define frame_useconds (1000000 / FPS)
|
||||
|
@ -1146,8 +1147,11 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){
|
|||
|
||||
#include "system_shared.cpp"
|
||||
#include "4ed_rendering.cpp"
|
||||
|
||||
#if USE_WIN32_FONTS
|
||||
# include "win32_font.cpp"
|
||||
#elif USE_FT_FONTS
|
||||
# include "win32_ft_font.cpp"
|
||||
#endif
|
||||
|
||||
internal f32
|
||||
|
@ -1174,7 +1178,7 @@ Font_Load_Sig(system_draw_font_load){
|
|||
for (b32 success = 0; success == 0;){
|
||||
#if USE_WIN32_FONTS
|
||||
|
||||
success = win32_draw_font_load(&win32vars.font_part,
|
||||
success = win32_font_load(&win32vars.font_part,
|
||||
font_out,
|
||||
filename,
|
||||
fontname,
|
||||
|
@ -1183,9 +1187,13 @@ Font_Load_Sig(system_draw_font_load){
|
|||
oversample,
|
||||
store_texture);
|
||||
|
||||
#elif USE_FT_FONTS
|
||||
|
||||
success = win32_ft_font_load();
|
||||
|
||||
#else
|
||||
|
||||
success = draw_font_load(&win32vars.font_part,
|
||||
success = font_load(&win32vars.font_part,
|
||||
font_out,
|
||||
filename,
|
||||
pt_size,
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
// NOTE(allen): Thanks to insofaras.
|
||||
// This is copy-pasted from some work he
|
||||
// did to get free type working on linux.
|
||||
// Once it is working on both sides it might
|
||||
// be possible to pull some parts out as
|
||||
// portable FT rendering.
|
||||
|
||||
|
||||
#undef internal
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_LCD_FILTER_H
|
||||
#define internal static
|
||||
|
||||
//TODO(inso): put in linuxvars
|
||||
static FcConfig* fc;
|
||||
|
||||
internal char*
|
||||
linux_get_sys_font(char* name, i32 pt_size){
|
||||
char* result = 0;
|
||||
|
||||
if(!fc){
|
||||
fc = FcInitLoadConfigAndFonts();
|
||||
}
|
||||
|
||||
FcPattern* pat = FcPatternBuild(
|
||||
NULL,
|
||||
FC_POSTSCRIPT_NAME, FcTypeString, name,
|
||||
FC_SIZE, FcTypeDouble, (double)pt_size,
|
||||
FC_FONTFORMAT, FcTypeString, "TrueType",
|
||||
NULL
|
||||
);
|
||||
|
||||
FcConfigSubstitute(fc, pat, FcMatchPattern);
|
||||
FcDefaultSubstitute(pat);
|
||||
|
||||
FcResult res;
|
||||
FcPattern* font = FcFontMatch(fc, pat, &res);
|
||||
FcChar8* fname = 0;
|
||||
|
||||
if(font){
|
||||
FcPatternGetString(font, FC_FILE, 0, &fname);
|
||||
if(fname){
|
||||
result = strdup((char*)fname);
|
||||
fprintf(stderr, "Got system font from FontConfig: %s\n", result);
|
||||
}
|
||||
FcPatternDestroy(font);
|
||||
}
|
||||
|
||||
FcPatternDestroy(pat);
|
||||
|
||||
if(!result){
|
||||
char space[1024];
|
||||
String str = make_fixed_width_string(space);
|
||||
if(sysshared_to_binary_path(&str, name)){
|
||||
result = strdup(space);
|
||||
} else {
|
||||
result = strdup(name);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal u32
|
||||
next_pow_of_2(u32 v){
|
||||
--v;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return ++v;
|
||||
}
|
||||
|
||||
#define NUM_GLYPHS 128
|
||||
#define ENABLE_LCD_FILTER 0
|
||||
|
||||
internal b32
|
||||
win32_ft_font_load(Render_Font *rf, char *name, i32 pt_size, i32 tab_width){
|
||||
|
||||
#if 0
|
||||
char* filename = linux_get_sys_font(name, pt_size);
|
||||
#else
|
||||
char* filename = (char*)malloc(256);
|
||||
String str = make_string(filename, 0, 256);
|
||||
sysshared_to_binary_path(&str, name);
|
||||
#endif
|
||||
|
||||
memset(rf, 0, sizeof(*rf));
|
||||
|
||||
//TODO(inso): put stuff in linuxvars / init in main
|
||||
FT_Library ft;
|
||||
FT_Face face;
|
||||
b32 use_lcd_filter = 0;
|
||||
|
||||
FT_Init_FreeType(&ft);
|
||||
|
||||
//NOTE(inso): i'm not sure the LCD filter looks better, and it doesn't work perfectly with the coloring stuff
|
||||
#if ENABLE_LCD_FILTER
|
||||
if(FT_Library_SetLcdFilter(ft, FT_LCD_FILTER_DEFAULT) == 0){
|
||||
puts("LCD Filter on");
|
||||
use_lcd_filter = 1;
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
#endif
|
||||
|
||||
FT_New_Face(ft, filename, 0, &face);
|
||||
|
||||
// set size & metrics
|
||||
FT_Size_RequestRec_ size = {};
|
||||
size.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
size.height = pt_size << 6;
|
||||
FT_Request_Size(face, &size);
|
||||
|
||||
rf->loaded = 1;
|
||||
rf->ascent = face->size->metrics.ascender / 64.0f;
|
||||
rf->descent = face->size->metrics.descender / 64.0f;
|
||||
rf->advance = face->size->metrics.max_advance / 64.0f;
|
||||
rf->height = face->size->metrics.height / 64.0f;
|
||||
rf->line_skip = rf->height - (rf->ascent - rf->descent);
|
||||
|
||||
int max_glyph_w = face->size->metrics.x_ppem;
|
||||
int max_glyph_h = rf->height;
|
||||
int tex_width = 64;
|
||||
int tex_height = 0;
|
||||
|
||||
// estimate upper bound on texture width
|
||||
do {
|
||||
tex_width *= 2;
|
||||
float glyphs_per_row = ceilf(tex_width / (float) max_glyph_w);
|
||||
float rows = ceilf(NUM_GLYPHS / glyphs_per_row);
|
||||
tex_height = rows * (max_glyph_h + 2);
|
||||
} while(tex_height > tex_width);
|
||||
|
||||
tex_height = next_pow_of_2(tex_height);
|
||||
|
||||
int pen_x = 0;
|
||||
int pen_y = 0;
|
||||
|
||||
u32* pixels = (u32*) calloc(tex_width * tex_height, sizeof(u32));
|
||||
|
||||
// XXX: test if AUTOHINT looks better or not
|
||||
const u32 ft_extra_flags = use_lcd_filter ? FT_LOAD_TARGET_LCD : FT_LOAD_FORCE_AUTOHINT;
|
||||
|
||||
for(int i = 0; i < NUM_GLYPHS; ++i){
|
||||
if(FT_Load_Char(face, i, FT_LOAD_RENDER | ft_extra_flags) != 0) continue;
|
||||
|
||||
int w = face->glyph->bitmap.width;
|
||||
int h = face->glyph->bitmap.rows;
|
||||
|
||||
// lcd filter produces RGB bitmaps, need to account for the extra components
|
||||
if(use_lcd_filter){
|
||||
w /= 3;
|
||||
}
|
||||
|
||||
// move to next line if necessary
|
||||
if(pen_x + w >= tex_width){
|
||||
pen_x = 0;
|
||||
pen_y += (max_glyph_h + 2);
|
||||
}
|
||||
|
||||
// set all this stuff the renderer needs
|
||||
stbtt_packedchar* c = rf->chardata + i;
|
||||
|
||||
c->x0 = pen_x;
|
||||
c->y0 = pen_y;
|
||||
c->x1 = pen_x + w;
|
||||
c->y1 = pen_y + h + 1;
|
||||
|
||||
c->xoff = face->glyph->bitmap_left;
|
||||
c->yoff = -face->glyph->bitmap_top;
|
||||
|
||||
c->xoff2 = w + c->xoff;
|
||||
c->yoff2 = h + c->yoff + 1;
|
||||
|
||||
c->xadvance = face->glyph->advance.x >> 6;
|
||||
|
||||
rf->advance_data[i] = c->xadvance;
|
||||
rf->glyphs[i].exists = 1;
|
||||
|
||||
|
||||
int pitch = face->glyph->bitmap.pitch;
|
||||
|
||||
// write to texture atlas
|
||||
for(int j = 0; j < h; ++j){
|
||||
for(int i = 0; i < w; ++i){
|
||||
int x = pen_x + i;
|
||||
int y = pen_y + j;
|
||||
|
||||
if(use_lcd_filter){
|
||||
u8 r = face->glyph->bitmap.buffer[j * pitch + i * 3];
|
||||
u8 g = face->glyph->bitmap.buffer[j * pitch + i * 3 + 1];
|
||||
u8 b = face->glyph->bitmap.buffer[j * pitch + i * 3 + 2];
|
||||
u8 a = (r + g + b) / 3.0f;
|
||||
|
||||
pixels[y * tex_width + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
} else {
|
||||
pixels[y * tex_width + x] = face->glyph->bitmap.buffer[j * pitch + i] * 0x1010101;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pen_x = c->x1 + 1;
|
||||
}
|
||||
|
||||
rf->chardata['\r'] = rf->chardata[' '];
|
||||
rf->chardata['\n'] = rf->chardata[' '];
|
||||
rf->chardata['\t'] = rf->chardata[' '];
|
||||
rf->chardata['\t'].xadvance *= tab_width;
|
||||
|
||||
FT_Done_FreeType(ft);
|
||||
|
||||
tex_height = next_pow_of_2(pen_y + max_glyph_h + 2);
|
||||
|
||||
rf->tex_width = tex_width;
|
||||
rf->tex_height = tex_height;
|
||||
|
||||
// upload texture
|
||||
glGenTextures(1, &rf->tex);
|
||||
glBindTexture(GL_TEXTURE_2D, rf->tex);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
if(use_lcd_filter){
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_INT, pixels);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
free(pixels);
|
||||
free(filename);
|
||||
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue