new protection API

This commit is contained in:
Allen Webster 2016-06-20 16:34:48 -04:00
parent e7b67f8236
commit e9c5f89575
16 changed files with 726 additions and 350 deletions

View File

@ -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)

View File

@ -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;\

View File

@ -39,13 +39,14 @@ CUSTOM_COMMAND_SIG(write_capital){
CUSTOM_COMMAND_SIG(switch_to_compilation){
View_Summary view;
Buffer_Summary buffer;
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);
@ -71,8 +73,8 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
string.str = (char*)app->memory;
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;

View File

@ -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,40 +146,37 @@ 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)){
app->view_set_cursor(app, &view,
seek_xy(rx, ry, true,
view.unwrapped_lines),
true);
}
Mouse_State mouse = app->get_mouse_state(app);
float rx = 0, ry = 0;
if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){
app->view_set_cursor(app, &view,
seek_xy(rx, ry, true,
view.unwrapped_lines),
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)){
app->view_set_mark(app, &view,
seek_xy(rx, ry, true,
view.unwrapped_lines)
);
}
Mouse_State mouse = app->get_mouse_state(app);
float rx = 0, ry = 0;
if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){
app->view_set_mark(app, &view,
seek_xy(rx, ry, true,
view.unwrapped_lines)
);
}
}
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,16 +819,18 @@ CUSTOM_COMMAND_SIG(save_as){
}
CUSTOM_COMMAND_SIG(goto_line){
unsigned int access = AccessProtected;
int line_number;
Query_Bar bar;
char string_space[256];
bar.prompt = make_lit_string("Goto Line: ");
bar.string = make_fixed_width_string(string_space);
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;
@ -945,33 +972,31 @@ CUSTOM_COMMAND_SIG(replace_in_range){
char replace_space[1024];
replace.prompt = make_lit_string("Replace: ");
replace.string = make_fixed_width_string(replace_space);
Query_Bar with;
char with_space[1024];
with.prompt = make_lit_string("With: ");
with.string = make_fixed_width_string(with_space);
if (!query_user_string(app, &replace)) return;
if (replace.string.size == 0) return;
if (!query_user_string(app, &with)) return;
String r, w;
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);
int pos, new_pos;
pos = range.min;
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
while (new_pos + r.size <= range.end){
app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size);
app->refresh_view(app, &view);
@ -986,45 +1011,46 @@ CUSTOM_COMMAND_SIG(query_replace){
char replace_space[1024];
replace.prompt = make_lit_string("Replace: ");
replace.string = make_fixed_width_string(replace_space);
Query_Bar with;
char with_space[1024];
with.prompt = make_lit_string("With: ");
with.string = make_fixed_width_string(with_space);
if (!query_user_string(app, &replace)) return;
if (replace.string.size == 0) return;
if (!query_user_string(app, &with)) return;
String r, w;
r = replace.string;
w = with.string;
Query_Bar bar;
Buffer_Summary buffer;
View_Summary view;
int pos, new_pos;
bar.prompt = make_lit_string("Replace? (y)es, (n)ext, (esc)\n");
bar.string = empty_string();
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);
User_Input in = {0};
while (new_pos < buffer.size){
Range match = make_range(new_pos, new_pos + r.size);
app->view_set_highlight(app, &view, match.min, match.max, 1);
in = app->get_user_input(app, EventOnAnyKey, EventOnButton);
if (in.abort || in.key.keycode == key_esc || !key_is_unmodified(&in.key)) break;
if (in.key.character == 'y' || in.key.character == 'Y' || in.key.character == '\n' || in.key.character == '\t'){
app->buffer_replace_range(app, &buffer, match.min, match.max, w.str, w.size);
pos = match.start + w.size;
@ -1032,13 +1058,13 @@ CUSTOM_COMMAND_SIG(query_replace){
else{
pos = match.max;
}
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
}
app->view_set_highlight(app, &view, 0, 0, 0);
if (in.abort) return;
app->view_set_cursor(app, &view, seek_pos(pos), 1);
}
@ -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);
@ -1267,7 +1296,7 @@ CUSTOM_COMMAND_SIG(build_search){
dir.str, dir.size,
command.str, command.size,
CLI_OverlapWithConflict);
return;
}
dir.size = old_size;
@ -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,

View File

@ -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
@ -255,11 +255,15 @@ inline View_Summary
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;

View File

@ -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

View File

@ -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->buffer_id = buffer_id;
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,84 +487,82 @@ 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;
i32 size = buffer_size(&file->state.buffer);
i32 pos[4] = {0};
i32 new_pos = 0;
if (start_pos < 0){
start_pos = 0;
}
else if (start_pos > size){
start_pos = size;
}
if (seek_forward){
for (i32 i = 0; i < ArrayCount(pos); ++i) pos[i] = size;
if (start_pos < 0){
start_pos = 0;
}
else if (start_pos > size){
start_pos = size;
if (flags & (1)){
pos[0] = buffer_seek_whitespace_right(&file->state.buffer, start_pos);
}
if (seek_forward){
for (i32 i = 0; i < ArrayCount(pos); ++i) pos[i] = size;
if (flags & (1)){
pos[0] = buffer_seek_whitespace_right(&file->state.buffer, start_pos);
}
if (flags & (1 << 1)){
if (file->state.tokens_complete){
pos[1] = seek_token_right(&file->state.token_stack, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_right(&file->state.buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_right(&file->state.buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_right(&file->state.buffer, start_pos, pos[2]);
}
if (flags & (1 << 1)){
if (file->state.tokens_complete){
pos[1] = seek_token_right(&file->state.token_stack, start_pos);
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, start_pos);
}
pos[1] = buffer_seek_whitespace_right(&file->state.buffer, start_pos);
}
new_pos = size;
for (i32 i = 0; i < ArrayCount(pos); ++i){
if (pos[i] < new_pos) new_pos = pos[i];
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_right(&file->state.buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_right(&file->state.buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1)){
pos[0] = buffer_seek_whitespace_left(&file->state.buffer, start_pos);
}
if (flags & (1 << 1)){
if (file->state.tokens_complete){
pos[1] = seek_token_left(&file->state.token_stack, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_left(&file->state.buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_left(&file->state.buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_left(&file->state.buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, start_pos);
}
}
new_pos = 0;
for (i32 i = 0; i < ArrayCount(pos); ++i){
if (pos[i] > new_pos) new_pos = pos[i];
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, start_pos);
}
}
result = new_pos;
new_pos = size;
for (i32 i = 0; i < ArrayCount(pos); ++i){
if (pos[i] < new_pos) new_pos = pos[i];
}
}
else{
if (flags & (1)){
pos[0] = buffer_seek_whitespace_left(&file->state.buffer, start_pos);
}
if (flags & (1 << 1)){
if (file->state.tokens_complete){
pos[1] = seek_token_left(&file->state.token_stack, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_left(&file->state.buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_left(&file->state.buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_left(&file->state.buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, start_pos);
}
}
new_pos = 0;
for (i32 i = 0; i < ArrayCount(pos); ++i){
if (pos[i] > new_pos) new_pos = pos[i];
}
}
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);
}

View File

@ -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);
}

View File

@ -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){

View File

@ -362,13 +362,13 @@ part_free(void *ptr, void *context){
// of this function (and other functions implementing
// the same interface).
internal i32
draw_font_load(Partition *part,
Render_Font *font_out,
char *filename_untranslated,
i32 pt_size,
i32 tab_width,
i32 oversample,
b32 store_texture){
font_load(Partition *part,
Render_Font *font_out,
char *filename_untranslated,
i32 pt_size,
i32 tab_width,
i32 oversample,
b32 store_texture){
char space_[1024];
String filename = make_fixed_width_string(space_);

View File

@ -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,23 +37,22 @@ 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);
int View_Auto_Tab(Application_Links *app, View_Summary *view, int start, int end, int tab_width, unsigned int flags);
Full_Cursor View_Compute_Cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek);
int View_Set_Cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, int set_preferred_x);
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);
int View_Auto_Tab (Application_Links *app, View_Summary *view, int start, int end, int tab_width, unsigned int flags);
Full_Cursor View_Compute_Cursor (Application_Links *app, View_Summary *view, Buffer_Seek seek);
int View_Set_Cursor (Application_Links *app, View_Summary *view, Buffer_Seek seek, int set_preferred_x);
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);
int View_Post_Fade (Application_Links *app, View_Summary *view, int ticks, int start, int end, unsigned int color);
// TODO(allen):
// Get rid of this temporary hack ass soon ass possible.

View File

@ -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,

View File

@ -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);
}
@ -496,9 +498,10 @@ SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIf
switch_to_result Result = {};
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;

View File

@ -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;

View File

@ -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"
# include "win32_font.cpp"
#elif USE_FT_FONTS
# include "win32_ft_font.cpp"
#endif
internal f32
@ -1174,24 +1178,28 @@ 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,
font_out,
filename,
fontname,
pt_size,
tab_width,
oversample,
store_texture);
success = win32_font_load(&win32vars.font_part,
font_out,
filename,
fontname,
pt_size,
tab_width,
oversample,
store_texture);
#elif USE_FT_FONTS
success = win32_ft_font_load();
#else
success = draw_font_load(&win32vars.font_part,
font_out,
filename,
pt_size,
tab_width,
oversample,
store_texture);
success = font_load(&win32vars.font_part,
font_out,
filename,
pt_size,
tab_width,
oversample,
store_texture);
#endif

242
win32_ft_font.cpp Normal file
View File

@ -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;
}