The size parameter expresses the initial size of the string.
diff --git a/4coder_auto_indent.cpp b/4coder_auto_indent.cpp
index ba791130..a98397e9 100644
--- a/4coder_auto_indent.cpp
+++ b/4coder_auto_indent.cpp
@@ -458,6 +458,56 @@ get_indentation_marks(Application_Links *app, Partition *part, Buffer_Summary *b
return(indent_marks);
}
+static void
+get_indent_lines_minimum(Application_Links *app, Buffer_Summary *buffer,
+ int32_t start_pos, int32_t end_pos,
+ int32_t *line_start_out, int32_t *line_end_out){
+ int32_t line_start = buffer_get_line_index(app, buffer, start_pos);
+ int32_t line_end = buffer_get_line_index(app, buffer, end_pos) + 1;
+
+ *line_start_out = line_start;
+ *line_end_out = line_end;
+}
+
+static void
+get_indent_lines_whole_tokens(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens,
+ int32_t start_pos, int32_t end_pos,
+ int32_t *line_start_out, int32_t *line_end_out){
+ int32_t line_start = buffer_get_line_index(app, buffer, start_pos);
+ int32_t line_end = buffer_get_line_index(app, buffer, end_pos);
+
+ for (;line_start > 0;){
+ int32_t line_start_pos = 0;
+ Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_start, &line_start_pos);
+ if (token->start < line_start_pos){
+ line_start = buffer_get_line_index(app, buffer, token->start);
+ }
+ else{
+ break;
+ }
+ }
+
+ for (;line_end+1 < buffer->line_count;){
+ int32_t next_line_start_pos = 0;
+ Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_end+1, &next_line_start_pos);
+ if (token && token->start < next_line_start_pos){
+ line_end = buffer_get_line_index(app, buffer, token->start+token->size);
+ }
+ else{
+ break;
+ }
+ }
+ if (line_end >= buffer->line_count){
+ line_end = buffer->line_count;
+ }
+ else{
+ line_end += 1;
+ }
+
+ *line_start_out = line_start;
+ *line_end_out = line_end;
+}
+
static bool32
buffer_auto_indent(Application_Links *app, Partition *part, Buffer_Summary *buffer,
int32_t start, int32_t end, int32_t tab_width, Auto_Indent_Flag flags){
@@ -468,25 +518,32 @@ buffer_auto_indent(Application_Links *app, Partition *part, Buffer_Summary *buff
Temp_Memory temp = begin_temp_memory(part);
- // Stage 1: Setup
- // Read the tokens to be used for indentation.
- // Get the first and last lines to indent.
+ // Stage 1: Read the tokens to be used for indentation.
Cpp_Token_Array tokens;
tokens.count = app->buffer_token_count(app, buffer);
tokens.max_count = tokens.count;
tokens.tokens = push_array(part, Cpp_Token, tokens.count);
app->buffer_read_tokens(app, buffer, 0, tokens.count, tokens.tokens);
- int32_t line_start = buffer_get_line_index(app, buffer, start);
- int32_t line_end = buffer_get_line_index(app, buffer, end) + 1;
+ // Stage 2: Decide where the first and last lines are.
+ // The lines in the range [line_start,line_end) will be indented.
+ int32_t do_whole_tokens = 1;
- // Stage 2: Decide Indent Amounts
- // Get an array representing how much each line in [line_start,line_end]
- // should be indented.
+ int32_t line_start = 0, line_end = 0;
+ if (do_whole_tokens){
+ get_indent_lines_whole_tokens(app, buffer, tokens, start, end, &line_start, &line_end);
+ }
+ else{
+ get_indent_lines_minimum(app, buffer, start, end, &line_start, &line_end);
+ }
+
+ // Stage 3: Decide Indent Amounts
+ // Get an array representing how much each line in
+ // the range [line_start,line_end) should be indented.
int32_t *indent_marks =
get_indentation_marks(app, part, buffer, tokens, line_start, line_end, tab_width);
- // Stage 3: Set the Line Indents
+ // Stage 4: Set the Line Indents
Indent_Options opts = {0};
opts.empty_blank_lines = (flags & AutoIndent_ClearLine);
opts.use_tabs = (flags & AutoIndent_UseTab);
diff --git a/4coder_custom_api.h b/4coder_custom_api.h
index 2ff4be34..32b31963 100644
--- a/4coder_custom_api.h
+++ b/4coder_custom_api.h
@@ -1,5 +1,5 @@
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
-#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Input_Flag flags)
+#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
#define CLIPBOARD_INDEX_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len)
diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp
index c92be080..65480ad2 100644
--- a/4coder_default_bindings.cpp
+++ b/4coder_default_bindings.cpp
@@ -282,7 +282,7 @@ default_keys(Bind_Helper *context){
bind(context, key_f2, MDFR_NONE, toggle_mouse);
bind(context, key_page_up, MDFR_CTRL, toggle_fullscreen);
- bind(context, key_f4, MDFR_ALT, exit_4coder);
+ bind(context, 'E', MDFR_ALT, exit_4coder);
end_map(context);
diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp
index 1e23d233..7869cad3 100644
--- a/4coder_default_include.cpp
+++ b/4coder_default_include.cpp
@@ -364,11 +364,10 @@ buffer_seek_string_forward(Application_Links *app, Buffer_Summary *buffer,
read_str.size = size;
char chunk[1024];
- int32_t chunk_size = sizeof(chunk);
Stream_Chunk stream = {0};
stream.max_end = end;
- if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
+ if (init_stream_chunk(&stream, app, buffer, pos, chunk, sizeof(chunk))){
int32_t still_looping = 1;
do{
for(; pos < stream.end; ++pos){
@@ -419,11 +418,10 @@ buffer_seek_string_backward(Application_Links *app, Buffer_Summary *buffer,
read_str.size = size;
char chunk[1024];
- int32_t chunk_size = sizeof(chunk);
Stream_Chunk stream = {0};
stream.min_start = min;
- if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
+ if (init_stream_chunk(&stream, app, buffer, pos, chunk, sizeof(chunk))){
int32_t still_looping = 1;
do{
for(; pos >= stream.start; --pos){
@@ -573,7 +571,8 @@ buffer_get_line_index(Application_Links *app, Buffer_Summary *buffer, int32_t po
}
static Cpp_Token*
-get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line){
+get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line,
+ int32_t *line_start_out = 0){
int32_t line_start = buffer_get_line_start(app, buffer, line);
Cpp_Get_Token_Result get_token = cpp_get_token(&tokens, line_start);
@@ -581,7 +580,14 @@ get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Toke
get_token.token_index += 1;
}
- Cpp_Token *result = tokens.tokens + get_token.token_index;
+ if (line_start_out){
+ *line_start_out = line_start;
+ }
+
+ Cpp_Token *result = 0;
+ if (get_token.token_index < tokens.count){
+ result = tokens.tokens + get_token.token_index;
+ }
return(result);
}
diff --git a/4coder_types.h b/4coder_types.h
index 4eb4426b..af566a86 100644
--- a/4coder_types.h
+++ b/4coder_types.h
@@ -201,7 +201,7 @@ access call. An access call is usually one the returns a summary struct. If a
4coder object has a particular protection flag set and the corresponding bit is
not set in the access field, that 4coder object is hidden. On the other hand if
a protection flag is set in the access parameter and the object does not have
-that protection flag, the object is still returned from the access call.) TODO */
+that protection flag, the object is still returned from the access call.) */
ENUM(uint32_t, Access_Flag){
/* DOC(AccessOpen does not include any bits, it indicates that the access should
only return objects that have no protection flags set.) */
@@ -218,6 +218,23 @@ ENUM(uint32_t, Access_Flag){
AccessAll = 0xFF
};
+/* DOC(A Dirty_State value describes whether changes have been made to a buffer
+or to an underlying file since the last sync time between the two. Saving a buffer
+to it's file or loading the buffer from the file both act as sync points.) */
+ENUM(uint32_t, Dirty_State){
+ /* DOC(DirtyState_UpToDate indicates that there are no unsaved changes and
+ the underlying system file still agrees with the buffer's state.) */
+ DirtyState_UpToDate,
+
+ /* DOC(DirtyState_UnsavedChanges indicates that there have been changes in the
+ buffer since the last sync point.) */
+ DirtyState_UnsavedChanges,
+
+ /* DOC(DirtyState_UnsavedChanges indicates that the underlying file has been
+ edited since the last sync point with the buffer.) */
+ DirtyState_UnloadedChanges
+};
+
/* DOC(A Seek_Boundary_Flag field specifies a set of "boundary" types used in seeks for the
beginning or end of different types of words.) */
ENUM(uint32_t, Seek_Boundary_Flag){
@@ -227,8 +244,8 @@ ENUM(uint32_t, Seek_Boundary_Flag){
BoundaryCamelCase = 0x8
};
-/* DOC(A Command_Line_Input_Flag field specifies the behavior of a call to a command line interface.) */
-ENUM(uint32_t, Command_Line_Input_Flag){
+/* DOC(A Command_Line_Interface_Flag field specifies the behavior of a call to a command line interface.) */
+ENUM(uint32_t, Command_Line_Interface_Flag){
/* DOC(If CLI_OverlapWithConflict is set if output buffer of the new command is already
in use by another command which is still executing, the older command relinquishes control
of the buffer and both operate simultaneously with only the newer command outputting to
@@ -561,7 +578,8 @@ struct Buffer_Edit{
};
/* DOC(Buffer_Summary acts as a handle to a buffer and describes the state of the buffer.)
-DOC_SEE(Access_Flag) */
+DOC_SEE(Access_Flag)
+DOC_SEE(Dirty_State) */
struct Buffer_Summary{
/* DOC(
This field indicates whether the Buffer_Summary describes a buffer that is open in 4coder.
@@ -595,6 +613,9 @@ struct Buffer_Summary{
/* DOC(This field specifies the length of the buffer_name string.) */
int32_t buffer_name_len;
+ /* DOC(This field indicates the dirty state of the buffer.) */
+ Dirty_State dirty;
+
/* DOC(If this is not a null summary, this field indicates whether the buffer is set to lex tokens.) */
bool32 is_lexed;
/* DOC(If this is not a null summary, this field indicates whether the buffer has up to date tokens available.
diff --git a/4cpp_lexer.h b/4cpp_lexer.h
index c19cc9ad..7409dfec 100644
--- a/4cpp_lexer.h
+++ b/4cpp_lexer.h
@@ -15,8 +15,10 @@
#define FCPP_INTERNAL FCPP_LINK
#include
-#define FSTRING_IMPLEMENTATION
-#include "4coder_string.h"
+#if !defined(FSTRING_GUARD)
+# define FSTRING_IMPLEMENTATION
+# include "4coder_string.h"
+#endif
#include "4cpp_lexer_types.h"
#include "4cpp_lexer_tables.c"
diff --git a/4ed.cpp b/4ed.cpp
index 3e349a9f..a4a06428 100644
--- a/4ed.cpp
+++ b/4ed.cpp
@@ -1989,13 +1989,20 @@ App_Step_Sig(app_step){
models->hooks[hook_start](&models->app_links);
}
+ char space[512];
+ String cl_filename = make_fixed_width_string(space);
+ copy_ss(&cl_filename, models->hot_directory.string);
+
+ i32 cl_filename_len = cl_filename.size;
+
i32 i = 0;
Panel *panel = models->layout.used_sentinel.next;
for (; i < models->settings.init_files_count; ++i, panel = panel->next){
- String filename = make_string_slowly(models->settings.init_files[i]);
+ cl_filename.size = cl_filename_len;
+ append_sc(&cl_filename, models->settings.init_files[i]);
if (i < models->layout.panel_count){
- view_open_file(system, models, panel->view, filename);
+ view_open_file(system, models, panel->view, cl_filename);
view_show_file(panel->view);
Assert("Earlier" && panel->view->file_data.file != 0);
#if 0
@@ -2009,14 +2016,14 @@ App_Step_Sig(app_step){
#endif
}
else{
- view_open_file(system, models, 0, filename);
+ view_open_file(system, models, 0, cl_filename);
}
+
}
if (i < models->layout.panel_count){
view_set_file(panel->view, models->message_buffer, models);
view_show_file(panel->view);
-
++i;
panel = panel->next;
}
@@ -2498,7 +2505,7 @@ App_Step_Sig(app_step){
"-4coder now supports proper, borderless, fullscreen with the flag -F\n"
" and fullscreen can be toggled with .\n"
" (This sometimes causes artifacts on the Windows task bar)\n"
- "- to exit\n"
+ "- to exit\n"
"-hook on exit for the customization system\n"
"-tokens now exposed in customization system\n"
"-mouse release events in customization system\n"
diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp
index 9230e1cb..797e9f59 100644
--- a/4ed_api_implementation.cpp
+++ b/4ed_api_implementation.cpp
@@ -31,6 +31,8 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor
buffer->file_name = file->name.source_path.str;
buffer->buffer_name = file->name.live_name.str;
+ buffer->dirty = file->state.dirty;
+
buffer->is_lexed = file->settings.tokens_exist;
if (file->state.token_array.tokens &&
@@ -180,9 +182,9 @@ DOC_SEE(Command_ID)
return(result);
}
-// TODO(allen): This is a bit of a mess and needs to be fixed soon
+// TODO(allen): This is a bit of a mess and needs to be fixed soon.
API_EXPORT bool32
-Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Input_Flag flags)/*
+Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)/*
DOC_PARAM(view, If the view parameter is non-null it specifies a view to display the command's output buffer.)
DOC_PARAM(buffer, The buffer the command will output to is specified by the buffer parameter.
See Buffer_Identifier for information on how this type specifies a buffer.)
diff --git a/4ed_file.cpp b/4ed_file.cpp
index a479513b..6ac5fd8c 100644
--- a/4ed_file.cpp
+++ b/4ed_file.cpp
@@ -100,12 +100,6 @@ struct Undo_Data{
b32 current_block_normal;
};
-enum File_Sync_State{
- SYNC_GOOD,
- SYNC_BEHIND_OS,
- SYNC_UNSAVED
-};
-
struct Text_Effect{
i32 start, end;
u32 color;
@@ -143,7 +137,7 @@ struct Editing_File_State{
Text_Effect paste_effect;
- File_Sync_State sync;
+ Dirty_State dirty;
u32 ignore_behind_os;
File_Edit_Positions edit_pos_space[16];
@@ -671,6 +665,7 @@ touch_file(Working_Set *working_set, Editing_File *file){
struct Hot_Directory{
String string;
File_List file_list;
+ // TODO(allen): eliminate slash
char slash;
};
@@ -765,7 +760,7 @@ inline b32
buffer_needs_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
- if (file->state.sync == SYNC_UNSAVED){
+ if (file->state.dirty == DirtyState_UnsavedChanges){
result = 1;
}
}
@@ -776,8 +771,8 @@ inline b32
buffer_can_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
- if (file->state.sync == SYNC_UNSAVED ||
- file->state.sync == SYNC_BEHIND_OS){
+ if (file->state.dirty == DirtyState_UnsavedChanges ||
+ file->state.dirty == DirtyState_UnloadedChanges){
result = 1;
}
}
@@ -814,26 +809,26 @@ file_set_to_loading(Editing_File *file){
inline void
file_mark_clean(Editing_File *file){
- if (file->state.sync != SYNC_BEHIND_OS){
- file->state.sync = SYNC_GOOD;
+ if (file->state.dirty != DirtyState_UnloadedChanges){
+ file->state.dirty = DirtyState_UpToDate;
}
}
inline void
file_mark_dirty(Editing_File *file){
- if (file->state.sync != SYNC_BEHIND_OS){
- file->state.sync = SYNC_UNSAVED;
+ if (file->state.dirty != DirtyState_UnloadedChanges){
+ file->state.dirty = DirtyState_UnsavedChanges;
}
}
inline void
file_mark_behind_os(Editing_File *file){
- file->state.sync = SYNC_BEHIND_OS;
+ file->state.dirty = DirtyState_UnloadedChanges;
}
-inline File_Sync_State
+inline Dirty_State
file_get_sync(Editing_File *file){
- return (file->state.sync);
+ return (file->state.dirty);
}
internal void
diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index 274781df..58d8661d 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -782,7 +782,7 @@ starts_new_line(u8 character){
inline void
file_synchronize_times(System_Functions *system, Editing_File *file){
- file->state.sync = SYNC_GOOD;
+ file->state.dirty = DirtyState_UpToDate;
}
internal b32
@@ -3217,9 +3217,9 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti
result.message = null_string;
if (result.is_loaded){
switch (file_get_sync(file)){
- case SYNC_GOOD: result.message = message_loaded; break;
- case SYNC_BEHIND_OS: result.message = message_unsynced; break;
- case SYNC_UNSAVED: result.message = message_unsaved; break;
+ case DirtyState_UpToDate: result.message = message_loaded; break;
+ case DirtyState_UnsavedChanges: result.message = message_unsaved; break;
+ case DirtyState_UnloadedChanges: result.message = message_unsynced; break;
}
}
@@ -4037,8 +4037,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
message = null_string;
if (!file->settings.unimportant){
switch (file_get_sync(file)){
- case SYNC_BEHIND_OS: message = message_unsynced; break;
- case SYNC_UNSAVED: message = message_unsaved; break;
+ case DirtyState_UnloadedChanges: message = message_unsynced; break;
+ case DirtyState_UnsavedChanges: message = message_unsaved; break;
}
}
@@ -4058,8 +4058,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
message = null_string;
if (!file->settings.unimportant){
switch (file_get_sync(file)){
- case SYNC_BEHIND_OS: message = message_unsynced; break;
- case SYNC_UNSAVED: message = message_unsaved; break;
+ case DirtyState_UnloadedChanges: message = message_unsynced; break;
+ case DirtyState_UnsavedChanges: message = message_unsaved; break;
}
}
@@ -5132,13 +5132,13 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re
if (!file->settings.unimportant){
switch (file_get_sync(file)){
- case SYNC_BEHIND_OS:
+ case DirtyState_UnloadedChanges:
{
persist String out_of_sync = make_lit_string(" !");
intbar_draw_string(target, &bar, out_of_sync, pop2_color);
}break;
- case SYNC_UNSAVED:
+ case DirtyState_UnsavedChanges:
{
persist String out_of_sync = make_lit_string(" *");
intbar_draw_string(target, &bar, out_of_sync, pop2_color);
diff --git a/TODO.txt b/TODO.txt
index ca7c95df..1b792d3a 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -41,7 +41,7 @@
; [X] switch to file "4ed.cpp" with "win32_4ed.cpp" open
; [X] inserting new line at top of file ~ scrolling jump when window is unaligned
; [X] saving/killing *compilation* doesn't work
-; [X] line wrapping also doesn't work
+; [X] line wrapping also doesn't work
; [X] save as corruptitates the filename
; [X] crash when leaving maximized mode and view get's weird
; [X] decrease scroll speed on short windows
@@ -87,18 +87,14 @@
; BEFORE I SHIP
;
-; [X] why are command line files not loading any more?
; [X] tokens in the custom API
; [X] token seeking on custom side
; [X] auto indent on the custom side
-; [] indent whole comments
+; [X] indent whole comments
; [] inserting lines at end of block comment
; [] clean up and comment the auto indent code to allow for customizations
; [] more built in options for auto indenting
-; [] expose dirty flags
; [] occasionally missing the (!) mark on files on windows
-; [] scroll down on compilation buffer durring compilation
-;
;
; TODOS
@@ -143,6 +139,8 @@
; [X] file out of sync
; [X] mouse down/up distinction
; [X] case insensitive interactive switch buffer
+; [X] expose dirty flags
+; [X] why are command line files not loading any more?
;
; [] binary buffers
diff --git a/linux_4ed.cpp b/linux_4ed.cpp
index 53a03240..7d4cb425 100644
--- a/linux_4ed.cpp
+++ b/linux_4ed.cpp
@@ -806,6 +806,11 @@ IS_FULLSCREEN_SIG(system_is_fullscreen){
return result;
}
+internal
+SEND_EXIT_SIGNAL_SIG(system_send_exit_signal){
+ linuxvars.keep_running = 0;
+}
+
//
// Clipboard
//
@@ -1502,6 +1507,7 @@ LinuxLoadSystemCode(){
linuxvars.system.show_mouse_cursor = system_show_mouse_cursor;
linuxvars.system.toggle_fullscreen = system_toggle_fullscreen;
linuxvars.system.is_fullscreen = system_is_fullscreen;
+ linuxvars.system.send_exit_signal = system_send_exit_signal;
// clipboard
linuxvars.system.post_clipboard = system_post_clipboard;
@@ -2214,10 +2220,23 @@ LinuxFatalErrorMsg(const char* msg)
exit(1);
}
- int win_w = 450;
- int win_h = 150 + (strlen(msg) / 40) * 24;
+ const int num_cols = 50;
+ int win_w = (num_cols + 10) * 9;
+ int win_h = 140;
- Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, win_w, win_h, 0, 0, 0x2EA44F);
+ {
+ const char *start_p = msg, *space_p = NULL;
+ for(const char* p = msg; *p; ++p){
+ if(*p == ' ') space_p = p;
+ if(*p == '\n' || p - start_p > num_cols){
+ win_h += 18;
+ start_p = space_p ? space_p + 1 : p;
+ space_p = NULL;
+ }
+ }
+ }
+
+ Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, win_w, win_h, 0, 0, 0x227A3B);
XStoreName(dpy, w, "4coder Error");
XSizeHints* sh = XAllocSizeHints();
@@ -2239,26 +2258,26 @@ LinuxFatalErrorMsg(const char* msg)
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(dpy, w, &WM_DELETE_WINDOW, 1);
+ LinuxSetIcon(dpy, w);
+
XMapRaised(dpy, w);
XSync(dpy, False);
- XSelectInput(dpy, w, ExposureMask | StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
+ XSelectInput(dpy, w, ExposureMask | StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask);
- XFontStruct* font = XLoadQueryFont(dpy, "-*-fixed-*-*-*-*-*-140-*-*-*-*-iso8859-1");
+ XFontStruct* font = XLoadQueryFont(dpy, "-*-fixed-bold-*-*-*-*-140-*-*-*-*-iso8859-1");
if(!font){
exit(1);
}
XGCValues gcv;
gcv.foreground = WhitePixel(dpy, 0);
- gcv.background = 0x2EA44F;
gcv.line_width = 2;
gcv.font = font->fid;
- GC gc = XCreateGC(dpy, w, GCForeground | GCBackground | GCFont | GCLineWidth, &gcv);
-
+ GC gc1 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
gcv.foreground = BlackPixel(dpy, 0);
- GC gc2 = XCreateGC(dpy, w, GCForeground | GCBackground | GCFont | GCLineWidth, &gcv);
+ GC gc2 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
int button_trigger = 0;
int button_hi = 0;
@@ -2273,7 +2292,6 @@ LinuxFatalErrorMsg(const char* msg)
if(ev.type == ConfigureNotify){
redraw = 1;
-
win_w = ev.xconfigure.width;
win_h = ev.xconfigure.height;
}
@@ -2292,6 +2310,13 @@ LinuxFatalErrorMsg(const char* msg)
}
}
+ if(ev.type == KeyPress){
+ KeySym sym = XLookupKeysym(&ev.xkey, 0);
+ if(sym == XK_Escape || sym == XK_Return){
+ exit(1);
+ }
+ }
+
if(ev.type == ButtonPress && ev.xbutton.button == Button1){
if(button_hi) button_trigger = 1;
redraw = 1;
@@ -2312,6 +2337,10 @@ LinuxFatalErrorMsg(const char* msg)
exit(1);
}
+#define DRAW_STR(x, y, str, len) \
+ XDrawString(dpy, w, gc2, (x)+1, (y)+1, (str), (len)); \
+ XDrawString(dpy, w, gc1, (x) , (y) , (str), (len))
+
if(redraw){
XClearWindow(dpy, w);
@@ -2323,38 +2352,39 @@ LinuxFatalErrorMsg(const char* msg)
const char title[] = "4coder - Fatal Error";
int width = XTextWidth(font, title, sizeof(title)-1);
int x = (win_w/2) - (width/2);
- XDrawString(dpy, w, gc2, x+2, y+2, title, sizeof(title)-1);
- XDrawString(dpy, w, gc, x, y, title, sizeof(title)-1);
+ DRAW_STR(x, y, title, sizeof(title)-1);
}
y += 36;
-
- int width = XTextWidth(font, "x", 1) * 40;
+ int width = XTextWidth(font, "x", 1) * num_cols;
int x = (win_w/2) - (width/2);
+
for(const char* p = line_start; *p; ++p){
if(*p == ' ') last_space = p;
- if(p - line_start > 40){
- if(!last_space) last_space = p;
+ if(p - line_start > num_cols || *p == '\n' || !p[1]){
- XDrawString(dpy, w, gc2, x+2, y+2, line_start, last_space - line_start);
- XDrawString(dpy, w, gc, x, y, line_start, last_space - line_start);
- line_start = *last_space == ' ' ? last_space + 1 : p;
+ const char* new_line_start = last_space + 1;
+ if(!last_space || *p == '\n' || !p[1]){
+ new_line_start = last_space = (p + !p[1]);
+ }
+
+ DRAW_STR(x, y, line_start, last_space - line_start);
+
+ line_start = new_line_start;
last_space = NULL;
y += 18;
}
}
- XDrawString(dpy, w, gc2, x+2, y+2, line_start, strlen(line_start));
- XDrawString(dpy, w, gc, x, y, line_start, strlen(line_start));
-
- XDrawRectangles(dpy, w, gc, &button_rect, 1);
+ XDrawRectangles(dpy, w, gc1, &button_rect, 1);
if(button_hi || button_trigger){
XDrawRectangle(dpy, w, gc2, button_rect.x+1, button_rect.y+1, button_rect.width-2, button_rect.height-2);
}
- XDrawString(dpy, w, gc2, button_rect.x + 22, button_rect.y + 17, "Drat!", 5);
- XDrawString(dpy, w, gc, button_rect.x + 20, button_rect.y + 15, "Drat!", 5);
+
+ DRAW_STR(button_rect.x + 20, button_rect.y + 15, "Drat!", 5);
}
}
+#undef DRAW_STR
}
internal int
@@ -3279,7 +3309,7 @@ main(int argc, char **argv)
Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
None,
- XCreateFontCursor(linuxvars.XDisplay, XC_arrow),
+ None,
XCreateFontCursor(linuxvars.XDisplay, XC_xterm),
XCreateFontCursor(linuxvars.XDisplay, XC_sb_h_double_arrow),
XCreateFontCursor(linuxvars.XDisplay, XC_sb_v_double_arrow)
@@ -3433,6 +3463,8 @@ main(int argc, char **argv)
linuxvars.input.clipboard = null_string;
}
+ b32 keep_running = linuxvars.keep_running;
+
linuxvars.app.step(
&linuxvars.system,
&linuxvars.target,
@@ -3443,7 +3475,7 @@ main(int argc, char **argv)
if(result.perform_kill){
break;
- } else {
+ } else if(!keep_running && !linuxvars.keep_running){
linuxvars.keep_running = 1;
}
diff --git a/win32_4ed.cpp b/win32_4ed.cpp
index 312bbf2e..e4a84323 100644
--- a/win32_4ed.cpp
+++ b/win32_4ed.cpp
@@ -904,7 +904,7 @@ win32_init_drive_strings(Drive_Strings *dstrings){
// for the ability to handle them very quickly when nothing strange is
// going on.
internal int32_t
-win32_canonical_ansi_name(Drive_Strings *dstrings, char *src, i32 len, char *dst, i32 max){
+win32_canonical_ascii_name(Drive_Strings *dstrings, char *src, i32 len, char *dst, i32 max){
char *wrt = dst;
char *wrt_stop = dst + max;
char *src_stop = src + len;
@@ -978,7 +978,7 @@ win32_canonical_ansi_name(Drive_Strings *dstrings, char *src, i32 len, char *dst
internal
Sys_Get_Canonical_Sig(system_get_canonical){
- i32 result = win32_canonical_ansi_name(&win32vars.dstrings, filename, len, buffer, max);
+ i32 result = win32_canonical_ascii_name(&win32vars.dstrings, filename, len, buffer, max);
return(result);
}