From fed69a7380a28aef8f00509c55ad35e477af13ca Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 27 Sep 2019 07:13:24 +0100 Subject: [PATCH] alert - move to using full efl stack for it still have a problem - cant work in wl drm/kms mode because e still holds the ownership/lock on the console, but using full efl to draw the alert and even blink it... this drops xcb requirement too. --- README | 3 - TODO | 9 +- src/bin/e_alert_main.c | 1303 ++++++---------------------------------- src/bin/meson.build | 11 +- 4 files changed, 204 insertions(+), 1122 deletions(-) diff --git a/README b/README index 7b71c018e..517e2c705 100644 --- a/README +++ b/README @@ -8,9 +8,6 @@ Requirements Must: * efl - * xcb - * xcb-shape - * xcb-keysyms * libpam (On Linux) Highly suggested: diff --git a/TODO b/TODO index 627398b40..dfa52b873 100644 --- a/TODO +++ b/TODO @@ -90,13 +90,8 @@ TODO: logging like tables, icons, timelines and graphs that can be output in text emulation and to screen - change eina log to go into here with eina_log_print_cb_set() ) -* crash alert: use full fat efl stack and remove xcb/ecore_drm2 stuff - * supply custom theme to guarantee theme is not an issue - * create text mode fallback with detection for crashes in crash handler - * turtles all the way down - a crash handler for our crash handler - * problem: we have to kill e to get kms control which breaks gdb - * grab data then kill e then display results? - * key combination to kill e and move on? +* crash alert: we have to kill e to get kms control which breaks gdb + * grab data then kill e then display results? * watchdog: add watchdog handling to e_start to detect a hung e * also detect if frames stop rendering but loop ok? * settings: config dialog redo and simplification diff --git a/src/bin/e_alert_main.c b/src/bin/e_alert_main.c index d30101e51..eaf7586ee 100644 --- a/src/bin/e_alert_main.c +++ b/src/bin/e_alert_main.c @@ -1,526 +1,217 @@ #include "config.h" -#ifdef HAVE_WL_DRM -# define EFL_BETA_API_SUPPORT -#endif +//# include "e_drm2.x" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #ifndef HAVE_WAYLAND_ONLY -#include -#include -#include -#include -#endif -#ifdef HAVE_WL_DRM -# include -# include -# include -# include -# include "e_drm2.x" +# include #endif -#ifdef HAVE_WL_DRM - -/* DRM_FORMAT_XRGB8888 and fourcc_code borrowed from - * - * Copyright 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -# define fourcc_code(a, b, c, d) \ - ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ - ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) -# define DRM_FORMAT_XRGB8888 \ - fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ -#endif - -#define WINDOW_WIDTH 320 -#define WINDOW_HEIGHT 240 - -#ifndef HAVE_WAYLAND_ONLY -#ifndef XCB_ATOM_NONE -# define XCB_ATOM_NONE 0 -#endif - -/* local function prototypes */ -static int _e_alert_connect(void); -static void _e_alert_create(void); -static void _e_alert_display(void); -static void _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h); -static void _e_alert_window_raise(xcb_window_t win); -static void _e_alert_sync(void); -static void _e_alert_shutdown(void); -static void _e_alert_run(void); -static void _e_alert_draw(void); -static int _e_alert_handle_key_press(xcb_generic_event_t *event); -static int _e_alert_handle_button_press(xcb_generic_event_t *event); -static xcb_char2b_t *_e_alert_build_string(const char *str); -static void _e_alert_draw_outline(void); -static void _e_alert_draw_title_outline(void); -static void _e_alert_draw_title(void); -static void _e_alert_draw_text(void); -static void _e_alert_draw_button_outlines(void); -static void _e_alert_draw_button_text(void); - -/* local variables */ -static xcb_connection_t *conn = NULL; -static xcb_screen_t *screen = NULL; -static xcb_window_t win = 0, comp_win = 0; -static xcb_window_t btn1 = 0; -static xcb_window_t btn2 = 0; -static xcb_font_t font = 0; -static xcb_gcontext_t gc = 0; -static int fa = 0, fw = 0; -#endif -static int sw = 0, sh = 0; -static int fh = 0; -static const char *title = NULL, *str1 = NULL, *str2 = NULL; -static int ret = 0, sig = 0; -static pid_t pid; -static Eina_Bool tainted = EINA_TRUE; +static int ret = 0, sig = 0, exit_gdb = 0; +static pid_t pid; +static Eina_Bool tainted = EINA_FALSE; static const char *backtrace_str = NULL; -static int exit_gdb = 0; -struct +#define FONT "Mono" +#define COL_BG 0, 0, 0, 255 +#define COL_FG 255, 0, 0, 255 +#define HDIV 10 +#define PDIV 20 +#define BLINK 0.8 +#define RECOVER_BUTTON 1 +#define RECOVER_KEY "F1" +#define ABORT_BUTTON 3 +#define ABORT_KEY "F12" + +static inline const char *title1(void) { + return "Software Failure. Press left mouse button / F1 to recover, right mouse button / F12 to abort."; +} +static inline const char *title2(void) { static char buf[512]; + if (tainted) snprintf + (buf, sizeof(buf), "Tainted by unsupported modules"); + else if (exit_gdb) snprintf + (buf, sizeof(buf), "Couldn't run gdb to collect a backtrace"); + else if (backtrace_str) snprintf + (buf, sizeof(buf), "Backtrace log: %s", backtrace_str); + else snprintf + (buf, sizeof(buf), " "); + return buf; +} +static inline const char *title3(void) { static char buf[512]; + snprintf(buf, sizeof(buf), "Guru Meditation #%08d.%08d", pid, sig); + return buf; +} + +///////////////////////////////////////////////////////////////////////////// + +static Evas_Object *obj_base = NULL; +static Evas_Object *obj_outer = NULL; +static Evas_Object *obj_inner = NULL; +static Evas_Object *obj_line1 = NULL; +static Evas_Object *obj_line2 = NULL; +static Evas_Object *obj_line3 = NULL; + +static void +mouse_up(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *info) { - int signal; - const char *name; -} signal_name[5] = { - { SIGSEGV, "SEGV" }, - { SIGILL, "SIGILL" }, - { SIGFPE, "SIGFPE" }, - { SIGBUS, "SIGBUS" }, - { SIGABRT, "SIGABRT" } -}; + Evas_Event_Mouse_Up *ev = info; -# ifdef HAVE_WL_DRM -static Evas *canvas = NULL; - -static Eina_Bool -_e_alert_drm_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Event_Key *ev; - - ev = event; - if (!strcmp(ev->key, "F12")) - { - ret = 1; - ecore_main_loop_quit(); - } - else if (!strcmp(ev->key, "F1")) + if (ev->button == RECOVER_BUTTON) { ret = 2; - ecore_main_loop_quit(); + elm_exit(); } - - return ECORE_CALLBACK_RENEW; -} - -static void -_e_alert_drm_draw_outline(void) -{ - Evas_Object *o; - int wx = 0, wy = 0; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - /* create background */ - o = evas_object_rectangle_add(canvas); - evas_object_move(o, wx, wy); - evas_object_resize(o, WINDOW_WIDTH, WINDOW_HEIGHT); - evas_object_show(o); - - /* create outline */ - o = evas_object_rectangle_add(canvas); - evas_object_color_set(o, 0, 0, 0, 255); - evas_object_move(o, wx, wy); - evas_object_resize(o, WINDOW_WIDTH, WINDOW_HEIGHT); - evas_object_show(o); - - /* create white inside */ - o = evas_object_rectangle_add(canvas); - evas_object_move(o, wx + 1, wy + 1); - evas_object_resize(o, WINDOW_WIDTH - 2, WINDOW_HEIGHT - 2); - evas_object_show(o); -} - -static void -_e_alert_drm_draw_title_outline(void) -{ - Evas_Object *o; - int wx = 0, wy = 0; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - /* create title outline */ - o = evas_object_rectangle_add(canvas); - evas_object_color_set(o, 0, 0, 0, 255); - evas_object_move(o, wx + 2, wy + 2); - evas_object_resize(o, WINDOW_WIDTH - 4, 20); - evas_object_show(o); - - /* create white inside */ - o = evas_object_rectangle_add(canvas); - evas_object_move(o, wx + 3, wy + 3); - evas_object_resize(o, WINDOW_WIDTH - 6, 18); - evas_object_show(o); -} - -static void -_e_alert_drm_draw_title(void) -{ - Evas_Object *o; - Evas_Textblock_Style *style; - int wx = 0, wy = 0; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - style = evas_textblock_style_new(); - evas_textblock_style_set(style, - "DEFAULT='font=Fixed font_size=8 color=#000000'" - "newline='br' align=center valign=center"); - - title = "Enlightenment Error"; - - o = evas_object_textblock_add(canvas); - evas_object_textblock_style_set(o, style); - evas_object_textblock_text_markup_set(o, title); - evas_object_color_set(o, 0, 0, 0, 255); - evas_object_move(o, wx + 4, wy + 4); - evas_object_resize(o, WINDOW_WIDTH - 8, 18); - evas_object_show(o); - - evas_textblock_style_free(style); -} - -static void -_e_alert_drm_draw_text(void) -{ - Evas_Object *o; - Evas_Textblock_Style *style; - char warn[4096], msg[4096]; - unsigned int i = 0; - int wx = 0, wy = 0; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - strcpy(warn, ""); - - for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i) - if (signal_name[i].signal == sig) - snprintf(warn, sizeof(warn), - "This is very bad. Enlightenment %s'd.

", - signal_name[i].name); - - if (!tainted) + else if (ev->button == ABORT_BUTTON) { - if (exit_gdb) + ret = 1; + elm_exit(); + } +} + +static void +key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *info) +{ + Evas_Event_Key_Down *ev = info; + + if (!strcmp(ev->key, RECOVER_KEY)) + { + ret = 2; + elm_exit(); + } + else if (!strcmp(ev->key, ABORT_KEY)) + { + ret = 1; + elm_exit(); + } +} + +static void +resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o, void *info EINA_UNUSED) +{ + Evas_Coord w, h, tw, th; + + evas_object_geometry_get(o, NULL, NULL, &w, &h); + h = w / HDIV; + + evas_object_geometry_set(obj_base, 0, 0, w, h * HDIV * 2); + evas_object_geometry_set(obj_outer, (1 * h) / PDIV, (1 * h) / PDIV, + w - ((h * 2) / PDIV), h - ((h * 2) / PDIV)); + evas_object_geometry_set(obj_inner, (2 * h) / PDIV, (2 * h) / PDIV, + w - ((h * 4) / PDIV), h - ((h * 4) / PDIV)); + + evas_object_text_font_set(obj_line1, FONT, h / 8); + evas_object_geometry_get(obj_line1, NULL, NULL, &tw, &th); + evas_object_move(obj_line1, (w - tw) / 2, (3 * h) / PDIV); + + evas_object_text_font_set(obj_line2, FONT, h / 8); + evas_object_geometry_get(obj_line2, NULL, NULL, &tw, &th); + evas_object_move(obj_line2, (w - tw) / 2, (h - th) / 2); + + evas_object_text_font_set(obj_line3, FONT, h / 8); + evas_object_geometry_get(obj_line3, NULL, NULL, &tw, &th); + evas_object_move(obj_line3, (w - tw) / 2, h - th - (3 * h) / PDIV); +} + +static Eina_Bool +timer(void *data EINA_UNUSED) +{ + if (evas_object_visible_get(obj_outer)) evas_object_hide(obj_outer); + else evas_object_show(obj_outer); + return EINA_TRUE; +} + +static Eina_Bool +setup_display(void) +{ + Evas *e; + Evas_Object *win, *o; + + win = o = elm_win_add(NULL, "e-alert", ELM_WIN_SPLASH); + if (!win) return EINA_FALSE; + e = evas_object_evas_get(win); + elm_win_override_set(o, EINA_TRUE); + + obj_base = o = evas_object_rectangle_add(e); + evas_object_color_set(o, COL_BG); + evas_object_show(o); + + obj_outer = o = evas_object_rectangle_add(e); + evas_object_color_set(o, COL_FG); + evas_object_pass_events_set(o, EINA_TRUE); + evas_object_show(o); + + obj_inner = o = evas_object_rectangle_add(e); + evas_object_color_set(o, COL_BG); + evas_object_pass_events_set(o, EINA_TRUE); + evas_object_show(o); + + obj_line1 = o = evas_object_text_add(e); + evas_object_color_set(o, COL_FG); + evas_object_text_font_set(o, FONT, 10); + evas_object_text_text_set(o, title1()); + evas_object_pass_events_set(o, EINA_TRUE); + evas_object_show(o); + + obj_line2 = o = evas_object_text_add(e); + evas_object_color_set(o, COL_FG); + evas_object_text_font_set(o, FONT, 10); + evas_object_text_text_set(o, title2()); + evas_object_pass_events_set(o, EINA_TRUE); + evas_object_show(o); + + obj_line3 = o = evas_object_text_add(e); + evas_object_color_set(o, COL_FG); + evas_object_text_font_set(o, FONT, 10); + evas_object_text_text_set(o, title3()); + evas_object_pass_events_set(o, EINA_TRUE); + evas_object_show(o); + + evas_object_event_callback_add(obj_base, EVAS_CALLBACK_MOUSE_UP, mouse_up, NULL); + evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN, key_down, NULL); + evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, resize, NULL); + + ecore_timer_add(BLINK, timer, NULL); + + resize(NULL, e, win, NULL); + +#ifndef HAVE_WAYLAND_ONLY + if (getenv("DISPLAY")) + { + Ecore_X_Window root = ecore_x_window_root_first_get(); + Ecore_X_Atom atom_composite_win = ecore_x_atom_get("_E_COMP_WINDOW"); + unsigned int id; + if (ecore_x_window_prop_card32_get(root, atom_composite_win, &id, 1) > 0) { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely a sign of
" - "a bug in Enlightenment or the libraries it relies
" - "on. We were not able to generate a backtrace, check
" - "if your 'sysactions.conf' has an 'gdb' action line.
" - "
" - "Please compile latest Git E and EFL with
" - "-g and -ggdb3 in your CFLAGS.
"); - } - else if (backtrace_str) - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely a sign of
" - "a bug in Enlightenment or the libraries it relies
" - "on. You will find an backtrace of E (%d) in :
" - "'%s'
" - "Before reporting issue, compile latest E and EFL
" - "from Git with '-g -ggdb3' in your CFLAGS.
" - "You can then report this crash on :
" - "https://phab.enlightenment.org/maniphest/.
", - pid, backtrace_str); - } - else - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely a sign of
" - "a bug in Enlightenment or the libraries it relies
" - "on. You can gdb attach to this process (%d) now
" - "to try debug it or you could logout, or just hit
" - "recover to try and get your desktop back the way
" - "it was.
" - "
" - "Please compile latest Git E and EFL with
" - "-g and -ggdb3 in your CFLAGS.
", pid); + Ecore_X_Window elmwin = elm_win_xwindow_get(win); + ecore_x_window_reparent(elmwin, id, 0, 0); + Ecore_X_Randr_Output output = ecore_x_randr_primary_output_get(root); + Ecore_X_Randr_Crtc crct = ecore_x_randr_output_crtc_get(root, output); + int x = 0, y = 0, w = 1, h = 1; + ecore_x_randr_crtc_geometry_get(root, crct, &x, &y, &w, &h); + ecore_x_window_move_resize(elmwin, x, y, w, w / HDIV); } } - else - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely
" - "a sign of a bug, but you are using
" - "unsupported modules; before reporting this
" - "issue, please unload them and try to
" - "see if the bug is still there.
" - "Also update to latest Git
" - "and be sure to compile E and EFL with
" - "-g and -ggdb3 in your CFLAGS"); - } - - style = evas_textblock_style_new(); - evas_textblock_style_set(style, - "DEFAULT='font=Fixed font_size=8 color=#000000'" - "newline='br' align=center valign=center wrap=word"); - - strcat(warn, msg); - - o = evas_object_textblock_add(canvas); - evas_object_textblock_style_set(o, style); - evas_object_textblock_text_markup_set(o, warn); - evas_object_color_set(o, 0, 0, 0, 255); - evas_object_move(o, wx + 4, wy + 28); - evas_object_resize(o, WINDOW_WIDTH - 4, WINDOW_HEIGHT - 30); - evas_object_show(o); - - evas_textblock_style_free(style); -} - -static void -_e_alert_drm_draw_button_outlines(void) -{ - Evas_Object *o; - int wx = 0, wy = 0; - int x = 0, w = 0; - int tx, ty, tw, th; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - x = wx + 20; - w = (WINDOW_WIDTH / 2) - 40; - - o = evas_object_rectangle_add(canvas); - evas_object_color_set(o, 0, 255, 0, 255); - evas_object_move(o, x, wy + WINDOW_HEIGHT - 20 - (fh + 20)); - evas_object_resize(o, w, (fh + 20)); - evas_object_show(o); - - evas_object_geometry_get(o, &tx, &ty, &tw, &th); - - o = evas_object_text_add(canvas); - evas_object_text_font_set(o, "Fixed", 8); - evas_object_text_text_set(o, str1); - evas_object_color_set(o, 0, 0, 0, 255); - evas_object_move(o, tx, ty); - evas_object_resize(o, tw, th); - evas_object_show(o); - - x = wx + ((WINDOW_WIDTH / 2) + 20); - o = evas_object_rectangle_add(canvas); - evas_object_color_set(o, 255, 0, 0, 255); - evas_object_move(o, x, wy + WINDOW_HEIGHT - 20 - (fh + 20)); - evas_object_resize(o, w, (fh + 20)); - evas_object_show(o); - - evas_object_geometry_get(o, &tx, &ty, &tw, &th); - - o = evas_object_text_add(canvas); - evas_object_text_font_set(o, "Fixed", 8); - evas_object_text_text_set(o, str2); - evas_object_color_set(o, 0, 0, 0, 255); - evas_object_move(o, tx, ty); - evas_object_resize(o, tw, th); - evas_object_show(o); -} - -static void -_e_alert_drm_run(void) -{ - printf("E_Alert Drm Run\n"); - ecore_main_loop_begin(); -} - -static Ecore_Drm2_Device *dev = NULL; -static Ecore_Drm2_Fb *buffer = NULL; -static Ecore_Drm2_Output *output = NULL; - -static int -_e_alert_drm_connect(void) -{ - fprintf(stderr, "E_Alert Drm Connect\n"); - - if (!evas_init()) - { - printf("\tCannot init evas\n"); - return 0; - } - - if (!e_drm2_compat_init() || !ecore_drm2_init()) - { - printf("\tCannot init ecore_drm\n"); - return 0; - } - - dev = e_drm2_device_open("seat0", 0); - if (!dev) - { - printf("\tCannot find drm device\n"); - return 0; - } - - - if (!ecore_drm2_outputs_create(dev)) - { - printf("\tCannot create drm outputs\n"); - return 0; - } - - output = ecore_drm2_output_find(dev, 0, 0); - if (output) e_drm2_output_info_get(output, NULL, NULL, &sw, &sh, NULL); - fprintf(stderr, "\tOutput Size: %d %d\n", sw, sh); - // force symbol usage to get rid of warnings for release. - // i think we'll replace all the x and drm2 stuff in e_alert with normal - // full fat efl stuff. it'll reduce duplication and simplify this - // e_alert stuff a lot with the downside of a broken efl breaking - // e_alert, but then a broken efl will affect it already. i'll look into - // a text mode fallback - so a crash handler for the crash handler... :) - // turtles all the way down. - e_drm2_output_rotation_set(output, e_drm2_output_rotation_get(output)); - - ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, - _e_alert_drm_cb_key_down, NULL); - - return 1; -} - -static void -_e_alert_drm_create(void) -{ - Evas_Engine_Info_Buffer *einfo; - int method = 0; - - fprintf(stderr, "E_Alert Drm Create\n"); - - fh = 13; - - buffer = e_drm2_fb_create(dev, sw, sh, 24, 32, DRM_FORMAT_XRGB8888); - - method = evas_render_method_lookup("buffer"); - if (method <= 0) - { - fprintf(stderr, "\tCould not get evas render method\n"); - return; - } - - canvas = evas_new(); - if (!canvas) - { - fprintf(stderr, "\tFailed to create new canvas\n"); - return; - } - - evas_output_method_set(canvas, method); - evas_output_size_set(canvas, sw, sh); - evas_output_viewport_set(canvas, 0, 0, sw, sh); - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas); - if (!einfo) - { - printf("\tFailed to get evas engine info\n"); - evas_free(canvas); - return; - } - - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - einfo->info.dest_buffer = ecore_drm2_fb_data_get(buffer); - einfo->info.dest_buffer_row_bytes = (sw * sizeof(int)); - einfo->info.use_color_key = 0; - einfo->info.alpha_threshold = 0; - einfo->info.func.new_update_region = NULL; - einfo->info.func.free_update_region = NULL; - evas_engine_info_set(canvas, (Evas_Engine_Info *)einfo); - - _e_alert_drm_draw_outline(); - _e_alert_drm_draw_title_outline(); - _e_alert_drm_draw_title(); - _e_alert_drm_draw_text(); - _e_alert_drm_draw_button_outlines(); -} - -static void -_e_alert_drm_display(void) -{ - Eina_List *updates; - - printf("E_Alert Drm Display\n"); - - updates = evas_render_updates(canvas); - evas_render_updates_free(updates); - - ecore_drm2_fb_flip(buffer, output); -} - -static void -_e_alert_drm_shutdown(void) -{ - printf("E_Alert Drm Shutdown\n"); - - evas_free(canvas); - - if (dev) - { - ecore_drm2_outputs_destroy(dev); - e_drm2_device_close(dev); - } - - ecore_drm2_shutdown(); - evas_shutdown(); - e_drm2_compat_shutdown(); -} - #endif + evas_object_show(win); + +#ifndef HAVE_WAYLAND_ONLY + if (getenv("DISPLAY")) + { + Ecore_X_Window elmwin = elm_win_xwindow_get(win); + ecore_x_pointer_grab(elmwin); + ecore_x_keyboard_grab(elmwin); + } +#endif + return EINA_TRUE; +} + int main(int argc, char **argv) { - const char *tmp; + const char *s; int i = 0; -/* XCB is not available when running in wayland only mode. No need to start anything here */ -/* #ifdef HAVE_WAYLAND_ONLY */ -/* printf("E Alert is not suitable to be used with E in wayland only mode\n"); */ -/* exit(0); */ -/* #endif */ - for (i = 1; i < argc; i++) { if ((!strcmp(argv[i], "-h")) || @@ -531,617 +222,21 @@ main(int argc, char **argv) "do not use it.\n"); exit(0); } - else if (i == 1) - sig = atoi(argv[i]); // signal - else if (i == 2) - pid = atoi(argv[i]); // E's pid - else if (i == 3) - exit_gdb = atoi(argv[i]); - else if (i == 4) - backtrace_str = argv[i]; + else if (i == 1) sig = atoi(argv[i]); // signal + else if (i == 2) pid = atoi(argv[i]); // E's pid + else if (i == 3) exit_gdb = atoi(argv[i]); + else if (i == 4) backtrace_str = argv[i]; } fprintf(stderr, "exit_gdb: %i\n", exit_gdb); - tmp = getenv("E_TAINTED"); - if (tmp && !strcmp(tmp, "NO")) - tainted = EINA_FALSE; + s = getenv("E_TAINTED"); + if (s && !strcmp(s, "NO")) tainted = EINA_FALSE; + else if (s && !strcmp(s, "YES")) tainted = EINA_TRUE; ecore_app_no_system_modules(); - if (!ecore_init()) return EXIT_FAILURE; - ecore_app_args_set(argc, (const char **)argv); + elm_init(argc, argv); + if (setup_display()) elm_run(); - title = "Enlightenment Error"; - str1 = "(F1) Recover"; - str2 = "(F12) Logout"; - -#ifdef HAVE_WL_DRM - if (!getenv("DISPLAY")) - { - if (!_e_alert_drm_connect()) - { - printf("FAILED TO INIT ALERT SYSTEM!!!\n"); - ecore_shutdown(); - return EXIT_FAILURE; - } - _e_alert_drm_create(); - _e_alert_drm_display(); - _e_alert_drm_run(); - _e_alert_drm_shutdown(); - } -#endif -#if defined(HAVE_WL_DRM) && !defined(HAVE_WAYLAND_ONLY) - else -#endif -#ifndef HAVE_WAYLAND_ONLY - { - if (!_e_alert_connect()) - { - printf("FAILED TO INIT ALERT SYSTEM!!!\n"); - ecore_shutdown(); - return EXIT_FAILURE; - } - _e_alert_create(); - _e_alert_display(); - _e_alert_run(); - _e_alert_shutdown(); - } -#endif - ecore_shutdown(); - - /* ret == 1 => exit e => exit code 1 */ - /* ret == 2 => restart e => any code will do that */ return ret; } -#ifndef HAVE_WAYLAND_ONLY -/* local functions */ -static int -_e_alert_connect(void) -{ - conn = xcb_connect(NULL, NULL); - if ((!conn) || (xcb_connection_has_error(conn))) - { - printf("E_Alert_Main: Error Trying to Connect!!\n"); - return 0; - } - - /* grab default screen */ - screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; - sw = screen->width_in_pixels; - sh = screen->height_in_pixels; - - return 1; -} - -static void -_e_alert_create(void) -{ - uint32_t mask, mask_list[4]; - int wx = 0, wy = 0; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - font = xcb_generate_id(conn); - xcb_open_font(conn, font, strlen("fixed"), "fixed"); - - /* create main window */ - mask = (XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | - XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK); - mask_list[0] = screen->white_pixel; - mask_list[1] = screen->black_pixel; - mask_list[2] = 1; - mask_list[3] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_EXPOSURE); - - win = xcb_generate_id(conn); - xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root, - wx, wy, WINDOW_WIDTH, WINDOW_HEIGHT, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - XCB_COPY_FROM_PARENT, mask, mask_list); - - /* create button 1 */ - mask_list[3] = (XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE); - - btn1 = xcb_generate_id(conn); - xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn1, win, - -100, -100, 1, 1, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - XCB_COPY_FROM_PARENT, mask, mask_list); - xcb_map_window(conn, btn1); - - /* create button 2 */ - btn2 = xcb_generate_id(conn); - xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn2, win, - -100, -100, 1, 1, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - XCB_COPY_FROM_PARENT, mask, mask_list); - xcb_map_window(conn, btn2); - - /* create drawing gc */ - mask = (XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT); - mask_list[0] = screen->black_pixel; - mask_list[1] = screen->white_pixel; - mask_list[2] = font; - - gc = xcb_generate_id(conn); - xcb_create_gc(conn, gc, win, mask, mask_list); -} - -static int -_e_alert_atom_get(const char *name) -{ - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t *reply; - int a; - - cookie = xcb_intern_atom_unchecked(conn, 0, strlen(name), name); - reply = xcb_intern_atom_reply(conn, cookie, NULL); - if (!reply) return XCB_ATOM_NONE; - a = reply->atom; - free(reply); - return a; -} - -static xcb_window_t -_e_alert_comp_win_get(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - uint32_t *v; - int atom_cardinal, atom_composite_win; - xcb_window_t r = 0; - - atom_cardinal = _e_alert_atom_get("CARDINAL"); - atom_composite_win = _e_alert_atom_get("_E_COMP_WINDOW"); - - cookie = xcb_get_property_unchecked(conn, 0, screen->root, atom_composite_win, - atom_cardinal, 0, 0x7fffffff); - reply = xcb_get_property_reply(conn, cookie, NULL); - if (!reply) return 0; - - v = xcb_get_property_value(reply); - if (v) r = v[0]; - - free(reply); - return r; -} - -static Eina_Bool -_e_alert_root_tainted_get(void) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - uint32_t *v; - int atom_cardinal, atom_tainted; - int r = 0; - - atom_cardinal = _e_alert_atom_get("CARDINAL"); - atom_tainted = _e_alert_atom_get("_E_TAINTED"); - - cookie = xcb_get_property_unchecked(conn, 0, screen->root, atom_tainted, - atom_cardinal, 0, 0x7fffffff); - reply = xcb_get_property_reply(conn, cookie, NULL); - if (!reply) return EINA_TRUE; - - v = xcb_get_property_value(reply); - if (v) r = v[0]; - - free(reply); - return !!r; -} - -static void -_e_alert_display(void) -{ - xcb_char2b_t *str = NULL; - xcb_query_text_extents_cookie_t cookie; - xcb_query_text_extents_reply_t *reply; - int x = 0, w = 0; - - tainted = _e_alert_root_tainted_get(); - - str = _e_alert_build_string(title); - - cookie = - xcb_query_text_extents_unchecked(conn, font, strlen(title), str); - reply = xcb_query_text_extents_reply(conn, cookie, NULL); - if (reply) - { - fa = reply->font_ascent; - fh = (fa + reply->font_descent); - fw = reply->overall_width; - free(reply); - } - free(str); - - /* move buttons */ - x = 20; - w = (WINDOW_WIDTH / 2) - 40; - _e_alert_button_move_resize(btn1, x, WINDOW_HEIGHT - 20 - (fh + 20), - w, (fh + 20)); - - x = ((WINDOW_WIDTH / 2) + 20); - _e_alert_button_move_resize(btn2, x, WINDOW_HEIGHT - 20 - (fh + 20), - w, (fh + 20)); - - comp_win = _e_alert_comp_win_get(); - if (comp_win) - { - xcb_rectangle_t rect; - int wx = 0, wy = 0; - - wx = ((sw - WINDOW_WIDTH) / 2); - wy = ((sh - WINDOW_HEIGHT) / 2); - - rect.x = wx; - rect.y = wy; - rect.width = WINDOW_WIDTH; - rect.height = WINDOW_HEIGHT; - - xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - comp_win, 0, 0, 1, &rect); - - xcb_reparent_window(conn, win, comp_win, wx, wy); - } - - /* map and raise main window */ - xcb_map_window(conn, win); - _e_alert_window_raise(win); - - /* grab pointer & keyboard */ - xcb_grab_pointer_unchecked(conn, 0, win, - (XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE), - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, - XCB_NONE, XCB_NONE, XCB_CURRENT_TIME); - xcb_grab_keyboard_unchecked(conn, 0, win, XCB_CURRENT_TIME, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, - win, XCB_CURRENT_TIME); - - /* flush screen */ - xcb_flush(conn); - - /* sync */ - _e_alert_sync(); -} - -static void -_e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h) -{ - uint32_t list[4], mask; - - if (!btn) return; - - mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); - list[0] = x; - list[1] = y; - list[2] = w; - list[3] = h; - - xcb_configure_window(conn, btn, mask, (const uint32_t *)&list); -} - -static void -_e_alert_window_raise(xcb_window_t window) -{ - uint32_t list[] = { XCB_STACK_MODE_ABOVE }; - - if (!window) return; - xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_STACK_MODE, list); -} - -static void -_e_alert_sync(void) -{ - free(xcb_get_input_focus_reply(conn, - xcb_get_input_focus(conn), NULL)); -} - -static void -_e_alert_shutdown(void) -{ - if (!xcb_connection_has_error(conn)) - { - xcb_close_font(conn, font); - xcb_destroy_window(conn, btn1); - xcb_destroy_window(conn, btn2); - xcb_destroy_window(conn, win); - if (comp_win) xcb_destroy_window(conn, comp_win); - xcb_free_gc(conn, gc); - xcb_disconnect(conn); - } -} - -static void -_e_alert_run(void) -{ - xcb_generic_event_t *event = NULL; - - xcb_flush(conn); - while ((event = xcb_wait_for_event(conn))) - { - switch (event->response_type & ~0x80) - { - case XCB_BUTTON_PRESS: - ret = _e_alert_handle_button_press(event); - break; - - case XCB_KEY_PRESS: - ret = _e_alert_handle_key_press(event); - break; - - case XCB_EXPOSE: - { - xcb_expose_event_t *ev; - - ev = (xcb_expose_event_t *)event; - if (ev->window != win) break; - - _e_alert_draw(); - _e_alert_sync(); - - break; - } - - default: - break; - } - free(event); - if (ret > 0) return; - } -} - -static void -_e_alert_draw(void) -{ - _e_alert_draw_outline(); - _e_alert_draw_title_outline(); - _e_alert_draw_title(); - _e_alert_draw_text(); - _e_alert_draw_button_outlines(); - _e_alert_draw_button_text(); - - xcb_flush(conn); -} - -static int -_e_alert_handle_key_press(xcb_generic_event_t *event) -{ - xcb_key_symbols_t *symbols; - xcb_key_press_event_t *ev; - xcb_keysym_t key; - int r = 0; - - ev = (xcb_key_press_event_t *)event; - symbols = xcb_key_symbols_alloc(conn); - key = xcb_key_symbols_get_keysym(symbols, ev->detail, 0); - - if (key == XK_F1) - r = 2; - else if (key == XK_F12) - r = 1; - - xcb_key_symbols_free(symbols); - - return r; -} - -static int -_e_alert_handle_button_press(xcb_generic_event_t *event) -{ - xcb_button_press_event_t *ev; - - ev = (xcb_button_press_event_t *)event; - if (ev->child == btn1) - return 1; - else if (ev->child == btn2) - return 2; - else - return 0; -} - -static xcb_char2b_t * -_e_alert_build_string(const char *str) -{ - unsigned int i = 0; - xcb_char2b_t *r = NULL; - - if (!(r = malloc(strlen(str) * sizeof(xcb_char2b_t)))) - return NULL; - - for (i = 0; i < strlen(str); i++) - { - r[i].byte1 = 0; - r[i].byte2 = str[i]; - } - - return r; -} - -static void -_e_alert_draw_outline(void) -{ - xcb_rectangle_t rect; - - /* draw outline */ - rect.x = 0; - rect.y = 0; - rect.width = (WINDOW_WIDTH - 1); - rect.height = (WINDOW_HEIGHT - 1); - xcb_poly_rectangle(conn, win, gc, 1, &rect); -} - -static void -_e_alert_draw_title_outline(void) -{ - xcb_rectangle_t rect; - - /* draw title box */ - rect.x = 2; - rect.y = 2; - rect.width = (WINDOW_WIDTH - 4 - 1); - rect.height = (fh + 4 + 2); - xcb_poly_rectangle(conn, win, gc, 1, &rect); -} - -static void -_e_alert_draw_title(void) -{ - int x = 0, y = 0; - - /* draw title */ - x = (2 + 2 + ((WINDOW_WIDTH - 4 - 4 - fw) / 2)); - y = (2 + 2 + fh); - - xcb_image_text_8(conn, strlen(title), win, gc, x, y, title); -} - -static void -_e_alert_draw_text(void) -{ - char warn[1024], msg[4096], line[1024]; - unsigned int i = 0, j = 0, k = 0; - - if (!tainted) - { - if (exit_gdb) - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely a sign of \n" - "a bug in Enlightenment or the libraries it relies \n" - "on. We were not able to generate a backtrace, check \n" - "if your 'sysactions.conf' has an 'gdb' action line.\n" - "\n" - "Please compile latest Git E and EFL with\n" - "-g and -ggdb3 in your CFLAGS.\n"); - } - else if (backtrace_str) - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely a sign of \n" - "a bug in Enlightenment or the libraries it relies \n" - "on. You will find an backtrace of E (%d) in :\n" - "'%s'\n" - "Before reporting issue, compile latest E and EFL\n" - "from Git with '-g -ggdb3' in your CFLAGS.\n" - "You can then report this crash on :\n" - "https://phab.enlightenment.org/maniphest/.\n", - pid, backtrace_str); - } - else - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely a sign of \n" - "a bug in Enlightenment or the libraries it relies \n" - "on. You can gdb attach to this process (%d) now \n" - "to try debug it or you could logout, or just hit \n" - "recover to try and get your desktop back the way \n" - "it was.\n" - "\n" - "Please compile latest Git E and EFL with\n" - "-g and -ggdb3 in your CFLAGS.\n", pid); - } - } - else - { - snprintf(msg, sizeof(msg), - "This is not meant to happen and is likely\n" - "a sign of a bug, but you are using unsupported\n" - "modules; before reporting this issue, please\n" - "unload them and try to see if the bug is still\n" - "there. Also update to latest Git and be sure to\n" - "compile E and EFL with -g and -ggdb3 in your CFLAGS"); - } - - strcpy(warn, ""); - - for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i) - if (signal_name[i].signal == sig) - snprintf(warn, sizeof(warn), - "This is very bad. Enlightenment %s'd.", - signal_name[i].name); - - /* draw text */ - k = (fh + 12); - xcb_image_text_8(conn, strlen(warn), win, gc, - 4, (k + fa), warn); - k += (2 * (fh + 2)); - for (i = 0; msg[i]; ) - { - line[j++] = msg[i++]; - if (line[j - 1] == '\n') - { - line[j - 1] = 0; - j = 0; - xcb_image_text_8(conn, strlen(line), win, gc, - 4, (k + fa), line); - k += (fh + 2); - } - } -} - -static void -_e_alert_draw_button_outlines(void) -{ - xcb_rectangle_t rect; - - rect.x = 0; - rect.y = 0; - rect.width = (WINDOW_WIDTH / 2) - 40 - 1; - rect.height = (fh + 20) - 1; - - /* draw button outlines */ - xcb_poly_rectangle(conn, btn1, gc, 1, &rect); - xcb_poly_rectangle(conn, btn2, gc, 1, &rect); -} - -static void -_e_alert_draw_button_text(void) -{ - xcb_char2b_t *str = NULL; - xcb_query_text_extents_cookie_t cookie; - xcb_query_text_extents_reply_t *reply; - int x = 0, w = 0, bw = 0; - - bw = (WINDOW_WIDTH / 2) - 40 - 1; - - /* draw button1 text */ - str = _e_alert_build_string(str1); - - cookie = - xcb_query_text_extents_unchecked(conn, font, strlen(str1), str); - reply = xcb_query_text_extents_reply(conn, cookie, NULL); - if (reply) - { - w = reply->overall_width; - free(reply); - } - free(str); - - x = (5 + ((bw - w) / 2)); - - xcb_image_text_8(conn, strlen(str1), btn1, gc, x, (10 + fa), str1); - - /* draw button2 text */ - str = _e_alert_build_string(str2); - - cookie = - xcb_query_text_extents_unchecked(conn, font, strlen(str2), str); - reply = xcb_query_text_extents_reply(conn, cookie, NULL); - if (reply) - { - w = reply->overall_width; - free(reply); - } - free(str); - - x = (5 + ((bw - w) / 2)); - - xcb_image_text_8(conn, strlen(str2), btn2, gc, x, (10 + fa), str2); -} -#endif diff --git a/src/bin/meson.build b/src/bin/meson.build index 959d4d2e2..138bb6596 100644 --- a/src/bin/meson.build +++ b/src/bin/meson.build @@ -530,21 +530,16 @@ executable('enlightenment_static_grabber', install : true ) -deps_e_alert = [] -if config_h.has('HAVE_WAYLAND') == true - deps_e_alert += [ dep_ecore_drm2, dep_ecore_input, dep_dl ] -endif +deps_e_alert = [ dep_elementary ] if config_h.has('HAVE_WAYLAND_ONLY') == false deps_e_alert += [ - dependency('xcb'), - dependency('xcb-shape'), - dependency('xcb-keysyms') + dep_ecore_x ] endif executable('enlightenment_alert', [ 'e_alert_main.c' ], include_directories: include_directories('../..'), - dependencies : [ dep_eina, dep_ecore, dep_evas, dep_ecore_ipc, deps_e_alert ], + dependencies : [ deps_e_alert ], install_dir : dir_e_utils, install : true )