1 #include "config.h"
2
3 //# include "e_drm2.x"
4
5 #include <Elementary.h>
6 #ifndef HAVE_WAYLAND_ONLY
7 # include <Ecore_X.h>
8 #endif
9
10 static int ret = 0, sig = 0, exit_gdb = 0;
11 static pid_t pid;
12 static Eina_Bool tainted = EINA_FALSE;
13 static const char *backtrace_str = NULL;
14
15 //#define FONT "TopazPlus_a500_v1.0.pcf"
16 //#define FONT "terminus-16.pcf"
17 #define FONT "Topaz_a500_v1.0.ttf"
18 #define FONT_FALLBACK "Mono"
19 #define COL_BG 0, 0, 0, 255
20 #define COL_FG 255, 0, 0, 255
21 #define HDIV 10
22 #define PDIV 20
23 #define BLINK 0.8
24 #define RECOVER_BUTTON 1
25 #define RECOVER_KEY "F1"
26 #define ABORT_BUTTON 3
27 #define ABORT_KEY "F12"
28
title1(void)29 static inline const char *title1(void) {
30 return "Software Failure. Press left mouse button / F1 to recover, right mouse button / F12 to abort.";
31 }
title2(void)32 static inline const char *title2(void) { static char buf[512];
33 if (tainted) snprintf
34 (buf, sizeof(buf), "Tainted by unsupported modules");
35 else if (exit_gdb) snprintf
36 (buf, sizeof(buf), "Couldn't run gdb to collect a backtrace");
37 else if (backtrace_str) snprintf
38 (buf, sizeof(buf), "Backtrace log: %s", backtrace_str);
39 else snprintf
40 (buf, sizeof(buf), " ");
41 return buf;
42 }
title3(void)43 static inline const char *title3(void) { static char buf[512];
44 snprintf(buf, sizeof(buf), "Guru Meditation #%08d.%08d", pid, sig);
45 return buf;
46 }
47
48 /////////////////////////////////////////////////////////////////////////////
49
50 static Evas_Object *obj_base = NULL;
51 static Evas_Object *obj_outer = NULL;
52 static Evas_Object *obj_inner = NULL;
53 static Evas_Object *obj_line1 = NULL;
54 static Evas_Object *obj_line2 = NULL;
55 static Evas_Object *obj_line3 = NULL;
56
57 static void
mouse_up(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * o EINA_UNUSED,void * info)58 mouse_up(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *info)
59 {
60 Evas_Event_Mouse_Up *ev = info;
61
62 if (ev->button == RECOVER_BUTTON)
63 {
64 ret = 2;
65 elm_exit();
66 }
67 else if (ev->button == ABORT_BUTTON)
68 {
69 ret = 1;
70 elm_exit();
71 }
72 }
73
74 static void
key_down(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * o EINA_UNUSED,void * info)75 key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *info)
76 {
77 Evas_Event_Key_Down *ev = info;
78
79 if (!strcmp(ev->key, RECOVER_KEY))
80 {
81 ret = 2;
82 elm_exit();
83 }
84 else if (!strcmp(ev->key, ABORT_KEY))
85 {
86 ret = 1;
87 elm_exit();
88 }
89 }
90
91 static const char *
font_get(void)92 font_get(void)
93 {
94 const char *s = getenv("E_ALERT_FONT_DIR");
95 static char buf[4096];
96
97 if (s) snprintf(buf, sizeof(buf), "%s/"FONT, s);
98 else snprintf(buf, sizeof(buf), "%s", FONT_FALLBACK);
99 return buf;
100 }
101
102 static void
resize(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * o,void * info EINA_UNUSED)103 resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o, void *info EINA_UNUSED)
104 {
105 Evas_Coord w, h, tw, th;
106 const char *font = font_get();
107
108 evas_object_geometry_get(o, NULL, NULL, &w, &h);
109 h = w / HDIV;
110
111 evas_object_geometry_set(obj_base, 0, 0, w, h * HDIV * 2);
112 evas_object_geometry_set(obj_outer, (1 * h) / PDIV, (1 * h) / PDIV,
113 w - ((h * 2) / PDIV), h - ((h * 2) / PDIV));
114 evas_object_geometry_set(obj_inner, (2 * h) / PDIV, (2 * h) / PDIV,
115 w - ((h * 4) / PDIV), h - ((h * 4) / PDIV));
116
117 evas_object_text_font_set(obj_line1, font, h / 8);
118 evas_object_geometry_get(obj_line1, NULL, NULL, &tw, &th);
119 evas_object_move(obj_line1, (w - tw) / 2, (3 * h) / PDIV);
120
121 evas_object_text_font_set(obj_line2, font, h / 8);
122 evas_object_geometry_get(obj_line2, NULL, NULL, &tw, &th);
123 evas_object_move(obj_line2, (w - tw) / 2, (h - th) / 2);
124
125 evas_object_text_font_set(obj_line3, font, h / 8);
126 evas_object_geometry_get(obj_line3, NULL, NULL, &tw, &th);
127 evas_object_move(obj_line3, (w - tw) / 2, h - th - (3 * h) / PDIV);
128 }
129
130 static Eina_Bool
timer(void * data EINA_UNUSED)131 timer(void *data EINA_UNUSED)
132 {
133 if (evas_object_visible_get(obj_outer)) evas_object_hide(obj_outer);
134 else evas_object_show(obj_outer);
135 return EINA_TRUE;
136 }
137
138 static Eina_Bool
setup_display(void)139 setup_display(void)
140 {
141 Evas *e;
142 Evas_Object *win, *o;
143 const char *font = font_get();
144
145 win = o = elm_win_add(NULL, "e-alert", ELM_WIN_SPLASH);
146 if (!win) return EINA_FALSE;
147 e = evas_object_evas_get(win);
148 elm_win_override_set(o, EINA_TRUE);
149
150 obj_base = o = evas_object_rectangle_add(e);
151 evas_object_color_set(o, COL_BG);
152 evas_object_show(o);
153
154 obj_outer = o = evas_object_rectangle_add(e);
155 evas_object_color_set(o, COL_FG);
156 evas_object_pass_events_set(o, EINA_TRUE);
157 evas_object_show(o);
158
159 obj_inner = o = evas_object_rectangle_add(e);
160 evas_object_color_set(o, COL_BG);
161 evas_object_pass_events_set(o, EINA_TRUE);
162 evas_object_show(o);
163
164 obj_line1 = o = evas_object_text_add(e);
165 evas_object_color_set(o, COL_FG);
166 evas_object_text_font_set(o, font, 10);
167 evas_object_text_text_set(o, title1());
168 evas_object_pass_events_set(o, EINA_TRUE);
169 evas_object_show(o);
170
171 obj_line2 = o = evas_object_text_add(e);
172 evas_object_color_set(o, COL_FG);
173 evas_object_text_font_set(o, font, 10);
174 evas_object_text_text_set(o, title2());
175 evas_object_pass_events_set(o, EINA_TRUE);
176 evas_object_show(o);
177
178 obj_line3 = o = evas_object_text_add(e);
179 evas_object_color_set(o, COL_FG);
180 evas_object_text_font_set(o, font, 10);
181 evas_object_text_text_set(o, title3());
182 evas_object_pass_events_set(o, EINA_TRUE);
183 evas_object_show(o);
184
185 evas_object_event_callback_add(obj_base, EVAS_CALLBACK_MOUSE_UP, mouse_up, NULL);
186 evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN, key_down, NULL);
187 evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, resize, NULL);
188
189 ecore_timer_add(BLINK, timer, NULL);
190
191 resize(NULL, e, win, NULL);
192
193 #ifndef HAVE_WAYLAND_ONLY
194 if (getenv("DISPLAY"))
195 {
196 Ecore_X_Window root = ecore_x_window_root_first_get();
197 Ecore_X_Atom atom_composite_win = ecore_x_atom_get("_E_COMP_WINDOW");
198 unsigned int id;
199 if (ecore_x_window_prop_card32_get(root, atom_composite_win, &id, 1) > 0)
200 {
201 Ecore_X_Window elmwin = elm_win_xwindow_get(win);
202 ecore_x_window_reparent(elmwin, id, 0, 0);
203 Ecore_X_Randr_Output output = ecore_x_randr_primary_output_get(root);
204 Ecore_X_Randr_Crtc crct = ecore_x_randr_output_crtc_get(root, output);
205 int x = 0, y = 0, w = 1, h = 1;
206 ecore_x_randr_crtc_geometry_get(root, crct, &x, &y, &w, &h);
207 ecore_x_window_move_resize(elmwin, x, y, w, w / HDIV);
208 }
209 }
210 #endif
211
212 evas_object_show(win);
213
214 #ifndef HAVE_WAYLAND_ONLY
215 if (getenv("DISPLAY"))
216 {
217 Ecore_X_Window elmwin = elm_win_xwindow_get(win);
218 ecore_x_pointer_grab(elmwin);
219 ecore_x_keyboard_grab(elmwin);
220 }
221 #endif
222 return EINA_TRUE;
223 }
224
225 int
main(int argc,char ** argv)226 main(int argc, char **argv)
227 {
228 const char *s;
229 int i = 0;
230
231 for (i = 1; i < argc; i++)
232 {
233 if ((!strcmp(argv[i], "-h")) ||
234 (!strcmp(argv[i], "-help")) ||
235 (!strcmp(argv[i], "--help")))
236 {
237 printf("This is an internal tool for Enlightenment.\n"
238 "do not use it.\n");
239 exit(0);
240 }
241 else if (i == 1) sig = atoi(argv[i]); // signal
242 else if (i == 2) pid = atoi(argv[i]); // E's pid
243 else if (i == 3) exit_gdb = atoi(argv[i]);
244 else if (i == 4) backtrace_str = argv[i];
245 }
246 fprintf(stderr, "exit_gdb: %i\n", exit_gdb);
247
248 s = getenv("E_TAINTED");
249 if (s && !strcmp(s, "NO")) tainted = EINA_FALSE;
250 else if (s && !strcmp(s, "YES")) tainted = EINA_TRUE;
251
252 ecore_app_no_system_modules();
253 elm_init(argc, argv);
254
255 if (setup_display())
256 {
257 s = getenv("E_ALERT_SYSTEM_BIN");
258 if (s && s[0])
259 {
260 putenv("E_ALERT_BACKLIGHT_RESET=1");
261 ecore_exe_pipe_run
262 (s, ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
263 ECORE_EXE_NOT_LEADER | ECORE_EXE_TERM_WITH_PARENT, NULL);
264 }
265
266 elm_run();
267 }
268
269 return ret;
270 }
271