forked from enlightenment/enlightenment
parent
1b07bbd5d3
commit
0f136c3582
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue