moved fatal error message as high up as possible
parent
b7dd4eb0a0
commit
7fa4bf30a9
|
@ -18,13 +18,13 @@
|
|||
#if defined(IS_PLAT_LAYER)
|
||||
|
||||
# if defined(USE_LOG)
|
||||
# define LOG(m) GEN_LOG(system_log, m)
|
||||
# define LOG(m) GEN_LOG(sysfunc.log, m)
|
||||
# else
|
||||
# define LOG(m)
|
||||
# endif
|
||||
|
||||
# if defined(USE_LOGF)
|
||||
# define LOGF(...) GEN_LOGF(system_log, __VA_ARGS__)
|
||||
# define LOGF(...) GEN_LOGF(sysfunc.log, __VA_ARGS__)
|
||||
# else
|
||||
# define LOGF(...)
|
||||
# endif
|
||||
|
|
|
@ -193,6 +193,193 @@ global Plat_Settings plat_settings;
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
#include "linux_icon.h"
|
||||
internal void
|
||||
LinuxSetIcon(Display* d, Window w){
|
||||
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));
|
||||
}
|
||||
|
||||
// HACK(allen):
|
||||
// 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
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#define SLASH '/'
|
||||
|
||||
internal sem_t*
|
||||
|
@ -1072,17 +1259,8 @@ LinuxStringDup(String* str, void* data, size_t size){
|
|||
// X11 utility funcs
|
||||
//
|
||||
|
||||
#include "linux_icon.h"
|
||||
internal void
|
||||
LinuxSetIcon(Display* d, Window w)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
internal void
|
||||
LinuxX11ConnectionWatch(Display* dpy, XPointer cdata, int fd, Bool opening, XPointer* wdata)
|
||||
{
|
||||
LinuxX11ConnectionWatch(Display* dpy, XPointer cdata, int fd, Bool opening, XPointer* wdata){
|
||||
struct epoll_event e = {};
|
||||
e.events = EPOLLIN | EPOLLET;
|
||||
e.data.u64 = LINUX_4ED_EVENT_X11_INTERNAL | fd;
|
||||
|
@ -1091,185 +1269,6 @@ LinuxX11ConnectionWatch(Display* dpy, XPointer cdata, int fd, Bool opening, XPoi
|
|||
epoll_ctl(linuxvars.epoll, op, fd, &e);
|
||||
}
|
||||
|
||||
// HACK(allen):
|
||||
// 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
|
||||
}
|
||||
|
||||
internal int
|
||||
LinuxGetXSettingsDPI(Display* dpy, int screen)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue