This commit is contained in:
Allen Webster 2016-03-04 18:10:08 -05:00
commit 9bf2a73640
2 changed files with 198 additions and 102 deletions

View File

@ -157,7 +157,7 @@ set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_hook; unit.type = unit_hook;
unit.hook.hook_id = hook_id; unit.hook.hook_id = hook_id;
unit.hook.func = func; unit.hook.func = (void*) func;
write_unit(helper, unit); write_unit(helper, unit);
} }
@ -167,7 +167,7 @@ set_scroll_rule(Bind_Helper *helper, Scroll_Rule_Function *func){
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_hook; unit.type = unit_hook;
unit.hook.hook_id = _hook_scroll_rule; unit.hook.hook_id = _hook_scroll_rule;
unit.hook.func = func; unit.hook.func = (void*) func;
write_unit(helper, unit); write_unit(helper, unit);
} }

View File

@ -127,6 +127,9 @@ struct Linux_Vars{
Atom atom_CLIPBOARD; Atom atom_CLIPBOARD;
Atom atom_UTF8_STRING; Atom atom_UTF8_STRING;
Atom atom_NET_WM_STATE;
Atom atom_NET_WM_STATE_MAXIMIZED_HORZ;
Atom atom_NET_WM_STATE_MAXIMIZED_VERT;
b32 has_xfixes; b32 has_xfixes;
int xfixes_selection_event; int xfixes_selection_event;
@ -1381,7 +1384,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
} }
internal b32 internal b32
GLXSupportsModernContexts(Display *XDisplay) GLXCanUseFBConfig(Display *XDisplay)
{ {
b32 Result = false; b32 Result = false;
@ -1684,6 +1687,32 @@ static void push_key(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[MDFR_INDEX_COUNT
} }
} }
internal void
LinuxMaximizeWindow(Display* d, Window w, b32 maximize){
//NOTE(inso): this will only work after it is mapped
enum { STATE_REMOVE, STATE_ADD, STATE_TOGGLE };
XEvent e = {};
e.xany.type = ClientMessage;
e.xclient.message_type = linuxvars.atom_NET_WM_STATE;
e.xclient.format = 32;
e.xclient.window = w;
e.xclient.data.l[0] = maximize ? STATE_ADD : STATE_REMOVE;
e.xclient.data.l[1] = linuxvars.atom_NET_WM_STATE_MAXIMIZED_VERT;
e.xclient.data.l[2] = linuxvars.atom_NET_WM_STATE_MAXIMIZED_HORZ;
e.xclient.data.l[3] = 0L;
XSendEvent(
d,
RootWindow(d, 0),
0,
SubstructureNotifyMask | SubstructureRedirectMask,
&e
);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -1697,6 +1726,8 @@ main(int argc, char **argv)
linuxvars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG; linuxvars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
#endif #endif
linuxvars.first = 1;
if (!LinuxLoadAppCode()){ if (!LinuxLoadAppCode()){
// TODO(allen): Failed to load app code, serious problem. // TODO(allen): Failed to load app code, serious problem.
return 99; return 99;
@ -1772,6 +1803,11 @@ main(int argc, char **argv)
linuxvars.XDisplay = XOpenDisplay(0); linuxvars.XDisplay = XOpenDisplay(0);
if(!linuxvars.XDisplay){
fprintf(stderr, "Can't open display!");
return 1;
}
keycode_init(linuxvars.XDisplay); keycode_init(linuxvars.XDisplay);
#ifdef FRED_SUPER #ifdef FRED_SUPER
@ -1843,7 +1879,6 @@ main(int argc, char **argv)
sysshared_init_font_params(&linuxvars.fnt, params, ArrayCount(params)); sysshared_init_font_params(&linuxvars.fnt, params, ArrayCount(params));
// NOTE(allen): Here begins the linux screen setup stuff. // NOTE(allen): Here begins the linux screen setup stuff.
// Behold the true nature of this wonderful OS: // Behold the true nature of this wonderful OS:
// (thanks again to Casey for providing this stuff) // (thanks again to Casey for providing this stuff)
@ -1852,12 +1887,22 @@ main(int argc, char **argv)
int WinWidth, WinHeight; int WinWidth, WinHeight;
b32 window_setup_success = 0; b32 window_setup_success = 0;
if (linuxvars.settings.set_window_size){
WinWidth = linuxvars.settings.window_w;
WinHeight = linuxvars.settings.window_h;
} else {
WinWidth = 800; WinWidth = 800;
WinHeight = 600; WinHeight = 600;
}
if(linuxvars.XDisplay && GLXSupportsModernContexts(linuxvars.XDisplay))
{
int XScreenCount = ScreenCount(linuxvars.XDisplay); int XScreenCount = ScreenCount(linuxvars.XDisplay);
glx_config_result Config = {};
if(!GLXCanUseFBConfig(linuxvars.XDisplay)){
fprintf(stderr, "Your GLX version is too old.\n");
exit(1);
}
for(int XScreenIndex = 0; for(int XScreenIndex = 0;
XScreenIndex < XScreenCount; XScreenIndex < XScreenCount;
++XScreenIndex) ++XScreenIndex)
@ -1871,7 +1916,7 @@ main(int argc, char **argv)
if (ScrnWidth + 50 < WinWidth) WinWidth = ScrnWidth + 50; if (ScrnWidth + 50 < WinWidth) WinWidth = ScrnWidth + 50;
if (ScrnHeight + 50 < WinHeight) WinHeight = ScrnHeight + 50; if (ScrnHeight + 50 < WinHeight) WinHeight = ScrnHeight + 50;
glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex); Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex);
if(Config.Found) if(Config.Found)
{ {
swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay, swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay,
@ -1891,8 +1936,18 @@ main(int argc, char **argv)
if(linuxvars.XWindow) if(linuxvars.XWindow)
{ {
XStoreName(linuxvars.XDisplay, linuxvars.XWindow, "4coder-window"); window_setup_success = 1;
break;
}
}
}
if (!window_setup_success){
fprintf(stderr, "Error creating window.");
exit(1);
}
//NOTE(inso): Set the window's type to normal
Atom _NET_WM_WINDOW_TYPE = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE", False); Atom _NET_WM_WINDOW_TYPE = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE", False);
Atom _NET_WIN_TYPE_NORMAL = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False); Atom _NET_WIN_TYPE_NORMAL = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
XChangeProperty( XChangeProperty(
@ -1906,6 +1961,7 @@ main(int argc, char **argv)
1 1
); );
//NOTE(inso): window managers want the PID as a window property for some reason.
Atom _NET_WM_PID = XInternAtom(linuxvars.XDisplay, "_NET_WM_PID", False); Atom _NET_WM_PID = XInternAtom(linuxvars.XDisplay, "_NET_WM_PID", False);
pid_t pid = getpid(); pid_t pid = getpid();
XChangeProperty( XChangeProperty(
@ -1919,6 +1975,47 @@ main(int argc, char **argv)
1 1
); );
//NOTE(inso): set wm properties
XStoreName(linuxvars.XDisplay, linuxvars.XWindow, "4coder-window");
char* win_name_list[] = { "4coder" };
XTextProperty win_name;
XStringListToTextProperty(win_name_list, 1, &win_name);
XSizeHints *sz_hints = XAllocSizeHints();
XWMHints *wm_hints = XAllocWMHints();
XClassHint *cl_hints = XAllocClassHint();
if(linuxvars.settings.set_window_pos){
sz_hints->flags |= USPosition;
sz_hints->x = linuxvars.settings.window_x;
sz_hints->y = linuxvars.settings.window_y;
}
wm_hints->flags |= InputHint;
wm_hints->input = True;
cl_hints->res_name = "4coder";
cl_hints->res_class = "4coder-class";
XSetWMProperties(
linuxvars.XDisplay,
linuxvars.XWindow,
&win_name,
NULL,
argv,
argc,
sz_hints,
wm_hints,
cl_hints
);
XFree(sz_hints);
XFree(wm_hints);
XFree(cl_hints);
//NOTE(inso): make the window visible
XMapWindow(linuxvars.XDisplay, linuxvars.XWindow); XMapWindow(linuxvars.XDisplay, linuxvars.XWindow);
Init_Input_Result input_result = Init_Input_Result input_result =
@ -1942,15 +2039,13 @@ main(int argc, char **argv)
XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow); XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
XSync(linuxvars.XDisplay, False); XSync(linuxvars.XDisplay, False);
window_setup_success = 1; if (linuxvars.settings.set_window_pos){
} XMoveWindow(
} linuxvars.XDisplay,
} linuxvars.XWindow,
} linuxvars.settings.window_x,
linuxvars.settings.window_y
if (!window_setup_success){ );
fprintf(stderr, "Error creating window.");
exit(1);
} }
Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = { Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
@ -1963,14 +2058,15 @@ main(int argc, char **argv)
XSetICFocus(linuxvars.input_context); XSetICFocus(linuxvars.input_context);
XWMHints *wm_hints = XAllocWMHints();
wm_hints->flags |= InputHint;
wm_hints->input = True;
XSetWMHints(linuxvars.XDisplay, linuxvars.XWindow, wm_hints);
XFree(wm_hints);
linuxvars.atom_CLIPBOARD = XInternAtom(linuxvars.XDisplay, "CLIPBOARD", False); linuxvars.atom_CLIPBOARD = XInternAtom(linuxvars.XDisplay, "CLIPBOARD", False);
linuxvars.atom_UTF8_STRING = XInternAtom(linuxvars.XDisplay, "UTF8_STRING", False); linuxvars.atom_UTF8_STRING = XInternAtom(linuxvars.XDisplay, "UTF8_STRING", False);
linuxvars.atom_NET_WM_STATE = XInternAtom(linuxvars.XDisplay, "_NET_WM_STATE", False);
linuxvars.atom_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(linuxvars.XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
linuxvars.atom_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(linuxvars.XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False);
if (linuxvars.settings.maximize_window){
LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1);
}
int xfixes_version_unused, xfixes_err_unused; int xfixes_version_unused, xfixes_err_unused;
@ -1991,7 +2087,6 @@ main(int argc, char **argv)
); );
} }
Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False); Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False);
Atom _NET_WM_PING = XInternAtom(linuxvars.XDisplay, "_NET_WM_PING", False); Atom _NET_WM_PING = XInternAtom(linuxvars.XDisplay, "_NET_WM_PING", False);
Atom wm_protos[] = { WM_DELETE_WINDOW, _NET_WM_PING }; Atom wm_protos[] = { WM_DELETE_WINDOW, _NET_WM_PING };
@ -2307,6 +2402,7 @@ main(int argc, char **argv)
linuxvars.cursor = result.mouse_cursor_type; linuxvars.cursor = result.mouse_cursor_type;
} }
linuxvars.first = 0;
linuxvars.redraw = 0; linuxvars.redraw = 0;
linuxvars.key_data = {}; linuxvars.key_data = {};
linuxvars.mouse_data.press_l = 0; linuxvars.mouse_data.press_l = 0;