Merge branch 'master' of https://bitbucket.org/4coder/4coder
commit
9bf2a73640
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
296
linux_4ed.cpp
296
linux_4ed.cpp
|
@ -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,10 +1384,10 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
GLXSupportsModernContexts(Display *XDisplay)
|
GLXCanUseFBConfig(Display *XDisplay)
|
||||||
{
|
{
|
||||||
b32 Result = false;
|
b32 Result = false;
|
||||||
|
|
||||||
int GLXMajor, GLXMinor;
|
int GLXMajor, GLXMinor;
|
||||||
|
|
||||||
char *XVendor = ServerVendor(XDisplay);
|
char *XVendor = ServerVendor(XDisplay);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -1696,7 +1725,9 @@ main(int argc, char **argv)
|
||||||
linuxvars.internal_bubble.prev = &linuxvars.internal_bubble;
|
linuxvars.internal_bubble.prev = &linuxvars.internal_bubble;
|
||||||
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
|
||||||
|
@ -1838,11 +1874,10 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
File_Slot file_slots[32];
|
File_Slot file_slots[32];
|
||||||
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
|
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
|
||||||
|
|
||||||
Font_Load_Parameters params[8];
|
Font_Load_Parameters params[8];
|
||||||
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:
|
||||||
|
@ -1852,107 +1887,167 @@ main(int argc, char **argv)
|
||||||
int WinWidth, WinHeight;
|
int WinWidth, WinHeight;
|
||||||
b32 window_setup_success = 0;
|
b32 window_setup_success = 0;
|
||||||
|
|
||||||
WinWidth = 800;
|
if (linuxvars.settings.set_window_size){
|
||||||
WinHeight = 600;
|
WinWidth = linuxvars.settings.window_w;
|
||||||
|
WinHeight = linuxvars.settings.window_h;
|
||||||
|
} else {
|
||||||
|
WinWidth = 800;
|
||||||
|
WinHeight = 600;
|
||||||
|
}
|
||||||
|
|
||||||
if(linuxvars.XDisplay && GLXSupportsModernContexts(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;
|
||||||
|
XScreenIndex < XScreenCount;
|
||||||
|
++XScreenIndex)
|
||||||
{
|
{
|
||||||
int XScreenCount = ScreenCount(linuxvars.XDisplay);
|
Screen *XScreen = ScreenOfDisplay(linuxvars.XDisplay, XScreenIndex);
|
||||||
for(int XScreenIndex = 0;
|
|
||||||
XScreenIndex < XScreenCount;
|
i32 ScrnWidth, ScrnHeight;
|
||||||
++XScreenIndex)
|
ScrnWidth = WidthOfScreen(XScreen);
|
||||||
|
ScrnHeight = HeightOfScreen(XScreen);
|
||||||
|
|
||||||
|
if (ScrnWidth + 50 < WinWidth) WinWidth = ScrnWidth + 50;
|
||||||
|
if (ScrnHeight + 50 < WinHeight) WinHeight = ScrnHeight + 50;
|
||||||
|
|
||||||
|
Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex);
|
||||||
|
if(Config.Found)
|
||||||
{
|
{
|
||||||
Screen *XScreen = ScreenOfDisplay(linuxvars.XDisplay, XScreenIndex);
|
swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay,
|
||||||
|
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen ),
|
||||||
|
Config.BestInfo.visual, AllocNone);
|
||||||
|
swa.background_pixmap = None;
|
||||||
|
swa.border_pixel = 0;
|
||||||
|
swa.event_mask = StructureNotifyMask;
|
||||||
|
|
||||||
i32 ScrnWidth, ScrnHeight;
|
linuxvars.XWindow =
|
||||||
ScrnWidth = WidthOfScreen(XScreen);
|
XCreateWindow(linuxvars.XDisplay,
|
||||||
ScrnHeight = HeightOfScreen(XScreen);
|
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen),
|
||||||
|
0, 0, WinWidth, WinHeight,
|
||||||
if (ScrnWidth + 50 < WinWidth) WinWidth = ScrnWidth + 50;
|
0, Config.BestInfo.depth, InputOutput,
|
||||||
if (ScrnHeight + 50 < WinHeight) WinHeight = ScrnHeight + 50;
|
Config.BestInfo.visual,
|
||||||
|
CWBorderPixel|CWColormap|CWEventMask, &swa );
|
||||||
glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex);
|
|
||||||
if(Config.Found)
|
if(linuxvars.XWindow)
|
||||||
{
|
{
|
||||||
swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay,
|
window_setup_success = 1;
|
||||||
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen ),
|
break;
|
||||||
Config.BestInfo.visual, AllocNone);
|
|
||||||
swa.background_pixmap = None;
|
|
||||||
swa.border_pixel = 0;
|
|
||||||
swa.event_mask = StructureNotifyMask;
|
|
||||||
|
|
||||||
linuxvars.XWindow =
|
|
||||||
XCreateWindow(linuxvars.XDisplay,
|
|
||||||
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen),
|
|
||||||
0, 0, WinWidth, WinHeight,
|
|
||||||
0, Config.BestInfo.depth, InputOutput,
|
|
||||||
Config.BestInfo.visual,
|
|
||||||
CWBorderPixel|CWColormap|CWEventMask, &swa );
|
|
||||||
|
|
||||||
if(linuxvars.XWindow)
|
|
||||||
{
|
|
||||||
XStoreName(linuxvars.XDisplay, linuxvars.XWindow, "4coder-window");
|
|
||||||
|
|
||||||
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);
|
|
||||||
XChangeProperty(
|
|
||||||
linuxvars.XDisplay,
|
|
||||||
linuxvars.XWindow,
|
|
||||||
_NET_WM_WINDOW_TYPE,
|
|
||||||
XA_ATOM,
|
|
||||||
32,
|
|
||||||
PropModeReplace,
|
|
||||||
(unsigned char*)&_NET_WIN_TYPE_NORMAL,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
Atom _NET_WM_PID = XInternAtom(linuxvars.XDisplay, "_NET_WM_PID", False);
|
|
||||||
pid_t pid = getpid();
|
|
||||||
XChangeProperty(
|
|
||||||
linuxvars.XDisplay,
|
|
||||||
linuxvars.XWindow,
|
|
||||||
_NET_WM_PID,
|
|
||||||
XA_CARDINAL,
|
|
||||||
32,
|
|
||||||
PropModeReplace,
|
|
||||||
(unsigned char*)&pid,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
XMapWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
|
||||||
|
|
||||||
Init_Input_Result input_result =
|
|
||||||
InitializeXInput(linuxvars.XDisplay, linuxvars.XWindow);
|
|
||||||
|
|
||||||
linuxvars.input_method = input_result.input_method;
|
|
||||||
linuxvars.input_style = input_result.best_style;
|
|
||||||
linuxvars.input_context = input_result.xic;
|
|
||||||
|
|
||||||
b32 IsLegacy = false;
|
|
||||||
GLXContext GLContext =
|
|
||||||
InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy);
|
|
||||||
|
|
||||||
XWindowAttributes WinAttribs;
|
|
||||||
if(XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs))
|
|
||||||
{
|
|
||||||
WinWidth = WinAttribs.width;
|
|
||||||
WinHeight = WinAttribs.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
|
||||||
XSync(linuxvars.XDisplay, False);
|
|
||||||
|
|
||||||
window_setup_success = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window_setup_success){
|
if (!window_setup_success){
|
||||||
fprintf(stderr, "Error creating window.");
|
fprintf(stderr, "Error creating window.");
|
||||||
exit(1);
|
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_WIN_TYPE_NORMAL = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||||
|
XChangeProperty(
|
||||||
|
linuxvars.XDisplay,
|
||||||
|
linuxvars.XWindow,
|
||||||
|
_NET_WM_WINDOW_TYPE,
|
||||||
|
XA_ATOM,
|
||||||
|
32,
|
||||||
|
PropModeReplace,
|
||||||
|
(unsigned char*)&_NET_WIN_TYPE_NORMAL,
|
||||||
|
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);
|
||||||
|
pid_t pid = getpid();
|
||||||
|
XChangeProperty(
|
||||||
|
linuxvars.XDisplay,
|
||||||
|
linuxvars.XWindow,
|
||||||
|
_NET_WM_PID,
|
||||||
|
XA_CARDINAL,
|
||||||
|
32,
|
||||||
|
PropModeReplace,
|
||||||
|
(unsigned char*)&pid,
|
||||||
|
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);
|
||||||
|
|
||||||
|
Init_Input_Result input_result =
|
||||||
|
InitializeXInput(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
|
|
||||||
|
linuxvars.input_method = input_result.input_method;
|
||||||
|
linuxvars.input_style = input_result.best_style;
|
||||||
|
linuxvars.input_context = input_result.xic;
|
||||||
|
|
||||||
|
b32 IsLegacy = false;
|
||||||
|
GLXContext GLContext =
|
||||||
|
InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy);
|
||||||
|
|
||||||
|
XWindowAttributes WinAttribs;
|
||||||
|
if(XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs))
|
||||||
|
{
|
||||||
|
WinWidth = WinAttribs.width;
|
||||||
|
WinHeight = WinAttribs.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
|
XSync(linuxvars.XDisplay, False);
|
||||||
|
|
||||||
|
if (linuxvars.settings.set_window_pos){
|
||||||
|
XMoveWindow(
|
||||||
|
linuxvars.XDisplay,
|
||||||
|
linuxvars.XWindow,
|
||||||
|
linuxvars.settings.window_x,
|
||||||
|
linuxvars.settings.window_y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
|
Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = {
|
||||||
None,
|
None,
|
||||||
XCreateFontCursor(linuxvars.XDisplay, XC_arrow),
|
XCreateFontCursor(linuxvars.XDisplay, XC_arrow),
|
||||||
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue