generalized the error box idea
parent
7fa4bf30a9
commit
def252481c
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
internal b32
|
internal void
|
||||||
system_memory_init(){
|
system_memory_init(){
|
||||||
#if defined(FRED_INTERNAL)
|
#if defined(FRED_INTERNAL)
|
||||||
# if defined(FTECH_64_BIT)
|
# if defined(FTECH_64_BIT)
|
||||||
|
@ -37,7 +37,10 @@ system_memory_init(){
|
||||||
alloc_success = false;
|
alloc_success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(alloc_success);
|
if (!alloc_success){
|
||||||
|
char msg[] = "Could not allocate sufficient memory. Please make sure you have atleast 512Mb of RAM free. (This requirement will be relaxed in the future).";
|
||||||
|
system_error_box(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
|
@ -195,188 +195,12 @@ global Plat_Settings plat_settings;
|
||||||
|
|
||||||
#include "linux_icon.h"
|
#include "linux_icon.h"
|
||||||
internal void
|
internal void
|
||||||
LinuxSetIcon(Display* d, Window w){
|
linux_set_icon(Display* d, Window w){
|
||||||
Atom WM_ICON = XInternAtom(d, "_NET_WM_ICON", False);
|
Atom WM_ICON = XInternAtom(d, "_NET_WM_ICON", False);
|
||||||
XChangeProperty(d, w, WM_ICON, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)linux_icon, sizeof(linux_icon) / sizeof(long));
|
XChangeProperty(d, w, WM_ICON, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)linux_icon, sizeof(linux_icon) / sizeof(long));
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK(allen):
|
#include "linux_error_box.cpp"
|
||||||
// NOTE(inso): this was a quick hack, might need some cleanup.
|
|
||||||
internal void
|
|
||||||
LinuxFatalErrorMsg(const char* msg){
|
|
||||||
LOGF("Fatal Error: %s\n", msg);
|
|
||||||
|
|
||||||
Display *dpy = XOpenDisplay(0);
|
|
||||||
if (!dpy){
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int num_cols = 50;
|
|
||||||
int win_w = (num_cols + 10) * 9;
|
|
||||||
int win_h = 140;
|
|
||||||
|
|
||||||
{
|
|
||||||
const char *start_p = msg, *space_p = NULL;
|
|
||||||
for(const char* p = msg; *p; ++p){
|
|
||||||
if (*p == ' ') space_p = p;
|
|
||||||
if (*p == '\n' || p - start_p > num_cols){
|
|
||||||
win_h += 18;
|
|
||||||
start_p = space_p ? space_p + 1 : p;
|
|
||||||
space_p = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, win_w, win_h, 0, 0, 0x227A3B);
|
|
||||||
XStoreName(dpy, w, "4coder Error");
|
|
||||||
|
|
||||||
XSizeHints* sh = XAllocSizeHints();
|
|
||||||
sh->flags = PMinSize;
|
|
||||||
sh->min_width = win_w;
|
|
||||||
sh->min_height = win_h;
|
|
||||||
XSetWMNormalHints(dpy, w, sh);
|
|
||||||
|
|
||||||
Atom type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
|
||||||
|
|
||||||
XChangeProperty(dpy, w,
|
|
||||||
XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False),
|
|
||||||
XA_ATOM,
|
|
||||||
32,
|
|
||||||
PropModeReplace,
|
|
||||||
(unsigned char*) &type,
|
|
||||||
1);
|
|
||||||
|
|
||||||
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
||||||
XSetWMProtocols(dpy, w, &WM_DELETE_WINDOW, 1);
|
|
||||||
|
|
||||||
LinuxSetIcon(dpy, w);
|
|
||||||
|
|
||||||
XMapRaised(dpy, w);
|
|
||||||
XSync(dpy, False);
|
|
||||||
|
|
||||||
XSelectInput(dpy, w, ExposureMask | StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask);
|
|
||||||
|
|
||||||
XFontStruct* font = XLoadQueryFont(dpy, "-*-fixed-bold-*-*-*-*-140-*-*-*-*-iso8859-1");
|
|
||||||
if (!font){
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XGCValues gcv;
|
|
||||||
gcv.foreground = WhitePixel(dpy, 0);
|
|
||||||
gcv.line_width = 2;
|
|
||||||
gcv.font = font->fid;
|
|
||||||
|
|
||||||
GC gc1 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
|
|
||||||
gcv.foreground = BlackPixel(dpy, 0);
|
|
||||||
GC gc2 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
|
|
||||||
|
|
||||||
int button_trigger = 0;
|
|
||||||
int button_hi = 0;
|
|
||||||
|
|
||||||
XEvent ev;
|
|
||||||
while (1){
|
|
||||||
XNextEvent(dpy, &ev);
|
|
||||||
|
|
||||||
int redraw = 0;
|
|
||||||
|
|
||||||
if (ev.type == Expose) redraw = 1;
|
|
||||||
|
|
||||||
if (ev.type == ConfigureNotify){
|
|
||||||
redraw = 1;
|
|
||||||
win_w = ev.xconfigure.width;
|
|
||||||
win_h = ev.xconfigure.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
XRectangle button_rect = { win_w/2-40, win_h*0.8f, 80, 20 };
|
|
||||||
|
|
||||||
if (ev.type == MotionNotify){
|
|
||||||
int new_hi = (ev.xmotion.x > button_rect.x &&
|
|
||||||
ev.xmotion.y > button_rect.y &&
|
|
||||||
ev.xmotion.x < button_rect.x + button_rect.width &&
|
|
||||||
ev.xmotion.y < button_rect.y + button_rect.height);
|
|
||||||
|
|
||||||
if (new_hi != button_hi){
|
|
||||||
button_hi = new_hi;
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.type == KeyPress){
|
|
||||||
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
|
||||||
if (sym == XK_Escape || sym == XK_Return){
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.type == ButtonPress && ev.xbutton.button == Button1){
|
|
||||||
if (button_hi) button_trigger = 1;
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.type == ButtonRelease && ev.xbutton.button == Button1){
|
|
||||||
if (button_trigger){
|
|
||||||
if (button_hi){
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
button_trigger = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.type == ClientMessage && ev.xclient.window == w && (Atom)ev.xclient.data.l[0] == WM_DELETE_WINDOW){
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DRAW_STR(x, y, str, len) \
|
|
||||||
XDrawString(dpy, w, gc2, (x)+1, (y)+1, (str), (len)); \
|
|
||||||
XDrawString(dpy, w, gc1, (x) , (y) , (str), (len))
|
|
||||||
|
|
||||||
if (redraw){
|
|
||||||
XClearWindow(dpy, w);
|
|
||||||
|
|
||||||
const char* line_start = msg;
|
|
||||||
const char* last_space = NULL;
|
|
||||||
int y = 30;
|
|
||||||
|
|
||||||
{
|
|
||||||
const char title[] = "4coder - Fatal Error";
|
|
||||||
int width = XTextWidth(font, title, sizeof(title)-1);
|
|
||||||
int x = (win_w/2) - (width/2);
|
|
||||||
DRAW_STR(x, y, title, sizeof(title)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += 36;
|
|
||||||
int width = XTextWidth(font, "x", 1) * num_cols;
|
|
||||||
int x = (win_w/2) - (width/2);
|
|
||||||
|
|
||||||
for(const char* p = line_start; *p; ++p){
|
|
||||||
if (*p == ' ') last_space = p;
|
|
||||||
if (p - line_start > num_cols || *p == '\n' || !p[1]){
|
|
||||||
|
|
||||||
const char* new_line_start = last_space + 1;
|
|
||||||
if (!last_space || *p == '\n' || !p[1]){
|
|
||||||
new_line_start = last_space = (p + !p[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
DRAW_STR(x, y, line_start, last_space - line_start);
|
|
||||||
|
|
||||||
line_start = new_line_start;
|
|
||||||
last_space = NULL;
|
|
||||||
y += 18;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XDrawRectangles(dpy, w, gc1, &button_rect, 1);
|
|
||||||
if (button_hi || button_trigger){
|
|
||||||
XDrawRectangle(dpy, w, gc2, button_rect.x+1, button_rect.y+1, button_rect.width-2, button_rect.height-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
DRAW_STR(button_rect.x + 20, button_rect.y + 15, "Drat!", 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef DRAW_STR
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
@ -1407,14 +1231,12 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
|
||||||
*window_height = Max(*window_height, 1);
|
*window_height = Max(*window_height, 1);
|
||||||
|
|
||||||
if (!GLXCanUseFBConfig(linuxvars.XDisplay)){
|
if (!GLXCanUseFBConfig(linuxvars.XDisplay)){
|
||||||
LinuxFatalErrorMsg("Your XServer's GLX version is too old. GLX 1.3+ is required.");
|
system_error_box("Your XServer's GLX version is too old. GLX 1.3+ is required.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, DefaultScreen(linuxvars.XDisplay));
|
glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, DefaultScreen(linuxvars.XDisplay));
|
||||||
if (!Config.Found){
|
if (!Config.Found){
|
||||||
LinuxFatalErrorMsg("Could not get a matching GLX FBConfig. Check your OpenGL drivers are installed correctly.");
|
system_error_box("Could not get a matching GLX FBConfig. Check your OpenGL drivers are installed correctly.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XSetWindowAttributes swa = {};
|
XSetWindowAttributes swa = {};
|
||||||
|
@ -1427,8 +1249,7 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
|
||||||
linuxvars.XWindow = XCreateWindow(linuxvars.XDisplay, RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), 0, 0, *window_width, *window_height, 0, Config.BestInfo.depth, InputOutput, Config.BestInfo.visual, CWflags, &swa);
|
linuxvars.XWindow = XCreateWindow(linuxvars.XDisplay, RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), 0, 0, *window_width, *window_height, 0, Config.BestInfo.depth, InputOutput, Config.BestInfo.visual, CWflags, &swa);
|
||||||
|
|
||||||
if (!linuxvars.XWindow){
|
if (!linuxvars.XWindow){
|
||||||
LinuxFatalErrorMsg("XCreateWindow failed. Make sure your display is set up correctly.");
|
system_error_box("XCreateWindow failed. Make sure your display is set up correctly.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE(inso): Set the window's type to normal
|
//NOTE(inso): Set the window's type to normal
|
||||||
|
@ -1485,7 +1306,7 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
|
||||||
XFree(wm_hints);
|
XFree(wm_hints);
|
||||||
XFree(cl_hints);
|
XFree(cl_hints);
|
||||||
|
|
||||||
LinuxSetIcon(linuxvars.XDisplay, linuxvars.XWindow);
|
linux_set_icon(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
|
|
||||||
// NOTE(inso): make the window visible
|
// NOTE(inso): make the window visible
|
||||||
XMapWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
XMapWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
|
@ -1842,20 +1663,13 @@ main(int argc, char **argv){
|
||||||
|
|
||||||
if (!LinuxLoadAppCode(&base_dir)){
|
if (!LinuxLoadAppCode(&base_dir)){
|
||||||
char msg[] = "Could not load '4ed_app.so'. This file should be in the same directory as the main '4ed' executable.";
|
char msg[] = "Could not load '4ed_app.so'. This file should be in the same directory as the main '4ed' executable.";
|
||||||
LinuxFatalErrorMsg(msg);
|
system_error_box(msg);
|
||||||
return 99;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
link_system_code(&sysfunc);
|
link_system_code(&sysfunc);
|
||||||
LinuxLoadRenderCode();
|
LinuxLoadRenderCode();
|
||||||
|
|
||||||
b32 alloc_success = system_memory_init();
|
system_memory_init();
|
||||||
|
|
||||||
if (!alloc_success){
|
|
||||||
char msg[] = "Could not allocate sufficient memory. Please make sure you have atleast 512Mb of RAM free. (This requirement will be relaxed in the future).";
|
|
||||||
LinuxFatalErrorMsg(msg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
init_shared_vars();
|
init_shared_vars();
|
||||||
|
|
||||||
|
@ -1867,8 +1681,7 @@ main(int argc, char **argv){
|
||||||
if (!cwd){
|
if (!cwd){
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
snprintf(buf, sizeof(buf), "Call to get_current_dir_name failed: %s", strerror(errno));
|
snprintf(buf, sizeof(buf), "Call to get_current_dir_name failed: %s", strerror(errno));
|
||||||
LinuxFatalErrorMsg(buf);
|
system_error_box(buf);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String current_directory = make_string_slowly(cwd);
|
String current_directory = make_string_slowly(cwd);
|
||||||
|
@ -1887,8 +1700,7 @@ main(int argc, char **argv){
|
||||||
LOGF("%.*s", output_size, (char*)memory_vars.target_memory);
|
LOGF("%.*s", output_size, (char*)memory_vars.target_memory);
|
||||||
}
|
}
|
||||||
if (output_size != 0){
|
if (output_size != 0){
|
||||||
LinuxFatalErrorMsg("Error reading command-line arguments.");
|
system_error_box("Error reading command-line arguments.");
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sysshared_filter_real_files(files, file_count);
|
sysshared_filter_real_files(files, file_count);
|
||||||
|
@ -1906,7 +1718,8 @@ main(int argc, char **argv){
|
||||||
char *custom_file;
|
char *custom_file;
|
||||||
if (plat_settings.custom_dll){
|
if (plat_settings.custom_dll){
|
||||||
custom_file = plat_settings.custom_dll;
|
custom_file = plat_settings.custom_dll;
|
||||||
} else {
|
}
|
||||||
|
else{
|
||||||
custom_file = custom_file_default;
|
custom_file = custom_file_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1923,31 +1736,29 @@ main(int argc, char **argv){
|
||||||
|
|
||||||
if (linuxvars.custom_api.get_alpha_4coder_version == 0 ||
|
if (linuxvars.custom_api.get_alpha_4coder_version == 0 ||
|
||||||
linuxvars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
linuxvars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
||||||
LinuxFatalErrorMsg("Failed to load 'custom_4coder.so': Version mismatch. Try rebuilding it with 'buildsuper.sh'.");
|
system_error_box("Failed to load 'custom_4coder.so': Version mismatch. Try rebuilding it with 'buildsuper.sh'.");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
linuxvars.custom_api.get_bindings = (Get_Binding_Data_Function*)
|
linuxvars.custom_api.get_bindings = (Get_Binding_Data_Function*)
|
||||||
dlsym(linuxvars.custom, "get_bindings");
|
dlsym(linuxvars.custom, "get_bindings");
|
||||||
|
|
||||||
if (linuxvars.custom_api.get_bindings == 0){
|
if (linuxvars.custom_api.get_bindings == 0){
|
||||||
LinuxFatalErrorMsg("Failed to load 'custom_4coder.so': "
|
system_error_box("Failed to load 'custom_4coder.so': "
|
||||||
"It does not export the required 'get_bindings' function. "
|
"It does not export the required 'get_bindings' function. "
|
||||||
"Try rebuilding it with 'buildsuper.sh'.");
|
"Try rebuilding it with 'buildsuper.sh'.");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
LOG("Successfully loaded custom_4coder.so\n");
|
LOG("Successfully loaded custom_4coder.so\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else{
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
const char* error = dlerror();
|
const char* error = dlerror();
|
||||||
snprintf(buf, sizeof(buf), "Error loading custom: %s. "
|
snprintf(buf, sizeof(buf), "Error loading custom: %s. "
|
||||||
"Make sure this file is in the same directory as the main '4ed' executable.",
|
"Make sure this file is in the same directory as the main '4ed' executable.",
|
||||||
error ? error : "'custom_4coder.so' missing");
|
error ? error : "'custom_4coder.so' missing");
|
||||||
LinuxFatalErrorMsg(buf);
|
system_error_box(buf);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
linuxvars.custom_api.get_bindings = get_bindings;
|
linuxvars.custom_api.get_bindings = get_bindings;
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
* (Mostly by insofaras)
|
||||||
|
*
|
||||||
|
* 18.07.2017
|
||||||
|
*
|
||||||
|
* Linux fatal error message box.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
// HACK(allen): // NOTE(inso): this was a quick hack, might need some cleanup.
|
||||||
|
internal void
|
||||||
|
system_error_box(char *msg){
|
||||||
|
LOGF("Fatal Error: %s\n", msg);
|
||||||
|
|
||||||
|
Display *dpy = XOpenDisplay(0);
|
||||||
|
if (!dpy){
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int num_cols = 50;
|
||||||
|
int win_w = (num_cols + 10) * 9;
|
||||||
|
int win_h = 140;
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *start_p = msg, *space_p = NULL;
|
||||||
|
for(const char* p = msg; *p; ++p){
|
||||||
|
if (*p == ' ') space_p = p;
|
||||||
|
if (*p == '\n' || p - start_p > num_cols){
|
||||||
|
win_h += 18;
|
||||||
|
start_p = space_p ? space_p + 1 : p;
|
||||||
|
space_p = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, win_w, win_h, 0, 0, 0x227A3B);
|
||||||
|
XStoreName(dpy, w, "4coder Error");
|
||||||
|
|
||||||
|
XSizeHints* sh = XAllocSizeHints();
|
||||||
|
sh->flags = PMinSize;
|
||||||
|
sh->min_width = win_w;
|
||||||
|
sh->min_height = win_h;
|
||||||
|
XSetWMNormalHints(dpy, w, sh);
|
||||||
|
|
||||||
|
Atom type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||||
|
|
||||||
|
XChangeProperty(dpy, w, XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False), XA_ATOM, 32, PropModeReplace, (unsigned char*) &type, 1);
|
||||||
|
|
||||||
|
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
||||||
|
XSetWMProtocols(dpy, w, &WM_DELETE_WINDOW, 1);
|
||||||
|
|
||||||
|
linux_set_icon(dpy, w);
|
||||||
|
|
||||||
|
XMapRaised(dpy, w);
|
||||||
|
XSync(dpy, False);
|
||||||
|
|
||||||
|
XSelectInput(dpy, w, ExposureMask | StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask);
|
||||||
|
|
||||||
|
XFontStruct* font = XLoadQueryFont(dpy, "-*-fixed-bold-*-*-*-*-140-*-*-*-*-iso8859-1");
|
||||||
|
if (!font){
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XGCValues gcv;
|
||||||
|
gcv.foreground = WhitePixel(dpy, 0);
|
||||||
|
gcv.line_width = 2;
|
||||||
|
gcv.font = font->fid;
|
||||||
|
|
||||||
|
GC gc1 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
|
||||||
|
gcv.foreground = BlackPixel(dpy, 0);
|
||||||
|
GC gc2 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
|
||||||
|
|
||||||
|
int button_trigger = 0;
|
||||||
|
int button_hi = 0;
|
||||||
|
|
||||||
|
XEvent ev;
|
||||||
|
while (1){
|
||||||
|
XNextEvent(dpy, &ev);
|
||||||
|
|
||||||
|
int redraw = 0;
|
||||||
|
|
||||||
|
if (ev.type == Expose) redraw = 1;
|
||||||
|
|
||||||
|
if (ev.type == ConfigureNotify){
|
||||||
|
redraw = 1;
|
||||||
|
win_w = ev.xconfigure.width;
|
||||||
|
win_h = ev.xconfigure.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
XRectangle button_rect = { win_w/2-40, win_h*0.8f, 80, 20 };
|
||||||
|
|
||||||
|
if (ev.type == MotionNotify){
|
||||||
|
int new_hi = (ev.xmotion.x > button_rect.x &&
|
||||||
|
ev.xmotion.y > button_rect.y &&
|
||||||
|
ev.xmotion.x < button_rect.x + button_rect.width &&
|
||||||
|
ev.xmotion.y < button_rect.y + button_rect.height);
|
||||||
|
|
||||||
|
if (new_hi != button_hi){
|
||||||
|
button_hi = new_hi;
|
||||||
|
redraw = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.type == KeyPress){
|
||||||
|
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
||||||
|
if (sym == XK_Escape || sym == XK_Return){
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.type == ButtonPress && ev.xbutton.button == Button1){
|
||||||
|
if (button_hi) button_trigger = 1;
|
||||||
|
redraw = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.type == ButtonRelease && ev.xbutton.button == Button1){
|
||||||
|
if (button_trigger){
|
||||||
|
if (button_hi){
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
button_trigger = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
redraw = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.type == ClientMessage && ev.xclient.window == w && (Atom)ev.xclient.data.l[0] == WM_DELETE_WINDOW){
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DRAW_STR(x, y, str, len) \
|
||||||
|
XDrawString(dpy, w, gc2, (x)+1, (y)+1, (str), (len)); \
|
||||||
|
XDrawString(dpy, w, gc1, (x) , (y) , (str), (len))
|
||||||
|
|
||||||
|
if (redraw){
|
||||||
|
XClearWindow(dpy, w);
|
||||||
|
|
||||||
|
const char* line_start = msg;
|
||||||
|
const char* last_space = NULL;
|
||||||
|
int y = 30;
|
||||||
|
|
||||||
|
{
|
||||||
|
const char title[] = "4coder - Fatal Error";
|
||||||
|
int width = XTextWidth(font, title, sizeof(title)-1);
|
||||||
|
int x = (win_w/2) - (width/2);
|
||||||
|
DRAW_STR(x, y, title, sizeof(title)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
y += 36;
|
||||||
|
int width = XTextWidth(font, "x", 1) * num_cols;
|
||||||
|
int x = (win_w/2) - (width/2);
|
||||||
|
|
||||||
|
for(const char* p = line_start; *p; ++p){
|
||||||
|
if (*p == ' ') last_space = p;
|
||||||
|
if (p - line_start > num_cols || *p == '\n' || !p[1]){
|
||||||
|
|
||||||
|
const char* new_line_start = last_space + 1;
|
||||||
|
if (!last_space || *p == '\n' || !p[1]){
|
||||||
|
new_line_start = last_space = (p + !p[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DRAW_STR(x, y, line_start, last_space - line_start);
|
||||||
|
|
||||||
|
line_start = new_line_start;
|
||||||
|
last_space = NULL;
|
||||||
|
y += 18;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XDrawRectangles(dpy, w, gc1, &button_rect, 1);
|
||||||
|
if (button_hi || button_trigger){
|
||||||
|
XDrawRectangle(dpy, w, gc2, button_rect.x+1, button_rect.y+1, button_rect.width-2, button_rect.height-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
DRAW_STR(button_rect.x + 20, button_rect.y + 15, "Drat!", 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef DRAW_STR
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
|
@ -87,8 +87,7 @@ linux_font_load(Partition *part, Render_Font *rf, char *name, i32 pt_size, i32 t
|
||||||
|
|
||||||
// NOTE(inso): if/when you can load fonts from anywhere, the message should be changed.
|
// NOTE(inso): if/when you can load fonts from anywhere, the message should be changed.
|
||||||
snprintf(buff, sizeof(buff), "Unable to load font '%s'. Make sure this file is in the same directory as the '4ed' executable.", filename);
|
snprintf(buff, sizeof(buff), "Unable to load font '%s'. Make sure this file is in the same directory as the '4ed' executable.", filename);
|
||||||
LinuxFatalErrorMsg(buff);
|
system_error_box(buff);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = font_load_freetype(part, rf, filename, pt_size, tab_width, use_hinting);
|
result = font_load_freetype(part, rf, filename, pt_size, tab_width, use_hinting);
|
||||||
|
|
|
@ -161,6 +161,10 @@ global Plat_Settings plat_settings;
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
#include "win32_error_box.cpp"
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
#define SLASH '\\'
|
#define SLASH '\\'
|
||||||
|
|
||||||
internal HANDLE
|
internal HANDLE
|
||||||
|
@ -1095,12 +1099,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
||||||
// Memory Initialization
|
// Memory Initialization
|
||||||
//
|
//
|
||||||
|
|
||||||
b32 alloc_success = system_memory_init();
|
system_memory_init();
|
||||||
if (!alloc_success){
|
|
||||||
// HACK(allen):
|
|
||||||
LOGF("Failed thingy");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// System and Application Layer Linkage
|
// System and Application Layer Linkage
|
||||||
|
@ -1171,16 +1170,14 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
||||||
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
|
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
|
||||||
|
|
||||||
if (win32vars.custom_api.get_alpha_4coder_version == 0 || win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
if (win32vars.custom_api.get_alpha_4coder_version == 0 || win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
||||||
MessageBox_utf8(0, (u8*)"Error: The application and custom version numbers don't match.\n", (u8*)"Error",0);
|
system_error_box("The application and custom version numbers don't match.");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)GetProcAddress(win32vars.custom, "get_bindings");
|
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)GetProcAddress(win32vars.custom, "get_bindings");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win32vars.custom_api.get_bindings == 0){
|
if (win32vars.custom_api.get_bindings == 0){
|
||||||
MessageBox_utf8(0, (u8*)"Error: The custom dll is missing.\n", (u8*)"Error", 0);
|
system_error_box("The custom dll is missing.");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 18.07.2017
|
||||||
|
*
|
||||||
|
* Linux fatal error message box.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_error_box(char *msg){
|
||||||
|
LOGF("Fatal Error: %s\n", msg);
|
||||||
|
MessageBox_utf8(0, (u8*)msg, (u8*)"Error",0);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
Loading…
Reference in New Issue