| 1021 | |
| 1022 | static Bool X11_FilterEvent(Display* d, XEvent* e, XPointer w) { return e->xany.window == (Window)w; } |
| 1023 | static void X11_MessageBox(const char* title, const char* text, struct X11MessageBox* m) { |
| 1024 | struct X11Button ok = { 0 }; |
| 1025 | struct X11Textbox body = { 0 }; |
| 1026 | Window win = Window_Main.Handle.val; |
| 1027 | |
| 1028 | Atom protocols[2]; |
| 1029 | XFontStruct* font; |
| 1030 | int x, y, width, height; |
| 1031 | XSizeHints hints = { 0 }; |
| 1032 | int mouseX = -1, mouseY = -1, over; |
| 1033 | XEvent e; |
| 1034 | |
| 1035 | X11MessageBox_Init(m); |
| 1036 | XMapWindow(m->dpy, m->win); |
| 1037 | XStoreName(m->dpy, m->win, title); |
| 1038 | |
| 1039 | protocols[0] = XInternAtom(m->dpy, "WM_DELETE_WINDOW", false); |
| 1040 | protocols[1] = XInternAtom(m->dpy, "_NET_WM_PING", false); |
| 1041 | XSetWMProtocols(m->dpy, m->win, protocols, 2); |
| 1042 | |
| 1043 | font = XQueryFont(m->dpy, XGContextFromGC(m->gc)); |
| 1044 | if (!font) return; |
| 1045 | |
| 1046 | /* Compute size of widgets */ |
| 1047 | body.text = text; |
| 1048 | X11Textbox_Measure(&body, font); |
| 1049 | ok.text.text = "OK"; |
| 1050 | X11Textbox_Measure(&ok.text, font); |
| 1051 | ok.width = ok.text.width + 70; |
| 1052 | ok.height = ok.text.height + 10; |
| 1053 | |
| 1054 | /* Compute size and position of window */ |
| 1055 | width = body.width + 20; |
| 1056 | height = body.height + 20 + ok.height + 20; |
| 1057 | x = DisplayWidth (m->dpy, DefaultScreen(m->dpy))/2 - width/2; |
| 1058 | y = DisplayHeight(m->dpy, DefaultScreen(m->dpy))/2 - height/2; |
| 1059 | XMoveResizeWindow(m->dpy, m->win, x, y, width, height); |
| 1060 | |
| 1061 | /* Adjust bounds of widgets */ |
| 1062 | body.x = 10; body.y = 10; |
| 1063 | ok.x = width/2 - ok.width/2; |
| 1064 | ok.y = height - ok.height - 10; |
| 1065 | |
| 1066 | /* This marks the window as popup window of the main window */ |
| 1067 | /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */ |
| 1068 | /* Depending on WM, removes minimise and doesn't show in taskbar */ |
| 1069 | if (win) XSetTransientForHint(m->dpy, m->win, win); |
| 1070 | |
| 1071 | XFreeFontInfo(NULL, font, 1); |
| 1072 | XUnmapWindow(m->dpy, m->win); /* Make window non resizeable */ |
| 1073 | |
| 1074 | hints.flags = PSize | PMinSize | PMaxSize; |
| 1075 | hints.min_width = hints.max_width = hints.base_width = width; |
| 1076 | hints.min_height = hints.max_height = hints.base_height = height; |
| 1077 | |
| 1078 | XSetWMNormalHints(m->dpy, m->win, &hints); |
| 1079 | XMapRaised(m->dpy, m->win); |
| 1080 | XFlush(m->dpy); |
no test coverage detected