diff options
Diffstat (limited to '')
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | TODO | 9 | ||||
-rw-r--r-- | src/bin/e_alert_main.c | 1221 | ||||
-rw-r--r-- | src/bin/meson.build | 11 |
4 files changed, 163 insertions, 1081 deletions
@@ -8,9 +8,6 @@ Requirements | |||
8 | 8 | ||
9 | Must: | 9 | Must: |
10 | * efl | 10 | * efl |
11 | * xcb | ||
12 | * xcb-shape | ||
13 | * xcb-keysyms | ||
14 | * libpam (On Linux) | 11 | * libpam (On Linux) |
15 | 12 | ||
16 | Highly suggested: | 13 | Highly suggested: |
@@ -90,13 +90,8 @@ TODO: | |||
90 | logging like tables, icons, timelines and graphs that can be output | 90 | logging like tables, icons, timelines and graphs that can be output |
91 | in text emulation and to screen - change eina log to go into here | 91 | in text emulation and to screen - change eina log to go into here |
92 | with eina_log_print_cb_set() ) | 92 | with eina_log_print_cb_set() ) |
93 | * crash alert: use full fat efl stack and remove xcb/ecore_drm2 stuff | 93 | * crash alert: we have to kill e to get kms control which breaks gdb |
94 | * supply custom theme to guarantee theme is not an issue | 94 | * grab data then kill e then display results? |
95 | * create text mode fallback with detection for crashes in crash handler | ||
96 | * turtles all the way down - a crash handler for our crash handler | ||
97 | * problem: we have to kill e to get kms control which breaks gdb | ||
98 | * grab data then kill e then display results? | ||
99 | * key combination to kill e and move on? | ||
100 | * watchdog: add watchdog handling to e_start to detect a hung e | 95 | * watchdog: add watchdog handling to e_start to detect a hung e |
101 | * also detect if frames stop rendering but loop ok? | 96 | * also detect if frames stop rendering but loop ok? |
102 | * settings: config dialog redo and simplification | 97 | * 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 @@ | |||
1 | #include "config.h" | 1 | #include "config.h" |
2 | 2 | ||
3 | #ifdef HAVE_WL_DRM | 3 | //# include "e_drm2.x" |
4 | # define EFL_BETA_API_SUPPORT | ||
5 | #endif | ||
6 | 4 | ||
7 | #include <stdio.h> | 5 | #include <Elementary.h> |
8 | #include <stdlib.h> | ||
9 | #include <stdarg.h> | ||
10 | #include <string.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <unistd.h> | ||
13 | #include <signal.h> | ||
14 | #include <limits.h> | ||
15 | #include <Eina.h> | ||
16 | #include <Ecore.h> | ||
17 | #include <Ecore_Ipc.h> | ||
18 | #ifndef HAVE_WAYLAND_ONLY | 6 | #ifndef HAVE_WAYLAND_ONLY |
19 | #include <xcb/xcb.h> | 7 | # include <Ecore_X.h> |
20 | #include <xcb/xcb_keysyms.h> | ||
21 | #include <xcb/shape.h> | ||
22 | #include <X11/keysym.h> | ||
23 | #endif | ||
24 | #ifdef HAVE_WL_DRM | ||
25 | # include <Ecore_Input.h> | ||
26 | # include <Ecore_Drm2.h> | ||
27 | # include <Evas.h> | ||
28 | # include <Evas_Engine_Buffer.h> | ||
29 | # include "e_drm2.x" | ||
30 | #endif | ||
31 | |||
32 | #ifdef HAVE_WL_DRM | ||
33 | |||
34 | /* DRM_FORMAT_XRGB8888 and fourcc_code borrowed from <drm_fourcc.h> | ||
35 | * | ||
36 | * Copyright 2011 Intel Corporation | ||
37 | * | ||
38 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
39 | * copy of this software and associated documentation files (the "Software"), | ||
40 | * to deal in the Software without restriction, including without limitation | ||
41 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
42 | * and/or sell copies of the Software, and to permit persons to whom the | ||
43 | * Software is furnished to do so, subject to the following conditions: | ||
44 | * | ||
45 | * The above copyright notice and this permission notice (including the next | ||
46 | * paragraph) shall be included in all copies or substantial portions of the | ||
47 | * Software. | ||
48 | * | ||
49 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
50 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
51 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
52 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
53 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
54 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
55 | * OTHER DEALINGS IN THE SOFTWARE. | ||
56 | */ | ||
57 | # define fourcc_code(a, b, c, d) \ | ||
58 | ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ | ||
59 | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) | ||
60 | # define DRM_FORMAT_XRGB8888 \ | ||
61 | fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ | ||
62 | #endif | 8 | #endif |
63 | 9 | ||
64 | #define WINDOW_WIDTH 320 | 10 | static int ret = 0, sig = 0, exit_gdb = 0; |
65 | #define WINDOW_HEIGHT 240 | 11 | static pid_t pid; |
66 | 12 | static Eina_Bool tainted = EINA_FALSE; | |
67 | #ifndef HAVE_WAYLAND_ONLY | ||
68 | #ifndef XCB_ATOM_NONE | ||
69 | # define XCB_ATOM_NONE 0 | ||
70 | #endif | ||
71 | |||
72 | /* local function prototypes */ | ||
73 | static int _e_alert_connect(void); | ||
74 | static void _e_alert_create(void); | ||
75 | static void _e_alert_display(void); | ||
76 | static void _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h); | ||
77 | static void _e_alert_window_raise(xcb_window_t win); | ||
78 | static void _e_alert_sync(void); | ||
79 | static void _e_alert_shutdown(void); | ||
80 | static void _e_alert_run(void); | ||
81 | static void _e_alert_draw(void); | ||
82 | static int _e_alert_handle_key_press(xcb_generic_event_t *event); | ||
83 | static int _e_alert_handle_button_press(xcb_generic_event_t *event); | ||
84 | static xcb_char2b_t *_e_alert_build_string(const char *str); | ||
85 | static void _e_alert_draw_outline(void); | ||
86 | static void _e_alert_draw_title_outline(void); | ||
87 | static void _e_alert_draw_title(void); | ||
88 | static void _e_alert_draw_text(void); | ||
89 | static void _e_alert_draw_button_outlines(void); | ||
90 | static void _e_alert_draw_button_text(void); | ||
91 | |||
92 | /* local variables */ | ||
93 | static xcb_connection_t *conn = NULL; | ||
94 | static xcb_screen_t *screen = NULL; | ||
95 | static xcb_window_t win = 0, comp_win = 0; | ||
96 | static xcb_window_t btn1 = 0; | ||
97 | static xcb_window_t btn2 = 0; | ||
98 | static xcb_font_t font = 0; | ||
99 | static xcb_gcontext_t gc = 0; | ||
100 | static int fa = 0, fw = 0; | ||
101 | #endif | ||
102 | static int sw = 0, sh = 0; | ||
103 | static int fh = 0; | ||
104 | static const char *title = NULL, *str1 = NULL, *str2 = NULL; | ||
105 | static int ret = 0, sig = 0; | ||
106 | static pid_t pid; | ||
107 | static Eina_Bool tainted = EINA_TRUE; | ||
108 | static const char *backtrace_str = NULL; | 13 | static const char *backtrace_str = NULL; |
109 | static int exit_gdb = 0; | ||
110 | 14 | ||
111 | struct | 15 | #define FONT "Mono" |
112 | { | 16 | #define COL_BG 0, 0, 0, 255 |
113 | int signal; | 17 | #define COL_FG 255, 0, 0, 255 |
114 | const char *name; | 18 | #define HDIV 10 |
115 | } signal_name[5] = { | 19 | #define PDIV 20 |
116 | { SIGSEGV, "SEGV" }, | 20 | #define BLINK 0.8 |
117 | { SIGILL, "SIGILL" }, | 21 | #define RECOVER_BUTTON 1 |
118 | { SIGFPE, "SIGFPE" }, | 22 | #define RECOVER_KEY "F1" |
119 | { SIGBUS, "SIGBUS" }, | 23 | #define ABORT_BUTTON 3 |
120 | { SIGABRT, "SIGABRT" } | 24 | #define ABORT_KEY "F12" |
121 | }; | ||
122 | |||
123 | # ifdef HAVE_WL_DRM | ||
124 | static Evas *canvas = NULL; | ||
125 | |||
126 | static Eina_Bool | ||
127 | _e_alert_drm_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) | ||
128 | { | ||
129 | Ecore_Event_Key *ev; | ||
130 | 25 | ||
131 | ev = event; | 26 | static inline const char *title1(void) { |
132 | if (!strcmp(ev->key, "F12")) | 27 | return "Software Failure. Press left mouse button / F1 to recover, right mouse button / F12 to abort."; |
133 | { | ||
134 | ret = 1; | ||
135 | ecore_main_loop_quit(); | ||
136 | } | ||
137 | else if (!strcmp(ev->key, "F1")) | ||
138 | { | ||
139 | ret = 2; | ||
140 | ecore_main_loop_quit(); | ||
141 | } | ||
142 | |||
143 | return ECORE_CALLBACK_RENEW; | ||
144 | } | 28 | } |
145 | 29 | static inline const char *title2(void) { static char buf[512]; | |
146 | static void | 30 | if (tainted) snprintf |
147 | _e_alert_drm_draw_outline(void) | 31 | (buf, sizeof(buf), "Tainted by unsupported modules"); |
148 | { | 32 | else if (exit_gdb) snprintf |
149 | Evas_Object *o; | 33 | (buf, sizeof(buf), "Couldn't run gdb to collect a backtrace"); |
150 | int wx = 0, wy = 0; | 34 | else if (backtrace_str) snprintf |
151 | 35 | (buf, sizeof(buf), "Backtrace log: %s", backtrace_str); | |
152 | wx = ((sw - WINDOW_WIDTH) / 2); | 36 | else snprintf |
153 | wy = ((sh - WINDOW_HEIGHT) / 2); | 37 | (buf, sizeof(buf), " "); |
154 | 38 | return buf; | |
155 | /* create background */ | 39 | } |
156 | o = evas_object_rectangle_add(canvas); | 40 | static inline const char *title3(void) { static char buf[512]; |
157 | evas_object_move(o, wx, wy); | 41 | snprintf(buf, sizeof(buf), "Guru Meditation #%08d.%08d", pid, sig); |
158 | evas_object_resize(o, WINDOW_WIDTH, WINDOW_HEIGHT); | 42 | return buf; |
159 | evas_object_show(o); | ||
160 | |||
161 | /* create outline */ | ||
162 | o = evas_object_rectangle_add(canvas); | ||
163 | evas_object_color_set(o, 0, 0, 0, 255); | ||
164 | evas_object_move(o, wx, wy); | ||
165 | evas_object_resize(o, WINDOW_WIDTH, WINDOW_HEIGHT); | ||
166 | evas_object_show(o); | ||
167 | |||
168 | /* create white inside */ | ||
169 | o = evas_object_rectangle_add(canvas); | ||
170 | evas_object_move(o, wx + 1, wy + 1); | ||
171 | evas_object_resize(o, WINDOW_WIDTH - 2, WINDOW_HEIGHT - 2); | ||
172 | evas_object_show(o); | ||
173 | } | 43 | } |
174 | 44 | ||
175 | static void | 45 | ///////////////////////////////////////////////////////////////////////////// |
176 | _e_alert_drm_draw_title_outline(void) | ||
177 | { | ||
178 | Evas_Object *o; | ||
179 | int wx = 0, wy = 0; | ||
180 | |||
181 | wx = ((sw - WINDOW_WIDTH) / 2); | ||
182 | wy = ((sh - WINDOW_HEIGHT) / 2); | ||
183 | |||
184 | /* create title outline */ | ||
185 | o = evas_object_rectangle_add(canvas); | ||
186 | evas_object_color_set(o, 0, 0, 0, 255); | ||
187 | evas_object_move(o, wx + 2, wy + 2); | ||
188 | evas_object_resize(o, WINDOW_WIDTH - 4, 20); | ||
189 | evas_object_show(o); | ||
190 | 46 | ||
191 | /* create white inside */ | 47 | static Evas_Object *obj_base = NULL; |
192 | o = evas_object_rectangle_add(canvas); | 48 | static Evas_Object *obj_outer = NULL; |
193 | evas_object_move(o, wx + 3, wy + 3); | 49 | static Evas_Object *obj_inner = NULL; |
194 | evas_object_resize(o, WINDOW_WIDTH - 6, 18); | 50 | static Evas_Object *obj_line1 = NULL; |
195 | evas_object_show(o); | 51 | static Evas_Object *obj_line2 = NULL; |
196 | } | 52 | static Evas_Object *obj_line3 = NULL; |
197 | 53 | ||
198 | static void | 54 | static void |
199 | _e_alert_drm_draw_title(void) | 55 | mouse_up(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *info) |
200 | { | 56 | { |
201 | Evas_Object *o; | 57 | Evas_Event_Mouse_Up *ev = info; |
202 | Evas_Textblock_Style *style; | ||
203 | int wx = 0, wy = 0; | ||
204 | 58 | ||
205 | wx = ((sw - WINDOW_WIDTH) / 2); | 59 | if (ev->button == RECOVER_BUTTON) |
206 | wy = ((sh - WINDOW_HEIGHT) / 2); | 60 | { |
207 | 61 | ret = 2; | |
208 | style = evas_textblock_style_new(); | 62 | elm_exit(); |
209 | evas_textblock_style_set(style, | 63 | } |
210 | "DEFAULT='font=Fixed font_size=8 color=#000000'" | 64 | else if (ev->button == ABORT_BUTTON) |
211 | "newline='br' align=center valign=center"); | 65 | { |
212 | 66 | ret = 1; | |
213 | title = "<align=center>Enlightenment Error</align>"; | 67 | elm_exit(); |
214 | 68 | } | |
215 | o = evas_object_textblock_add(canvas); | ||
216 | evas_object_textblock_style_set(o, style); | ||
217 | evas_object_textblock_text_markup_set(o, title); | ||
218 | evas_object_color_set(o, 0, 0, 0, 255); | ||
219 | evas_object_move(o, wx + 4, wy + 4); | ||
220 | evas_object_resize(o, WINDOW_WIDTH - 8, 18); | ||
221 | evas_object_show(o); | ||
222 | |||
223 | evas_textblock_style_free(style); | ||
224 | } | 69 | } |
225 | 70 | ||
226 | static void | 71 | static void |
227 | _e_alert_drm_draw_text(void) | 72 | key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *info) |
228 | { | 73 | { |
229 | Evas_Object *o; | 74 | Evas_Event_Key_Down *ev = info; |
230 | Evas_Textblock_Style *style; | ||
231 | char warn[4096], msg[4096]; | ||
232 | unsigned int i = 0; | ||
233 | int wx = 0, wy = 0; | ||
234 | 75 | ||
235 | wx = ((sw - WINDOW_WIDTH) / 2); | 76 | if (!strcmp(ev->key, RECOVER_KEY)) |
236 | wy = ((sh - WINDOW_HEIGHT) / 2); | ||
237 | |||
238 | strcpy(warn, ""); | ||
239 | |||
240 | for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i) | ||
241 | if (signal_name[i].signal == sig) | ||
242 | snprintf(warn, sizeof(warn), | ||
243 | "This is very bad. Enlightenment %s'd.<br/><br/>", | ||
244 | signal_name[i].name); | ||
245 | |||
246 | if (!tainted) | ||
247 | { | 77 | { |
248 | if (exit_gdb) | 78 | ret = 2; |
249 | { | 79 | elm_exit(); |
250 | snprintf(msg, sizeof(msg), | ||
251 | "This is not meant to happen and is likely a sign of <br/>" | ||
252 | "a bug in Enlightenment or the libraries it relies <br/>" | ||
253 | "on. We were not able to generate a backtrace, check <br/>" | ||
254 | "if your 'sysactions.conf' has an 'gdb' action line.<br/>" | ||
255 | "<br/>" | ||
256 | "Please compile latest Git E and EFL with<br/>" | ||
257 | "-g and -ggdb3 in your CFLAGS.<br/>"); | ||
258 | } | ||
259 | else if (backtrace_str) | ||
260 | { | ||
261 | snprintf(msg, sizeof(msg), | ||
262 | "This is not meant to happen and is likely a sign of <br/>" | ||
263 | "a bug in Enlightenment or the libraries it relies <br/>" | ||
264 | "on. You will find an backtrace of E (%d) in :<br/>" | ||
265 | "'%s'<br/>" | ||
266 | "Before reporting issue, compile latest E and EFL<br/>" | ||
267 | "from Git with '-g -ggdb3' in your CFLAGS.<br/>" | ||
268 | "You can then report this crash on :<br/>" | ||
269 | "https://phab.enlightenment.org/maniphest/.<br/>", | ||
270 | pid, backtrace_str); | ||
271 | } | ||
272 | else | ||
273 | { | ||
274 | snprintf(msg, sizeof(msg), | ||
275 | "This is not meant to happen and is likely a sign of <br/>" | ||
276 | "a bug in Enlightenment or the libraries it relies <br/>" | ||
277 | "on. You can gdb attach to this process (%d) now <br/>" | ||
278 | "to try debug it or you could logout, or just hit <br/>" | ||
279 | "recover to try and get your desktop back the way <br/>" | ||
280 | "it was.<br/>" | ||
281 | "<br/>" | ||
282 | "Please compile latest Git E and EFL with<br/>" | ||
283 | "-g and -ggdb3 in your CFLAGS.<br/>", pid); | ||
284 | } | ||
285 | } | 80 | } |
286 | else | 81 | else if (!strcmp(ev->key, ABORT_KEY)) |
287 | { | 82 | { |
288 | snprintf(msg, sizeof(msg), | 83 | ret = 1; |
289 | "This is not meant to happen and is likely<br/>" | 84 | elm_exit(); |
290 | "a sign of a bug, but you are using<br/>" | ||
291 | "unsupported modules; before reporting this<br/>" | ||
292 | "issue, please unload them and try to<br/>" | ||
293 | "see if the bug is still there.<br/>" | ||
294 | "Also update to latest Git<br/>" | ||
295 | "and be sure to compile E and EFL with<br/>" | ||
296 | "-g and -ggdb3 in your CFLAGS"); | ||
297 | } | 85 | } |
298 | |||
299 | style = evas_textblock_style_new(); | ||
300 | evas_textblock_style_set(style, | ||
301 | "DEFAULT='font=Fixed font_size=8 color=#000000'" | ||
302 | "newline='br' align=center valign=center wrap=word"); | ||
303 | |||
304 | strcat(warn, msg); | ||
305 | |||
306 | o = evas_object_textblock_add(canvas); | ||
307 | evas_object_textblock_style_set(o, style); | ||
308 | evas_object_textblock_text_markup_set(o, warn); | ||
309 | evas_object_color_set(o, 0, 0, 0, 255); | ||
310 | evas_object_move(o, wx + 4, wy + 28); | ||
311 | evas_object_resize(o, WINDOW_WIDTH - 4, WINDOW_HEIGHT - 30); | ||
312 | evas_object_show(o); | ||
313 | |||
314 | evas_textblock_style_free(style); | ||
315 | } | 86 | } |
316 | 87 | ||
317 | static void | 88 | static void |
318 | _e_alert_drm_draw_button_outlines(void) | 89 | resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o, void *info EINA_UNUSED) |
319 | { | 90 | { |
320 | Evas_Object *o; | 91 | Evas_Coord w, h, tw, th; |
321 | int wx = 0, wy = 0; | ||
322 | int x = 0, w = 0; | ||
323 | int tx, ty, tw, th; | ||
324 | |||
325 | wx = ((sw - WINDOW_WIDTH) / 2); | ||
326 | wy = ((sh - WINDOW_HEIGHT) / 2); | ||
327 | |||
328 | x = wx + 20; | ||
329 | w = (WINDOW_WIDTH / 2) - 40; | ||
330 | |||
331 | o = evas_object_rectangle_add(canvas); | ||
332 | evas_object_color_set(o, 0, 255, 0, 255); | ||
333 | evas_object_move(o, x, wy + WINDOW_HEIGHT - 20 - (fh + 20)); | ||
334 | evas_object_resize(o, w, (fh + 20)); | ||
335 | evas_object_show(o); | ||
336 | 92 | ||
337 | evas_object_geometry_get(o, &tx, &ty, &tw, &th); | 93 | evas_object_geometry_get(o, NULL, NULL, &w, &h); |
94 | h = w / HDIV; | ||
338 | 95 | ||
339 | o = evas_object_text_add(canvas); | 96 | evas_object_geometry_set(obj_base, 0, 0, w, h * HDIV * 2); |
340 | evas_object_text_font_set(o, "Fixed", 8); | 97 | evas_object_geometry_set(obj_outer, (1 * h) / PDIV, (1 * h) / PDIV, |
341 | evas_object_text_text_set(o, str1); | 98 | w - ((h * 2) / PDIV), h - ((h * 2) / PDIV)); |
342 | evas_object_color_set(o, 0, 0, 0, 255); | 99 | evas_object_geometry_set(obj_inner, (2 * h) / PDIV, (2 * h) / PDIV, |
343 | evas_object_move(o, tx, ty); | 100 | w - ((h * 4) / PDIV), h - ((h * 4) / PDIV)); |
344 | evas_object_resize(o, tw, th); | ||
345 | evas_object_show(o); | ||
346 | 101 | ||
347 | x = wx + ((WINDOW_WIDTH / 2) + 20); | 102 | evas_object_text_font_set(obj_line1, FONT, h / 8); |
348 | o = evas_object_rectangle_add(canvas); | 103 | evas_object_geometry_get(obj_line1, NULL, NULL, &tw, &th); |
349 | evas_object_color_set(o, 255, 0, 0, 255); | 104 | evas_object_move(obj_line1, (w - tw) / 2, (3 * h) / PDIV); |
350 | evas_object_move(o, x, wy + WINDOW_HEIGHT - 20 - (fh + 20)); | ||
351 | evas_object_resize(o, w, (fh + 20)); | ||
352 | evas_object_show(o); | ||
353 | 105 | ||
354 | evas_object_geometry_get(o, &tx, &ty, &tw, &th); | 106 | evas_object_text_font_set(obj_line2, FONT, h / 8); |
107 | evas_object_geometry_get(obj_line2, NULL, NULL, &tw, &th); | ||
108 | evas_object_move(obj_line2, (w - tw) / 2, (h - th) / 2); | ||
355 | 109 | ||
356 | o = evas_object_text_add(canvas); | 110 | evas_object_text_font_set(obj_line3, FONT, h / 8); |
357 | evas_object_text_font_set(o, "Fixed", 8); | 111 | evas_object_geometry_get(obj_line3, NULL, NULL, &tw, &th); |
358 | evas_object_text_text_set(o, str2); | 112 | evas_object_move(obj_line3, (w - tw) / 2, h - th - (3 * h) / PDIV); |
359 | evas_object_color_set(o, 0, 0, 0, 255); | ||
360 | evas_object_move(o, tx, ty); | ||
361 | evas_object_resize(o, tw, th); | ||
362 | evas_object_show(o); | ||
363 | } | 113 | } |
364 | 114 | ||
365 | static void | 115 | static Eina_Bool |
366 | _e_alert_drm_run(void) | 116 | timer(void *data EINA_UNUSED) |
367 | { | 117 | { |
368 | printf("E_Alert Drm Run\n"); | 118 | if (evas_object_visible_get(obj_outer)) evas_object_hide(obj_outer); |
369 | ecore_main_loop_begin(); | 119 | else evas_object_show(obj_outer); |
120 | return EINA_TRUE; | ||
370 | } | 121 | } |
371 | 122 | ||
372 | static Ecore_Drm2_Device *dev = NULL; | 123 | static Eina_Bool |
373 | static Ecore_Drm2_Fb *buffer = NULL; | 124 | setup_display(void) |
374 | static Ecore_Drm2_Output *output = NULL; | ||
375 | |||
376 | static int | ||
377 | _e_alert_drm_connect(void) | ||
378 | { | 125 | { |
379 | fprintf(stderr, "E_Alert Drm Connect\n"); | 126 | Evas *e; |
127 | Evas_Object *win, *o; | ||
380 | 128 | ||
381 | if (!evas_init()) | 129 | win = o = elm_win_add(NULL, "e-alert", ELM_WIN_SPLASH); |
382 | { | 130 | if (!win) return EINA_FALSE; |
383 | printf("\tCannot init evas\n"); | 131 | e = evas_object_evas_get(win); |
384 | return 0; | 132 | elm_win_override_set(o, EINA_TRUE); |
385 | } | ||
386 | 133 | ||
387 | if (!e_drm2_compat_init() || !ecore_drm2_init()) | 134 | obj_base = o = evas_object_rectangle_add(e); |
388 | { | 135 | evas_object_color_set(o, COL_BG); |
389 | printf("\tCannot init ecore_drm\n"); | 136 | evas_object_show(o); |
390 | return 0; | ||
391 | } | ||
392 | |||
393 | dev = e_drm2_device_open("seat0", 0); | ||
394 | if (!dev) | ||
395 | { | ||
396 | printf("\tCannot find drm device\n"); | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | |||
401 | if (!ecore_drm2_outputs_create(dev)) | ||
402 | { | ||
403 | printf("\tCannot create drm outputs\n"); | ||
404 | return 0; | ||
405 | } | ||
406 | 137 | ||
407 | output = ecore_drm2_output_find(dev, 0, 0); | 138 | obj_outer = o = evas_object_rectangle_add(e); |
408 | if (output) e_drm2_output_info_get(output, NULL, NULL, &sw, &sh, NULL); | 139 | evas_object_color_set(o, COL_FG); |
409 | fprintf(stderr, "\tOutput Size: %d %d\n", sw, sh); | 140 | evas_object_pass_events_set(o, EINA_TRUE); |
410 | // force symbol usage to get rid of warnings for release. | 141 | evas_object_show(o); |
411 | // i think we'll replace all the x and drm2 stuff in e_alert with normal | ||
412 | // full fat efl stuff. it'll reduce duplication and simplify this | ||
413 | // e_alert stuff a lot with the downside of a broken efl breaking | ||
414 | // e_alert, but then a broken efl will affect it already. i'll look into | ||
415 | // a text mode fallback - so a crash handler for the crash handler... :) | ||
416 | // turtles all the way down. | ||
417 | e_drm2_output_rotation_set(output, e_drm2_output_rotation_get(output)); | ||
418 | 142 | ||
419 | ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, | 143 | obj_inner = o = evas_object_rectangle_add(e); |
420 | _e_alert_drm_cb_key_down, NULL); | 144 | evas_object_color_set(o, COL_BG); |
145 | evas_object_pass_events_set(o, EINA_TRUE); | ||
146 | evas_object_show(o); | ||
421 | 147 | ||
422 | return 1; | 148 | obj_line1 = o = evas_object_text_add(e); |
423 | } | 149 | evas_object_color_set(o, COL_FG); |
150 | evas_object_text_font_set(o, FONT, 10); | ||
151 | evas_object_text_text_set(o, title1()); | ||
152 | evas_object_pass_events_set(o, EINA_TRUE); | ||
153 | evas_object_show(o); | ||
424 | 154 | ||
425 | static void | 155 | obj_line2 = o = evas_object_text_add(e); |
426 | _e_alert_drm_create(void) | 156 | evas_object_color_set(o, COL_FG); |
427 | { | 157 | evas_object_text_font_set(o, FONT, 10); |
428 | Evas_Engine_Info_Buffer *einfo; | 158 | evas_object_text_text_set(o, title2()); |
429 | int method = 0; | 159 | evas_object_pass_events_set(o, EINA_TRUE); |
160 | evas_object_show(o); | ||
430 | 161 | ||
431 | fprintf(stderr, "E_Alert Drm Create\n"); | 162 | obj_line3 = o = evas_object_text_add(e); |
163 | evas_object_color_set(o, COL_FG); | ||
164 | evas_object_text_font_set(o, FONT, 10); | ||
165 | evas_object_text_text_set(o, title3()); | ||
166 | evas_object_pass_events_set(o, EINA_TRUE); | ||
167 | evas_object_show(o); | ||
432 | 168 | ||
433 | fh = 13; | 169 | evas_object_event_callback_add(obj_base, EVAS_CALLBACK_MOUSE_UP, mouse_up, NULL); |
170 | evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN, key_down, NULL); | ||
171 | evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, resize, NULL); | ||
434 | 172 | ||
435 | buffer = e_drm2_fb_create(dev, sw, sh, 24, 32, DRM_FORMAT_XRGB8888); | 173 | ecore_timer_add(BLINK, timer, NULL); |
436 | 174 | ||
437 | method = evas_render_method_lookup("buffer"); | 175 | resize(NULL, e, win, NULL); |
438 | if (method <= 0) | ||
439 | { | ||
440 | fprintf(stderr, "\tCould not get evas render method\n"); | ||
441 | return; | ||
442 | } | ||
443 | 176 | ||
444 | canvas = evas_new(); | 177 | #ifndef HAVE_WAYLAND_ONLY |
445 | if (!canvas) | 178 | if (getenv("DISPLAY")) |
446 | { | ||
447 | fprintf(stderr, "\tFailed to create new canvas\n"); | ||
448 | return; | ||
449 | } | ||
450 | |||
451 | evas_output_method_set(canvas, method); | ||
452 | evas_output_size_set(canvas, sw, sh); | ||
453 | evas_output_viewport_set(canvas, 0, 0, sw, sh); | ||
454 | |||
455 | einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas); | ||
456 | if (!einfo) | ||
457 | { | 179 | { |
458 | printf("\tFailed to get evas engine info\n"); | 180 | Ecore_X_Window root = ecore_x_window_root_first_get(); |
459 | evas_free(canvas); | 181 | Ecore_X_Atom atom_composite_win = ecore_x_atom_get("_E_COMP_WINDOW"); |
460 | return; | 182 | unsigned int id; |
183 | if (ecore_x_window_prop_card32_get(root, atom_composite_win, &id, 1) > 0) | ||
184 | { | ||
185 | Ecore_X_Window elmwin = elm_win_xwindow_get(win); | ||
186 | ecore_x_window_reparent(elmwin, id, 0, 0); | ||
187 | Ecore_X_Randr_Output output = ecore_x_randr_primary_output_get(root); | ||
188 | Ecore_X_Randr_Crtc crct = ecore_x_randr_output_crtc_get(root, output); | ||
189 | int x = 0, y = 0, w = 1, h = 1; | ||
190 | ecore_x_randr_crtc_geometry_get(root, crct, &x, &y, &w, &h); | ||
191 | ecore_x_window_move_resize(elmwin, x, y, w, w / HDIV); | ||
192 | } | ||
461 | } | 193 | } |
194 | #endif | ||
462 | 195 | ||
463 | einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; | 196 | evas_object_show(win); |
464 | einfo->info.dest_buffer = ecore_drm2_fb_data_get(buffer); | ||
465 | einfo->info.dest_buffer_row_bytes = (sw * sizeof(int)); | ||
466 | einfo->info.use_color_key = 0; | ||
467 | einfo->info.alpha_threshold = 0; | ||
468 | einfo->info.func.new_update_region = NULL; | ||
469 | einfo->info.func.free_update_region = NULL; | ||
470 | evas_engine_info_set(canvas, (Evas_Engine_Info *)einfo); | ||
471 | |||
472 | _e_alert_drm_draw_outline(); | ||
473 | _e_alert_drm_draw_title_outline(); | ||
474 | _e_alert_drm_draw_title(); | ||
475 | _e_alert_drm_draw_text(); | ||
476 | _e_alert_drm_draw_button_outlines(); | ||
477 | } | ||
478 | |||
479 | static void | ||
480 | _e_alert_drm_display(void) | ||
481 | { | ||
482 | Eina_List *updates; | ||
483 | |||
484 | printf("E_Alert Drm Display\n"); | ||
485 | |||
486 | updates = evas_render_updates(canvas); | ||
487 | evas_render_updates_free(updates); | ||
488 | |||
489 | ecore_drm2_fb_flip(buffer, output); | ||
490 | } | ||
491 | |||
492 | static void | ||
493 | _e_alert_drm_shutdown(void) | ||
494 | { | ||
495 | printf("E_Alert Drm Shutdown\n"); | ||
496 | |||
497 | evas_free(canvas); | ||
498 | 197 | ||
499 | if (dev) | 198 | #ifndef HAVE_WAYLAND_ONLY |
199 | if (getenv("DISPLAY")) | ||
500 | { | 200 | { |
501 | ecore_drm2_outputs_destroy(dev); | 201 | Ecore_X_Window elmwin = elm_win_xwindow_get(win); |
502 | e_drm2_device_close(dev); | 202 | ecore_x_pointer_grab(elmwin); |
203 | ecore_x_keyboard_grab(elmwin); | ||
503 | } | 204 | } |
504 | |||
505 | ecore_drm2_shutdown(); | ||
506 | evas_shutdown(); | ||
507 | e_drm2_compat_shutdown(); | ||
508 | } | ||
509 | |||
510 | #endif | 205 | #endif |
206 | return EINA_TRUE; | ||
207 | } | ||
511 | 208 | ||
512 | int | 209 | int |
513 | main(int argc, char **argv) | 210 | main(int argc, char **argv) |
514 | { | 211 | { |
515 | const char *tmp; | 212 | const char *s; |
516 | int i = 0; | 213 | int i = 0; |
517 | 214 | ||
518 | /* XCB is not available when running in wayland only mode. No need to start anything here */ | ||
519 | /* #ifdef HAVE_WAYLAND_ONLY */ | ||
520 | /* printf("E Alert is not suitable to be used with E in wayland only mode\n"); */ | ||
521 | /* exit(0); */ | ||
522 | /* #endif */ | ||
523 | |||
524 | for (i = 1; i < argc; i++) | 215 | for (i = 1; i < argc; i++) |
525 | { | 216 | { |
526 | if ((!strcmp(argv[i], "-h")) || | 217 | if ((!strcmp(argv[i], "-h")) || |
@@ -531,617 +222,21 @@ main(int argc, char **argv) | |||
531 | "do not use it.\n"); | 222 | "do not use it.\n"); |
532 | exit(0); | 223 | exit(0); |
533 | } | 224 | } |
534 | else if (i == 1) | 225 | else if (i == 1) sig = atoi(argv[i]); // signal |
535 | sig = atoi(argv[i]); // signal | 226 | else if (i == 2) pid = atoi(argv[i]); // E's pid |
536 | else if (i == 2) | 227 | else if (i == 3) exit_gdb = atoi(argv[i]); |
537 | pid = atoi(argv[i]); // E's pid | 228 | else if (i == 4) backtrace_str = argv[i]; |
538 | else if (i == 3) | ||
539 | exit_gdb = atoi(argv[i]); | ||
540 | else if (i == 4) | ||
541 | backtrace_str = argv[i]; | ||
542 | } | 229 | } |
543 | 230 | ||
544 | fprintf(stderr, "exit_gdb: %i\n", exit_gdb); | 231 | fprintf(stderr, "exit_gdb: %i\n", exit_gdb); |
545 | 232 | ||
546 | tmp = getenv("E_TAINTED"); | 233 | s = getenv("E_TAINTED"); |
547 | if (tmp && !strcmp(tmp, "NO")) | 234 | if (s && !strcmp(s, "NO")) tainted = EINA_FALSE; |
548 | tainted = EINA_FALSE; | 235 | else if (s && !strcmp(s, "YES")) tainted = EINA_TRUE; |
549 | 236 | ||
550 | ecore_app_no_system_modules(); | 237 | ecore_app_no_system_modules(); |
551 | if (!ecore_init()) return EXIT_FAILURE; | 238 | elm_init(argc, argv); |
552 | ecore_app_args_set(argc, (const char **)argv); | 239 | if (setup_display()) elm_run(); |
553 | |||
554 | title = "Enlightenment Error"; | ||
555 | str1 = "(F1) Recover"; | ||
556 | str2 = "(F12) Logout"; | ||
557 | |||
558 | #ifdef HAVE_WL_DRM | ||
559 | if (!getenv("DISPLAY")) | ||
560 | { | ||
561 | if (!_e_alert_drm_connect()) | ||
562 | { | ||
563 | printf("FAILED TO INIT ALERT SYSTEM!!!\n"); | ||
564 | ecore_shutdown(); | ||
565 | return EXIT_FAILURE; | ||
566 | } | ||
567 | _e_alert_drm_create(); | ||
568 | _e_alert_drm_display(); | ||
569 | _e_alert_drm_run(); | ||
570 | _e_alert_drm_shutdown(); | ||
571 | } | ||
572 | #endif | ||
573 | #if defined(HAVE_WL_DRM) && !defined(HAVE_WAYLAND_ONLY) | ||
574 | else | ||
575 | #endif | ||
576 | #ifndef HAVE_WAYLAND_ONLY | ||
577 | { | ||
578 | if (!_e_alert_connect()) | ||
579 | { | ||
580 | printf("FAILED TO INIT ALERT SYSTEM!!!\n"); | ||
581 | ecore_shutdown(); | ||
582 | return EXIT_FAILURE; | ||
583 | } | ||
584 | _e_alert_create(); | ||
585 | _e_alert_display(); | ||
586 | _e_alert_run(); | ||
587 | _e_alert_shutdown(); | ||
588 | } | ||
589 | #endif | ||
590 | ecore_shutdown(); | ||
591 | 240 | ||
592 | /* ret == 1 => exit e => exit code 1 */ | ||
593 | /* ret == 2 => restart e => any code will do that */ | ||
594 | return ret; | 241 | return ret; |
595 | } | 242 | } |
596 | #ifndef HAVE_WAYLAND_ONLY | ||
597 | /* local functions */ | ||
598 | static int | ||
599 | _e_alert_connect(void) | ||
600 | { | ||
601 | conn = xcb_connect(NULL, NULL); | ||
602 | if ((!conn) || (xcb_connection_has_error(conn))) | ||
603 | { | ||
604 | printf("E_Alert_Main: Error Trying to Connect!!\n"); | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | /* grab default screen */ | ||
609 | screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; | ||
610 | sw = screen->width_in_pixels; | ||
611 | sh = screen->height_in_pixels; | ||
612 | |||
613 | return 1; | ||
614 | } | ||
615 | |||
616 | static void | ||
617 | _e_alert_create(void) | ||
618 | { | ||
619 | uint32_t mask, mask_list[4]; | ||
620 | int wx = 0, wy = 0; | ||
621 | |||
622 | wx = ((sw - WINDOW_WIDTH) / 2); | ||
623 | wy = ((sh - WINDOW_HEIGHT) / 2); | ||
624 | |||
625 | font = xcb_generate_id(conn); | ||
626 | xcb_open_font(conn, font, strlen("fixed"), "fixed"); | ||
627 | |||
628 | /* create main window */ | ||
629 | mask = (XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | | ||
630 | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK); | ||
631 | mask_list[0] = screen->white_pixel; | ||
632 | mask_list[1] = screen->black_pixel; | ||
633 | mask_list[2] = 1; | ||
634 | mask_list[3] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | | ||
635 | XCB_EVENT_MASK_EXPOSURE); | ||
636 | |||
637 | win = xcb_generate_id(conn); | ||
638 | xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root, | ||
639 | wx, wy, WINDOW_WIDTH, WINDOW_HEIGHT, 0, | ||
640 | XCB_WINDOW_CLASS_INPUT_OUTPUT, | ||
641 | XCB_COPY_FROM_PARENT, mask, mask_list); | ||
642 | |||
643 | /* create button 1 */ | ||
644 | mask_list[3] = (XCB_EVENT_MASK_BUTTON_PRESS | | ||
645 | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE); | ||
646 | |||
647 | btn1 = xcb_generate_id(conn); | ||
648 | xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn1, win, | ||
649 | -100, -100, 1, 1, 0, | ||
650 | XCB_WINDOW_CLASS_INPUT_OUTPUT, | ||
651 | XCB_COPY_FROM_PARENT, mask, mask_list); | ||
652 | xcb_map_window(conn, btn1); | ||
653 | |||
654 | /* create button 2 */ | ||
655 | btn2 = xcb_generate_id(conn); | ||
656 | xcb_create_window(conn, XCB_COPY_FROM_PARENT, btn2, win, | ||
657 | -100, -100, 1, 1, 0, | ||
658 | XCB_WINDOW_CLASS_INPUT_OUTPUT, | ||
659 | XCB_COPY_FROM_PARENT, mask, mask_list); | ||
660 | xcb_map_window(conn, btn2); | ||
661 | |||
662 | /* create drawing gc */ | ||
663 | mask = (XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT); | ||
664 | mask_list[0] = screen->black_pixel; | ||
665 | mask_list[1] = screen->white_pixel; | ||
666 | mask_list[2] = font; | ||
667 | |||
668 | gc = xcb_generate_id(conn); | ||
669 | xcb_create_gc(conn, gc, win, mask, mask_list); | ||
670 | } | ||
671 | |||
672 | static int | ||
673 | _e_alert_atom_get(const char *name) | ||
674 | { | ||
675 | xcb_intern_atom_cookie_t cookie; | ||
676 | xcb_intern_atom_reply_t *reply; | ||
677 | int a; | ||
678 | |||
679 | cookie = xcb_intern_atom_unchecked(conn, 0, strlen(name), name); | ||
680 | reply = xcb_intern_atom_reply(conn, cookie, NULL); | ||
681 | if (!reply) return XCB_ATOM_NONE; | ||
682 | a = reply->atom; | ||
683 | free(reply); | ||
684 | return a; | ||
685 | } | ||
686 | |||
687 | static xcb_window_t | ||
688 | _e_alert_comp_win_get(void) | ||
689 | { | ||
690 | xcb_get_property_cookie_t cookie; | ||
691 | xcb_get_property_reply_t *reply; | ||
692 | uint32_t *v; | ||
693 | int atom_cardinal, atom_composite_win; | ||
694 | xcb_window_t r = 0; | ||
695 | |||
696 | atom_cardinal = _e_alert_atom_get("CARDINAL"); | ||
697 | atom_composite_win = _e_alert_atom_get("_E_COMP_WINDOW"); | ||
698 | |||
699 | cookie = xcb_get_property_unchecked(conn, 0, screen->root, atom_composite_win, | ||
700 | atom_cardinal, 0, 0x7fffffff); | ||
701 | reply = xcb_get_property_reply(conn, cookie, NULL); | ||
702 | if (!reply) return 0; | ||
703 | |||
704 | v = xcb_get_property_value(reply); | ||
705 | if (v) r = v[0]; | ||
706 | |||
707 | free(reply); | ||
708 | return r; | ||
709 | } | ||
710 | |||
711 | static Eina_Bool | ||
712 | _e_alert_root_tainted_get(void) | ||
713 | { | ||
714 | xcb_get_property_cookie_t cookie; | ||
715 | xcb_get_property_reply_t *reply; | ||
716 | uint32_t *v; | ||
717 | int atom_cardinal, atom_tainted; | ||
718 | int r = 0; | ||
719 | |||
720 | atom_cardinal = _e_alert_atom_get("CARDINAL"); | ||
721 | atom_tainted = _e_alert_atom_get("_E_TAINTED"); | ||
722 | |||
723 | cookie = xcb_get_property_unchecked(conn, 0, screen->root, atom_tainted, | ||
724 | atom_cardinal, 0, 0x7fffffff); | ||
725 | reply = xcb_get_property_reply(conn, cookie, NULL); | ||
726 | if (!reply) return EINA_TRUE; | ||
727 | |||
728 | v = xcb_get_property_value(reply); | ||
729 | if (v) r = v[0]; | ||
730 | |||
731 | free(reply); | ||
732 | return !!r; | ||
733 | } | ||
734 | |||
735 | static void | ||
736 | _e_alert_display(void) | ||
737 | { | ||
738 | xcb_char2b_t *str = NULL; | ||
739 | xcb_query_text_extents_cookie_t cookie; | ||
740 | xcb_query_text_extents_reply_t *reply; | ||
741 | int x = 0, w = 0; | ||
742 | |||
743 | tainted = _e_alert_root_tainted_get(); | ||
744 | |||
745 | str = _e_alert_build_string(title); | ||
746 | |||
747 | cookie = | ||
748 | xcb_query_text_extents_unchecked(conn, font, strlen(title), str); | ||
749 | reply = xcb_query_text_extents_reply(conn, cookie, NULL); | ||
750 | if (reply) | ||
751 | { | ||
752 | fa = reply->font_ascent; | ||
753 | fh = (fa + reply->font_descent); | ||
754 | fw = reply->overall_width; | ||
755 | free(reply); | ||
756 | } | ||
757 | free(str); | ||
758 | |||
759 | /* move buttons */ | ||
760 | x = 20; | ||
761 | w = (WINDOW_WIDTH / 2) - 40; | ||
762 | _e_alert_button_move_resize(btn1, x, WINDOW_HEIGHT - 20 - (fh + 20), | ||
763 | w, (fh + 20)); | ||
764 | |||
765 | x = ((WINDOW_WIDTH / 2) + 20); | ||
766 | _e_alert_button_move_resize(btn2, x, WINDOW_HEIGHT - 20 - (fh + 20), | ||
767 | w, (fh + 20)); | ||
768 | |||
769 | comp_win = _e_alert_comp_win_get(); | ||
770 | if (comp_win) | ||
771 | { | ||
772 | xcb_rectangle_t rect; | ||
773 | int wx = 0, wy = 0; | ||
774 | |||
775 | wx = ((sw - WINDOW_WIDTH) / 2); | ||
776 | wy = ((sh - WINDOW_HEIGHT) / 2); | ||
777 | |||
778 | rect.x = wx; | ||
779 | rect.y = wy; | ||
780 | rect.width = WINDOW_WIDTH; | ||
781 | rect.height = WINDOW_HEIGHT; | ||
782 | |||
783 | xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET, | ||
784 | XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, | ||
785 | comp_win, 0, 0, 1, &rect); | ||
786 | |||
787 | xcb_reparent_window(conn, win, comp_win, wx, wy); | ||
788 | } | ||
789 | |||
790 | /* map and raise main window */ | ||
791 | xcb_map_window(conn, win); | ||
792 | _e_alert_window_raise(win); | ||
793 | |||
794 | /* grab pointer & keyboard */ | ||
795 | xcb_grab_pointer_unchecked(conn, 0, win, | ||
796 | (XCB_EVENT_MASK_BUTTON_PRESS | | ||
797 | XCB_EVENT_MASK_BUTTON_RELEASE), | ||
798 | XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, | ||
799 | XCB_NONE, XCB_NONE, XCB_CURRENT_TIME); | ||
800 | xcb_grab_keyboard_unchecked(conn, 0, win, XCB_CURRENT_TIME, | ||
801 | XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); | ||
802 | xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, | ||
803 | win, XCB_CURRENT_TIME); | ||
804 | |||
805 | /* flush screen */ | ||
806 | xcb_flush(conn); | ||
807 | |||
808 | /* sync */ | ||
809 | _e_alert_sync(); | ||
810 | } | ||
811 | |||
812 | static void | ||
813 | _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h) | ||
814 | { | ||
815 | uint32_t list[4], mask; | ||
816 | |||
817 | if (!btn) return; | ||
818 | |||
819 | mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | | ||
820 | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); | ||
821 | list[0] = x; | ||
822 | list[1] = y; | ||
823 | list[2] = w; | ||
824 | list[3] = h; | ||
825 | |||
826 | xcb_configure_window(conn, btn, mask, (const uint32_t *)&list); | ||
827 | } | ||
828 | |||
829 | static void | ||
830 | _e_alert_window_raise(xcb_window_t window) | ||
831 | { | ||
832 | uint32_t list[] = { XCB_STACK_MODE_ABOVE }; | ||
833 | |||
834 | if (!window) return; | ||
835 | xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_STACK_MODE, list); | ||
836 | } | ||
837 | |||
838 | static void | ||
839 | _e_alert_sync(void) | ||
840 | { | ||
841 | free(xcb_get_input_focus_reply(conn, | ||
842 | xcb_get_input_focus(conn), NULL)); | ||
843 | } | ||
844 | |||
845 | static void | ||
846 | _e_alert_shutdown(void) | ||
847 | { | ||
848 | if (!xcb_connection_has_error(conn)) | ||
849 | { | ||
850 | xcb_close_font(conn, font); | ||
851 | xcb_destroy_window(conn, btn1); | ||
852 | xcb_destroy_window(conn, btn2); | ||
853 | xcb_destroy_window(conn, win); | ||
854 | if (comp_win) xcb_destroy_window(conn, comp_win); | ||
855 | xcb_free_gc(conn, gc); | ||
856 | xcb_disconnect(conn); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | static void | ||
861 | _e_alert_run(void) | ||
862 | { | ||
863 | xcb_generic_event_t *event = NULL; | ||
864 | |||
865 | xcb_flush(conn); | ||
866 | while ((event = xcb_wait_for_event(conn))) | ||
867 | { | ||
868 | switch (event->response_type & ~0x80) | ||
869 | { | ||
870 | case XCB_BUTTON_PRESS: | ||
871 | ret = _e_alert_handle_button_press(event); | ||
872 | break; | ||
873 | |||
874 | case XCB_KEY_PRESS: | ||
875 | ret = _e_alert_handle_key_press(event); | ||
876 | break; | ||
877 | |||
878 | case XCB_EXPOSE: | ||
879 | { | ||
880 | xcb_expose_event_t *ev; | ||
881 | |||
882 | ev = (xcb_expose_event_t *)event; | ||
883 | if (ev->window != win) break; | ||
884 | |||
885 | _e_alert_draw(); | ||
886 | _e_alert_sync(); | ||
887 | |||
888 | break; | ||
889 | } | ||
890 | |||
891 | default: | ||
892 | break; | ||
893 | } | ||
894 | free(event); | ||
895 | if (ret > 0) return; | ||
896 | } | ||
897 | } | ||
898 | |||
899 | static void | ||
900 | _e_alert_draw(void) | ||
901 | { | ||
902 | _e_alert_draw_outline(); | ||
903 | _e_alert_draw_title_outline(); | ||
904 | _e_alert_draw_title(); | ||
905 | _e_alert_draw_text(); | ||
906 | _e_alert_draw_button_outlines(); | ||
907 | _e_alert_draw_button_text(); | ||
908 | |||
909 | xcb_flush(conn); | ||
910 | } | ||
911 | |||
912 | static int | ||
913 | _e_alert_handle_key_press(xcb_generic_event_t *event) | ||
914 | { | ||
915 | xcb_key_symbols_t *symbols; | ||
916 | xcb_key_press_event_t *ev; | ||
917 | xcb_keysym_t key; | ||
918 | int r = 0; | ||
919 | |||
920 | ev = (xcb_key_press_event_t *)event; | ||
921 | symbols = xcb_key_symbols_alloc(conn); | ||
922 | key = xcb_key_symbols_get_keysym(symbols, ev->detail, 0); | ||
923 | |||
924 | if (key == XK_F1) | ||
925 | r = 2; | ||
926 | else if (key == XK_F12) | ||
927 | r = 1; | ||
928 | |||
929 | xcb_key_symbols_free(symbols); | ||
930 | |||
931 | return r; | ||
932 | } | ||
933 | |||
934 | static int | ||
935 | _e_alert_handle_button_press(xcb_generic_event_t *event) | ||
936 | { | ||
937 | xcb_button_press_event_t *ev; | ||
938 | |||
939 | ev = (xcb_button_press_event_t *)event; | ||
940 | if (ev->child == btn1) | ||
941 | return 1; | ||
942 | else if (ev->child == btn2) | ||
943 | return 2; | ||
944 | else | ||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | static xcb_char2b_t * | ||
949 | _e_alert_build_string(const char *str) | ||
950 | { | ||
951 | unsigned int i = 0; | ||
952 | xcb_char2b_t *r = NULL; | ||
953 | |||
954 | if (!(r = malloc(strlen(str) * sizeof(xcb_char2b_t)))) | ||
955 | return NULL; | ||
956 | |||
957 | for (i = 0; i < strlen(str); i++) | ||
958 | { | ||
959 | r[i].byte1 = 0; | ||
960 | r[i].byte2 = str[i]; | ||
961 | } | ||
962 | |||
963 | return r; | ||
964 | } | ||
965 | |||
966 | static void | ||
967 | _e_alert_draw_outline(void) | ||
968 | { | ||
969 | xcb_rectangle_t rect; | ||
970 | |||
971 | /* draw outline */ | ||
972 | rect.x = 0; | ||
973 | rect.y = 0; | ||
974 | rect.width = (WINDOW_WIDTH - 1); | ||
975 | rect.height = (WINDOW_HEIGHT - 1); | ||
976 | xcb_poly_rectangle(conn, win, gc, 1, &rect); | ||
977 | } | ||
978 | |||
979 | static void | ||
980 | _e_alert_draw_title_outline(void) | ||
981 | { | ||
982 | xcb_rectangle_t rect; | ||
983 | |||
984 | /* draw title box */ | ||
985 | rect.x = 2; | ||
986 | rect.y = 2; | ||
987 | rect.width = (WINDOW_WIDTH - 4 - 1); | ||
988 | rect.height = (fh + 4 + 2); | ||
989 | xcb_poly_rectangle(conn, win, gc, 1, &rect); | ||
990 | } | ||
991 | |||
992 | static void | ||
993 | _e_alert_draw_title(void) | ||
994 | { | ||
995 | int x = 0, y = 0; | ||
996 | |||
997 | /* draw title */ | ||
998 | x = (2 + 2 + ((WINDOW_WIDTH - 4 - 4 - fw) / 2)); | ||
999 | y = (2 + 2 + fh); | ||
1000 | |||
1001 | xcb_image_text_8(conn, strlen(title), win, gc, x, y, title); | ||
1002 | } | ||
1003 | |||
1004 | static void | ||
1005 | _e_alert_draw_text(void) | ||
1006 | { | ||
1007 | char warn[1024], msg[4096], line[1024]; | ||
1008 | unsigned int i = 0, j = 0, k = 0; | ||
1009 | |||
1010 | if (!tainted) | ||
1011 | { | ||
1012 | if (exit_gdb) | ||
1013 | { | ||
1014 | snprintf(msg, sizeof(msg), | ||
1015 | "This is not meant to happen and is likely a sign of \n" | ||
1016 | "a bug in Enlightenment or the libraries it relies \n" | ||
1017 | "on. We were not able to generate a backtrace, check \n" | ||
1018 | "if your 'sysactions.conf' has an 'gdb' action line.\n" | ||
1019 | "\n" | ||
1020 | "Please compile latest Git E and EFL with\n" | ||
1021 | "-g and -ggdb3 in your CFLAGS.\n"); | ||
1022 | } | ||
1023 | else if (backtrace_str) | ||
1024 | { | ||
1025 | snprintf(msg, sizeof(msg), | ||
1026 | "This is not meant to happen and is likely a sign of \n" | ||
1027 | "a bug in Enlightenment or the libraries it relies \n" | ||
1028 | "on. You will find an backtrace of E (%d) in :\n" | ||
1029 | "'%s'\n" | ||
1030 | "Before reporting issue, compile latest E and EFL\n" | ||
1031 | "from Git with '-g -ggdb3' in your CFLAGS.\n" | ||
1032 | "You can then report this crash on :\n" | ||
1033 | "https://phab.enlightenment.org/maniphest/.\n", | ||
1034 | pid, backtrace_str); | ||
1035 | } | ||
1036 | else | ||
1037 | { | ||
1038 | snprintf(msg, sizeof(msg), | ||
1039 | "This is not meant to happen and is likely a sign of \n" | ||
1040 | "a bug in Enlightenment or the libraries it relies \n" | ||
1041 | "on. You can gdb attach to this process (%d) now \n" | ||
1042 | "to try debug it or you could logout, or just hit \n" | ||
1043 | "recover to try and get your desktop back the way \n" | ||
1044 | "it was.\n" | ||
1045 | "\n" | ||
1046 | "Please compile latest Git E and EFL with\n" | ||
1047 | "-g and -ggdb3 in your CFLAGS.\n", pid); | ||
1048 | } | ||
1049 | } | ||
1050 | else | ||
1051 | { | ||
1052 | snprintf(msg, sizeof(msg), | ||
1053 | "This is not meant to happen and is likely\n" | ||
1054 | "a sign of a bug, but you are using unsupported\n" | ||
1055 | "modules; before reporting this issue, please\n" | ||
1056 | "unload them and try to see if the bug is still\n" | ||
1057 | "there. Also update to latest Git and be sure to\n" | ||
1058 | "compile E and EFL with -g and -ggdb3 in your CFLAGS"); | ||
1059 | } | ||
1060 | |||
1061 | strcpy(warn, ""); | ||
1062 | |||
1063 | for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i) | ||
1064 | if (signal_name[i].signal == sig) | ||
1065 | snprintf(warn, sizeof(warn), | ||
1066 | "This is very bad. Enlightenment %s'd.", | ||
1067 | signal_name[i].name); | ||
1068 | |||
1069 | /* draw text */ | ||
1070 | k = (fh + 12); | ||
1071 | xcb_image_text_8(conn, strlen(warn), win, gc, | ||
1072 | 4, (k + fa), warn); | ||
1073 | k += (2 * (fh + 2)); | ||
1074 | for (i = 0; msg[i]; ) | ||
1075 | { | ||
1076 | line[j++] = msg[i++]; | ||
1077 | if (line[j - 1] == '\n') | ||
1078 | { | ||
1079 | line[j - 1] = 0; | ||
1080 | j = 0; | ||
1081 | xcb_image_text_8(conn, strlen(line), win, gc, | ||
1082 | 4, (k + fa), line); | ||
1083 | k += (fh + 2); | ||
1084 | } | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | static void | ||
1089 | _e_alert_draw_button_outlines(void) | ||
1090 | { | ||
1091 | xcb_rectangle_t rect; | ||
1092 | |||
1093 | rect.x = 0; | ||
1094 | rect.y = 0; | ||
1095 | rect.width = (WINDOW_WIDTH / 2) - 40 - 1; | ||
1096 | rect.height = (fh + 20) - 1; | ||
1097 | |||
1098 | /* draw button outlines */ | ||
1099 | xcb_poly_rectangle(conn, btn1, gc, 1, &rect); | ||
1100 | xcb_poly_rectangle(conn, btn2, gc, 1, &rect); | ||
1101 | } | ||
1102 | |||
1103 | static void | ||
1104 | _e_alert_draw_button_text(void) | ||
1105 | { | ||
1106 | xcb_char2b_t *str = NULL; | ||
1107 | xcb_query_text_extents_cookie_t cookie; | ||
1108 | xcb_query_text_extents_reply_t *reply; | ||
1109 | int x = 0, w = 0, bw = 0; | ||
1110 | |||
1111 | bw = (WINDOW_WIDTH / 2) - 40 - 1; | ||
1112 | |||
1113 | /* draw button1 text */ | ||
1114 | str = _e_alert_build_string(str1); | ||
1115 | |||
1116 | cookie = | ||
1117 | xcb_query_text_extents_unchecked(conn, font, strlen(str1), str); | ||
1118 | reply = xcb_query_text_extents_reply(conn, cookie, NULL); | ||
1119 | if (reply) | ||
1120 | { | ||
1121 | w = reply->overall_width; | ||
1122 | free(reply); | ||
1123 | } | ||
1124 | free(str); | ||
1125 | |||
1126 | x = (5 + ((bw - w) / 2)); | ||
1127 | |||
1128 | xcb_image_text_8(conn, strlen(str1), btn1, gc, x, (10 + fa), str1); | ||
1129 | |||
1130 | /* draw button2 text */ | ||
1131 | str = _e_alert_build_string(str2); | ||
1132 | |||
1133 | cookie = | ||
1134 | xcb_query_text_extents_unchecked(conn, font, strlen(str2), str); | ||
1135 | reply = xcb_query_text_extents_reply(conn, cookie, NULL); | ||
1136 | if (reply) | ||
1137 | { | ||
1138 | w = reply->overall_width; | ||
1139 | free(reply); | ||
1140 | } | ||
1141 | free(str); | ||
1142 | |||
1143 | x = (5 + ((bw - w) / 2)); | ||
1144 | |||
1145 | xcb_image_text_8(conn, strlen(str2), btn2, gc, x, (10 + fa), str2); | ||
1146 | } | ||
1147 | #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', | |||
530 | install : true | 530 | install : true |
531 | ) | 531 | ) |
532 | 532 | ||
533 | deps_e_alert = [] | 533 | deps_e_alert = [ dep_elementary ] |
534 | if config_h.has('HAVE_WAYLAND') == true | ||
535 | deps_e_alert += [ dep_ecore_drm2, dep_ecore_input, dep_dl ] | ||
536 | endif | ||
537 | if config_h.has('HAVE_WAYLAND_ONLY') == false | 534 | if config_h.has('HAVE_WAYLAND_ONLY') == false |
538 | deps_e_alert += [ | 535 | deps_e_alert += [ |
539 | dependency('xcb'), | 536 | dep_ecore_x |
540 | dependency('xcb-shape'), | ||
541 | dependency('xcb-keysyms') | ||
542 | ] | 537 | ] |
543 | endif | 538 | endif |
544 | executable('enlightenment_alert', | 539 | executable('enlightenment_alert', |
545 | [ 'e_alert_main.c' ], | 540 | [ 'e_alert_main.c' ], |
546 | include_directories: include_directories('../..'), | 541 | include_directories: include_directories('../..'), |
547 | dependencies : [ dep_eina, dep_ecore, dep_evas, dep_ecore_ipc, deps_e_alert ], | 542 | dependencies : [ deps_e_alert ], |
548 | install_dir : dir_e_utils, | 543 | install_dir : dir_e_utils, |
549 | install : true | 544 | install : true |
550 | ) | 545 | ) |