post-insofaras-patch-1
This commit is contained in:
parent
762e31bed0
commit
ca72d0f1e0
|
@ -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
|
||||||
|
|
217
linux_4ed.cpp
217
linux_4ed.cpp
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue