11 #include <Ecore_Ipc.h>
13 #include <xcb/shape.h>
15 #define WINDOW_WIDTH 320
16 #define WINDOW_HEIGHT 240
18 /* local function prototypes */
19 static int _e_alert_connect(void);
20 static void _e_alert_create(void);
21 static void _e_alert_display(void);
22 static void _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h);
23 static void _e_alert_window_raise(xcb_window_t win);
24 static void _e_alert_sync(void);
25 static void _e_alert_shutdown(void);
26 static void _e_alert_run(void);
27 static void _e_alert_draw(void);
28 static int _e_alert_handle_key_press(xcb_generic_event_t *event);
29 static int _e_alert_handle_button_press(xcb_generic_event_t *event);
30 static xcb_char2b_t *_e_alert_build_string(const char *str);
31 static void _e_alert_draw_outline(void);
32 static void _e_alert_draw_title_outline(void);
33 static void _e_alert_draw_title(void);
34 static void _e_alert_draw_text(void);
35 static void _e_alert_draw_button_outlines(void);
36 static void _e_alert_draw_button_text(void);
39 static xcb_connection_t *conn = NULL;
40 static xcb_screen_t *screen = NULL;
41 static xcb_window_t win = 0, comp_win = 0;
42 static xcb_window_t btn1 = 0;
43 static xcb_window_t btn2 = 0;
44 static xcb_font_t font = 0;
45 static xcb_gcontext_t gc = 0;
46 static int sw = 0, sh = 0;
47 static int fa = 0, fh = 0, fw = 0;
48 static const char *title = NULL, *str1 = NULL, *str2 = NULL;
49 static int ret = 0, sig = 0;
53 main(int argc, char **argv)
57 for (i = 1; i < argc; i++)
59 if ((!strcmp(argv[i], "-h")) ||
60 (!strcmp(argv[i], "-help")) ||
61 (!strcmp(argv[i], "--help")))
63 printf("This is an internal tool for Enlightenment.\n"
68 sig = atoi(argv[i]); // signal
70 pid = atoi(argv[i]); // E's pid
72 comp_win = atoi(argv[i]); // Composite Alert Window
75 if (!ecore_init()) return EXIT_FAILURE;
76 ecore_app_args_set(argc, (const char **)argv);
78 if (!_e_alert_connect())
80 printf("FAILED TO INIT ALERT SYSTEM!!!\n");
85 title = "Enlightenment Error";
86 str1 = "(F1) Recover";
96 /* ret == 1 => restart e => exit code 1 */
97 /* ret == 2 => exit e => any code will do that */
101 /* local functions */
103 _e_alert_connect(void)
105 conn = xcb_connect(NULL, NULL);
106 if ((!conn) || (xcb_connection_has_error(conn)))
108 printf("E_Alert_Main: Error Trying to Connect!!\n");
112 /* grab default screen */
113 screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
114 sw = screen->width_in_pixels;
115 sh = screen->height_in_pixels;
121 _e_alert_create(void)
123 uint32_t mask, mask_list[4];
126 wx = ((sw - WINDOW_WIDTH) / 2);
127 wy = ((sh - WINDOW_HEIGHT) / 2);
129 font = xcb_generate_id(conn);
130 xcb_open_font(conn, font, strlen("fixed"), "fixed");
132 /* create main window */
133 mask = (XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL |
134 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK);
135 mask_list[0] = screen->white_pixel;
136 mask_list[1] = screen->black_pixel;
138 mask_list[3] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
139 XCB_EVENT_MASK_EXPOSURE);
141 win = xcb_generate_id(conn);
142 xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root,
143 wx, wy, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
144 XCB_WINDOW_CLASS_INPUT_OUTPUT,
145 XCB_COPY_FROM_PARENT, mask, mask_list);
147 /* create button 1 */
148 mask_list[3] = (XCB_EVENT_MASK_BUTTON_PRESS |
149 XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE);
151 btn1 = xcb_generate_id(conn);
152 xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn1, win,
154 XCB_WINDOW_CLASS_INPUT_OUTPUT,
155 XCB_COPY_FROM_PARENT, mask, mask_list);
156 xcb_map_window(conn, btn1);
158 /* create button 2 */
159 btn2 = xcb_generate_id(conn);
160 xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn2, win,
162 XCB_WINDOW_CLASS_INPUT_OUTPUT,
163 XCB_COPY_FROM_PARENT, mask, mask_list);
164 xcb_map_window(conn, btn2);
166 /* create drawing gc */
167 mask = (XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT);
168 mask_list[0] = screen->black_pixel;
169 mask_list[1] = screen->white_pixel;
172 gc = xcb_generate_id(conn);
173 xcb_create_gc(conn, gc, win, mask, mask_list);
177 _e_alert_display(void)
179 xcb_char2b_t *str = NULL;
180 xcb_query_text_extents_cookie_t cookie;
181 xcb_query_text_extents_reply_t *reply;
184 str = _e_alert_build_string(title);
187 xcb_query_text_extents_unchecked(conn, font, strlen(title), str);
188 reply = xcb_query_text_extents_reply(conn, cookie, NULL);
191 fa = reply->font_ascent;
192 fh = (fa + reply->font_descent);
193 fw = reply->overall_width;
200 w = (WINDOW_WIDTH / 2) - 40;
201 _e_alert_button_move_resize(btn1, x, WINDOW_HEIGHT - 20 - (fh + 20),
204 x = ((WINDOW_WIDTH / 2) + 20);
205 _e_alert_button_move_resize(btn2, x, WINDOW_HEIGHT - 20 - (fh + 20),
210 xcb_rectangle_t rect;
213 wx = ((sw - WINDOW_WIDTH) / 2);
214 wy = ((sh - WINDOW_HEIGHT) / 2);
218 rect.width = WINDOW_WIDTH;
219 rect.height = WINDOW_HEIGHT;
221 xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET,
222 XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
223 comp_win, 0, 0, 1, &rect);
225 xcb_reparent_window(conn, win, comp_win, wx, wy);
228 /* map and raise main window */
229 xcb_map_window(conn, win);
230 _e_alert_window_raise(win);
232 /* grab pointer & keyboard */
233 xcb_grab_pointer_unchecked(conn, 0, win,
234 (XCB_EVENT_MASK_BUTTON_PRESS |
235 XCB_EVENT_MASK_BUTTON_RELEASE),
236 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
237 XCB_NONE, XCB_NONE, XCB_CURRENT_TIME);
238 xcb_grab_keyboard_unchecked(conn, 0, win, XCB_CURRENT_TIME,
239 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
240 xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT,
241 win, XCB_CURRENT_TIME);
251 _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h)
253 uint32_t list[4], mask;
257 mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
258 XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
264 xcb_configure_window(conn, btn, mask, (const uint32_t *)&list);
268 _e_alert_window_raise(xcb_window_t window)
270 uint32_t list[] = { XCB_STACK_MODE_ABOVE };
273 xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_STACK_MODE, list);
279 free(xcb_get_input_focus_reply(conn,
280 xcb_get_input_focus(conn), NULL));
284 _e_alert_shutdown(void)
286 if (!xcb_connection_has_error(conn))
288 xcb_close_font(conn, font);
289 xcb_destroy_window(conn, btn1);
290 xcb_destroy_window(conn, btn2);
291 xcb_destroy_window(conn, win);
292 if (comp_win) xcb_destroy_window(conn, comp_win);
293 xcb_free_gc(conn, gc);
294 xcb_disconnect(conn);
301 xcb_generic_event_t *event = NULL;
304 while ((event = xcb_wait_for_event(conn)))
306 switch (event->response_type & ~0x80)
308 case XCB_BUTTON_PRESS:
309 ret = _e_alert_handle_button_press(event);
312 ret = _e_alert_handle_key_press(event);
316 xcb_expose_event_t *ev;
318 ev = (xcb_expose_event_t *)event;
319 if (ev->window != win) break;
337 _e_alert_draw_outline();
338 _e_alert_draw_title_outline();
339 _e_alert_draw_title();
340 _e_alert_draw_text();
341 _e_alert_draw_button_outlines();
342 _e_alert_draw_button_text();
348 _e_alert_handle_key_press(xcb_generic_event_t *event)
350 xcb_key_press_event_t *ev;
352 ev = (xcb_key_press_event_t *)event;
353 if (ev->detail == 67) // F1
355 else if (ev->detail == 68) // F2
362 _e_alert_handle_button_press(xcb_generic_event_t *event)
364 xcb_button_press_event_t *ev;
366 ev = (xcb_button_press_event_t *)event;
367 if (ev->child == btn1)
369 else if (ev->child == btn2)
375 static xcb_char2b_t *
376 _e_alert_build_string(const char *str)
379 xcb_char2b_t *r = NULL;
381 if (!(r = malloc(strlen(str) * sizeof(xcb_char2b_t))))
384 for (i = 0; i < strlen(str); i++)
394 _e_alert_draw_outline(void)
396 xcb_rectangle_t rect;
401 rect.width = (WINDOW_WIDTH - 1);
402 rect.height = (WINDOW_HEIGHT - 1);
403 xcb_poly_rectangle(conn, win, gc, 1, &rect);
407 _e_alert_draw_title_outline(void)
409 xcb_rectangle_t rect;
414 rect.width = (WINDOW_WIDTH - 4 - 1);
415 rect.height = (fh + 4 + 2);
416 xcb_poly_rectangle(conn, win, gc, 1, &rect);
420 _e_alert_draw_title(void)
422 xcb_void_cookie_t cookie;
426 x = (2 + 2 + ((WINDOW_WIDTH - 4 - 4 - fw) / 2));
430 xcb_image_text_8(conn, strlen(title), win, gc, x, y, title);
438 { SIGILL, "SIGILL" },
439 { SIGFPE, "SIGFPE" },
440 { SIGBUS, "SIGBUS" },
441 { SIGABRT, "SIGABRT" }
445 _e_alert_draw_text(void)
447 xcb_void_cookie_t cookie;
448 char warn[1024], msg[PATH_MAX], line[1024];
449 unsigned int i = 0, j = 0, k = 0;
451 snprintf(msg, sizeof(msg),
452 "This is not meant to happen and is likely a sign of \n"
453 "a bug in Enlightenment or the libraries it relies \n"
454 "on. You can gdb attach to this process (%d) now \n"
455 "to try debug it or you could exit, or just hit \n"
456 "restart to try and get your desktop back the way \n"
459 "Please compile everything with -g in your CFLAGS.", pid);
463 for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i)
464 if (signal_name[i].signal == sig)
465 snprintf(warn, sizeof(warn),
466 "This is very bad. Enlightenment %s'd.",
467 signal_name[i].name);
472 xcb_image_text_8(conn, strlen(warn), win, gc,
477 line[j++] = msg[i++];
478 if (line[j - 1] == '\n')
483 xcb_image_text_8(conn, strlen(line), win, gc,
491 _e_alert_draw_button_outlines(void)
493 xcb_rectangle_t rect;
497 rect.width = (WINDOW_WIDTH / 2) - 40 - 1;
498 rect.height = (fh + 20) - 1;
500 /* draw button outlines */
501 xcb_poly_rectangle(conn, btn1, gc, 1, &rect);
502 xcb_poly_rectangle(conn, btn2, gc, 1, &rect);
506 _e_alert_draw_button_text(void)
508 xcb_void_cookie_t dcookie;
509 xcb_char2b_t *str = NULL;
510 xcb_query_text_extents_cookie_t cookie;
511 xcb_query_text_extents_reply_t *reply;
512 int x = 0, w = 0, bw = 0;
514 bw = (WINDOW_WIDTH / 2) - 40 - 1;
516 /* draw button1 text */
517 str = _e_alert_build_string(str1);
520 xcb_query_text_extents_unchecked(conn, font, strlen(str1), str);
521 reply = xcb_query_text_extents_reply(conn, cookie, NULL);
524 w = reply->overall_width;
529 x = (5 + ((bw - w) / 2));
532 xcb_image_text_8(conn, strlen(str1), btn1, gc, x, (10 + fa), str1);
534 /* draw button2 text */
535 str = _e_alert_build_string(str2);
538 xcb_query_text_extents_unchecked(conn, font, strlen(str2), str);
539 reply = xcb_query_text_extents_reply(conn, cookie, NULL);
542 w = reply->overall_width;
547 x = (5 + ((bw - w) / 2));
550 xcb_image_text_8(conn, strlen(str2), btn2, gc, x, (10 + fa), str2);