about to patch linux clipboard

master
Allen Webster 2016-02-22 22:14:23 -05:00
parent 46aaa4ac5b
commit 2f1486c9dd
16 changed files with 1356 additions and 292 deletions

View File

@ -0,0 +1,600 @@
From 6d24dc4f80df0816a2c34b2a56026cb10ea1fd79 Mon Sep 17 00:00:00 2001
From: insofaras <iaminsofaras@gmail.com>
Date: Mon, 22 Feb 2016 21:22:52 +0000
Subject: [PATCH] fix set_file_list a bit + add clipboard paste
---
code/linux_4ed.cpp | 493 +++++++++++++++++++++++++++++++++--------------------
1 file changed, 310 insertions(+), 183 deletions(-)
diff --git a/code/linux_4ed.cpp b/code/linux_4ed.cpp
index cea1099..af37526 100644
--- a/code/linux_4ed.cpp
+++ b/code/linux_4ed.cpp
@@ -72,7 +72,11 @@ struct Linux_Vars{
Mouse_State mouse_data;
String clipboard_contents;
-
+ String clipboard_outgoing;
+
+ Atom atom_CLIPBOARD;
+ Atom atom_UTF8_STRING;
+
void *app_code;
void *custom;
@@ -89,6 +93,8 @@ struct Linux_Vars{
Font_Load_System fnt;
};
+#define LINUX_MAX_PASTE_CHARS 0x10000L
+
globalvar Linux_Vars linuxvars;
globalvar Application_Memory memory_vars;
globalvar Exchange exchange_vars;
@@ -180,6 +186,21 @@ Sys_Free_Memory_Sig(system_free_memory){
LinuxFreeMemory(block);
}
+internal void
+LinuxStringDup(String* str, void* data, size_t size){
+ if(str->memory_size < size){
+ if(str->str){
+ LinuxFreeMemory(str->str);
+ }
+ str->memory_size = size;
+ str->str = (char*)LinuxGetMemory(size);
+ //TODO(inso): handle alloc failure case
+ }
+
+ str->size = size;
+ memcpy(str->str, data, size);
+}
+
#if (defined(_BSD_SOURCE) || defined(_SVID_SOURCE))
#define TimeBySt
#endif
@@ -231,9 +252,11 @@ Sys_Set_File_List_Sig(system_set_file_list){
i32 count, file_count, size, required_size;
terminate_with_null(&directory);
+
d = opendir(directory.str);
if (d){
count = 0;
+ file_count = 0;
for (entry = readdir(d);
entry != 0;
entry = readdir(d)){
@@ -242,7 +265,6 @@ Sys_Set_File_List_Sig(system_set_file_list){
for (size = 0; fname[size]; ++size);
count += size + 1;
}
- closedir(d);
required_size = count + file_count * sizeof(File_Info);
if (file_list->block_size < required_size){
@@ -253,33 +275,41 @@ Sys_Set_File_List_Sig(system_set_file_list){
file_list->infos = (File_Info*)file_list->block;
cursor = (char*)(file_list->infos + file_count);
- d = opendir(directory.str);
- if (d){
- info_ptr = file_list->infos;
- for (entry = readdir(d);
- entry != 0;
- entry = readdir(d), ++info_ptr){
- fname = entry->d_name;
- cursor_start = cursor;
- for (; *fname; ) *cursor++ = *fname++;
+ rewinddir(d);
+ info_ptr = file_list->infos;
+ for (entry = readdir(d);
+ entry != 0;
+ entry = readdir(d), ++info_ptr){
+ fname = entry->d_name;
+ cursor_start = cursor;
+ for (; *fname; ) *cursor++ = *fname++;
- // TODO(allen): detect file/folder status
- // (also make sure this even GETS folders!!!)
- info_ptr->folder = 0;
- info_ptr->filename.str = cursor_start;
- info_ptr->filename.size = (i32)(cursor - cursor_start);
- *cursor++ = 0;
- info_ptr->filename.memory_size = info_ptr->filename.size + 1;
+#ifdef _DIRENT_HAVE_D_TYPE
+ if(entry->d_type != DT_UNKNOWN){
+ info_ptr->folder = entry->d_type == DT_DIR;
+ } else
+#endif
+ {
+ struct stat st;
+ if(lstat(entry->d_name, &st) != -1){
+ info_ptr->folder = S_ISDIR(st.st_mode);
+ } else {
+ info_ptr->folder = 0;
+ }
}
+
+ info_ptr->filename.str = cursor_start;
+ info_ptr->filename.size = (i32)(cursor - cursor_start);
+ *cursor++ = 0;
+ info_ptr->filename.memory_size = info_ptr->filename.size + 1;
}
closedir(d);
}
- closedir(d);
}
Sys_Post_Clipboard_Sig(system_post_clipboard){
- // TODO(allen): Implement
- AllowLocal(str);
+ LinuxStringDup(&linuxvars.clipboard_outgoing, str.str, str.size);
+ XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
}
Sys_CLI_Call_Sig(system_cli_call){
@@ -573,6 +603,8 @@ LinuxLoadSystemCode(){
linuxvars.system->internal_sentinel = internal_sentinel;
linuxvars.system->internal_get_thread_states = internal_get_thread_states;
linuxvars.system->internal_debug_message = internal_debug_message;
+
+ linuxvars.system->slash = '/';
}
internal void
@@ -591,7 +623,7 @@ LinuxRedrawTarget(){
system_acquire_lock(RENDER_LOCK);
launch_rendering(&linuxvars.target);
system_release_lock(RENDER_LOCK);
- glFlush();
+// glFlush();
glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow);
}
@@ -1258,70 +1290,76 @@ main(int argc, char **argv)
}
}
+ if (!window_setup_success){
+ fprintf(stderr, "Error creating window.");
+ exit(1);
+ }
+
XSetICFocus(linuxvars.input_context);
-
- if (window_setup_success){
- linuxvars.app.init(linuxvars.system, &linuxvars.target,
- &memory_vars, &exchange_vars, &linuxvars.key_codes,
- linuxvars.clipboard_contents, current_directory,
- linuxvars.custom_api);
- LinuxResizeTarget(WinWidth, WinHeight);
+ linuxvars.atom_CLIPBOARD = XInternAtom(linuxvars.XDisplay, "CLIPBOARD", False);
+ linuxvars.atom_UTF8_STRING = XInternAtom(linuxvars.XDisplay, "UTF8_STRING", False);
- Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False);
- if(WM_DELETE_WINDOW != None){
- XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, &WM_DELETE_WINDOW, 1);
- }
+ Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False);
+ if(WM_DELETE_WINDOW != None){
+ XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, &WM_DELETE_WINDOW, 1);
+ }
- b32 keep_running = 1;
+ linuxvars.app.init(linuxvars.system, &linuxvars.target,
+ &memory_vars, &exchange_vars, &linuxvars.key_codes,
+ linuxvars.clipboard_contents, current_directory,
+ linuxvars.custom_api);
- while(keep_running)
+ LinuxResizeTarget(WinWidth, WinHeight);
+ b32 keep_running = 1;
+
+ while(keep_running)
+ {
+ XEvent PrevEvent = {};
+
+ while(XPending(linuxvars.XDisplay))
{
- XEvent PrevEvent = {};
-
- while(XPending(linuxvars.XDisplay))
- {
- XEvent Event;
- XNextEvent(linuxvars.XDisplay, &Event);
-
- if (XFilterEvent(&Event, None) == True){
- continue;
- }
-
- switch (Event.type){
- case KeyPress: {
- b32 is_hold =
- PrevEvent.type == KeyRelease &&
- PrevEvent.xkey.time == Event.xkey.time &&
- PrevEvent.xkey.keycode == Event.xkey.keycode;
-
- b8 mods[CONTROL_KEY_COUNT] = {};
- if(Event.xkey.state & ShiftMask) mods[CONTROL_KEY_SHIFT] = 1;
- if(Event.xkey.state & ControlMask) mods[CONTROL_KEY_CONTROL] = 1;
- if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1;
- if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1;
- // NOTE(inso): mod5 == AltGr
- // if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
-
- KeySym keysym = NoSymbol;
- char buff[32], no_caps_buff[32];
-
- // NOTE(inso): Turn ControlMask off like the win32 code does.
- if(mods[CONTROL_KEY_CONTROL] && !mods[CONTROL_KEY_ALT]){
- Event.xkey.state &= ~(ControlMask);
- }
-
- // TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars
- XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
-
- Event.xkey.state &= ~LockMask;
- XLookupString(&Event.xkey, no_caps_buff, sizeof(no_caps_buff), NULL, NULL);
-
- u8 key = keycode_lookup(Event.xkey.keycode);
-
- if(key){
- push_key(key, 0, 0, &mods, is_hold);
- } else {
+ XEvent Event;
+ XNextEvent(linuxvars.XDisplay, &Event);
+
+ if (XFilterEvent(&Event, None) == True){
+ continue;
+ }
+
+ switch (Event.type){
+ case KeyPress: {
+ b32 is_hold =
+ PrevEvent.type == KeyRelease &&
+ PrevEvent.xkey.time == Event.xkey.time &&
+ PrevEvent.xkey.keycode == Event.xkey.keycode;
+
+ b8 mods[CONTROL_KEY_COUNT] = {};
+ if(Event.xkey.state & ShiftMask) mods[CONTROL_KEY_SHIFT] = 1;
+ if(Event.xkey.state & ControlMask) mods[CONTROL_KEY_CONTROL] = 1;
+ if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1;
+ if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1;
+ // NOTE(inso): mod5 == AltGr
+ // if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
+
+ KeySym keysym = NoSymbol;
+ char buff[32], no_caps_buff[32];
+
+ // NOTE(inso): Turn ControlMask off like the win32 code does.
+ if(mods[CONTROL_KEY_CONTROL] && !mods[CONTROL_KEY_ALT]){
+ Event.xkey.state &= ~(ControlMask);
+ }
+
+ // TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars
+ XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
+
+ Event.xkey.state &= ~LockMask;
+ XLookupString(&Event.xkey, no_caps_buff, sizeof(no_caps_buff), NULL, NULL);
+
+ u8 key = keycode_lookup(Event.xkey.keycode);
+
+ if(key){
+ push_key(key, 0, 0, &mods, is_hold);
+ } else {
key = buff[0] & 0xFF;
if(key < 128){
u8 no_caps_key = no_caps_buff[0] & 0xFF;
@@ -1331,113 +1369,202 @@ main(int argc, char **argv)
} else {
push_key(0, 0, 0, &mods, is_hold);
}
- }
- }break;
-
- case MotionNotify: {
- linuxvars.mouse_data.x = Event.xmotion.x;
- linuxvars.mouse_data.y = Event.xmotion.y;
- }break;
-
- case ButtonPress: {
- switch(Event.xbutton.button){
- case Button1: {
- linuxvars.mouse_data.left_button_pressed = 1;
- linuxvars.mouse_data.left_button = 1;
- } break;
- case Button3: {
- linuxvars.mouse_data.right_button_pressed = 1;
- linuxvars.mouse_data.right_button = 1;
- } break;
- }
- }break;
-
- case ButtonRelease: {
- switch(Event.xbutton.button){
- case Button1: {
- linuxvars.mouse_data.left_button_released = 1;
- linuxvars.mouse_data.left_button = 0;
- } break;
- case Button3: {
- linuxvars.mouse_data.right_button_released = 1;
- linuxvars.mouse_data.right_button = 0;
- } break;
- }
- }break;
-
- case EnterNotify: {
- linuxvars.mouse_data.out_of_window = 0;
- }break;
-
- case LeaveNotify: {
- linuxvars.mouse_data.out_of_window = 1;
- }break;
-
- case FocusIn:
- case FocusOut: {
- linuxvars.mouse_data.left_button = 0;
- linuxvars.mouse_data.right_button = 0;
- }break;
-
- case ConfigureNotify: {
- i32 w = Event.xconfigure.width, h = Event.xconfigure.height;
-
- if(w != linuxvars.target.width || h != linuxvars.target.height){
- LinuxResizeTarget(Event.xconfigure.width, Event.xconfigure.height);
- }
- }break;
-
- case MappingNotify: {
- if(Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){
- XRefreshKeyboardMapping(&Event.xmapping);
- keycode_init(linuxvars.XDisplay, &linuxvars.key_codes);
- }
- }break;
-
- case ClientMessage: {
- if ((Atom)Event.xclient.data.l[0] == WM_DELETE_WINDOW) {
- keep_running = false;
- }
- }break;
- }
-
- PrevEvent = Event;
+ }
+ }break;
+
+ case MotionNotify: {
+ linuxvars.mouse_data.x = Event.xmotion.x;
+ linuxvars.mouse_data.y = Event.xmotion.y;
+ }break;
+
+ case ButtonPress: {
+ switch(Event.xbutton.button){
+ case Button1: {
+ linuxvars.mouse_data.left_button_pressed = 1;
+ linuxvars.mouse_data.left_button = 1;
+ } break;
+ case Button3: {
+ linuxvars.mouse_data.right_button_pressed = 1;
+ linuxvars.mouse_data.right_button = 1;
+ } break;
+ }
+ }break;
+
+ case ButtonRelease: {
+ switch(Event.xbutton.button){
+ case Button1: {
+ linuxvars.mouse_data.left_button_released = 1;
+ linuxvars.mouse_data.left_button = 0;
+ } break;
+ case Button3: {
+ linuxvars.mouse_data.right_button_released = 1;
+ linuxvars.mouse_data.right_button = 0;
+ } break;
+ }
+ }break;
+
+ case EnterNotify: {
+ linuxvars.mouse_data.out_of_window = 0;
+ }break;
+
+ case LeaveNotify: {
+ linuxvars.mouse_data.out_of_window = 1;
+ }break;
+
+ case FocusIn:
+ case FocusOut: {
+ linuxvars.mouse_data.left_button = 0;
+ linuxvars.mouse_data.right_button = 0;
+ }break;
+
+ case ConfigureNotify: {
+ i32 w = Event.xconfigure.width, h = Event.xconfigure.height;
+
+ if(w != linuxvars.target.width || h != linuxvars.target.height){
+ LinuxResizeTarget(Event.xconfigure.width, Event.xconfigure.height);
+ }
+ }break;
+
+ case MappingNotify: {
+ if(Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){
+ XRefreshKeyboardMapping(&Event.xmapping);
+ keycode_init(linuxvars.XDisplay, &linuxvars.key_codes);
+ }
+ }break;
+
+ case ClientMessage: {
+ if ((Atom)Event.xclient.data.l[0] == WM_DELETE_WINDOW) {
+ keep_running = false;
+ }
+ }break;
+
+ // NOTE(inso): Someone wants us to give them the clipboard data.
+ case SelectionRequest: {
+ XSelectionRequestEvent request = Event.xselectionrequest;
+
+ XSelectionEvent response = {};
+ response.type = SelectionNotify;
+ response.requestor = request.requestor;
+ response.selection = request.selection;
+ response.target = request.target;
+ response.time = request.time;
+ response.property = None;
+
+ //TODO(inso): handle TARGETS negotiation instead of requiring UTF8_STRING
+ if (
+ linuxvars.clipboard_outgoing.size &&
+ request.target == linuxvars.atom_UTF8_STRING &&
+ request.selection == linuxvars.atom_CLIPBOARD &&
+ request.property != None &&
+ request.display &&
+ request.requestor
+ ){
+ XChangeProperty(
+ request.display,
+ request.requestor,
+ request.property,
+ request.target,
+ 8,
+ PropModeReplace,
+ (unsigned char*)linuxvars.clipboard_outgoing.str,
+ linuxvars.clipboard_outgoing.size
+ );
+
+ response.property = request.property;
+ }
+
+ XSendEvent(request.display, request.requestor, True, 0, (XEvent*)&response);
+
+ }break;
+
+ // NOTE(inso): Another program is now the clipboard owner.
+ case SelectionClear: {
+ if(Event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){
+ linuxvars.clipboard_outgoing.size = 0;
+ }
+ }break;
+
+ // NOTE(inso): A program is giving us the clipboard data we asked for.
+ case SelectionNotify: {
+ XSelectionEvent* e = (XSelectionEvent*)&Event;
+ if(
+ e->selection == linuxvars.atom_CLIPBOARD &&
+ e->target == linuxvars.atom_UTF8_STRING &&
+ e->property != None
+ ){
+ Atom type;
+ int fmt;
+ unsigned long nitems, bytes_left;
+ u8 *data;
+
+ XGetWindowProperty(
+ linuxvars.XDisplay,
+ linuxvars.XWindow,
+ linuxvars.atom_CLIPBOARD,
+ 0L,
+ LINUX_MAX_PASTE_CHARS/4L,
+ False,
+ linuxvars.atom_UTF8_STRING,
+ &type,
+ &fmt,
+ &nitems,
+ &bytes_left,
+ &data
+ );
+
+ LinuxStringDup(&linuxvars.clipboard_contents, data, nitems);
+
+ XFree(data);
+ }
+ }break;
}
- b32 redraw = 1;
-
- Key_Input_Data input_data;
- Mouse_State mouse;
- Application_Step_Result result;
-
- input_data = linuxvars.key_data;
- mouse = linuxvars.mouse_data;
-
- result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
- result.redraw = redraw;
- result.lctrl_lalt_is_altgr = 0;
-
- linuxvars.app.step(linuxvars.system,
- &linuxvars.key_codes,
- &input_data,
- &mouse,
- &linuxvars.target,
- &memory_vars,
- &exchange_vars,
- linuxvars.clipboard_contents,
- 1, linuxvars.first, redraw,
- &result);
-
- if (result.redraw){
- LinuxRedrawTarget();
- }
+ PrevEvent = Event;
+ }
- linuxvars.key_data = {};
- linuxvars.mouse_data.left_button_pressed = 0;
- linuxvars.mouse_data.left_button_released = 0;
- linuxvars.mouse_data.right_button_pressed = 0;
- linuxvars.mouse_data.right_button_released = 0;
+ // FIXME(inso): is getting the clipboard every frame a bad idea?
+ XConvertSelection(
+ linuxvars.XDisplay,
+ linuxvars.atom_CLIPBOARD,
+ linuxvars.atom_UTF8_STRING,
+ linuxvars.atom_CLIPBOARD,
+ linuxvars.XWindow,
+ CurrentTime
+ );
+
+ b32 redraw = 1;
+
+ Key_Input_Data input_data;
+ Mouse_State mouse;
+ Application_Step_Result result;
+
+ input_data = linuxvars.key_data;
+ mouse = linuxvars.mouse_data;
+
+ result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
+ result.redraw = redraw;
+ result.lctrl_lalt_is_altgr = 0;
+
+ linuxvars.app.step(linuxvars.system,
+ &linuxvars.key_codes,
+ &input_data,
+ &mouse,
+ &linuxvars.target,
+ &memory_vars,
+ &exchange_vars,
+ linuxvars.clipboard_contents,
+ 1, linuxvars.first, redraw,
+ &result);
+
+ if (result.redraw){
+ LinuxRedrawTarget();
}
+
+ linuxvars.key_data = {};
+ linuxvars.mouse_data.left_button_pressed = 0;
+ linuxvars.mouse_data.left_button_released = 0;
+ linuxvars.mouse_data.right_button_pressed = 0;
+ linuxvars.mouse_data.right_button_released = 0;
}
}
--
1.9.1

View File

@ -0,0 +1,102 @@
From 2e9c55181ecb0a0f94c7f1b389f19fd76e856d55 Mon Sep 17 00:00:00 2001
From: insofaras <iaminsofaras@gmail.com>
Date: Tue, 23 Feb 2016 02:01:26 +0000
Subject: [PATCH] get file list working
---
code/4ed_color_view.cpp | 11 ++++++-----
code/linux_4ed.cpp | 12 ++++++++----
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/code/4ed_color_view.cpp b/code/4ed_color_view.cpp
index 391d891..2b170a6 100644
--- a/code/4ed_color_view.cpp
+++ b/code/4ed_color_view.cpp
@@ -1429,11 +1429,12 @@ do_checkbox_list_option(i32 id, UI_State *state, UI_Layout *layout, String text,
internal b32
-do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, b32 is_folder, String extra){
+do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, b32 is_folder, String extra, char slash){
b32 result = 0;
Style *style = state->style;
i16 font_id = style->font_id;
i32 character_h = get_font_info(state->font_set, font_id)->height;
+ char slash_buf[2] = { slash, 0 };
i32_Rect box = layout_rect(layout, character_h*2);
Widget_ID wid = make_id(state, id);
@@ -1456,7 +1457,7 @@ do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, b32
draw_rectangle(target, inner, back);
i32 x = inner.x0, y = box.y0 + character_h/2;
x = draw_string(target, font_id, filename, x, y, fore);
- if (is_folder) x = draw_string(target, font_id, "\\", x, y, fore);
+ if (is_folder) x = draw_string(target, font_id, slash_buf, x, y, fore);
draw_string(target, font_id, extra, x, y, pop);
draw_margin(target, box, inner, outline);
}
@@ -1522,13 +1523,13 @@ do_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layout,
}
if ((is_folder || !has_filter || ext_match) && name_match){
- if (do_file_option(100+i, state, layout, filename, is_folder, message)){
+ if (do_file_option(100+i, state, layout, filename, is_folder, message, system->slash)){
result = 1;
hot_directory_clean_end(hot_dir);
append(&hot_dir->string, filename);
if (is_folder){
*new_dir = 1;
- append(&hot_dir->string, "\\");
+ append(&hot_dir->string, system->slash);
}
else{
*selected = 1;
@@ -1572,7 +1573,7 @@ do_live_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layo
}
if (filename_match(*string, &absolutes, file->name.live_name, 1)){
- if (do_file_option(100+i, state, layout, file->name.live_name, 0, message)){
+ if (do_file_option(100+i, state, layout, file->name.live_name, 0, message, system->slash)){
result = 1;
*selected = 1;
copy(string, file->name.source_path);
diff --git a/code/linux_4ed.cpp b/code/linux_4ed.cpp
index af37526..1fa7a54 100644
--- a/code/linux_4ed.cpp
+++ b/code/linux_4ed.cpp
@@ -303,6 +303,9 @@ Sys_Set_File_List_Sig(system_set_file_list){
*cursor++ = 0;
info_ptr->filename.memory_size = info_ptr->filename.size + 1;
}
+
+ file_list->count = file_count;
+
closedir(d);
}
}
@@ -1497,7 +1500,7 @@ main(int argc, char **argv)
unsigned long nitems, bytes_left;
u8 *data;
- XGetWindowProperty(
+ int result = XGetWindowProperty(
linuxvars.XDisplay,
linuxvars.XWindow,
linuxvars.atom_CLIPBOARD,
@@ -1512,9 +1515,10 @@ main(int argc, char **argv)
&data
);
- LinuxStringDup(&linuxvars.clipboard_contents, data, nitems);
-
- XFree(data);
+ if(result == Success && fmt == 8){
+ LinuxStringDup(&linuxvars.clipboard_contents, data, nitems);
+ XFree(data);
+ }
}
}break;
}
--
1.9.1

View File

@ -247,6 +247,9 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
bind(context, '\t', MDFR_SHIFT, cmdid_auto_tab_line_at_cursor);
bind_me(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind_me(context, ' ', MDFR_SHIFT, cmdid_write_character);
end_map(context);

View File

@ -174,8 +174,8 @@ FCPP_LINK int reverse_seek_slash(String str, int start_pos);
inline bool get_front_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, reverse_seek_slash(dir) + 1)); }
inline bool get_path_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, 0, reverse_seek_slash(dir) + 1)); }
inline void truncate_to_path_of_directory(String *dir) { dir->size = reverse_seek_slash(*dir) + 1; }
FCPP_LINK bool set_last_folder(String *dir, char *folder_name);
FCPP_LINK bool set_last_folder(String *dir, String folder_name);
FCPP_LINK bool set_last_folder(String *dir, char *folder_name, char slash);
FCPP_LINK bool set_last_folder(String *dir, String folder_name, char slash);
FCPP_LINK String file_extension(String str);
FCPP_LINK String file_extension_slowly(char *str);
FCPP_LINK bool remove_last_folder(String *str);
@ -980,12 +980,15 @@ reverse_seek_slash(String str){
}
FCPP_LINK bool
set_last_folder(String *dir, char *folder_name){
set_last_folder(String *dir, char *folder_name, char slash){
char str[2];
bool result = 0;
int size = reverse_seek_slash(*dir) + 1;
dir->size = size;
str[0] = slash;
str[1] = 0;
if (append(dir, folder_name)){
if (append(dir, (char*)"\\")){
if (append(dir, str)){
result = 1;
}
}
@ -996,12 +999,15 @@ set_last_folder(String *dir, char *folder_name){
}
FCPP_LINK bool
set_last_folder(String *dir, String folder_name){
set_last_folder(String *dir, String folder_name, char slash){
char str[2];
bool result = 0;
int size = reverse_seek_slash(*dir) + 1;
dir->size = size;
str[0] = slash;
str[1] = 0;
if (append(dir, folder_name)){
if (append(dir, (char*)"\\")){
if (append(dir, str)){
result = 1;
}
}

26
4ed.cpp
View File

@ -1496,7 +1496,7 @@ COMMAND_DECL(move_up){
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_FONT_SET(font_set);
f32 font_height = (f32)get_font_info(font_set, view->style->font_id)->height;
f32 cy = view_get_cursor_y(view)-font_height;
f32 px = view->preferred_x;
@ -1541,33 +1541,27 @@ COMMAND_DECL(page_down){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
real32 height = view_compute_height(view);
real32 max_target_y = view_compute_max_target_y(view);
real32 cursor_y = view_get_cursor_y(view);
f32 height = view_compute_height(view);
f32 max_target_y = view_compute_max_target_y(view);
view->target_y += height;
if (view->target_y > max_target_y) view->target_y = max_target_y;
if (view->target_y >= cursor_y){
view->cursor =
view_compute_cursor_from_xy(view, 0, view->target_y);
}
view->cursor = view_compute_cursor_from_xy(
view, 0, view->target_y + (height - view->font_height)*.5f);
}
COMMAND_DECL(page_up){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
real32 height = view_compute_height(view);
real32 cursor_y = view_get_cursor_y(view);
f32 height = view_compute_height(view);
view->target_y -= height;
if (view->target_y < 0) view->target_y = 0;
if (view->target_y + height <= cursor_y){
view->cursor =
view_compute_cursor_from_xy(view, 0, view->target_y + height - view->font_height);
}
view->cursor = view_compute_cursor_from_xy(
view, 0, view->target_y + (height - view->font_height)*.5f);
}
inline void
@ -3004,7 +2998,7 @@ App_Init_Sig(app_init){
panel_init(&panels[0]);
String hdbase = make_fixed_width_string(vars->hot_dir_base_);
hot_directory_init(&vars->hot_directory, hdbase, current_directory);
hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash);
vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512);

16
4ed.h
View File

@ -111,14 +111,14 @@ struct Plat_Settings{
typedef App_Read_Command_Line_Sig(App_Read_Command_Line);
#define App_Init_Sig(name) void \
name(System_Functions *system, \
Render_Target *target, \
Application_Memory *memory, \
Exchange *exchange, \
Key_Codes *codes, \
String clipboard, \
String current_directory, \
Custom_API api)
name(System_Functions *system, \
Render_Target *target, \
Application_Memory *memory, \
Exchange *exchange, \
Key_Codes *codes, \
String clipboard, \
String current_directory, \
Custom_API api)
typedef App_Init_Sig(App_Init);

View File

@ -251,21 +251,23 @@ struct Working_Set{
struct Hot_Directory{
String string;
File_List file_list;
char slash;
};
internal void
hot_directory_init(Hot_Directory *hot_directory, String base, String dir){
hot_directory_init(Hot_Directory *hot_directory, String base, String dir, char slash){
hot_directory->string = base;
hot_directory->string.str[255] = 0;
hot_directory->string.size = 0;
copy(&hot_directory->string, dir);
append(&hot_directory->string, "\\");
append(&hot_directory->string, slash);
hot_directory->slash = slash;
}
internal void
hot_directory_clean_end(Hot_Directory *hot_directory){
String *str = &hot_directory->string;
if (str->size != 0 && str->str[str->size-1] != '\\'){
if (str->size != 0 && str->str[str->size-1] != hot_directory->slash){
str->size = reverse_seek_slash(*str) + 1;
str->str[str->size] = 0;
}

View File

@ -3239,6 +3239,9 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
#endif
if (view->widget.type != FWIDG_NONE){
#if 1
ui_render(target, view->gui_target);
#else
UI_Style ui_style = get_ui_style_upper(style);
i32_Rect widg_rect = view_widget_rect(view, view->font_height);
@ -3307,6 +3310,7 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
}
ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0);
#endif
}
draw_file_bar(view, &bar, target);

View File

@ -9,6 +9,118 @@
// TOP
enum GUI_Piece_Type{
gui_type_text_input,
gui_type_number_input,
gui_type_label,
gui_type_slider
};
struct GUI_Piece_Header{
i32 type;
i32 padding;
};
// TODO(allen): Inline string for prompt?
struct GUI_Piece_Text_Input{
String *dest;
f32_Rect rect;
String prompt;
};
struct GUI_Piece_Number_Input{
i32 *dest;
f32_Rect rect;
String prompt;
};
struct GUI_Piece_Label{
f32_Rect rect;
String text;
};
struct GUI_Piece_Slider{
i32 *dest;
f32_Rect rect;
i32 max;
};
struct GUI_Layout_Engine{
i32_Rect region;
i32 x, y;
};
struct GUI_Target{
Partition push_buffer;
GUI_Layout_Engine layout;
};
internal void
refresh_gui(GUI_Target *target, i32_Rect region){
target->push_buffer.pos = 0;
target->layout.region = region;
target->layout.x = 0;
target->layout.y = 0;
}
internal void
push_gui_item(GUI_Target *target, GUI_Piece_Header header, void *item, i32 size){
GUI_Piece_Header *ptr;
i32 total_size;
Assert(sizeof(header) == 8);
total_size = sizeof(header) + size;
total_size = ((total_size + 7) & ~7);
ptr = (GUI_Piece_Header*)push_block(&target->push_buffer, size);
if (ptr){
*ptr = header;
memcpy(ptr + 1, item, size);
}
else{
Assert(!"bad situation");
}
}
internal void
push_gui_text_in(GUI_Target *target, String prompt, String *dest){
GUI_Piece_Header header = {};
GUI_Piece_Text_Input item = {};
header.type = gui_type_text_input;
item.dest = dest;
item.rect = gui_layout(target); // ?? what do we need here?
item.prompt = prompt;
push_gui_item(target, header, &item, sizeof(item));
}
internal void
push_gui_number_in(GUI_Target *target, String prompt, i32 *dest){
GUI_Piece_Header header = {};
GUI_Piece_Number_Input item = {};
header.type = gui_type_number_input;
item.dest = dest;
item.rect = gui_layout(target); // ?? what do we need here?
item.prompt = prompt;
push_gui_item(target, header, &item, sizeof(item));
}
internal void
push_gui_label(GUI_Target *target, String text){
GUI_Piece_Header header = {};
GUI_Piece_Label item = {};
header.type = gui_type_label;
item.rect = gui_layout(target); // ?? what do we need here?
item.text = text;
push_gui_item(target, header, &item, sizeof(item));
}
struct Single_Line_Input_Step{
b8 hit_newline;
b8 hit_ctrl_newline;
@ -87,7 +199,7 @@ app_single_line_input_core(System_Functions *system,
}
if (match.filename.str){
if (match.is_folder){
set_last_folder(mode.string, match.filename);
set_last_folder(mode.string, match.filename, mode.hot_directory->slash);
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
result.hit_newline = 0;
}

View File

@ -15,7 +15,8 @@ internal void
keycode_init(Display* dpy, Key_Codes *codes){
set_dynamic_key_names(codes);
/* NOTE(inso): these are for XInput, currently not used.
#if 0
// NOTE(inso): these are for XInput, currently not used.
keycode_lookup_table[KEY_BACKSPACE] = codes->back;
keycode_lookup_table[KEY_DELETE] = codes->del;
@ -29,26 +30,61 @@ keycode_init(Display* dpy, Key_Codes *codes){
keycode_lookup_table[KEY_PAGEUP] = codes->page_up;
keycode_lookup_table[KEY_PAGEDOWN] = codes->page_down;
keycode_lookup_table[KEY_ESC] = codes->esc;
*/
#endif
#define XK_(x) XK_##x
#define XKEY(x) keycode_lookup_table[XKeysymToKeycode(dpy, XK_(x))]
// NOTE(inso): This looks a bit dumb, but it's the best way I can think of to do it, since:
// KeySyms are the type representing "virtual" keys, like XK_BackSpace, but they are 32-bit ints.
// KeyCodes are guaranteed to fit in 1 byte (and therefore the keycode_lookup_table) but
// have dynamic numbers assigned by the XServer.
// There is XKeysymToKeycode, but it only returns 1 KeyCode for a KeySym. I have my capslock
// rebound to esc, so there are two KeyCodes for the XK_Escape KeyCode but XKeysymToKeycode only
// gets one of them, hence the need for this crazy lookup which works correctly with rebound keys.
XKEY(BackSpace) = codes->back;
XKEY(Delete) = codes->del;
XKEY(Up) = codes->up;
XKEY(Down) = codes->down;
XKEY(Left) = codes->left;
XKEY(Right) = codes->right;
XKEY(Insert) = codes->insert;
XKEY(Home) = codes->home;
XKEY(End) = codes->end;
XKEY(Page_Up) = codes->page_up;
XKEY(Page_Down) = codes->page_down;
XKEY(Escape) = codes->esc;
struct SymMapping {
KeySym sym;
Code code;
} sym_table[] = {
{ XK_BackSpace, codes->back },
{ XK_Delete, codes->del },
{ XK_Up, codes->up },
{ XK_Down, codes->down },
{ XK_Left, codes->left },
{ XK_Right, codes->right },
{ XK_Insert, codes->insert },
{ XK_Home, codes->home },
{ XK_End, codes->end },
{ XK_Page_Up, codes->page_up },
{ XK_Page_Down, codes->page_down },
{ XK_Escape, codes->esc }
};
#undef XKEY
#undef XK_
const int table_size = sizeof(sym_table) / sizeof(struct SymMapping);
int key_min, key_max, syms_per_code;
XDisplayKeycodes(dpy, &key_min, &key_max);
int key_count = (key_max - key_min) + 1;
KeySym* syms = XGetKeyboardMapping(
dpy,
key_min,
key_count,
&syms_per_code
);
if(!syms) return;
int key = key_min;
for(int i = 0; i < key_count * syms_per_code; ++i){
for(int j = 0; j < table_size; ++j){
if(sym_table[j].sym == syms[i]){
keycode_lookup_table[key + (i/syms_per_code)] = sym_table[j].code;
break;
}
}
}
XFree(syms);
}

View File

@ -65,7 +65,8 @@ partition_allocate(Partition *data, i32 size){
inline void
partition_align(Partition *data, u32 boundary){
data->pos = (data->pos + (boundary - 1)) & (~boundary);
--boundary;
data->pos = (data->pos + boundary) & (~boundary);
}
inline void*

View File

@ -1,204 +1,206 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 17.12.2014
*
* Rendering layer for project codename "4ed"
*
*/
// TOP
#ifndef FRED_RENDERING_H
#define FRED_RENDERING_H
internal void*
part_alloc(int size, void *context){
Partition *part = (Partition*)context;
void *result = push_block(part, size);
return(result);
}
internal void
part_free(void *ptr, void *context){
}
#define STBTT_malloc part_alloc
#define STBTT_free part_free
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
struct Glyph_Data{
b32 exists;
};
struct Render_Font{
char name_[24];
String name;
b32 loaded;
Glyph_Data glyphs[256];
stbtt_packedchar chardata[256];
float advance_data[256];
i32 height, ascent, descent, line_skip;
i32 advance;
u32 tex;
i32 tex_width, tex_height;
};
struct Render_Target;
#define Draw_Push_Clip_Sig(name) void name(Render_Target *target, i32_Rect clip_box)
typedef Draw_Push_Clip_Sig(Draw_Push_Clip);
#define Draw_Pop_Clip_Sig(name) void name(Render_Target *target)
typedef Draw_Pop_Clip_Sig(Draw_Pop_Clip);
enum Render_Piece_Type{
piece_type_rectangle,
piece_type_outline,
piece_type_gradient,
piece_type_glyph,
piece_type_mono_glyph,
piece_type_mono_glyph_advance,
piece_type_change_clip
};
struct Render_Piece_Header{
i32 type;
};
struct Render_Piece_Rectangle{
f32_Rect rect;
u32 color;
};
struct Render_Piece_Gradient{
f32_Rect rect;
u32 left_color, right_color;
};
struct Render_Piece_Glyph{
Vec2 pos;
u32 color;
i16 font_id;
u8 character;
};
struct Render_Piece_Glyph_Advance{
Vec2 pos;
u32 color;
f32 advance;
i16 font_id;
u8 character;
};
struct Render_Piece_Change_Clip{
i32_Rect box;
};
struct Render_Piece_Combined{
Render_Piece_Header header;
union{
Render_Piece_Rectangle rectangle;
Render_Piece_Gradient gradient;
Render_Piece_Glyph glyph;
Render_Piece_Glyph_Advance glyph_advance;
};
};
#define Draw_Push_Piece_Sig(name) void name(Render_Target *target, Render_Piece_Combined piece)
typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
#define Font_Load_Sig(name) i32 name( \
Render_Font *font_out, \
char *filename, \
i32 pt_size, \
i32 tab_width)
typedef Font_Load_Sig(Font_Load);
#define Font_Info_Load_Sig(name) i32 name( \
Partition *partition, \
char *filename, \
i32 pt_size, \
i32 *height, \
i32 *advance)
typedef Font_Info_Load_Sig(Font_Info_Load);
#define Release_Font_Sig(name) void name(Render_Font *font)
typedef Release_Font_Sig(Release_Font);
struct Font_Table_Entry{
u32 hash;
String name;
i16 font_id;
};
struct Font_Info{
Render_Font *font;
String filename;
String name;
i32 height, advance;
i32 pt_size;
};
struct Font_Slot{
Font_Slot *next, *prev;
i16 font_id;
u8 padding[14];
};
struct Font_Set{
Font_Info *info;
Font_Table_Entry *entries;
u32 count, max;
void *font_block;
Font_Slot free_slots;
Font_Slot used_slots;
Font_Info_Load *font_info_load;
Font_Load *font_load;
Release_Font *release_font;
b8 *font_used_flags;
i16 used_this_frame;
i16 live_max;
};
struct Render_Target{
void *handle;
void *context;
i32_Rect clip_boxes[5];
i32 clip_top;
i32 width, height;
i32 bound_texture;
u32 color;
byte *push_buffer;
i32 size, max;
Font_Set font_set;
Partition *partition;
Draw_Push_Clip *push_clip;
Draw_Pop_Clip *pop_clip;
Draw_Push_Piece *push_piece;
};
inline i32_Rect
rect_from_target(Render_Target *target){
return i32R(0, 0, target->width, target->height);
}
inline Font_Info*
get_font_info(Font_Set *set, i16 font_id){
Font_Info *result = set->info + font_id - 1;
return(result);
}
#endif
// BOTTOM
/*
* Mr. 4th Dimention - Allen Webster
*
* 17.12.2014
*
* Rendering layer for project codename "4ed"
*
*/
// TOP
#ifndef FRED_RENDERING_H
#define FRED_RENDERING_H
internal void*
part_alloc(int size, void *context){
Partition *part = (Partition*)context;
void *result = push_block(part, size);
return(result);
}
internal void
part_free(void *ptr, void *context){
}
#define STBTT_malloc part_alloc
#define STBTT_free part_free
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
struct Glyph_Data{
b32 exists;
};
struct Render_Font{
char name_[24];
String name;
b32 loaded;
Glyph_Data glyphs[256];
stbtt_packedchar chardata[256];
float advance_data[256];
i32 height, ascent, descent, line_skip;
i32 advance;
u32 tex;
i32 tex_width, tex_height;
};
struct Render_Target;
#define Draw_Push_Clip_Sig(name) void name(Render_Target *target, i32_Rect clip_box)
typedef Draw_Push_Clip_Sig(Draw_Push_Clip);
#define Draw_Pop_Clip_Sig(name) void name(Render_Target *target)
typedef Draw_Pop_Clip_Sig(Draw_Pop_Clip);
enum Render_Piece_Type{
piece_type_rectangle,
piece_type_outline,
piece_type_gradient,
piece_type_glyph,
piece_type_mono_glyph,
piece_type_mono_glyph_advance,
piece_type_change_clip
};
struct Render_Piece_Header{
i32 type;
};
struct Render_Piece_Rectangle{
f32_Rect rect;
u32 color;
};
struct Render_Piece_Gradient{
f32_Rect rect;
u32 left_color, right_color;
};
struct Render_Piece_Glyph{
Vec2 pos;
u32 color;
i16 font_id;
u8 character;
};
struct Render_Piece_Glyph_Advance{
Vec2 pos;
u32 color;
f32 advance;
i16 font_id;
u8 character;
};
struct Render_Piece_Change_Clip{
i32_Rect box;
};
struct Render_Piece_Combined{
Render_Piece_Header header;
union{
Render_Piece_Rectangle rectangle;
Render_Piece_Gradient gradient;
Render_Piece_Glyph glyph;
Render_Piece_Glyph_Advance glyph_advance;
};
};
#define Draw_Push_Piece_Sig(name) void name(Render_Target *target, Render_Piece_Combined piece)
typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
#define Font_Load_Sig(name) i32 name( \
Render_Font *font_out, \
char *filename, \
i32 pt_size, \
i32 tab_width)
typedef Font_Load_Sig(Font_Load);
#define Font_Info_Load_Sig(name) i32 name( \
Partition *partition, \
char *filename, \
i32 pt_size, \
i32 *height, \
i32 *advance)
typedef Font_Info_Load_Sig(Font_Info_Load);
#define Release_Font_Sig(name) void name(Render_Font *font)
typedef Release_Font_Sig(Release_Font);
struct Font_Table_Entry{
u32 hash;
String name;
i16 font_id;
};
struct Font_Info{
Render_Font *font;
String filename;
String name;
i32 height, advance;
i32 pt_size;
};
struct Font_Slot{
Font_Slot *next, *prev;
i16 font_id;
u8 padding[14];
};
struct Font_Set{
Font_Info *info;
Font_Table_Entry *entries;
u32 count, max;
void *font_block;
Font_Slot free_slots;
Font_Slot used_slots;
Font_Info_Load *font_info_load;
Font_Load *font_load;
Release_Font *release_font;
b8 *font_used_flags;
i16 used_this_frame;
i16 live_max;
};
struct Render_Target{
void *handle;
void *context;
i32_Rect clip_boxes[5];
i32 clip_top;
i32 width, height;
i32 bound_texture;
u32 color;
// TODO(allen): change this to a Partition
byte *push_buffer;
i32 size, max;
// TODO(allen): rename this to font_partition
Font_Set font_set;
Partition *partition;
Draw_Push_Clip *push_clip;
Draw_Pop_Clip *pop_clip;
Draw_Push_Piece *push_piece;
};
inline i32_Rect
rect_from_target(Render_Target *target){
return i32R(0, 0, target->width, target->height);
}
inline Font_Info*
get_font_info(Font_Set *set, i16 font_id){
Font_Info *result = set->info + font_id - 1;
return(result);
}
#endif
// BOTTOM

View File

@ -185,6 +185,9 @@ struct System_Functions{
INTERNAL_System_Sentinel *internal_sentinel;
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
INTERNAL_System_Debug_Message *internal_debug_message;
// non-function details
char slash;
};
#define FileNameMax (1 << 9)

View File

@ -38,6 +38,8 @@
#include <stdio.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <xmmintrin.h>
#include <linux/fs.h>
//#include <X11/extensions/XInput2.h>
@ -52,6 +54,9 @@
#include <stdlib.h>
#include <locale.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
struct Linux_Vars{
Display *XDisplay;
@ -88,8 +93,10 @@ globalvar Linux_Vars linuxvars;
globalvar Application_Memory memory_vars;
globalvar Exchange exchange_vars;
internal
Sys_Get_Memory_Sig(system_get_memory_){
#define LinuxGetMemory(size) LinuxGetMemory_(size, __LINE__, __FILE__)
internal void*
LinuxGetMemory_(i32 size, i32 line_number, char *file_name){
// TODO(allen): Implement without stdlib.h
void *result = 0;
@ -116,8 +123,8 @@ Sys_Get_Memory_Sig(system_get_memory_){
return(result);
}
internal
Sys_Free_Memory_Sig(system_free_memory){
internal void
LinuxFreeMemory(void *block){
// TODO(allen): Implement without stdlib.h
if (block){
@ -138,6 +145,41 @@ Sys_Free_Memory_Sig(system_free_memory){
}
}
internal Partition
LinuxScratchPartition(i32 size){
Partition part;
void *data;
data = LinuxGetMemory(size);
part = partition_open(data, size);
return(part);
}
internal void
LinuxScratchPartitionGrow(Partition *part, i32 new_size){
void *data;
if (new_size > part->max){
data = LinuxGetMemory(new_size);
memcpy(data, part->base, part->pos);
LinuxFreeMemory(part->base);
part->base = (u8*)data;
}
}
internal void
LinuxScratchPartitionDouble(Partition *part){
LinuxScratchPartitionGrow(part, part->max*2);
}
internal
Sys_Get_Memory_Sig(system_get_memory_){
return(LinuxGetMemory_(size, line_number, file_name));
}
internal
Sys_Free_Memory_Sig(system_free_memory){
LinuxFreeMemory(block);
}
#if (defined(_BSD_SOURCE) || defined(_SVID_SOURCE))
#define TimeBySt
#endif
@ -170,6 +212,7 @@ Sys_File_Time_Stamp_Sig(system_file_time_stamp){
}
// TODO(allen): DOES THIS AGREE WITH THE FILESTAMP TIMES?
// NOTE(inso): I don't think so, CLOCK_MONOTONIC is an arbitrary number
Sys_Time_Sig(system_time){
struct timespec spec;
u64 result;
@ -326,15 +369,21 @@ INTERNAL_Sys_Debug_Message_Sig(internal_debug_message){
DIRECTORY_HAS_FILE_SIG(system_directory_has_file){
int result = 0;
// TODO(allen): Implement
AllowLocal(dir);
AllowLocal(filename);
//TODO(inso): implement
char buff[PATH_MAX] = {};
memcpy(buff, dir.str, dir.size);
printf("Has file %s\n", buff);
return(result);
}
DIRECTORY_CD_SIG(system_directory_cd){
int result = 0;
// TODO(allen): Implement
printf("Dir CD: %.*s\n", dir->size, dir->str);
AllowLocal(dir);
AllowLocal(rel_path);
return(result);
@ -343,6 +392,8 @@ DIRECTORY_CD_SIG(system_directory_cd){
internal
Sys_File_Can_Be_Made(system_file_can_be_made){
// TODO(allen): Implement
printf("File can be made: %s\n", filename);
AllowLocal(filename);
return(0);
}
@ -350,8 +401,57 @@ Sys_File_Can_Be_Made(system_file_can_be_made){
internal
Sys_Load_File_Sig(system_load_file){
Data result = {};
// TODO(allen): Implement
AllowLocal(filename);
struct stat info = {};
int fd;
u8 *ptr, *read_ptr;
size_t bytes_to_read;
ssize_t num;
fd = open(filename, O_RDONLY);
if(fd < 0){
perror("sys_open_file: open");
goto out;
}
if(fstat(fd, &info) < 0){
perror("sys_open_file: stat");
goto out;
}
if(info.st_size <= 0){
printf("st_size < 0: %ld\n", info.st_size);
goto out;
}
ptr = (u8*)LinuxGetMemory(info.st_size);
if(!ptr){
puts("null pointer from LGM");
goto out;
}
read_ptr = ptr;
bytes_to_read = info.st_size;
do {
num = read(fd, read_ptr, bytes_to_read);
if(num < 0){
if(errno == EINTR){
continue;
} else {
//TODO(inso): error handling
perror("sys_load_file: read");
LinuxFreeMemory(ptr);
goto out;
}
} else {
bytes_to_read -= num;
read_ptr += num;
}
} while(bytes_to_read);
result.size = info.st_size;
result.data = ptr;
out:
if(fd >= 0) close(fd);
return(result);
}
@ -370,8 +470,46 @@ Sys_Save_File_Sig(system_save_file){
// a little better now that they're starting to settle
// into their places.
#include "system_shared.cpp"
#include "4ed_rendering.cpp"
internal
Font_Load_Sig(system_draw_font_load){
Font_Load_Parameters *params;
system_acquire_lock(FONT_LOCK);
params = linuxvars.fnt.free_param.next;
fnt__remove(params);
fnt__insert(&linuxvars.fnt.used_param, params);
system_release_lock(FONT_LOCK);
if (linuxvars.fnt.part.base == 0){
linuxvars.fnt.part = LinuxScratchPartition(Mbytes(8));
}
b32 done = 0;
while(!(done =
draw_font_load(
linuxvars.fnt.part.base,
linuxvars.fnt.part.max,
font_out,
filename,
pt_size,
tab_width
)
)){
//FIXME(inso): This is an infinite loop if the fonts aren't found!
// Figure out how draw_font_load can fail
printf("draw_font_load failed, %d\n", linuxvars.fnt.part.max);
LinuxScratchPartitionDouble(&linuxvars.fnt.part);
}
system_acquire_lock(FONT_LOCK);
fnt__remove(params);
fnt__insert(&linuxvars.fnt.free_param, params);
system_release_lock(FONT_LOCK);
return(0);
}
@ -437,9 +575,6 @@ LinuxLoadSystemCode(){
linuxvars.system->internal_debug_message = internal_debug_message;
}
#include "system_shared.cpp"
#include "4ed_rendering.cpp"
internal void
LinuxLoadRenderCode(){
linuxvars.target.push_clip = draw_push_clip;
@ -484,6 +619,20 @@ ctxErrorHandler( Display *dpy, XErrorEvent *ev )
return 0;
}
#if FRED_INTERNAL
static void gl_log(
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam
){
printf("GL DEBUG: %s\n", message);
}
#endif
internal GLXContext
InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, b32 &IsLegacy)
{
@ -510,9 +659,12 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
{
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
#if FRED_INTERNAL
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_DEBUG_BIT_ARB,
#endif
None
};
@ -599,7 +751,21 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
printf("GL_RENDERER: %s\n", Renderer);
printf("GL_VERSION: %s\n", Version);
printf("GL_EXTENSIONS: %s\n", Extensions);
#if FRED_INTERNAL
PFNGLDEBUGMESSAGECALLBACKARBPROC gl_dbg_callback = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glXGetProcAddress((const GLubyte*)"glDebugMessageCallback");
if(gl_dbg_callback){
puts("enabling gl debug");
gl_dbg_callback(&gl_log, 0);
glEnable(GL_DEBUG_OUTPUT);
}
#endif
glEnable(GL_TEXTURE_2D);
glEnable(GL_SCISSOR_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return(ctx);
}
@ -831,7 +997,8 @@ InitializeXInput(Display *dpy, Window XWindow)
EnterWindowMask | LeaveWindowMask |
PointerMotionMask |
FocusChangeMask |
StructureNotifyMask
StructureNotifyMask |
MappingNotify
);
result.input_method = XOpenIM(dpy, 0, 0, 0);
@ -894,11 +1061,11 @@ static void push_key(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[CONTROL_KEY_COUN
}
if(*count < KEY_INPUT_BUFFER_SIZE){
linuxvars.key_data.press[*count].keycode = code;
linuxvars.key_data.press[*count].character = chr;
linuxvars.key_data.press[*count].character_no_caps_lock = chr_nocaps;
data[*count].keycode = code;
data[*count].character = chr;
data[*count].character_no_caps_lock = chr_nocaps;
memcpy(linuxvars.key_data.press[*count].modifiers, *mods, sizeof(*mods));
memcpy(data[*count].modifiers, *mods, sizeof(*mods));
++(*count);
}
@ -1012,10 +1179,7 @@ main(int argc, char **argv)
Font_Load_Parameters params[8];
sysshared_init_font_params(&linuxvars.fnt, params, ArrayCount(params));
linuxvars.app.init(linuxvars.system, &linuxvars.target,
&memory_vars, &exchange_vars, &linuxvars.key_codes,
linuxvars.clipboard_contents, current_directory,
linuxvars.custom_api);
// NOTE(allen): Here begins the linux screen setup stuff.
// Behold the true nature of this wonderful OS:
@ -1028,7 +1192,6 @@ main(int argc, char **argv)
WinWidth = 800;
WinHeight = 600;
if(linuxvars.XDisplay && GLXSupportsModernContexts(linuxvars.XDisplay))
{
int XScreenCount = ScreenCount(linuxvars.XDisplay);
@ -1098,9 +1261,21 @@ main(int argc, char **argv)
XSetICFocus(linuxvars.input_context);
if (window_setup_success){
linuxvars.app.init(linuxvars.system, &linuxvars.target,
&memory_vars, &exchange_vars, &linuxvars.key_codes,
linuxvars.clipboard_contents, current_directory,
linuxvars.custom_api);
LinuxResizeTarget(WinWidth, WinHeight);
for(;;)
Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False);
if(WM_DELETE_WINDOW != None){
XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, &WM_DELETE_WINDOW, 1);
}
b32 keep_running = 1;
while(keep_running)
{
XEvent PrevEvent = {};
@ -1115,7 +1290,6 @@ main(int argc, char **argv)
switch (Event.type){
case KeyPress: {
b32 is_press = Event.type == KeyPress;
b32 is_hold =
PrevEvent.type == KeyRelease &&
PrevEvent.xkey.time == Event.xkey.time &&
@ -1127,25 +1301,35 @@ main(int argc, char **argv)
if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1;
if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1;
// NOTE(inso): mod5 == AltGr
if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
// if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
KeySym keysym = NoSymbol;
char buff[32];
char buff[32], no_caps_buff[32];
// NOTE(inso): We only want XLookupString to consider shift / capslock mods
Event.xkey.state &= (ShiftMask | LockMask);
// NOTE(inso): Turn ControlMask off like the win32 code does.
if(mods[CONTROL_KEY_CONTROL] && !mods[CONTROL_KEY_ALT]){
Event.xkey.state &= ~(ControlMask);
}
// TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars
XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
Event.xkey.state &= ~LockMask;
XLookupString(&Event.xkey, no_caps_buff, sizeof(no_caps_buff), NULL, NULL);
u8 key = keycode_lookup(Event.xkey.keycode);
if(key){
push_key(0, 0, key, &mods, is_hold);
push_key(key, 0, 0, &mods, is_hold);
} else {
key = buff[0] & 0xFF;
if(key < 128){
push_key(key, key, key, &mods, is_hold);
u8 no_caps_key = no_caps_buff[0] & 0xFF;
if(key == '\r') key = '\n';
if(no_caps_key == '\r') no_caps_key = '\n';
push_key(key, key, no_caps_key, &mods, is_hold);
} else {
push_key(0, 0, 0, &mods, is_hold);
}
}
}break;
@ -1202,6 +1386,19 @@ main(int argc, char **argv)
LinuxResizeTarget(Event.xconfigure.width, Event.xconfigure.height);
}
}break;
case MappingNotify: {
if(Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){
XRefreshKeyboardMapping(&Event.xmapping);
keycode_init(linuxvars.XDisplay, &linuxvars.key_codes);
}
}break;
case ClientMessage: {
if ((Atom)Event.xclient.data.l[0] == WM_DELETE_WINDOW) {
keep_running = false;
}
}break;
}
PrevEvent = Event;

BIN
vc120.pdb

Binary file not shown.

View File

@ -946,6 +946,8 @@ Win32LoadSystemCode(){
win32vars.system->internal_sentinel = INTERNAL_system_sentinel;
win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states;
win32vars.system->internal_debug_message = INTERNAL_system_debug_message;
win32vars.system->slash = '\\';
}
#include "system_shared.cpp"