Allen Webster 2016-02-27 14:33:49 -05:00
commit 1352a1fae3
1 changed files with 133 additions and 22 deletions

View File

@ -67,6 +67,7 @@
#include <signal.h> #include <signal.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <ucontext.h>
//#define FRED_USE_FONTCONFIG 1 //#define FRED_USE_FONTCONFIG 1
@ -84,6 +85,13 @@ struct Linux_Semaphore_Handle {
pthread_cond_t *cond_p; pthread_cond_t *cond_p;
}; };
struct Linux_Coroutine {
Coroutine coroutine;
Linux_Coroutine *next;
ucontext_t ctx, yield_ctx;
b32 done;
};
struct Thread_Context{ struct Thread_Context{
u32 job_id; u32 job_id;
b32 running; b32 running;
@ -143,6 +151,9 @@ struct Linux_Vars{
#endif #endif
Font_Load_System fnt; Font_Load_System fnt;
Linux_Coroutine coroutine_data[2];
Linux_Coroutine *coroutine_free;
}; };
#define LINUX_MAX_PASTE_CHARS 0x10000L #define LINUX_MAX_PASTE_CHARS 0x10000L
@ -394,6 +405,91 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){
XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime); XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
} }
internal Linux_Coroutine*
LinuxAllocCoroutine(){
Linux_Coroutine *result = linuxvars.coroutine_free;
Assert(result != 0);
if(getcontext(&result->ctx) == -1){
perror("getcontext");
}
linuxvars.coroutine_free = result->next;
return(result);
}
internal void
LinuxFreeCoroutine(Linux_Coroutine *data){
data->next = linuxvars.coroutine_free;
linuxvars.coroutine_free = data;
}
internal void
LinuxCoroutineMain(void *arg_){
Linux_Coroutine *c = (Linux_Coroutine*)arg_;
c->coroutine.func(&c->coroutine);
c->done = 1;
LinuxFreeCoroutine(c);
setcontext((ucontext_t*)c->coroutine.yield_handle);
}
static_assert(sizeof(Plat_Handle) >= sizeof(ucontext_t*), "Plat handle not big enough");
internal
Sys_Create_Coroutine_Sig(system_create_coroutine){
Linux_Coroutine *c = LinuxAllocCoroutine();
c->done = 0;
makecontext(&c->ctx, (void (*)())LinuxCoroutineMain, 1, &c->coroutine);
*(ucontext_t**)&c->coroutine.plat_handle = &c->ctx;
c->coroutine.func = func;
return(&c->coroutine);
}
internal
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
Linux_Coroutine *c = (Linux_Coroutine*)coroutine;
ucontext_t* ctx = *(ucontext**)&coroutine->plat_handle;
coroutine->yield_handle = &c->yield_ctx;
coroutine->in = in;
coroutine->out = out;
swapcontext(&c->yield_ctx, ctx);
if (c->done){
LinuxFreeCoroutine(c);
coroutine = 0;
}
return(coroutine);
}
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
Linux_Coroutine *c = (Linux_Coroutine*)coroutine;
void *fiber;
Assert(!c->done);
coroutine->yield_handle = &c->yield_ctx;
coroutine->in = in;
coroutine->out = out;
ucontext *ctx = *(ucontext**)&coroutine->plat_handle;
swapcontext(&c->yield_ctx, ctx);
if (c->done){
LinuxFreeCoroutine(c);
coroutine = 0;
}
return(coroutine);
}
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
swapcontext(*(ucontext_t**)&coroutine->plat_handle, (ucontext*)coroutine->yield_handle);
}
Sys_CLI_Call_Sig(system_cli_call){ Sys_CLI_Call_Sig(system_cli_call){
// TODO(allen): Implement // TODO(allen): Implement
@ -998,6 +1094,11 @@ LinuxLoadSystemCode(){
linuxvars.system->post_clipboard = system_post_clipboard; linuxvars.system->post_clipboard = system_post_clipboard;
linuxvars.system->time = system_time; linuxvars.system->time = system_time;
linuxvars.system->create_coroutine = system_create_coroutine;
linuxvars.system->launch_coroutine = system_launch_coroutine;
linuxvars.system->resume_coroutine = system_resume_coroutine;
linuxvars.system->yield_coroutine = system_yield_coroutine;
linuxvars.system->cli_call = system_cli_call; linuxvars.system->cli_call = system_cli_call;
linuxvars.system->cli_begin_update = system_cli_begin_update; linuxvars.system->cli_begin_update = system_cli_begin_update;
linuxvars.system->cli_update_step = system_cli_update_step; linuxvars.system->cli_update_step = system_cli_update_step;
@ -1536,7 +1637,7 @@ InitializeXInput(Display *dpy, Window XWindow)
return(result); return(result);
} }
static void push_key(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[CONTROL_KEY_COUNT], b32 is_hold){ static void push_key(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[MDFR_INDEX_COUNT], b32 is_hold){
i32 *count; i32 *count;
Key_Event_Data *data; Key_Event_Data *data;
@ -1582,6 +1683,16 @@ main(int argc, char **argv)
linuxvars.system = system; linuxvars.system = system;
LinuxLoadSystemCode(); LinuxLoadSystemCode();
linuxvars.coroutine_free = linuxvars.coroutine_data;
for (i32 i = 0; i+1 < ArrayCount(linuxvars.coroutine_data); ++i){
linuxvars.coroutine_data[i].next = linuxvars.coroutine_data + i + 1;
}
for (i32 i = 0; i < ArrayCount(linuxvars.coroutine_data); ++i){
linuxvars.coroutine_data[i].ctx.uc_stack.ss_sp = system_get_memory(Mbytes(16));
linuxvars.coroutine_data[i].ctx.uc_stack.ss_size = Mbytes(16);
}
memory_vars.vars_memory_size = Mbytes(2); memory_vars.vars_memory_size = Mbytes(2);
memory_vars.vars_memory = system_get_memory(memory_vars.vars_memory_size); memory_vars.vars_memory = system_get_memory(memory_vars.vars_memory_size);
memory_vars.target_memory_size = Mbytes(512); memory_vars.target_memory_size = Mbytes(512);
@ -1831,19 +1942,19 @@ main(int argc, char **argv)
PrevEvent.xkey.time == Event.xkey.time && PrevEvent.xkey.time == Event.xkey.time &&
PrevEvent.xkey.keycode == Event.xkey.keycode; PrevEvent.xkey.keycode == Event.xkey.keycode;
b8 mods[CONTROL_KEY_COUNT] = {}; b8 mods[MDFR_INDEX_COUNT] = {};
if(Event.xkey.state & ShiftMask) mods[CONTROL_KEY_SHIFT] = 1; if(Event.xkey.state & ShiftMask) mods[MDFR_SHIFT_INDEX] = 1;
if(Event.xkey.state & ControlMask) mods[CONTROL_KEY_CONTROL] = 1; if(Event.xkey.state & ControlMask) mods[MDFR_CONTROL_INDEX] = 1;
if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1; if(Event.xkey.state & LockMask) mods[MDFR_CAPS_INDEX] = 1;
if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1; if(Event.xkey.state & Mod1Mask) mods[MDFR_ALT_INDEX] = 1;
// NOTE(inso): mod5 == AltGr // NOTE(inso): mod5 == AltGr
// if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1; // if(Event.xkey.state & Mod5Mask) mods[MDFR_ALT_INDEX] = 1;
KeySym keysym = NoSymbol; KeySym keysym = NoSymbol;
char buff[32], no_caps_buff[32]; char buff[32], no_caps_buff[32];
// NOTE(inso): Turn ControlMask off like the win32 code does. // NOTE(inso): Turn ControlMask off like the win32 code does.
if(mods[CONTROL_KEY_CONTROL] && !mods[CONTROL_KEY_ALT]){ if(mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]){
Event.xkey.state &= ~(ControlMask); Event.xkey.state &= ~(ControlMask);
} }
@ -1878,12 +1989,12 @@ main(int argc, char **argv)
case ButtonPress: { case ButtonPress: {
switch(Event.xbutton.button){ switch(Event.xbutton.button){
case Button1: { case Button1: {
linuxvars.mouse_data.left_button_pressed = 1; linuxvars.mouse_data.press_l = 1;
linuxvars.mouse_data.left_button = 1; linuxvars.mouse_data.l = 1;
} break; } break;
case Button3: { case Button3: {
linuxvars.mouse_data.right_button_pressed = 1; linuxvars.mouse_data.press_r = 1;
linuxvars.mouse_data.right_button = 1; linuxvars.mouse_data.r = 1;
} break; } break;
//NOTE(inso): scroll up //NOTE(inso): scroll up
@ -1901,12 +2012,12 @@ main(int argc, char **argv)
case ButtonRelease: { case ButtonRelease: {
switch(Event.xbutton.button){ switch(Event.xbutton.button){
case Button1: { case Button1: {
linuxvars.mouse_data.left_button_released = 1; linuxvars.mouse_data.release_l = 1;
linuxvars.mouse_data.left_button = 0; linuxvars.mouse_data.l = 0;
} break; } break;
case Button3: { case Button3: {
linuxvars.mouse_data.right_button_released = 1; linuxvars.mouse_data.release_r = 1;
linuxvars.mouse_data.right_button = 0; linuxvars.mouse_data.r = 0;
} break; } break;
} }
}break; }break;
@ -1921,8 +2032,8 @@ main(int argc, char **argv)
case FocusIn: case FocusIn:
case FocusOut: { case FocusOut: {
linuxvars.mouse_data.left_button = 0; linuxvars.mouse_data.l = 0;
linuxvars.mouse_data.right_button = 0; linuxvars.mouse_data.r = 0;
}break; }break;
case ConfigureNotify: { case ConfigureNotify: {
@ -2090,10 +2201,10 @@ main(int argc, char **argv)
linuxvars.redraw = 0; linuxvars.redraw = 0;
linuxvars.key_data = {}; linuxvars.key_data = {};
linuxvars.mouse_data.left_button_pressed = 0; linuxvars.mouse_data.press_l = 0;
linuxvars.mouse_data.left_button_released = 0; linuxvars.mouse_data.release_l = 0;
linuxvars.mouse_data.right_button_pressed = 0; linuxvars.mouse_data.press_r = 0;
linuxvars.mouse_data.right_button_released = 0; linuxvars.mouse_data.release_r = 0;
linuxvars.mouse_data.wheel = 0; linuxvars.mouse_data.wheel = 0;
ProfileStart(OS_file_process); ProfileStart(OS_file_process);