X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fsighandler.c;h=4a0c13b5aa1a396f40fa5f29af9c7ff820652aa8;hb=622b94f176c3a6959c13ca2162be673c7b8028c4;hp=4b5fb103f41526d2bb07c29ee139ceda8d06edd5;hpb=5b6ef3e665eacec38dcbcde93c83090864477eb7;p=i3%2Fi3 diff --git a/src/sighandler.c b/src/sighandler.c index 4b5fb103..4a0c13b5 100644 --- a/src/sighandler.c +++ b/src/sighandler.c @@ -2,37 +2,23 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * - * © 2009-2010 Michael Stapelberg and contributors + * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) * © 2009-2010 Jan-Erik Rediger * - * See file LICENSE for license information. - * - * sighandler.c: contains all functions for signal handling + * sighandler.c: Interactive crash dialog upon SIGSEGV/SIGABRT/SIGFPE (offers + * to restart inplace). * */ +#include "all.h" + #include -#include -#include -#include -#include #include #include -#include -#include #include -#include #include -#include "i3.h" -#include "util.h" -#include "xcb.h" -#include "log.h" -#include "config.h" -#include "randr.h" - static xcb_gcontext_t pixmap_gc; static xcb_pixmap_t pixmap; static int raised_signal; @@ -55,21 +41,17 @@ static int sig_draw_window(xcb_window_t win, int width, int height, int font_hei /* re-draw the background */ xcb_rectangle_t border = { 0, 0, width, height}, inner = { 2, 2, width - 4, height - 4}; - xcb_change_gc_single(conn, pixmap_gc, XCB_GC_FOREGROUND, get_colorpixel("#FF0000")); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") }); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border); - xcb_change_gc_single(conn, pixmap_gc, XCB_GC_FOREGROUND, get_colorpixel("#000000")); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") }); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner); /* restore font color */ - xcb_change_gc_single(conn, pixmap_gc, XCB_GC_FOREGROUND, get_colorpixel("#FFFFFF")); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); for (int i = 0; i < sizeof(crash_text) / sizeof(char*); i++) { - int text_len = strlen(crash_text[i]); - char *full_text = convert_utf8_to_ucs2(crash_text[i], &text_len); - xcb_image_text_16(conn, text_len, pixmap, pixmap_gc, 8 /* X */, - 3 + (i + 1) * font_height /* Y = baseline of font */, - (xcb_char2b_t*)full_text); - free(full_text); + draw_text(crash_text[i], strlen(crash_text[i]), false, pixmap, pixmap_gc, + 8, 5 + i * font_height, width - 16); } /* Copy the contents of the pixmap to the real window */ @@ -159,22 +141,14 @@ void handle_signal(int sig, siginfo_t *info, void *data) { sigaction(sig, &action, NULL); raised_signal = sig; - /* setup event handler for key presses */ - xcb_event_handlers_t sig_evenths; - memset(&sig_evenths, 0, sizeof(xcb_event_handlers_t)); - xcb_event_handlers_init(conn, &sig_evenths); - xcb_event_set_key_press_handler(&sig_evenths, sig_handle_key_press, NULL); - - i3Font *font = load_font(conn, config.font); - /* width and height of the popup window, so that the text fits in */ int crash_text_num = sizeof(crash_text) / sizeof(char*); - int height = 13 + (crash_text_num * font->height); + int height = 13 + (crash_text_num * config.font.height); /* calculate width for longest text */ - int text_len = strlen(crash_text[crash_text_longest]); - char *longest_text = convert_utf8_to_ucs2(crash_text[crash_text_longest], &text_len); - int font_width = predict_text_width(conn, config.font, longest_text, text_len); + size_t text_len = strlen(crash_text[crash_text_longest]); + xcb_char2b_t *longest_text = convert_utf8_to_ucs2(crash_text[crash_text_longest], &text_len); + int font_width = predict_text_width((char *)longest_text, text_len, true); int width = font_width + 20; /* Open a popup window on each virtual screen */ @@ -191,9 +165,6 @@ void handle_signal(int sig, siginfo_t *info, void *data) { xcb_create_pixmap(conn, root_depth, pixmap, win, width, height); xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); - /* Create graphics context */ - xcb_change_gc_single(conn, pixmap_gc, XCB_GC_FONT, font->id); - /* Grab the keyboard to get all input */ xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); @@ -201,11 +172,20 @@ void handle_signal(int sig, siginfo_t *info, void *data) { xcb_grab_pointer(conn, false, win, XCB_NONE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, win, XCB_NONE, XCB_CURRENT_TIME); - sig_draw_window(win, width, height, font->height); + sig_draw_window(win, width, height, config.font.height); xcb_flush(conn); } - xcb_event_wait_for_event_loop(&sig_evenths); + xcb_generic_event_t *event; + /* Yay, more own eventhandlers… */ + while ((event = xcb_wait_for_event(conn))) { + /* Strip off the highest bit (set if the event is generated) */ + int type = (event->response_type & 0x7F); + if (type == XCB_KEY_PRESS) { + sig_handle_key_press(NULL, conn, (xcb_key_press_event_t*)event); + } + free(event); + } } /* @@ -219,8 +199,11 @@ void setup_signal_handler() { action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO; sigemptyset(&action.sa_mask); - if (sigaction(SIGSEGV, &action, NULL) == -1 || + /* Catch all signals with default action "Core", see signal(7) */ + if (sigaction(SIGQUIT, &action, NULL) == -1 || + sigaction(SIGILL, &action, NULL) == -1 || sigaction(SIGABRT, &action, NULL) == -1 || - sigaction(SIGFPE, &action, NULL) == -1) + sigaction(SIGFPE, &action, NULL) == -1 || + sigaction(SIGSEGV, &action, NULL) == -1) ELOG("Could not setup signal handler"); }