|
|
|
@ -2,3 +2,692 @@ |
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 |
|
|
|
|
*/ |
|
|
|
|
#include "e.h" |
|
|
|
|
|
|
|
|
|
#define MAX_OUTPUT_CHARACTERS 5000 |
|
|
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
|
* - Clear e_exec_instances on shutdown |
|
|
|
|
* - Clear e_exec_start_pending on shutdown |
|
|
|
|
* - Create border add handler |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
typedef struct _E_Exec_Launch E_Exec_Launch; |
|
|
|
|
typedef struct _E_Exec_Instance E_Exec_Instance; |
|
|
|
|
|
|
|
|
|
struct _E_Exec_Launch |
|
|
|
|
{ |
|
|
|
|
E_Zone *zone; |
|
|
|
|
const char *launch_method; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct _E_Exec_Instance |
|
|
|
|
{ |
|
|
|
|
Efreet_Desktop *desktop; |
|
|
|
|
Ecore_Exe *exe; |
|
|
|
|
int launch_id; |
|
|
|
|
double launch_time; |
|
|
|
|
Ecore_Timer *expire_timer; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct _E_Config_Dialog_Data |
|
|
|
|
{ |
|
|
|
|
Efreet_Desktop *desktop; |
|
|
|
|
char *exec; |
|
|
|
|
|
|
|
|
|
Ecore_Exe_Event_Del event; |
|
|
|
|
Ecore_Exe_Event_Data *error; |
|
|
|
|
Ecore_Exe_Event_Data *read; |
|
|
|
|
|
|
|
|
|
char *label; |
|
|
|
|
char *exit; |
|
|
|
|
char *signal; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void _e_exec_cb_exec(void *data, Efreet_Desktop *desktop, char *exec, int remaining); |
|
|
|
|
static int _e_exec_cb_expire_timer(void *data); |
|
|
|
|
static int _e_exec_cb_exit(void *data, int type, void *event); |
|
|
|
|
|
|
|
|
|
static void _e_exec_error_dialog(Efreet_Desktop *desktop, const char *exec, Ecore_Exe_Event_Del *event, Ecore_Exe_Event_Data *error, Ecore_Exe_Event_Data *read); |
|
|
|
|
static void _fill_data(E_Config_Dialog_Data *cfdata); |
|
|
|
|
static void *_create_data(E_Config_Dialog *cfd); |
|
|
|
|
static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); |
|
|
|
|
static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); |
|
|
|
|
static Evas_Object *_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); |
|
|
|
|
static Evas_Object *_dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines); |
|
|
|
|
static void _dialog_save_cb(void *data, void *data2); |
|
|
|
|
|
|
|
|
|
static Evas_List *e_exec_start_pending = NULL; |
|
|
|
|
static Evas_Hash *e_exec_instances = NULL; |
|
|
|
|
static int startup_id = 0; |
|
|
|
|
|
|
|
|
|
static Ecore_Event_Handler *_e_exec_exit_handler = NULL; |
|
|
|
|
static Ecore_Event_Handler *_e_exec_border_add_handler = NULL; |
|
|
|
|
|
|
|
|
|
EAPI int |
|
|
|
|
e_exec_init(void) |
|
|
|
|
{ |
|
|
|
|
_e_exec_exit_handler = |
|
|
|
|
ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_exec_cb_exit, NULL); |
|
|
|
|
#if 0 |
|
|
|
|
_e_exec_border_add_handler = |
|
|
|
|
ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_exec_cb_event_border_add, NULL); |
|
|
|
|
#endif |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EAPI int |
|
|
|
|
e_exec_shutdown(void) |
|
|
|
|
{ |
|
|
|
|
char buf[256]; |
|
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%i", startup_id); |
|
|
|
|
e_util_env_set("E_STARTUP_ID", buf); |
|
|
|
|
|
|
|
|
|
if (_e_exec_exit_handler) ecore_event_handler_del(_e_exec_exit_handler); |
|
|
|
|
if (_e_exec_border_add_handler) ecore_event_handler_del(_e_exec_border_add_handler); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EAPI int |
|
|
|
|
e_exec(E_Zone *zone, Efreet_Desktop *desktop, const char *exec, |
|
|
|
|
Ecore_List *files, const char *launch_method) |
|
|
|
|
{ |
|
|
|
|
E_Exec_Launch *launch; |
|
|
|
|
|
|
|
|
|
if ((!desktop) && (!exec)) return 0; |
|
|
|
|
launch = E_NEW(E_Exec_Launch, 1); |
|
|
|
|
if (!launch) return 0; |
|
|
|
|
if (zone) |
|
|
|
|
{ |
|
|
|
|
launch->zone = zone; |
|
|
|
|
e_object_ref(E_OBJECT(launch->zone)); |
|
|
|
|
} |
|
|
|
|
if (launch_method) launch->launch_method = evas_stringshare_add(launch_method); |
|
|
|
|
|
|
|
|
|
if (desktop) |
|
|
|
|
{ |
|
|
|
|
if (exec) |
|
|
|
|
_e_exec_cb_exec(launch, NULL, strdup(exec), 0); |
|
|
|
|
else |
|
|
|
|
efreet_desktop_command_get(desktop, files, _e_exec_cb_exec, launch); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_e_exec_cb_exec(launch, NULL, strdup(exec), 0); |
|
|
|
|
} |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_e_exec_cb_exec(void *data, Efreet_Desktop *desktop, char *exec, int remaining) |
|
|
|
|
{ |
|
|
|
|
E_Exec_Instance *inst = NULL; |
|
|
|
|
E_Exec_Launch *launch; |
|
|
|
|
Ecore_Exe *exe; |
|
|
|
|
char *penv_display; |
|
|
|
|
char buf[4096]; |
|
|
|
|
|
|
|
|
|
launch = data; |
|
|
|
|
if (desktop) |
|
|
|
|
{ |
|
|
|
|
inst = E_NEW(E_Exec_Instance, 1); |
|
|
|
|
if (!inst) return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (startup_id == 0) |
|
|
|
|
{ |
|
|
|
|
const char *p; |
|
|
|
|
p = getenv("E_STARTUP_ID"); |
|
|
|
|
if (p) startup_id = atoi(p); |
|
|
|
|
e_util_env_set("E_STARTUP_ID", NULL); |
|
|
|
|
} |
|
|
|
|
if (++startup_id < 1) startup_id = 1; |
|
|
|
|
/* save previous env vars we need to save */ |
|
|
|
|
penv_display = getenv("DISPLAY"); |
|
|
|
|
if (penv_display) penv_display = strdup(penv_display); |
|
|
|
|
if ((penv_display) && (launch->zone)) |
|
|
|
|
{ |
|
|
|
|
const char *p1, *p2; |
|
|
|
|
char buf2[32]; |
|
|
|
|
int head; |
|
|
|
|
|
|
|
|
|
head = launch->zone->container->manager->num; |
|
|
|
|
|
|
|
|
|
/* set env vars */ |
|
|
|
|
p1 = strrchr(penv_display, ':'); |
|
|
|
|
p2 = strrchr(penv_display, '.'); |
|
|
|
|
if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */ |
|
|
|
|
{ |
|
|
|
|
/* yes it could overflow... but who will overflow DISPLAY eh? why? to
|
|
|
|
|
* "exploit" your own applications running as you? |
|
|
|
|
*/ |
|
|
|
|
strcpy(buf, penv_display); |
|
|
|
|
buf[p2 - penv_display + 1] = 0; |
|
|
|
|
snprintf(buf2, sizeof(buf2), "%i", head); |
|
|
|
|
strcat(buf, buf2); |
|
|
|
|
} |
|
|
|
|
else if (p1) /* "blah:x */ |
|
|
|
|
{ |
|
|
|
|
strcpy(buf, penv_display); |
|
|
|
|
snprintf(buf2, sizeof(buf2), ".%i", head); |
|
|
|
|
strcat(buf, buf2); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
strcpy(buf, penv_display); |
|
|
|
|
e_util_env_set("DISPLAY", buf); |
|
|
|
|
} |
|
|
|
|
snprintf(buf, sizeof(buf), "E_START|%i", startup_id); |
|
|
|
|
e_util_env_set("DESKTOP_STARTUP_ID", buf); |
|
|
|
|
|
|
|
|
|
e_util_library_path_strip(); |
|
|
|
|
exe = ecore_exe_pipe_run(exec, |
|
|
|
|
ECORE_EXE_PIPE_AUTO | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR | |
|
|
|
|
ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED, |
|
|
|
|
inst); |
|
|
|
|
e_util_library_path_restore(); |
|
|
|
|
if (penv_display) |
|
|
|
|
{ |
|
|
|
|
e_util_env_set("DISPLAY", penv_display); |
|
|
|
|
free(penv_display); |
|
|
|
|
} |
|
|
|
|
if (!exe) |
|
|
|
|
{ |
|
|
|
|
E_FREE(inst); |
|
|
|
|
e_util_dialog_show(_("Run Error"), |
|
|
|
|
_("Enlightenment was unable to fork a child process:<br>" |
|
|
|
|
"<br>" |
|
|
|
|
"%s<br>"), |
|
|
|
|
exec); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
/* reset env vars */ |
|
|
|
|
if (launch->launch_method) e_exehist_add(launch->launch_method, exec); |
|
|
|
|
free(exec); |
|
|
|
|
/* 20 lines at start and end, 20x100 limit on bytes at each end. */ |
|
|
|
|
ecore_exe_auto_limits_set(exe, 2000, 2000, 20, 20); |
|
|
|
|
ecore_exe_tag_set(exe, "E/exec"); |
|
|
|
|
|
|
|
|
|
if (desktop) |
|
|
|
|
{ |
|
|
|
|
Evas_List *l; |
|
|
|
|
|
|
|
|
|
inst->desktop = desktop; |
|
|
|
|
inst->exe = exe; |
|
|
|
|
inst->launch_id = startup_id; |
|
|
|
|
inst->launch_time = ecore_time_get(); |
|
|
|
|
inst->expire_timer = ecore_timer_add(10.0, _e_exec_cb_expire_timer, inst); |
|
|
|
|
|
|
|
|
|
l = evas_hash_find(e_exec_instances, desktop->orig_path); |
|
|
|
|
l = evas_list_append(l, inst); |
|
|
|
|
evas_hash_direct_add(e_exec_instances, desktop->orig_path, l); |
|
|
|
|
e_exec_start_pending = evas_list_append(e_exec_start_pending, desktop); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
ecore_exe_free(exe); |
|
|
|
|
if (!remaining) |
|
|
|
|
{ |
|
|
|
|
if (launch->launch_method) evas_stringshare_del(launch->launch_method); |
|
|
|
|
if (launch->zone) e_object_unref(E_OBJECT(launch->zone)); |
|
|
|
|
free(launch); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
_e_exec_cb_expire_timer(void *data) |
|
|
|
|
{ |
|
|
|
|
E_Exec_Instance *inst; |
|
|
|
|
|
|
|
|
|
inst = data; |
|
|
|
|
e_exec_start_pending = evas_list_remove(e_exec_start_pending, inst->desktop); |
|
|
|
|
inst->expire_timer = NULL; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
_e_exec_cb_exit(void *data, int type, void *event) |
|
|
|
|
{ |
|
|
|
|
Evas_List *instances; |
|
|
|
|
Ecore_Exe_Event_Del *ev; |
|
|
|
|
E_Exec_Instance *inst; |
|
|
|
|
|
|
|
|
|
ev = event; |
|
|
|
|
if (!ev->exe) return 1; |
|
|
|
|
if (!(ecore_exe_tag_get(ev->exe) &&
|
|
|
|
|
(!strcmp(ecore_exe_tag_get(ev->exe), "E/exec")))) return 1; |
|
|
|
|
inst = ecore_exe_data_get(ev->exe); |
|
|
|
|
if (!inst) return 1; |
|
|
|
|
|
|
|
|
|
/* /bin/sh uses this if cmd not found */ |
|
|
|
|
if ((ev->exited) && |
|
|
|
|
((ev->exit_code == 127) || (ev->exit_code == 255))) |
|
|
|
|
{ |
|
|
|
|
E_Dialog *dia; |
|
|
|
|
|
|
|
|
|
dia = e_dialog_new(e_container_current_get(e_manager_current_get()), |
|
|
|
|
"E", "_e_exec_run_error_dialog"); |
|
|
|
|
if (dia) |
|
|
|
|
{ |
|
|
|
|
char buf[4096]; |
|
|
|
|
|
|
|
|
|
e_dialog_title_set(dia, _("Application run error")); |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("Enlightenment was unable to run the application:<br>" |
|
|
|
|
"<br>" |
|
|
|
|
"%s<br>" |
|
|
|
|
"<br>" |
|
|
|
|
"The application failed to start."), |
|
|
|
|
ecore_exe_cmd_get(ev->exe)); |
|
|
|
|
e_dialog_text_set(dia, buf); |
|
|
|
|
e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL); |
|
|
|
|
e_dialog_button_focus_num(dia, 1); |
|
|
|
|
e_win_centered_set(dia->win, 1); |
|
|
|
|
e_dialog_show(dia); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* Let's hope that everything returns this properly. */ |
|
|
|
|
else if (!((ev->exited) && (ev->exit_code == EXIT_SUCCESS)))
|
|
|
|
|
{ |
|
|
|
|
/* Show the error dialog with details from the exe. */ |
|
|
|
|
_e_exec_error_dialog(inst->desktop, ecore_exe_cmd_get(ev->exe), ev, |
|
|
|
|
ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_ERROR), |
|
|
|
|
ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_READ)); |
|
|
|
|
} |
|
|
|
|
instances = evas_hash_find(e_exec_instances, inst->desktop->orig_path); |
|
|
|
|
instances = evas_list_remove(instances, inst); |
|
|
|
|
evas_hash_direct_add(e_exec_instances, inst->desktop->orig_path, instances); |
|
|
|
|
e_exec_start_pending = evas_list_remove(e_exec_start_pending, inst->desktop); |
|
|
|
|
if (inst->expire_timer) ecore_timer_del(inst->expire_timer); |
|
|
|
|
free(inst); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_e_exec_error_dialog(Efreet_Desktop *desktop, const char *exec, Ecore_Exe_Event_Del *event, |
|
|
|
|
Ecore_Exe_Event_Data *error, Ecore_Exe_Event_Data *read) |
|
|
|
|
{ |
|
|
|
|
E_Config_Dialog *cfd; |
|
|
|
|
E_Config_Dialog_View *v; |
|
|
|
|
E_Config_Dialog_Data *cfdata; |
|
|
|
|
E_Container *con; |
|
|
|
|
|
|
|
|
|
v = E_NEW(E_Config_Dialog_View, 1); |
|
|
|
|
if (!v) return; |
|
|
|
|
cfdata = E_NEW(E_Config_Dialog_Data, 1); |
|
|
|
|
if (!cfdata) |
|
|
|
|
{ |
|
|
|
|
free(v); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
cfdata->desktop = desktop; |
|
|
|
|
if (exec) cfdata->exec = strdup(exec); |
|
|
|
|
cfdata->error = error; |
|
|
|
|
cfdata->read = read; |
|
|
|
|
cfdata->event = *event; |
|
|
|
|
|
|
|
|
|
v->create_cfdata = _create_data; |
|
|
|
|
v->free_cfdata = _free_data; |
|
|
|
|
v->basic.create_widgets = _basic_create_widgets; |
|
|
|
|
v->advanced.create_widgets = _advanced_create_widgets; |
|
|
|
|
|
|
|
|
|
con = e_container_current_get(e_manager_current_get()); |
|
|
|
|
/* Create The Dialog */ |
|
|
|
|
cfd = e_config_dialog_new(con, _("Application Execution Error"),
|
|
|
|
|
"E", "_e_exec_error_exit_dialog", |
|
|
|
|
NULL, 0, v, cfdata); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_fill_data(E_Config_Dialog_Data *cfdata) |
|
|
|
|
{ |
|
|
|
|
char buf[4096]; |
|
|
|
|
|
|
|
|
|
if (!cfdata->label) |
|
|
|
|
{ |
|
|
|
|
snprintf(buf, sizeof(buf), _("%s stopped running unexpectedly."), cfdata->desktop->name); |
|
|
|
|
cfdata->label = strdup(buf); |
|
|
|
|
} |
|
|
|
|
if ((cfdata->event.exited) && (!cfdata->exit)) |
|
|
|
|
{ |
|
|
|
|
snprintf(buf, sizeof(buf),
|
|
|
|
|
_("An exit code of %i was returned from %s."), cfdata->event.exit_code, cfdata->exec); |
|
|
|
|
cfdata->exit = strdup(buf); |
|
|
|
|
} |
|
|
|
|
if ((cfdata->event.signalled) && (!cfdata->signal)) |
|
|
|
|
{ |
|
|
|
|
if (cfdata->event.exit_signal == SIGINT) |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by an Interrupt Signal."), cfdata->desktop->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGQUIT) |
|
|
|
|
snprintf(buf, sizeof(buf), _("%s was interrupted by a Quit Signal."), |
|
|
|
|
cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGABRT) |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by an Abort Signal."), cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGFPE) |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by a Floating Point Error."), cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGKILL) |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by an Uninterruptable Kill Signal."), cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGSEGV) |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by a Segmentation Fault."), cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGPIPE) |
|
|
|
|
snprintf(buf, sizeof(buf),
|
|
|
|
|
_("%s was interrupted by a Broken Pipe."), cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGTERM) |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by a Termination Signal."), cfdata->exec); |
|
|
|
|
else if (cfdata->event.exit_signal == SIGBUS) |
|
|
|
|
snprintf(buf, sizeof(buf),
|
|
|
|
|
_("%s was interrupted by a Bus Error."), cfdata->exec); |
|
|
|
|
else |
|
|
|
|
snprintf(buf, sizeof(buf), |
|
|
|
|
_("%s was interrupted by the signal number %i."), |
|
|
|
|
cfdata->exec, cfdata->event.exit_signal); |
|
|
|
|
cfdata->signal = strdup(buf); |
|
|
|
|
/* FIXME: Add sigchld_info stuff
|
|
|
|
|
* cfdata->event.data |
|
|
|
|
* siginfo_t |
|
|
|
|
* { |
|
|
|
|
* int si_signo; Signal number |
|
|
|
|
* int si_errno; An errno value |
|
|
|
|
* int si_code; Signal code |
|
|
|
|
* pid_t si_pid; Sending process ID |
|
|
|
|
* uid_t si_uid; Real user ID of sending process |
|
|
|
|
* int si_status; Exit value or signal |
|
|
|
|
* clock_t si_utime; User time consumed |
|
|
|
|
* clock_t si_stime; System time consumed |
|
|
|
|
* sigval_t si_value; Signal value |
|
|
|
|
* int si_int; POSIX.1b signal |
|
|
|
|
* void * si_ptr; POSIX.1b signal |
|
|
|
|
* void * si_addr; Memory location which caused fault |
|
|
|
|
* int si_band; Band event |
|
|
|
|
* int si_fd; File descriptor |
|
|
|
|
* } |
|
|
|
|
*/ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void * |
|
|
|
|
_create_data(E_Config_Dialog *cfd) |
|
|
|
|
{ |
|
|
|
|
E_Config_Dialog_Data *cfdata; |
|
|
|
|
|
|
|
|
|
cfdata = cfd->data; |
|
|
|
|
_fill_data(cfdata); |
|
|
|
|
return cfdata; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) |
|
|
|
|
{ |
|
|
|
|
if (cfdata->error) ecore_exe_event_data_free(cfdata->error); |
|
|
|
|
if (cfdata->read) ecore_exe_event_data_free(cfdata->read); |
|
|
|
|
|
|
|
|
|
E_FREE(cfdata->exec); |
|
|
|
|
E_FREE(cfdata->signal); |
|
|
|
|
E_FREE(cfdata->exit); |
|
|
|
|
E_FREE(cfdata->label); |
|
|
|
|
|
|
|
|
|
free(cfdata); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static Evas_Object * |
|
|
|
|
_dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
Evas_Object *obj, *os; |
|
|
|
|
char *text; |
|
|
|
|
char *trunc_note = _("***The remaining output has been truncated. Save the output to view.***\n"); |
|
|
|
|
int tlen, max_lines; |
|
|
|
|
|
|
|
|
|
os = e_widget_framelist_add(evas, _(title), 0); |
|
|
|
|
|
|
|
|
|
obj = e_widget_textblock_add(evas); |
|
|
|
|
|
|
|
|
|
tlen = 0; |
|
|
|
|
for (i = 0; lines[i].line != NULL; i++) |
|
|
|
|
{ |
|
|
|
|
tlen += lines[i].size + 1; |
|
|
|
|
/* When the program output is extraordinarily long, it can cause
|
|
|
|
|
* significant delays during text rendering. Limit to a fixed |
|
|
|
|
* number of characters. */ |
|
|
|
|
if (tlen > MAX_OUTPUT_CHARACTERS) |
|
|
|
|
{ |
|
|
|
|
tlen -= lines[i].size + 1; |
|
|
|
|
tlen += strlen(trunc_note); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
max_lines = i; |
|
|
|
|
text = alloca(tlen + 1); |
|
|
|
|
|
|
|
|
|
if (text) |
|
|
|
|
{ |
|
|
|
|
text[0] = 0; |
|
|
|
|
for (i = 0; i < max_lines; i++) |
|
|
|
|
{ |
|
|
|
|
strcat(text, lines[i].line); |
|
|
|
|
strcat(text, "\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Append the warning about truncated output. */ |
|
|
|
|
if (lines[max_lines].line != NULL) |
|
|
|
|
strcat(text, trunc_note); |
|
|
|
|
|
|
|
|
|
e_widget_textblock_plain_set(obj, text); |
|
|
|
|
} |
|
|
|
|
e_widget_min_size_set(obj, 240, 120); |
|
|
|
|
|
|
|
|
|
e_widget_framelist_object_append(os, obj); |
|
|
|
|
|
|
|
|
|
return os; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static Evas_Object * |
|
|
|
|
_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) |
|
|
|
|
{ |
|
|
|
|
char buf[4096]; |
|
|
|
|
int error_length = 0; |
|
|
|
|
Evas_Object *o, *ob, *os; |
|
|
|
|
|
|
|
|
|
_fill_data(cfdata); |
|
|
|
|
|
|
|
|
|
o = e_widget_list_add(evas, 0, 0); |
|
|
|
|
|
|
|
|
|
ob = e_widget_label_add(evas, cfdata->label); |
|
|
|
|
e_widget_list_object_append(o, ob, 1, 1, 0.5); |
|
|
|
|
|
|
|
|
|
if (cfdata->error) |
|
|
|
|
error_length = cfdata->error->size; |
|
|
|
|
if (error_length) |
|
|
|
|
{ |
|
|
|
|
os = _dialog_scrolltext_create(evas, _("Error Logs"), cfdata->error->lines); |
|
|
|
|
e_widget_list_object_append(o, os, 1, 1, 0.5); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
ob = e_widget_label_add(evas, _("There was no error message.")); |
|
|
|
|
e_widget_list_object_append(o, ob, 1, 1, 0.5); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ob = e_widget_button_add(evas, _("Save This Message"), "enlightenment/run",
|
|
|
|
|
_dialog_save_cb, NULL, cfdata); |
|
|
|
|
e_widget_list_object_append(o, ob, 0, 0, 0.5); |
|
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
|
|
|
|
|
e_user_homedir_get(), cfdata->desktop->name); |
|
|
|
|
ob = e_widget_label_add(evas, buf); |
|
|
|
|
e_widget_list_object_append(o, ob, 1, 1, 0.5); |
|
|
|
|
|
|
|
|
|
return o; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static Evas_Object * |
|
|
|
|
_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) |
|
|
|
|
{ |
|
|
|
|
char buf[4096]; |
|
|
|
|
int read_length = 0; |
|
|
|
|
int error_length = 0; |
|
|
|
|
Evas_Object *o, *of, *ob, *ot; |
|
|
|
|
|
|
|
|
|
_fill_data(cfdata); |
|
|
|
|
|
|
|
|
|
o = e_widget_list_add(evas, 0, 0); |
|
|
|
|
ot = e_widget_table_add(evas, 0); |
|
|
|
|
|
|
|
|
|
ob = e_widget_label_add(evas, cfdata->label); |
|
|
|
|
e_widget_list_object_append(o, ob, 1, 1, 0.5); |
|
|
|
|
|
|
|
|
|
if (cfdata->exit) |
|
|
|
|
{ |
|
|
|
|
of = e_widget_framelist_add(evas, _("Error Information"), 0); |
|
|
|
|
ob = e_widget_label_add(evas, _(cfdata->exit)); |
|
|
|
|
e_widget_framelist_object_append(of, ob); |
|
|
|
|
e_widget_list_object_append(o, of, 1, 1, 0.5); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cfdata->signal) |
|
|
|
|
{ |
|
|
|
|
of = e_widget_framelist_add(evas, _("Error Signal Information"), 0); |
|
|
|
|
ob = e_widget_label_add(evas, _(cfdata->signal)); |
|
|
|
|
e_widget_framelist_object_append(of, ob); |
|
|
|
|
e_widget_list_object_append(o, of, 1, 1, 0.5); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cfdata->read) |
|
|
|
|
read_length = cfdata->read->size; |
|
|
|
|
|
|
|
|
|
if (read_length) |
|
|
|
|
{ |
|
|
|
|
of = _dialog_scrolltext_create(evas, _("Output Data"), cfdata->read->lines); |
|
|
|
|
/* FIXME: Add stdout "start". */ |
|
|
|
|
/* FIXME: Add stdout "end". */ |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
of = e_widget_framelist_add(evas, _("Output Data"), 0); |
|
|
|
|
ob = e_widget_label_add(evas, _("There was no output.")); |
|
|
|
|
e_widget_framelist_object_append(of, ob); |
|
|
|
|
} |
|
|
|
|
e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1); |
|
|
|
|
|
|
|
|
|
if (cfdata->error) |
|
|
|
|
error_length = cfdata->error->size; |
|
|
|
|
if (error_length) |
|
|
|
|
{ |
|
|
|
|
of = _dialog_scrolltext_create(evas, _("Error Logs"), cfdata->error->lines); |
|
|
|
|
/* FIXME: Add stderr "start". */ |
|
|
|
|
/* FIXME: Add stderr "end". */ |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
of = e_widget_framelist_add(evas, _("Error Logs"), 0); |
|
|
|
|
ob = e_widget_label_add(evas, _("There was no error message.")); |
|
|
|
|
e_widget_framelist_object_append(of, ob); |
|
|
|
|
} |
|
|
|
|
e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1); |
|
|
|
|
|
|
|
|
|
e_widget_list_object_append(o, ot, 1, 1, 0.5); |
|
|
|
|
|
|
|
|
|
ob = e_widget_button_add(evas, _("Save This Message"), "enlightenment/run", _dialog_save_cb, NULL, cfdata); |
|
|
|
|
e_widget_list_object_append(o, ob, 0, 0, 0.5); |
|
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
|
|
|
|
|
e_user_homedir_get(), cfdata->desktop->name); |
|
|
|
|
ob = e_widget_label_add(evas, buf); |
|
|
|
|
e_widget_list_object_append(o, ob, 1, 1, 0.5); |
|
|
|
|
|
|
|
|
|
return o; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_dialog_save_cb(void *data, void *data2) |
|
|
|
|
{ |
|
|
|
|
E_Config_Dialog_Data *cfdata; |
|
|
|
|
FILE *f; |
|
|
|
|
char *text; |
|
|
|
|
char buf[1024]; |
|
|
|
|
char buffer[4096]; |
|
|
|
|
int read_length = 0; |
|
|
|
|
int i, tlen; |
|
|
|
|
|
|
|
|
|
cfdata = data2; |
|
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s.log", e_user_homedir_get(), |
|
|
|
|
e_util_filename_escape(cfdata->desktop->name)); |
|
|
|
|
f = fopen(buf, "w"); |
|
|
|
|
if (!f) return; |
|
|
|
|
|
|
|
|
|
if (cfdata->exit) |
|
|
|
|
{ |
|
|
|
|
snprintf(buffer, sizeof(buffer), "Error Information:\n\t%s\n\n", cfdata->exit); |
|
|
|
|
fwrite(buffer, sizeof(char), strlen(buffer), f); |
|
|
|
|
} |
|
|
|
|
if (cfdata->signal) |
|
|
|
|
{ |
|
|
|
|
snprintf(buffer, sizeof(buffer), "Error Signal Information:\n\t%s\n\n", cfdata->signal); |
|
|
|
|
fwrite(buffer, sizeof(char), strlen(buffer), f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cfdata->read) |
|
|
|
|
read_length = cfdata->read->size; |
|
|
|
|
|
|
|
|
|
if (read_length) |
|
|
|
|
{ |
|
|
|
|
tlen = 0; |
|
|
|
|
for (i = 0; cfdata->read->lines[i].line != NULL; i++) |
|
|
|
|
tlen += cfdata->read->lines[i].size + 2; |
|
|
|
|
text = alloca(tlen + 1); |
|
|
|
|
if (text) |
|
|
|
|
{ |
|
|
|
|
text[0] = 0; |
|
|
|
|
for (i = 0; cfdata->read->lines[i].line != NULL; i++) |
|
|
|
|
{ |
|
|
|
|
strcat(text, "\t"); |
|
|
|
|
strcat(text, cfdata->read->lines[i].line); |
|
|
|
|
strcat(text, "\n"); |
|
|
|
|
} |
|
|
|
|
snprintf(buffer, sizeof(buffer), "Output Data:\n%s\n\n", text); |
|
|
|
|
fwrite(buffer, sizeof(char), strlen(buffer), f); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
snprintf(buffer, sizeof(buffer), "Output Data:\n\tThere was no output\n\n"); |
|
|
|
|
fwrite(buffer, sizeof(char), strlen(buffer), f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Reusing this var */ |
|
|
|
|
read_length = 0; |
|
|
|
|
if (cfdata->error) |
|
|
|
|
read_length = cfdata->error->size; |
|
|
|
|
|
|
|
|
|
if (read_length) |
|
|
|
|
{ |
|
|
|
|
tlen = 0; |
|
|
|
|
for (i = 0; cfdata->error->lines[i].line != NULL; i++) |
|
|
|
|
tlen += cfdata->error->lines[i].size + 1; |
|
|
|
|
text = alloca(tlen + 1); |
|
|
|
|
if (text) |
|
|
|
|
{ |
|
|
|
|
text[0] = 0; |
|
|
|
|
for (i = 0; cfdata->error->lines[i].line != NULL; i++) |
|
|
|
|
{ |
|
|
|
|
strcat(text, "\t"); |
|
|
|
|
strcat(text, cfdata->error->lines[i].line); |
|
|
|
|
strcat(text, "\n"); |
|
|
|
|
} |
|
|
|
|
snprintf(buffer, sizeof(buffer), "Error Logs:\n%s\n", text); |
|
|
|
|
fwrite(buffer, sizeof(char), strlen(buffer), f); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
snprintf(buffer, sizeof(buffer), "Error Logs:\n\tThere was no error message\n"); |
|
|
|
|
fwrite(buffer, sizeof(char), strlen(buffer), f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fclose(f); |
|
|
|
|
} |
|
|
|
|