e: simplify e_alert code.

SVN revision: 63035
This commit is contained in:
Cedric BAIL 2011-08-31 13:52:29 +00:00
parent 1b07bbd5d3
commit 0f136c3582
4 changed files with 118 additions and 167 deletions

View File

@ -1,64 +1,77 @@
#include "e.h" #include "e.h"
/* local function prototypes */
static Eina_Bool _e_alert_cb_exe_del(void *data __UNUSED__, int type __UNUSED__, void *event);
/* local variables */
static Ecore_Exe *alert_exe = NULL;
static Ecore_Event_Handler *alert_exe_hdl = NULL;
/* public variables */ /* public variables */
EAPI unsigned long e_alert_composite_win = 0; EAPI unsigned long e_alert_composite_win = 0;
EINTERN int EINTERN int
e_alert_init(void) e_alert_init(void)
{ {
alert_exe_hdl =
ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_alert_cb_exe_del, NULL);
return 1; return 1;
} }
EINTERN int EINTERN int
e_alert_shutdown(void) e_alert_shutdown(void)
{ {
e_alert_hide();
if (alert_exe_hdl) ecore_event_handler_del(alert_exe_hdl);
alert_exe_hdl = NULL;
return 1; return 1;
} }
EAPI void EAPI void
e_alert_show(int sig) e_alert_show(int sig)
{ {
char buf[8192]; char *args[4];
pid_t pid;
snprintf(buf, sizeof(buf), #define E_ALERT_EXE "/enlightenment/utils/enlightenment_alert"
"%s/enlightenment/utils/enlightenment_alert %d %lu %lu",
e_prefix_lib_get(), sig, (long unsigned int)getpid(),
e_alert_composite_win);
alert_exe = ecore_exe_run(buf, NULL); args[0] = alloca(strlen(e_prefix_lib_get()) + strlen(E_ALERT_EXE) + 1);
pause(); strcpy(args[0], e_prefix_lib_get());
strcat(args[0], E_ALERT_EXE);
args[1] = alloca(10);
snprintf(args[1], 10, "%d", sig);
args[2] = alloca(21);
snprintf(args[2], 21, "%lu", (long unsigned int)getpid());
args[3] = alloca(21);
snprintf(args[3], 21, "%lu", e_alert_composite_win);
pid = fork();
if (pid < -1)
goto restart_e;
if (pid == 0)
{
/* The child process */
execvp(args[0], args);
}
else
{
/* The parent process */
pid_t ret;
int status = 0;
do
{
ret = waitpid(pid, &status, 0);
if (errno == ECHILD)
break ;
}
while (ret != pid);
if (status == 0)
goto restart_e;
if (!WIFEXITED(status))
goto restart_e;
if (WEXITSTATUS(status) == 1)
goto restart_e;
exit(-11);
}
restart_e:
ecore_app_restart();
} }
EAPI void
e_alert_hide(void)
{
if (alert_exe) ecore_exe_terminate(alert_exe);
}
/* local functions */
static Eina_Bool
_e_alert_cb_exe_del(void *data __UNUSED__, int type __UNUSED__, void *event)
{
Ecore_Exe_Event_Del *ev;
ev = event;
if (!alert_exe) return ECORE_CALLBACK_RENEW;
if (ev->exe == alert_exe) alert_exe = NULL;
return ECORE_CALLBACK_RENEW;
}

View File

@ -14,7 +14,6 @@ EINTERN int e_alert_init(void);
EINTERN int e_alert_shutdown(void); EINTERN int e_alert_shutdown(void);
EAPI void e_alert_show(int sig); EAPI void e_alert_show(int sig);
EAPI void e_alert_hide(void);
#endif #endif
#endif #endif

View File

@ -16,8 +16,6 @@
#define WINDOW_HEIGHT 240 #define WINDOW_HEIGHT 240
/* local function prototypes */ /* local function prototypes */
static int _e_alert_ipc_init(void);
static Eina_Bool _e_alert_ipc_server_add(void *data, int type, void *event);
static int _e_alert_connect(void); static int _e_alert_connect(void);
static void _e_alert_create(void); static void _e_alert_create(void);
static void _e_alert_display(void); static void _e_alert_display(void);
@ -36,11 +34,8 @@ static void _e_alert_draw_title(void);
static void _e_alert_draw_text(void); static void _e_alert_draw_text(void);
static void _e_alert_draw_button_outlines(void); static void _e_alert_draw_button_outlines(void);
static void _e_alert_draw_button_text(void); static void _e_alert_draw_button_text(void);
static void _e_alert_restart_e(void);
static void _e_alert_exit_e(void);
/* local variables */ /* local variables */
static Ecore_Ipc_Server *_ipc_server = NULL;
static xcb_connection_t *conn = NULL; static xcb_connection_t *conn = NULL;
static xcb_screen_t *screen = NULL; static xcb_screen_t *screen = NULL;
static xcb_window_t win = 0, comp_win = 0; static xcb_window_t win = 0, comp_win = 0;
@ -54,8 +49,8 @@ static const char *title = NULL, *str1 = NULL, *str2 = NULL;
static int ret = 0, sig = 0; static int ret = 0, sig = 0;
static pid_t pid; static pid_t pid;
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int i = 0; int i = 0;
@ -69,9 +64,9 @@ main(int argc, char **argv)
"do not use it.\n"); "do not use it.\n");
exit(0); exit(0);
} }
else if ((i == 1)) else if ((i == 1))
sig = atoi(argv[i]); // signal sig = atoi(argv[i]); // signal
else if ((i == 2)) else if ((i == 2))
pid = atoi(argv[i]); // E's pid pid = atoi(argv[i]); // E's pid
else if ((i == 3)) else if ((i == 3))
comp_win = atoi(argv[i]); // Composite Alert Window comp_win = atoi(argv[i]); // Composite Alert Window
@ -79,24 +74,10 @@ main(int argc, char **argv)
if (!ecore_init()) return EXIT_FAILURE; if (!ecore_init()) return EXIT_FAILURE;
ecore_app_args_set(argc, (const char **)argv); ecore_app_args_set(argc, (const char **)argv);
if (!ecore_ipc_init())
{
ecore_shutdown();
return EXIT_FAILURE;
}
if (!_e_alert_connect()) if (!_e_alert_connect())
{ {
printf("FAILED TO INIT ALERT SYSTEM!!!\n"); printf("FAILED TO INIT ALERT SYSTEM!!!\n");
ecore_ipc_shutdown();
ecore_shutdown();
return EXIT_FAILURE;
}
if (!_e_alert_ipc_init())
{
printf("Failed to Connect to Enlightenment!!!\n");
ecore_ipc_shutdown();
ecore_shutdown(); ecore_shutdown();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -110,35 +91,16 @@ main(int argc, char **argv)
_e_alert_run(); _e_alert_run();
_e_alert_shutdown(); _e_alert_shutdown();
if (ret == 1)
_e_alert_restart_e();
else if (ret == 2)
_e_alert_exit_e();
if (_ipc_server)
ecore_ipc_server_del(_ipc_server);
ecore_ipc_shutdown();
ecore_shutdown(); ecore_shutdown();
return EXIT_SUCCESS; /* ret == 1 => restart e => exit code 1 */
/* ret == 2 => exit e => any code will do that */
return ret;
} }
/* local functions */ /* local functions */
static int static int
_e_alert_ipc_init(void) _e_alert_connect(void)
{
char *edir = NULL;
if (!(edir = getenv("E_IPC_SOCKET"))) return 0;
_ipc_server =
ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, edir, 0, NULL);
if (!_ipc_server) return 0;
return 1;
}
static int
_e_alert_connect(void)
{ {
conn = xcb_connect(NULL, NULL); conn = xcb_connect(NULL, NULL);
if ((!conn) || (xcb_connection_has_error(conn))) if ((!conn) || (xcb_connection_has_error(conn)))
@ -302,13 +264,13 @@ _e_alert_button_move_resize(xcb_window_t btn, int x, int y, int w, int h)
xcb_configure_window(conn, btn, mask, (const uint32_t *)&list); xcb_configure_window(conn, btn, mask, (const uint32_t *)&list);
} }
static void static void
_e_alert_window_raise(xcb_window_t win) _e_alert_window_raise(xcb_window_t window)
{ {
uint32_t list[] = { XCB_STACK_MODE_ABOVE }; uint32_t list[] = { XCB_STACK_MODE_ABOVE };
if (!win) return; if (!window) return;
xcb_configure_window(conn, win, XCB_CONFIG_WINDOW_STACK_MODE, list); xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_STACK_MODE, list);
} }
static void static void
@ -411,21 +373,21 @@ _e_alert_handle_button_press(xcb_generic_event_t *event)
} }
static xcb_char2b_t * static xcb_char2b_t *
_e_alert_build_string(const char *str) _e_alert_build_string(const char *str)
{ {
unsigned int i = 0; unsigned int i = 0;
xcb_char2b_t *ret = NULL; xcb_char2b_t *r = NULL;
if (!(ret = malloc(strlen(str) * sizeof(xcb_char2b_t)))) if (!(r = malloc(strlen(str) * sizeof(xcb_char2b_t))))
return NULL; return NULL;
for (i = 0; i < strlen(str); i++) for (i = 0; i < strlen(str); i++)
{ {
ret[i].byte1 = 0; r[i].byte1 = 0;
ret[i].byte2 = str[i]; r[i].byte2 = str[i];
} }
return ret; return r;
} }
static void static void
@ -468,14 +430,25 @@ _e_alert_draw_title(void)
xcb_image_text_8(conn, strlen(title), win, gc, x, y, title); xcb_image_text_8(conn, strlen(title), win, gc, x, y, title);
} }
static void struct {
_e_alert_draw_text(void) int signal;
const char *name;
} signal_name[5] = {
{ SIGSEGV, "SEGV" },
{ SIGILL, "SIGILL" },
{ SIGFPE, "SIGFPE" },
{ SIGBUS, "SIGBUS" },
{ SIGABRT, "SIGABRT" }
};
static void
_e_alert_draw_text(void)
{ {
xcb_void_cookie_t cookie; xcb_void_cookie_t cookie;
char warn[1024], msg[PATH_MAX], line[1024]; char warn[1024], msg[PATH_MAX], line[1024];
int i = 0, j = 0, k = 0; unsigned int i = 0, j = 0, k = 0;
snprintf(msg, sizeof(msg), snprintf(msg, sizeof(msg),
"This is not meant to happen and is likely a sign of \n" "This is not meant to happen and is likely a sign of \n"
"a bug in Enlightenment or the libraries it relies \n" "a bug in Enlightenment or the libraries it relies \n"
"on. You can gdb attach to this process (%d) now \n" "on. You can gdb attach to this process (%d) now \n"
@ -485,55 +458,37 @@ _e_alert_draw_text(void)
"\n" "\n"
"Please compile everything with -g in your CFLAGS.", pid); "Please compile everything with -g in your CFLAGS.", pid);
switch (sig) strcpy(warn, "");
{
case SIGSEGV: for (i = 0; i < sizeof(signal_name) / sizeof(signal_name[0]); ++i)
snprintf(warn, sizeof(warn), if (signal_name[i].signal == sig)
"This is very bad. Enlightenment SEGV'd."); snprintf(warn, sizeof(warn),
break; "This is very bad. Enlightenment %s'd.",
case SIGILL: signal_name[i].name);
snprintf(warn, sizeof(warn),
"This is very bad. Enlightenment SIGILL'd.");
break;
case SIGFPE:
snprintf(warn, sizeof(warn),
"This is very bad. Enlightenment SIGFPE'd.");
break;
case SIGBUS:
snprintf(warn, sizeof(warn),
"This is very bad. Enlightenment SIGBUS'd.");
break;
case SIGABRT:
snprintf(warn, sizeof(warn),
"This is very bad. Enlightenment SIGABRT'd.");
break;
default:
break;
}
/* draw text */ /* draw text */
k = (fh + 12); k = (fh + 12);
cookie = cookie =
xcb_image_text_8(conn, strlen(warn), win, gc, xcb_image_text_8(conn, strlen(warn), win, gc,
4, (k + fa), warn); 4, (k + fa), warn);
k += (2 * (fh + 2)); k += (2 * (fh + 2));
while (msg[i]) while (msg[i])
{ {
line[j++] = msg[i++]; line[j++] = msg[i++];
if (line[j - 1] == '\n') if (line[j - 1] == '\n')
{ {
line[j - 1] = 0; line[j - 1] = 0;
j = 0; j = 0;
cookie = cookie =
xcb_image_text_8(conn, strlen(line), win, gc, xcb_image_text_8(conn, strlen(line), win, gc,
4, (k + fa), line); 4, (k + fa), line);
k += (fh + 2); k += (fh + 2);
} }
} }
} }
static void static void
_e_alert_draw_button_outlines(void) _e_alert_draw_button_outlines(void)
{ {
xcb_rectangle_t rect; xcb_rectangle_t rect;
@ -547,8 +502,8 @@ _e_alert_draw_button_outlines(void)
xcb_poly_rectangle(conn, btn2, gc, 1, &rect); xcb_poly_rectangle(conn, btn2, gc, 1, &rect);
} }
static void static void
_e_alert_draw_button_text(void) _e_alert_draw_button_text(void)
{ {
xcb_void_cookie_t dcookie; xcb_void_cookie_t dcookie;
xcb_char2b_t *str = NULL; xcb_char2b_t *str = NULL;
@ -561,10 +516,10 @@ _e_alert_draw_button_text(void)
/* draw button1 text */ /* draw button1 text */
str = _e_alert_build_string(str1); str = _e_alert_build_string(str1);
cookie = cookie =
xcb_query_text_extents_unchecked(conn, font, strlen(str1), str); xcb_query_text_extents_unchecked(conn, font, strlen(str1), str);
reply = xcb_query_text_extents_reply(conn, cookie, NULL); reply = xcb_query_text_extents_reply(conn, cookie, NULL);
if (reply) if (reply)
{ {
w = reply->overall_width; w = reply->overall_width;
free(reply); free(reply);
@ -573,16 +528,16 @@ _e_alert_draw_button_text(void)
x = (5 + ((bw - w) / 2)); x = (5 + ((bw - w) / 2));
dcookie = dcookie =
xcb_image_text_8(conn, strlen(str1), btn1, gc, x, (10 + fa), str1); xcb_image_text_8(conn, strlen(str1), btn1, gc, x, (10 + fa), str1);
/* draw button2 text */ /* draw button2 text */
str = _e_alert_build_string(str2); str = _e_alert_build_string(str2);
cookie = cookie =
xcb_query_text_extents_unchecked(conn, font, strlen(str2), str); xcb_query_text_extents_unchecked(conn, font, strlen(str2), str);
reply = xcb_query_text_extents_reply(conn, cookie, NULL); reply = xcb_query_text_extents_reply(conn, cookie, NULL);
if (reply) if (reply)
{ {
w = reply->overall_width; w = reply->overall_width;
free(reply); free(reply);
@ -591,22 +546,6 @@ _e_alert_draw_button_text(void)
x = (5 + ((bw - w) / 2)); x = (5 + ((bw - w) / 2));
dcookie = dcookie =
xcb_image_text_8(conn, strlen(str2), btn2, gc, x, (10 + fa), str2); xcb_image_text_8(conn, strlen(str2), btn2, gc, x, (10 + fa), str2);
} }
static void
_e_alert_restart_e(void)
{
kill(pid, SIGUSR2);
ecore_ipc_server_send(_ipc_server, 8, 0, 0, 0, 0, NULL, 0);
ecore_ipc_server_flush(_ipc_server);
}
static void
_e_alert_exit_e(void)
{
kill(pid, SIGUSR2);
ecore_ipc_server_send(_ipc_server, 8, 1, 0, 0, 0, NULL, 0);
ecore_ipc_server_flush(_ipc_server);
}

View File

@ -202,9 +202,9 @@ _e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event)
e_init_client_data(e); e_init_client_data(e);
break; break;
case E_IPC_DOMAIN_ALERT: case E_IPC_DOMAIN_ALERT:
{ {
switch (e->minor) switch (e->minor)
{ {
case E_ALERT_OP_RESTART: case E_ALERT_OP_RESTART:
ecore_app_restart(); ecore_app_restart();