2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2008 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include <X11/keysym.h>
37 #define ExTextExtents XmbTextExtents
38 #define ExDrawString XmbDrawString
40 #define ExSetColor(pxc, r, g, b) \
42 (pxc)->red = (r << 8) | r; (pxc)->green = (g << 8) | g; (pxc)->blue = (b << 8) | b; \
45 static XFontSet xfs = NULL;
47 #define DRAW_BOX_OUT(mdd, mgc, mwin, mx, my, mw, mh) \
48 AlertDrawBox(mdd, mgc, mwin, mx, my, mw, mh, \
49 colorful, cols[0], cols[2], cols[3])
50 #define DRAW_BOX_IN(mdd, mgc, mwin, mx, my, mw, mh) \
51 AlertDrawBox(mdd, mgc, mwin, mx, my, mw, mh, \
52 colorful, cols[2], cols[0], cols[3])
54 AlertDrawBox(Display * mdd, GC mgc, Window mwin, int mx, int my, int mw, int mh,
55 int colorful, unsigned long c1, unsigned long c2, unsigned long cb)
59 XSetForeground(mdd, mgc, cb);
60 XDrawRectangle(mdd, mwin, mgc, mx, my, mw - 1, mh - 1);
61 XSetForeground(mdd, mgc, c1);
62 XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + mw - 3, my + 1);
63 XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + 1, my + mh - 3);
64 XSetForeground(mdd, mgc, c2);
65 XDrawLine(mdd, mwin, mgc, mx + 2, my + mh - 2, mx + mw - 2,
67 XDrawLine(mdd, mwin, mgc, mx + mw - 2, my + 2, mx + mw - 2,
72 XDrawRectangle(mdd, mwin, mgc, mx, my, mw - 1, mh - 1);
76 #define DRAW_THIN_BOX_IN(mdd, mgc, mwin, mx, my, mw, mh) \
77 AlertDrawThinBoxIn(mdd, mgc, mwin, mx, my, mw, mh, \
78 colorful, cols[2], cols[0])
80 AlertDrawThinBoxIn(Display * mdd, GC mgc, Window mwin, int mx, int my, int mw,
81 int mh, int colorful, unsigned long c1, unsigned long c2)
85 XSetForeground(mdd, mgc, c1);
86 XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + mw - 3, my + 1);
87 XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + 1, my + mh - 3);
88 XSetForeground(mdd, mgc, c2);
89 XDrawLine(mdd, mwin, mgc, mx + 2, my + mh - 2, mx + mw - 2,
91 XDrawLine(mdd, mwin, mgc, mx + mw - 2, my + 2, mx + mw - 2,
96 #define DRAW_HEADER(mdd, mgc, mwin, mx, my, mstr) \
97 AlertDrawHeader(mdd, mgc, mwin, mx, my, mstr, \
98 colorful, cols[2], cols[3], cols[4])
100 AlertDrawHeader(Display * mdd, GC mgc, Window mwin, int mx, int my,
101 const char *mstr, int colorful, unsigned long cb,
102 unsigned long ct1, unsigned long ct2)
104 int len = strlen(mstr);
108 XSetForeground(mdd, mgc, cb);
109 ExDrawString(mdd, mwin, xfs, mgc, mx + 1, my + 1, mstr, len);
110 ExDrawString(mdd, mwin, xfs, mgc, mx + 2, my + 1, mstr, len);
111 ExDrawString(mdd, mwin, xfs, mgc, mx + 2, my + 2, mstr, len);
112 ExDrawString(mdd, mwin, xfs, mgc, mx + 1, my + 2, mstr, len);
113 XSetForeground(mdd, mgc, ct1);
114 ExDrawString(mdd, mwin, xfs, mgc, mx - 1, my, mstr, len);
115 ExDrawString(mdd, mwin, xfs, mgc, mx, my - 1, mstr, len);
116 ExDrawString(mdd, mwin, xfs, mgc, mx + 1, my, mstr, len);
117 ExDrawString(mdd, mwin, xfs, mgc, mx, my + 1, mstr, len);
118 XSetForeground(mdd, mgc, ct2);
119 ExDrawString(mdd, mwin, xfs, mgc, mx, my, mstr, len);
123 ExDrawString(mdd, mwin, xfs, mgc, mx, my, mstr, len);
127 #define DRAW_STRING(mdd, mgc, mwin, mx, my, mstr) \
128 AlertDrawString(mdd, mgc, mwin, mx, my, mstr, \
131 AlertDrawString(Display * mdd, GC mgc, Window mwin, int mx, int my,
132 const char *mstr, int colorful, unsigned long ct1)
134 int len = strlen(mstr);
138 XSetForeground(mdd, mgc, ct1);
139 ExDrawString(mdd, mwin, xfs, mgc, mx, my, mstr, len);
143 ExDrawString(mdd, mwin, xfs, mgc, mx, my, mstr, len);
148 AlertButtonText(int btn, const char *text)
155 s = EMALLOC(char, strlen(text) + 6);
159 sprintf(s, "(F%d) %s", btn, text);
165 ShowAlert(const char *title,
166 const char *ignore, const char *restart, const char *quit, char *text)
168 Window win = 0, b1 = 0, b2 = 0, b3 = 0;
170 int wid, hih, w, h, i, j, k, mask;
175 XSetWindowAttributes att;
176 XRectangle rect1, rect2;
178 unsigned long cols[5];
181 int cnum, fh, x, y, ww, hh, mh;
182 char *str1, *str2, *str3;
185 char **missing_charset_list_return, *def_string_return;
186 int missing_charset_count_return;
187 XFontStruct **font_struct_list_return;
188 char **font_name_list_return;
190 SoundPlay(SOUND_ALERT);
196 * We may get here from obscure places like an X-error or signal handler
197 * and things seem to work properly only if we do a new XOpenDisplay().
199 dd = XOpenDisplay(NULL);
202 fprintf(stderr, "%s", text);
207 cmap = DefaultColormap(dd, DefaultScreen(dd));
210 title = _("Enlightenment Error");
211 str1 = AlertButtonText(1, ignore);
212 str2 = AlertButtonText(2, restart);
213 str3 = AlertButtonText(3, quit);
217 cols[0] = cols[1] = cols[2] = cols[3] = cols[4] = 0;
218 if (DefaultDepth(dd, DefaultScreen(dd)) > 4)
220 ExSetColor(&xcl, 220, 220, 220);
221 if (!XAllocColor(dd, cmap, &xcl))
223 cols[cnum++] = xcl.pixel;
224 ExSetColor(&xcl, 160, 160, 160);
225 if (!XAllocColor(dd, cmap, &xcl))
227 cols[cnum++] = xcl.pixel;
228 ExSetColor(&xcl, 100, 100, 100);
229 if (!XAllocColor(dd, cmap, &xcl))
231 cols[cnum++] = xcl.pixel;
232 ExSetColor(&xcl, 0, 0, 0);
233 if (!XAllocColor(dd, cmap, &xcl))
235 cols[cnum++] = xcl.pixel;
236 ExSetColor(&xcl, 255, 255, 255);
237 if (!XAllocColor(dd, cmap, &xcl))
239 cols[cnum++] = xcl.pixel;
245 att.background_pixel = cols[1];
247 att.background_pixel = BlackPixel(dd, DefaultScreen(dd));
249 att.border_pixel = cols[3];
251 att.border_pixel = WhitePixel(dd, DefaultScreen(dd));
252 att.backing_store = Always;
253 att.save_under = True;
254 att.override_redirect = True;
255 mask = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder |
257 win = XCreateWindow(dd, DefaultRootWindow(dd), -100, -100, 1, 1, 0,
258 CopyFromParent, InputOutput, CopyFromParent, mask, &att);
260 if (str1 && sscanf(str1, "%s", line) > 0)
262 b1 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, CopyFromParent,
263 InputOutput, CopyFromParent, mask, &att);
266 if (str2 && sscanf(str2, "%s", line) > 0)
268 b2 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, CopyFromParent,
269 InputOutput, CopyFromParent, mask, &att);
272 if (str3 && sscanf(str3, "%s", line) > 0)
274 b3 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, CopyFromParent,
275 InputOutput, CopyFromParent, mask, &att);
279 gc = XCreateGC(dd, win, 0, &gcv);
281 XSetForeground(dd, gc, cols[3]);
283 XSetForeground(dd, gc, att.border_pixel);
285 xfs = XCreateFontSet(dd, "-*-sans unicode-*-r-*-*-12-*-*-*-*-*-*-*,"
286 "-*-helvetica-*-r-*-*-12-*-*-*-*-*-*-*,fixed",
287 &missing_charset_list_return,
288 &missing_charset_count_return, &def_string_return);
292 if (missing_charset_list_return)
293 XFreeStringList(missing_charset_list_return);
295 k = XFontsOfFontSet(xfs, &font_struct_list_return, &font_name_list_return);
297 for (i = 0; i < k; i++)
299 h = font_struct_list_return[i]->ascent +
300 font_struct_list_return[i]->descent;
305 XSelectInput(dd, win, KeyPressMask | KeyReleaseMask | ExposureMask);
307 XGrabPointer(dd, win, True, ButtonPressMask | ButtonReleaseMask,
308 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
309 XGrabKeyboard(dd, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
310 XSetInputFocus(dd, win, RevertToPointerRoot, CurrentTime);
315 wid = DisplayWidth(dd, DefaultScreen(dd));
316 hih = DisplayHeight(dd, DefaultScreen(dd));
317 ww = (wid >= 600) ? 600 : (wid / 40) * 40;
318 hh = (hih >= 440) ? 440 : (hih / 40) * 40;
320 for (i = 40; i < ww; i += 40)
326 XMoveResizeWindow(dd, win, x, y, w, h);
327 DRAW_BOX_OUT(dd, gc, win, 0, 0, w, h);
332 XMoveResizeWindow(dd, win, x, y, ww, hh);
339 ExTextExtents(xfs, str1, strlen(str1), &rect1, &rect2);
340 mh = (rect2.width > mh) ? rect2.width : mh;
344 ExTextExtents(xfs, str2, strlen(str2), &rect1, &rect2);
345 mh = (rect2.width > mh) ? rect2.width : mh;
349 ExTextExtents(xfs, str3, strlen(str3), &rect1, &rect2);
350 mh = (rect2.width > mh) ? rect2.width : mh;
356 if (str1 && sscanf(str1, "%s", line) > 0)
358 w = 5 + (((ww - 20 - mh) * 0) / 4);
359 XMoveResizeWindow(dd, b1, w, hh - 15 - fh, mh + 10, fh + 10);
361 ButtonPressMask | ButtonReleaseMask | ExposureMask);
363 if (str2 && sscanf(str2, "%s", line) > 0)
365 w = 5 + (((ww - 20 - mh) * 1) / 2);
366 XMoveResizeWindow(dd, b2, w, hh - 15 - fh, mh + 10, fh + 10);
368 ButtonPressMask | ButtonReleaseMask | ExposureMask);
370 if (str3 && sscanf(str3, "%s", line) > 0)
372 w = 5 + (((ww - 20 - mh) * 2) / 2);
373 XMoveResizeWindow(dd, b3, w, hh - 15 - fh, mh + 10, fh + 10);
375 ButtonPressMask | ButtonReleaseMask | ExposureMask);
386 key = XKeysymToKeycode(dd, XK_F1);
387 if (key == ev.xkey.keycode)
389 DRAW_BOX_IN(dd, gc, b1, 0, 0, mh + 10, fh + 10);
392 DRAW_BOX_OUT(dd, gc, b1, 0, 0, mh + 10, fh + 10);
396 key = XKeysymToKeycode(dd, XK_F2);
397 if (key == ev.xkey.keycode)
399 DRAW_BOX_IN(dd, gc, b2, 0, 0, mh + 10, fh + 10);
402 DRAW_BOX_OUT(dd, gc, b2, 0, 0, mh + 10, fh + 10);
406 key = XKeysymToKeycode(dd, XK_F3);
407 if (key == ev.xkey.keycode)
409 DRAW_BOX_IN(dd, gc, b3, 0, 0, mh + 10, fh + 10);
412 DRAW_BOX_OUT(dd, gc, b3, 0, 0, mh + 10, fh + 10);
420 if (ev.xbutton.window == b1)
422 DRAW_BOX_IN(dd, gc, b1, 0, 0, mh + 10, fh + 10);
424 else if (ev.xbutton.window == b2)
426 DRAW_BOX_IN(dd, gc, b2, 0, 0, mh + 10, fh + 10);
428 else if (ev.xbutton.window == b3)
430 DRAW_BOX_IN(dd, gc, b3, 0, 0, mh + 10, fh + 10);
436 if (ev.xbutton.window == b1)
438 DRAW_BOX_OUT(dd, gc, b1, 0, 0, mh + 10, fh + 10);
441 else if (ev.xbutton.window == b2)
443 DRAW_BOX_OUT(dd, gc, b2, 0, 0, mh + 10, fh + 10);
446 else if (ev.xbutton.window == b3)
448 DRAW_BOX_OUT(dd, gc, b3, 0, 0, mh + 10, fh + 10);
455 /* Flush all other Expose events */
456 while (XCheckTypedWindowEvent(dd, ev.xexpose.window, Expose, &ev))
459 ExTextExtents(xfs, title, strlen(title), &rect1, &rect2);
462 DRAW_HEADER(dd, gc, win, (ww - w) / 2, 5 - rect2.y, title);
463 DRAW_BOX_OUT(dd, gc, win, 0, 0, ww, fh + 10);
464 DRAW_BOX_OUT(dd, gc, win, 0, fh + 10 - 1, ww,
465 hh - fh - fh - 30 + 2);
466 DRAW_BOX_OUT(dd, gc, win, 0, hh - fh - 20, ww, fh + 20);
472 line[j++] = text[i++];
473 if (line[j - 1] == '\n')
477 DRAW_STRING(dd, gc, win, 6, 6 + k + fh, line);
481 if (str1 && sscanf(str1, "%s", line) > 0)
483 ExTextExtents(xfs, str1, strlen(str1), &rect1, &rect2);
485 w = 3 + (((ww - 20 - mh) * 0) / 4);
486 DRAW_HEADER(dd, gc, b1, 5 + (mh - h) / 2, 5 - rect2.y, str1);
487 DRAW_BOX_OUT(dd, gc, b1, 0, 0, mh + 10, fh + 10);
488 DRAW_THIN_BOX_IN(dd, gc, win, w, hh - 17 - fh, mh + 14,
491 if (str2 && sscanf(str2, "%s", line) > 0)
493 ExTextExtents(xfs, str2, strlen(str2), &rect1, &rect2);
495 w = 3 + (((ww - 20 - mh) * 1) / 2);
496 DRAW_HEADER(dd, gc, b2, 5 + (mh - h) / 2, 5 - rect2.y, str2);
497 DRAW_BOX_OUT(dd, gc, b2, 0, 0, mh + 10, fh + 10);
498 DRAW_THIN_BOX_IN(dd, gc, win, w, hh - 17 - fh, mh + 14,
501 if (str3 && sscanf(str3, "%s", line) > 0)
503 ExTextExtents(xfs, str3, strlen(str3), &rect1, &rect2);
505 w = 3 + (((ww - 20 - mh) * 2) / 2);
506 DRAW_HEADER(dd, gc, b3, 5 + (mh - h) / 2, 5 - rect2.y, str3);
507 DRAW_BOX_OUT(dd, gc, b3, 0, 0, mh + 10, fh + 10);
508 DRAW_THIN_BOX_IN(dd, gc, win, w, hh - 17 - fh, mh + 14,
519 XDestroyWindow(dd, win);
521 XFreeFontSet(dd, xfs);
523 XFreeColors(dd, cmap, cols, cnum, 0);
532 SessionExit(EEXIT_RESTART, NULL);
535 SessionExit(EEXIT_EXIT, NULL);
546 AlertX(const char *title, const char *ignore,
547 const char *restart, const char *quit, const char *fmt, ...)
553 Evsnprintf(text, sizeof(text), fmt, args);
556 ShowAlert(title, ignore, restart, quit, text);
560 Alert(const char *fmt, ...)
566 Evsnprintf(text, sizeof(text), fmt, args);
569 ShowAlert(_("Enlightenment Message Dialog"), _("Ignore this"),
570 _("Restart Enlightenment"), _("Quit Enlightenment"), text);
574 AlertOK(const char *fmt, ...)
580 Evsnprintf(text, 10240, fmt, args);
583 ShowAlert(_("Attention !!!"), _("OK"), NULL, NULL, text);