13 #include <Ecore_Ipc.h>
15 #include <xcb/shape.h>
17 #define WINDOW_WIDTH 320
18 #define WINDOW_HEIGHT 240
20 /* local function prototypes */
21 static int _e_alert_connect(void);
22 static void _e_alert_create(void);
23 static void _e_alert_display(void);
24 static void _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h);
25 static void _e_alert_window_raise(xcb_window_t win);
26 static void _e_alert_sync(void);
27 static void _e_alert_shutdown(void);
28 static void _e_alert_run(void);
29 static void _e_alert_draw(void);
30 static int _e_alert_handle_key_press(xcb_generic_event_t *event);
31 static int _e_alert_handle_button_press(xcb_generic_event_t *event);
32 static xcb_char2b_t *_e_alert_build_string(const char *str);
33 static void _e_alert_draw_outline(void);
34 static void _e_alert_draw_title_outline(void);
35 static void _e_alert_draw_title(void);
36 static void _e_alert_draw_text(void);
37 static void _e_alert_draw_button_outlines(void);
38 static void _e_alert_draw_button_text(void);
41 static xcb_connection_t *conn = NULL;
42 static xcb_screen_t *screen = NULL;
43 static xcb_window_t win = 0, comp_win = 0;
44 static xcb_window_t btn1 = 0;
45 static xcb_window_t btn2 = 0;
46 static xcb_font_t font = 0;
47 static xcb_gcontext_t gc = 0;
48 static int sw = 0, sh = 0;
49 static int fa = 0, fh = 0, fw = 0;
50 static const char *title = NULL, *str1 = NULL, *str2 = NULL;
51 static int ret = 0, sig = 0;
55 main(int argc, char **argv)
59 for (i = 1; i < argc; i++)
61 if ((!strcmp(argv[i], "-h")) ||
62 (!strcmp(argv[i], "-help")) ||
63 (!strcmp(argv[i], "--help")))
65 printf("This is an internal tool for Enlightenment.\n"
70 sig = atoi(argv[i]); // signal
72 pid = atoi(argv[i]); // E's pid
74 comp_win = atoi(argv[i]); // Composite Alert Window
77 if (!ecore_init()) return EXIT_FAILURE;
78 ecore_app_args_set(argc, (const char **)argv);
80 if (!_e_alert_connect())
82 printf("FAILED TO INIT ALERT SYSTEM!!!\n");
87 title = "Enlightenment Error";
88 str1 = "(F1) Recover";
98 /* ret == 1 => restart e => exit code 1 */
99 /* ret == 2 => exit e => any code will do that */
103 /* local functions */
105 _e_alert_connect(void)
107 conn = xcb_connect(NULL, NULL);
108 if ((!conn) || (xcb_connection_has_error(conn)))
110 printf("E_Alert_Main: Error Trying to Connect!!\n");
114 /* grab default screen */
115 screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
116 sw = screen->width_in_pixels;
117 sh = screen->height_in_pixels;
123 _e_alert_create(void)
125 uint32_t mask, mask_list[4];
128 wx = ((sw - WINDOW_WIDTH) / 2);
129 wy = ((sh - WINDOW_HEIGHT) / 2);
131 font = xcb_generate_id(conn);
132 xcb_open_font(conn, font, strlen("fixed"), "fixed");
134 /* create main window */
135 mask = (XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL |
136 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK);
137 mask_list[0] = screen->white_pixel;
138 mask_list[1] = screen->black_pixel;
140 mask_list[3] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
141 XCB_EVENT_MASK_EXPOSURE);
143 win = xcb_generate_id(conn);
144 xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root,
145 wx, wy, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
146 XCB_WINDOW_CLASS_INPUT_OUTPUT,
147 XCB_COPY_FROM_PARENT, mask, mask_list);
149 /* create button 1 */
150 mask_list[3] = (XCB_EVENT_MASK_BUTTON_PRESS |
151 XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE);
153 btn1 = xcb_generate_id(conn);
154 xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn1, win,
156 XCB_WINDOW_CLASS_INPUT_OUTPUT,
157 XCB_COPY_FROM_PARENT, mask, mask_list);
158 xcb_map_window(conn, btn1);
160 /* create button 2 */
161 btn2 = xcb_generate_id(conn);
162 xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn2, win,
164 XCB_WINDOW_CLASS_INPUT_OUTPUT,
165 XCB_COPY_FROM_PARENT, mask, mask_list);
166 xcb_map_window(conn, btn2);
168 /* create drawing gc */
169 mask = (XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT);
170 mask_list[0] = screen->black_pixel;
171 mask_list[1] = screen->white_pixel;
174 gc = xcb_generate_id(conn);
175 xcb_create_gc(conn, gc, win, mask, mask_list);
179 _e_alert_display(void)
181 xcb_char2b_t *str = NULL;
182 xcb_query_text_extents_cookie_t cookie;
183 xcb_query_text_extents_reply_t *reply;
186 str = _e_alert_build_string(title);
189 xcb_query_text_extents_unchecked(conn, font, strlen(title), str);
190 reply = xcb_query_text_extents_reply(conn, cookie, NULL);
193 fa = reply->font_ascent;
194 fh = (fa + reply->font_descent);
195 fw = reply->overall_width;
202 w = (WINDOW_WIDTH / 2) - 40;
203 _e_alert_button_move_resize(btn1, x, WINDOW_HEIGHT - 20 - (fh + 20),
206 x = ((WINDOW_WIDTH / 2) + 20);
207 _e_alert_button_move_resize(btn2, x, WINDOW_HEIGHT - 20 - (fh + 20),
212 xcb_rectangle_t rect;
215 wx = ((sw - WINDOW_WIDTH) / 2);
216 wy = ((sh - WINDOW_HEIGHT) / 2);
220 rect.width = WINDOW_WIDTH;
221 rect.height = WINDOW_HEIGHT;
223 xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET,
224 XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
225 comp_win, 0, 0, 1, &rect);
227 xcb_reparent_window(conn, win, comp_win, wx, wy);
230 /* map and raise main window */
231 xcb_map_window(conn, win);
232 _e_alert_window_raise(win);
234 /* grab pointer & keyboard */
235 xcb_grab_pointer_unchecked(conn, 0, win,
236 (XCB_EVENT_MASK_BUTTON_PRESS |
237 XCB_EVENT_MASK_BUTTON_RELEASE),
238 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
239 XCB_NONE, XCB_NONE, XCB_CURRENT_TIME);
240 xcb_grab_keyboard_unchecked(conn, 0, win, XCB_CURRENT_TIME,
241 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
242 xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT,
243 win, XCB_CURRENT_TIME);
253 _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h)
255 uint32_t list[4], mask;
259 mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
260 XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
266 xcb_configure_window(conn, btn, mask, (const uint32_t *)&list);
270 _e_alert_window_raise(xcb_window_t window)
272 uint32_t list[] = { XCB_STACK_MODE_ABOVE };
275 xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_STACK_MODE, list);
281 free(xcb_get_input_focus_reply(conn,
282 xcb_get_input_focus(conn), NULL));
286 _e_alert_shutdown(void)
288 if (!xcb_connection_has_error(conn))
290 xcb_close_font(conn, font);
291 xcb_destroy_window(conn, btn1);
292 xcb_destroy_window(conn, btn2);
293 xcb_destroy_window(conn, win);
294 if (comp_win) xcb_destroy_window(conn, comp_win);
295 xcb_free_gc(conn, gc);
296 xcb_disconnect(conn);
303 xcb_generic_event_t *event = NULL;
306 while ((event = xcb_wait_for_event(conn)))
308 switch (event->response_type & ~0x80)
310 case XCB_BUTTON_PRESS:
311 ret = _e_alert_handle_button_press(event);
314 ret = _e_alert_handle_key_press(event);
318 xcb_expose_event_t *ev;
320 ev = (xcb_expose_event_t *)event;
321 if (ev->window != win) break;
339 _e_alert_draw_outline();
340 _e_alert_draw_title_outline();
341 _e_alert_draw_title();
342 _e_alert_draw_text();
343 _e_alert_draw_button_outlines();
344 _e_alert_draw_button_text();
350 _e_alert_handle_key_press(xcb_generic_event_t *event)
352 xcb_key_press_event_t *ev;
354 ev = (xcb_key_press_event_t *)event;
355 if (ev->detail == 67) // F1
357 else if (ev->detail == 68) // F2
364 _e_alert_handle_button_press(xcb_generic_event_t *event)
366 xcb_button_press_event_t *ev;
368 ev = (xcb_button_press_event_t *)event;
369 if (ev->child == btn1)
371 else if (ev->child == btn2)
377 static xcb_char2b_t *
378 _e_alert_build_string(const char *str)
381 xcb_char2b_t *r = NULL;
383 if (!(r = malloc(strlen(str) * sizeof(xcb_char2b_t))))
386 for (i = 0; i < strlen(str); i++)
396 _e_alert_draw_outline(void)
398 xcb_rectangle_t rect;
403 rect.width = (WINDOW_WIDTH - 1);
404 rect.height = (WINDOW_HEIGHT - 1);
405 xcb_poly_rectangle(conn, win, gc, 1, &rect);
409 _e_alert_draw_title_outline(void)
411 xcb_rectangle_t rect;
416 rect.width = (WINDOW_WIDTH - 4 - 1);
417 rect.height = (fh + 4 + 2);
418 xcb_poly_rectangle(conn, win, gc, 1, &rect);
422 _e_alert_draw_title(void)
424 xcb_void_cookie_t cookie;
428 x = (2 + 2 + ((WINDOW_WIDTH - 4 - 4 - fw) / 2));
432 xcb_image_text_8(conn, strlen(title), win, gc, x, y, title);
440 { SIGILL, "SIGILL" },
441 { SIGFPE, "SIGFPE" },
442 { SIGBUS, "SIGBUS" },
443 { SIGABRT, "SIGABRT" }
447 _e_alert_draw_text(void)
449 xcb_void_cookie_t cookie;
450 char warn[1024], msg[4096], line[1024];
451 unsigned int i = 0, j = 0, k = 0;
453 snprintf(msg, sizeof(msg),
454 "This is not meant to happen and is likely a sign of \n"
455 "a bug in Enlightenment or the libraries it relies \n"
456 "on. You can gdb attach to this process (%d) now \n"
457 "to try debug it or you could exit, or just hit \n"
458 "restart to try and get your desktop back the way \n"
461 "Please compile everything with -g in your CFLAGS.", pid);
465 for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i)
466 if (signal_name[i].signal == sig)
467 snprintf(warn, sizeof(warn),
468 "This is very bad. Enlightenment %s'd.",
469 signal_name[i].name);
474 xcb_image_text_8(conn, strlen(warn), win, gc,
479 line[j++] = msg[i++];
480 if (line[j - 1] == '\n')
485 xcb_image_text_8(conn, strlen(line), win, gc,
493 _e_alert_draw_button_outlines(void)
495 xcb_rectangle_t rect;
499 rect.width = (WINDOW_WIDTH / 2) - 40 - 1;
500 rect.height = (fh + 20) - 1;
502 /* draw button outlines */
503 xcb_poly_rectangle(conn, btn1, gc, 1, &rect);
504 xcb_poly_rectangle(conn, btn2, gc, 1, &rect);
508 _e_alert_draw_button_text(void)
510 xcb_void_cookie_t dcookie;
511 xcb_char2b_t *str = NULL;
512 xcb_query_text_extents_cookie_t cookie;
513 xcb_query_text_extents_reply_t *reply;
514 int x = 0, w = 0, bw = 0;
516 bw = (WINDOW_WIDTH / 2) - 40 - 1;
518 /* draw button1 text */
519 str = _e_alert_build_string(str1);
522 xcb_query_text_extents_unchecked(conn, font, strlen(str1), str);
523 reply = xcb_query_text_extents_reply(conn, cookie, NULL);
526 w = reply->overall_width;
531 x = (5 + ((bw - w) / 2));
534 xcb_image_text_8(conn, strlen(str1), btn1, gc, x, (10 + fa), str1);
536 /* draw button2 text */
537 str = _e_alert_build_string(str2);
540 xcb_query_text_extents_unchecked(conn, font, strlen(str2), str);
541 reply = xcb_query_text_extents_reply(conn, cookie, NULL);
544 w = reply->overall_width;
549 x = (5 + ((bw - w) / 2));
552 xcb_image_text_8(conn, strlen(str2), btn2, gc, x, (10 + fa), str2);