post-insofaras-patch-1

This commit is contained in:
Allen Webster 2016-02-21 12:59:47 -05:00
parent 762e31bed0
commit ca72d0f1e0
2 changed files with 219 additions and 61 deletions

View File

@ -12,9 +12,11 @@
#include "4ed_keyboard.cpp" #include "4ed_keyboard.cpp"
internal void internal void
keycode_init(Key_Codes *codes){ keycode_init(Display* dpy, Key_Codes *codes){
set_dynamic_key_names(codes); set_dynamic_key_names(codes);
/* NOTE(inso): these are for XInput, currently not used.
keycode_lookup_table[KEY_BACKSPACE] = codes->back; keycode_lookup_table[KEY_BACKSPACE] = codes->back;
keycode_lookup_table[KEY_DELETE] = codes->del; keycode_lookup_table[KEY_DELETE] = codes->del;
keycode_lookup_table[KEY_UP] = codes->up; keycode_lookup_table[KEY_UP] = codes->up;
@ -27,6 +29,27 @@ keycode_init(Key_Codes *codes){
keycode_lookup_table[KEY_PAGEUP] = codes->page_up; keycode_lookup_table[KEY_PAGEUP] = codes->page_up;
keycode_lookup_table[KEY_PAGEDOWN] = codes->page_down; keycode_lookup_table[KEY_PAGEDOWN] = codes->page_down;
keycode_lookup_table[KEY_ESC] = codes->esc; keycode_lookup_table[KEY_ESC] = codes->esc;
*/
#define XK_(x) XK_##x
#define XKEY(x) keycode_lookup_table[XKeysymToKeycode(dpy, XK_(x))]
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;
#undef XKEY
#undef XK_
} }
// BOTTOM // BOTTOM

View File

@ -41,7 +41,6 @@
#include <xmmintrin.h> #include <xmmintrin.h>
#include <linux/fs.h> #include <linux/fs.h>
//#include <X11/extensions/XInput2.h> //#include <X11/extensions/XInput2.h>
#include <X11/XKBlib.h>
#include <linux/input.h> #include <linux/input.h>
#include <time.h> #include <time.h>
#include <dlfcn.h> #include <dlfcn.h>
@ -52,6 +51,7 @@
#include "system_shared.h" #include "system_shared.h"
#include <stdlib.h> #include <stdlib.h>
#include <locale.h>
struct Linux_Vars{ struct Linux_Vars{
Display *XDisplay; Display *XDisplay;
@ -60,10 +60,13 @@ struct Linux_Vars{
XIM input_method; XIM input_method;
XIMStyle input_style; XIMStyle input_style;
XIC xic; XIC input_context;
Key_Codes key_codes; Key_Codes key_codes;
Clipboard_Contents clipboard_contents; Key_Input_Data key_data;
Mouse_State mouse_data;
String clipboard_contents;
void *app_code; void *app_code;
void *custom; void *custom;
@ -372,6 +375,22 @@ Font_Load_Sig(system_draw_font_load){
return(0); return(0);
} }
internal
Sys_To_Binary_Path(system_to_binary_path){
b32 translate_success = 0;
i32 max = out_filename->memory_size;
i32 size = readlink("/proc/self/exe", out_filename->str, max);
if (size > 0 && size < max-1){
out_filename->str[size] = '\0';
out_filename->size = size + 1;
truncate_to_path_of_directory(out_filename);
if (append(out_filename, filename) && terminate_with_null(out_filename)){
translate_success = 1;
}
}
return (translate_success);
}
internal b32 internal b32
LinuxLoadAppCode(){ LinuxLoadAppCode(){
b32 result = 0; b32 result = 0;
@ -491,8 +510,8 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
{ {
int context_attribs[] = int context_attribs[] =
{ {
GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None None
}; };
@ -572,6 +591,8 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
char *Vendor = (char *)glGetString(GL_VENDOR); char *Vendor = (char *)glGetString(GL_VENDOR);
char *Renderer = (char *)glGetString(GL_RENDERER); char *Renderer = (char *)glGetString(GL_RENDERER);
char *Version = (char *)glGetString(GL_VERSION); char *Version = (char *)glGetString(GL_VERSION);
//TODO(inso): glGetStringi is required if the GL version is >= 3.0
char *Extensions = (char *)glGetString(GL_EXTENSIONS); char *Extensions = (char *)glGetString(GL_EXTENSIONS);
printf("GL_VENDOR: %s\n", Vendor); printf("GL_VENDOR: %s\n", Vendor);
@ -796,13 +817,34 @@ InitializeXInput(Display *dpy, Window XWindow)
XIMStyles *styles = 0; XIMStyles *styles = 0;
i32 i, count; i32 i, count;
setlocale(LC_ALL, "");
XSetLocaleModifiers(""); XSetLocaleModifiers("");
printf("supported locales: %d\n", XSupportsLocale()); printf("is current locale supported?: %d\n", XSupportsLocale());
// TODO(inso): handle the case where it isn't supported somehow?
XSelectInput(linuxvars.XDisplay, linuxvars.XWindow, ExposureMask | KeyPressMask); XSelectInput(
linuxvars.XDisplay,
linuxvars.XWindow,
ExposureMask |
KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask |
FocusChangeMask |
StructureNotifyMask
);
result.input_method = XOpenIM(dpy, 0, 0, 0); result.input_method = XOpenIM(dpy, 0, 0, 0);
if (!result.input_method){
// NOTE(inso): Try falling back to the internal XIM implementation that
// should in theory always exist.
XSetLocaleModifiers("@im=none");
result.input_method = XOpenIM(dpy, 0, 0, 0);
}
if (result.input_method){ if (result.input_method){
if (!XGetIMValues(result.input_method, XNQueryInputStyle, &styles, NULL) && if (!XGetIMValues(result.input_method, XNQueryInputStyle, &styles, NULL) &&
styles){ styles){
result.best_style = 0; result.best_style = 0;
@ -827,18 +869,41 @@ InitializeXInput(Display *dpy, Window XWindow)
} }
else{ else{
result = {}; result = {};
printf("Could not get minimum required input style"); puts("Could not get minimum required input style");
} }
} }
} }
else{ else{
result = {}; result = {};
printf("Could not open X Input Method\n"); puts("Could not open X Input Method");
} }
return(result); return(result);
} }
static void push_key(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[CONTROL_KEY_COUNT], b32 is_hold){
i32 *count;
Key_Event_Data *data;
if(is_hold){
count = &linuxvars.key_data.hold_count;
data = linuxvars.key_data.hold;
} else {
count = &linuxvars.key_data.press_count;
data = linuxvars.key_data.press;
}
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;
memcpy(linuxvars.key_data.press[*count].modifiers, *mods, sizeof(*mods));
++(*count);
}
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -912,7 +977,9 @@ main(int argc, char **argv)
sysshared_filter_real_files(files, file_count); sysshared_filter_real_files(files, file_count);
keycode_init(&linuxvars.key_codes); linuxvars.XDisplay = XOpenDisplay(0);
keycode_init(linuxvars.XDisplay, &linuxvars.key_codes);
#ifdef FRED_SUPER #ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.so"; char *custom_file_default = "4coder_custom.so";
@ -961,9 +1028,7 @@ main(int argc, char **argv)
WinWidth = 800; WinWidth = 800;
WinHeight = 600; WinHeight = 600;
i32 xkb_ev_code = 0, xkb_err_code = 0;
linuxvars.XDisplay = XkbOpenDisplay(0, &xkb_ev_code, &xkb_err_code, 0, 0, 0);
if(linuxvars.XDisplay && GLXSupportsModernContexts(linuxvars.XDisplay)) if(linuxvars.XDisplay && GLXSupportsModernContexts(linuxvars.XDisplay))
{ {
int XScreenCount = ScreenCount(linuxvars.XDisplay); int XScreenCount = ScreenCount(linuxvars.XDisplay);
@ -1008,7 +1073,7 @@ main(int argc, char **argv)
linuxvars.input_method = input_result.input_method; linuxvars.input_method = input_result.input_method;
linuxvars.input_style = input_result.best_style; linuxvars.input_style = input_result.best_style;
linuxvars.xic = input_result.xic; linuxvars.input_context = input_result.xic;
b32 IsLegacy = false; b32 IsLegacy = false;
GLXContext GLContext = GLXContext GLContext =
@ -1030,13 +1095,15 @@ main(int argc, char **argv)
} }
} }
XSetICFocus(linuxvars.xic); XSetICFocus(linuxvars.input_context);
if (window_setup_success){ if (window_setup_success){
LinuxResizeTarget(WinWidth, WinHeight); LinuxResizeTarget(WinWidth, WinHeight);
for(;;) for(;;)
{ {
XEvent PrevEvent = {};
while(XPending(linuxvars.XDisplay)) while(XPending(linuxvars.XDisplay))
{ {
XEvent Event; XEvent Event;
@ -1047,20 +1114,97 @@ main(int argc, char **argv)
} }
switch (Event.type){ switch (Event.type){
case KeyPress: case KeyPress: {
{ b32 is_press = Event.type == KeyPress;
KeySym ks = NoSymbol; b32 is_hold =
XkbLookupKeySym(linuxvars.XDisplay, Event.xkey.keycode, Event.xkey.state, NULL, &ks); PrevEvent.type == KeyRelease &&
printf("keysym: %s\n", XKeysymToString(ks)); PrevEvent.xkey.time == Event.xkey.time &&
PrevEvent.xkey.keycode == Event.xkey.keycode;
Status st; b8 mods[CONTROL_KEY_COUNT] = {};
char buff[256]; if(Event.xkey.state & ShiftMask) mods[CONTROL_KEY_SHIFT] = 1;
memset(buff, 0, sizeof(buff)); if(Event.xkey.state & ControlMask) mods[CONTROL_KEY_CONTROL] = 1;
XmbLookupString(linuxvars.xic, &Event.xkey, buff, sizeof(buff), &ks, &st); if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1;
printf("IC status: %d, code: %u, sym: %s, str: %s\n", st, Event.xkey.keycode, XKeysymToString(ks), buff); if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1;
}break; // NOTE(inso): mod5 == AltGr
if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
KeySym keysym = NoSymbol;
char buff[32];
// NOTE(inso): We only want XLookupString to consider shift / capslock mods
Event.xkey.state &= (ShiftMask | LockMask);
// TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars
XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
u8 key = keycode_lookup(Event.xkey.keycode);
if(key){
push_key(0, 0, key, &mods, is_hold);
} else {
key = buff[0] & 0xFF;
if(key < 128){
push_key(key, key, key, &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;
} }
PrevEvent = Event;
} }
b32 redraw = 1; b32 redraw = 1;
@ -1069,8 +1213,8 @@ main(int argc, char **argv)
Mouse_State mouse; Mouse_State mouse;
Application_Step_Result result; Application_Step_Result result;
input_data = {}; input_data = linuxvars.key_data;
mouse = {}; mouse = linuxvars.mouse_data;
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.redraw = redraw; result.redraw = redraw;
@ -1091,20 +1235,11 @@ main(int argc, char **argv)
LinuxRedrawTarget(); LinuxRedrawTarget();
} }
glBegin(GL_QUADS); linuxvars.key_data = {};
{ linuxvars.mouse_data.left_button_pressed = 0;
glVertex2f(.5f, .5f); linuxvars.mouse_data.left_button_released = 0;
glVertex2f(1.f, .5f); linuxvars.mouse_data.right_button_pressed = 0;
glVertex2f(1.f, 1.f); linuxvars.mouse_data.right_button_released = 0;
glVertex2f(.5f, 1.f);
glVertex2f(0.f, 0.f);
glVertex2f(.2f, 0.f);
glVertex2f(.2f, .2f);
glVertex2f(0.f, .2f);
}
glEnd();
glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow);
} }
} }
} }