3 #define MAX_OUTPUT_CHARACTERS 5000
6 * - Clear e_exec_instances on shutdown
7 * - Clear e_exec_start_pending on shutdown
8 * - Create border add handler
9 * - Launch .desktop in terminal if .desktop requires it
12 typedef struct _E_Exec_Launch E_Exec_Launch;
13 typedef struct _E_Exec_Search E_Exec_Search;
14 typedef struct _E_Exec_Watch E_Exec_Watch;
19 const char *launch_method;
24 E_Exec_Instance *inst;
25 Efreet_Desktop *desktop;
32 void (*func) (void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type);
34 Eina_Bool delete_me : 1;
37 struct _E_Config_Dialog_Data
39 Efreet_Desktop *desktop;
42 Ecore_Exe_Event_Del event;
43 Ecore_Exe_Event_Data *error;
44 Ecore_Exe_Event_Data *read;
46 char *label, *exit, *signal;
49 /* local subsystem functions */
50 static E_Exec_Instance *_e_exec_cb_exec(void *data, Efreet_Desktop *desktop, char *exec, int remaining);
51 static Eina_Bool _e_exec_cb_expire_timer(void *data);
52 static Eina_Bool _e_exec_cb_exit(void *data, int type, void *event);
54 static Eina_Bool _e_exec_startup_id_pid_find(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *value, void *data);
56 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);
57 static void _fill_data(E_Config_Dialog_Data *cfdata);
58 static void *_create_data(E_Config_Dialog *cfd);
59 static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
60 static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
61 static Evas_Object *_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
62 static Evas_Object *_dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines);
63 static void _dialog_save_cb(void *data, void *data2);
64 static void _e_exec_instance_free(E_Exec_Instance *inst);
66 /* local subsystem globals */
67 static Eina_List *e_exec_start_pending = NULL;
68 static Eina_Hash *e_exec_instances = NULL;
69 static int startup_id = 0;
71 static Ecore_Event_Handler *_e_exec_exit_handler = NULL;
72 static Ecore_Event_Handler *_e_exec_border_add_handler = NULL;
74 static E_Exec_Instance *(*_e_exec_executor_func) (void *data, E_Zone *zone, Efreet_Desktop *desktop, const char *exec, Eina_List *files, const char *launch_method) = NULL;
75 static void *_e_exec_executor_data = NULL;
77 /* externally accessible functions */
81 e_exec_instances = eina_hash_string_superfast_new(NULL);
83 _e_exec_exit_handler =
84 ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_exec_cb_exit, NULL);
86 _e_exec_border_add_handler =
87 ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_exec_cb_event_border_add, NULL);
97 snprintf(buf, sizeof(buf), "%i", startup_id);
98 e_util_env_set("E_STARTUP_ID", buf);
100 if (_e_exec_exit_handler) ecore_event_handler_del(_e_exec_exit_handler);
101 if (_e_exec_border_add_handler)
102 ecore_event_handler_del(_e_exec_border_add_handler);
103 eina_hash_free(e_exec_instances);
104 eina_list_free(e_exec_start_pending);
109 e_exec_executor_set(E_Exec_Instance *(*func) (void *data, E_Zone *zone, Efreet_Desktop *desktop, const char *exec, Eina_List *files, const char *launch_method), const void *data)
111 _e_exec_executor_func = func;
112 _e_exec_executor_data = (void *)data;
115 EAPI E_Exec_Instance *
116 e_exec(E_Zone *zone, Efreet_Desktop *desktop, const char *exec,
117 Eina_List *files, const char *launch_method)
119 E_Exec_Launch *launch;
120 E_Exec_Instance *inst = NULL;
122 if ((!desktop) && (!exec)) return NULL;
124 if (_e_exec_executor_func)
125 return _e_exec_executor_func(_e_exec_executor_data, zone,
126 desktop, exec, files, launch_method);
132 single = eina_hash_find(desktop->x, "X-Enlightenment-Single-Instance");
134 (e_config->exe_always_single_instance))
136 Eina_Bool dosingle = EINA_FALSE;
138 // first take system config for always single instance if set
139 if (e_config->exe_always_single_instance) dosingle = EINA_TRUE;
141 // and now let desktop file override it
144 if ((!strcasecmp(single, "true")) ||
145 (!strcasecmp(single, "yes"))||
146 (!strcasecmp(single, "1")))
147 dosingle = EINA_TRUE;
148 else if ((!strcasecmp(single, "false")) ||
149 (!strcasecmp(single, "no"))||
150 (!strcasecmp(single, "0")))
151 dosingle = EINA_FALSE;
159 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
161 if ((bd) && (bd->desktop == desktop))
164 e_border_activate(bd, EINA_TRUE);
174 launch = E_NEW(E_Exec_Launch, 1);
175 if (!launch) return NULL;
179 e_object_ref(E_OBJECT(launch->zone));
182 launch->launch_method = eina_stringshare_add(launch_method);
187 inst = _e_exec_cb_exec(launch, NULL, strdup(exec), 0);
189 inst = efreet_desktop_command_get
190 (desktop, files, (Efreet_Desktop_Command_Cb)_e_exec_cb_exec, launch);
193 inst = _e_exec_cb_exec(launch, NULL, strdup(exec), 0);
194 if ((zone) && (inst))
196 inst->screen = zone->num;
197 inst->desk_x = zone->desk_x_current;
198 inst->desk_y = zone->desk_y_current;
203 EAPI E_Exec_Instance *
204 e_exec_startup_id_pid_instance_find(int id, pid_t pid)
206 E_Exec_Search search;
209 search.desktop = NULL;
210 search.startup_id = id;
212 eina_hash_foreach(e_exec_instances, _e_exec_startup_id_pid_find, &search);
216 EAPI Efreet_Desktop *
217 e_exec_startup_id_pid_find(int id, pid_t pid)
219 E_Exec_Instance *inst;
221 inst = e_exec_startup_id_pid_instance_find(id, pid);
222 if (!inst) return NULL;
223 return inst->desktop;
226 EAPI E_Exec_Instance *
227 e_exec_startup_desktop_instance_find(Efreet_Desktop *desktop)
229 E_Exec_Search search;
232 search.desktop = desktop;
233 search.startup_id = 0;
235 eina_hash_foreach(e_exec_instances, _e_exec_startup_id_pid_find, &search);
240 _e_exe_instance_watchers_call(E_Exec_Instance *inst, E_Exec_Watch_Type type)
246 EINA_LIST_FOREACH(inst->watchers, l, iw)
248 if (iw->func) iw->func((void *)(iw->data), inst, type);
251 if (inst->walking == 0)
253 EINA_LIST_FOREACH_SAFE(inst->watchers, l, ln, iw)
257 inst->watchers = eina_list_remove_list(inst->watchers, l);
265 e_exec_instance_found(E_Exec_Instance *inst)
267 _e_exe_instance_watchers_call(inst, E_EXEC_WATCH_STARTED);
271 e_exec_instance_watcher_add(E_Exec_Instance *inst, void (*func) (void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data)
275 iw = E_NEW(E_Exec_Watch, 1);
279 inst->watchers = eina_list_append(inst->watchers, iw);
283 e_exec_instance_watcher_del(E_Exec_Instance *inst, void (*func) (void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data)
288 EINA_LIST_FOREACH_SAFE(inst->watchers, l, ln, iw)
290 if ((iw->func == func) && (iw->data == data))
292 if (inst->walking == 0)
294 inst->watchers = eina_list_remove_list(inst->watchers, l);
300 iw->delete_me = EINA_TRUE;
307 /* local subsystem functions */
308 static E_Exec_Instance *
309 _e_exec_cb_exec(void *data, Efreet_Desktop *desktop, char *exec, int remaining)
311 E_Exec_Instance *inst = NULL;
312 E_Exec_Launch *launch;
314 Ecore_Exe *exe = NULL;
319 inst = E_NEW(E_Exec_Instance, 1);
320 if (!inst) return NULL;
326 p = getenv("E_STARTUP_ID");
327 if (p) startup_id = atoi(p);
328 e_util_env_set("E_STARTUP_ID", NULL);
330 if (++startup_id < 1) startup_id = 1;
331 /* save previous env vars we need to save */
332 penv_display = getenv("DISPLAY");
333 if (penv_display) penv_display = strdup(penv_display);
334 if ((penv_display) && (launch->zone))
341 int penv_display_length;
343 head = launch->zone->container->manager->num;
345 penv_display_length = strlen(penv_display);
346 /* Check for insane length for DISPLAY env */
347 if (penv_display_length + 32 > 4096)
355 head_length = eina_convert_itoa(head, buf2 + 1) + 2;
358 p1 = strrchr(penv_display, ':');
359 p2 = strrchr(penv_display, '.');
360 if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */
362 buf3 = alloca((p2 - penv_display) + head_length + 1);
364 memcpy(buf3, penv_display, p2 - penv_display);
365 memcpy(buf3 + (p2 - penv_display), buf2, head_length);
367 else if (p1) /* "blah:x */
369 buf3 = alloca(penv_display_length + head_length);
371 memcpy(buf3, penv_display, penv_display_length);
372 memcpy(buf3 + penv_display_length, buf2, head_length);
376 buf3 = alloca(penv_display_length + 1);
377 memcpy(buf3, penv_display, penv_display_length + 1);
380 e_util_env_set("DISPLAY", buf3);
382 snprintf(buf, sizeof(buf), "E_START|%i", startup_id);
383 e_util_env_set("DESKTOP_STARTUP_ID", buf);
385 // dont set vsync for clients - maybe inherited from compositore. fixme:
386 // need a way to still inherit from parent env of wm.
387 e_util_env_set("__GL_SYNC_TO_VBLANK", NULL);
389 //// FIXME: seem to be some issues with the pipe and filling up ram - need to
390 //// check. for now disable.
391 // exe = ecore_exe_pipe_run(exec,
392 // ECORE_EXE_PIPE_AUTO | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR |
393 // ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED,
395 if ((desktop) && (desktop->path) && (desktop->path[0]))
397 if (!getcwd(buf, sizeof(buf)))
402 _("Enlightenment was unable to get current directory"));
405 if (chdir(desktop->path))
410 _("Enlightenment was unable to change to directory:<br>"
416 e_util_library_path_strip();
417 exe = ecore_exe_run(exec, inst);
418 e_util_library_path_restore();
423 _("Enlightenment was unable to restore to directory:<br>"
433 e_util_library_path_strip();
434 if ((desktop) && (desktop->terminal))
436 Efreet_Desktop *tdesktop;
438 tdesktop = e_util_terminal_desktop_get();
445 sb = eina_strbuf_new();
448 eina_strbuf_append(sb, tdesktop->exec);
449 eina_strbuf_append(sb, " -e ");
450 eina_strbuf_append_escaped(sb, exec);
451 exe = ecore_exe_run(eina_strbuf_string_get(sb),
453 eina_strbuf_free(sb);
457 exe = ecore_exe_run(exec, inst);
458 efreet_desktop_free(tdesktop);
461 exe = ecore_exe_run(exec, inst);
464 exe = ecore_exe_run(exec, inst);
465 e_util_library_path_restore();
470 e_util_env_set("DISPLAY", penv_display);
476 e_util_dialog_show(_("Run Error"),
477 _("Enlightenment was unable to fork a child process:<br>"
484 if ((launch->launch_method) && (!desktop))
485 e_exehist_add(launch->launch_method, exec);
486 /* 20 lines at start and end, 20x100 limit on bytes at each end. */
487 //// FIXME: seem to be some issues with the pipe and filling up ram - need to
488 //// check. for now disable.
489 // ecore_exe_auto_limits_set(exe, 2000, 2000, 20, 20);
490 ecore_exe_tag_set(exe, "E/exec");
494 efreet_desktop_ref(desktop);
495 inst->desktop = desktop;
496 inst->key = eina_stringshare_add(desktop->orig_path);
499 inst->key = eina_stringshare_add(exec);
502 inst->startup_id = startup_id;
503 inst->launch_time = ecore_time_get();
504 inst->expire_timer = ecore_timer_add(e_config->exec.expire_timeout,
505 _e_exec_cb_expire_timer, inst);
506 l = eina_hash_find(e_exec_instances, inst->key);
507 lnew = eina_list_append(l, inst);
508 if (l) eina_hash_modify(e_exec_instances, inst->key, lnew);
509 else eina_hash_add(e_exec_instances, inst->key, lnew);
512 e_exec_start_pending = eina_list_append(e_exec_start_pending,
514 e_exehist_add(launch->launch_method, inst->desktop->exec);
519 if (launch->launch_method) eina_stringshare_del(launch->launch_method);
520 if (launch->zone) e_object_unref(E_OBJECT(launch->zone));
527 _e_exec_cb_expire_timer(void *data)
529 E_Exec_Instance *inst;
533 e_exec_start_pending = eina_list_remove(e_exec_start_pending,
535 inst->expire_timer = NULL;
536 _e_exe_instance_watchers_call(inst, E_EXEC_WATCH_TIMEOUT);
537 return ECORE_CALLBACK_CANCEL;
541 _e_exec_instance_free(E_Exec_Instance *inst)
543 Eina_List *instances;
546 _e_exe_instance_watchers_call(inst, E_EXEC_WATCH_STOPPED);
547 EINA_LIST_FREE(inst->watchers, iw) free(iw);
551 instances = eina_hash_find(e_exec_instances, inst->key);
554 instances = eina_list_remove(instances, inst);
556 eina_hash_modify(e_exec_instances, inst->key, instances);
558 eina_hash_del(e_exec_instances, inst->key, NULL);
560 eina_stringshare_del(inst->key);
563 e_exec_start_pending = eina_list_remove(e_exec_start_pending,
565 if (inst->expire_timer) ecore_timer_del(inst->expire_timer);
566 if (inst->desktop) efreet_desktop_free(inst->desktop);
571 _e_exec_cb_instance_finish(void *data)
573 _e_exec_instance_free(data);
574 return ECORE_CALLBACK_CANCEL;
579 _e_exec_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
581 Ecore_Exe_Event_Del *ev;
582 E_Exec_Instance *inst;
585 if (!ev->exe) return ECORE_CALLBACK_PASS_ON;
586 // if (ecore_exe_tag_get(ev->exe)) printf(" tag %s\n", ecore_exe_tag_get(ev->exe));
587 if (!(ecore_exe_tag_get(ev->exe) &&
588 (!strcmp(ecore_exe_tag_get(ev->exe), "E/exec"))))
589 return ECORE_CALLBACK_PASS_ON;
590 inst = ecore_exe_data_get(ev->exe);
591 if (!inst) return ECORE_CALLBACK_PASS_ON;
593 /* /bin/sh uses this if cmd not found */
595 ((ev->exit_code == 127) || (ev->exit_code == 255)))
597 if (e_config->exec.show_run_dialog)
601 dia = e_dialog_new(e_container_current_get(e_manager_current_get()),
602 "E", "_e_exec_run_error_dialog");
607 e_dialog_title_set(dia, _("Application run error"));
608 snprintf(buf, sizeof(buf),
609 _("Enlightenment was unable to run the application:<br>"
613 "The application failed to start."),
614 ecore_exe_cmd_get(ev->exe));
615 e_dialog_text_set(dia, buf);
616 e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
617 e_dialog_button_focus_num(dia, 1);
618 e_win_centered_set(dia->win, 1);
623 /* Let's hope that everything returns this properly. */
624 else if (!((ev->exited) && (ev->exit_code == EXIT_SUCCESS)))
626 if (e_config->exec.show_exit_dialog)
628 /* filter out common exits via signals - int/term/quit. not really
629 * worth popping up a dialog for */
630 if (!((ev->signalled) &&
631 ((ev->exit_signal == SIGINT) ||
632 (ev->exit_signal == SIGQUIT) ||
633 (ev->exit_signal == SIGTERM)))
636 /* Show the error dialog with details from the exe. */
637 _e_exec_error_dialog(inst->desktop, ecore_exe_cmd_get(ev->exe), ev,
638 ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_ERROR),
639 ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_READ));
644 /* scripts that fork off children with & break child tracking... but this hack
645 * also breaks apps that handle single-instance themselves */
647 if ((ecore_time_get() - inst->launch_time) < 2.0)
650 if (inst->expire_timer) ecore_timer_del(inst->expire_timer);
651 inst->expire_timer = ecore_timer_add(e_config->exec.expire_timeout, _e_exec_cb_instance_finish, inst);
655 _e_exec_instance_free(inst);
657 return ECORE_CALLBACK_PASS_ON;
661 _e_exec_startup_id_pid_find(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *value, void *data)
663 E_Exec_Search *search;
664 E_Exec_Instance *inst;
668 EINA_LIST_FOREACH(value, l, inst)
670 if (((search->desktop) &&
671 (search->desktop == inst->desktop)) ||
673 ((search->startup_id > 0) &&
674 (search->startup_id == inst->startup_id)) ||
676 ((inst->exe) && (search->pid > 1) &&
677 (search->pid == ecore_exe_pid_get(inst->exe))))
687 _e_exec_error_dialog(Efreet_Desktop *desktop, const char *exec, Ecore_Exe_Event_Del *exe_event,
688 Ecore_Exe_Event_Data *exe_error, Ecore_Exe_Event_Data *exe_read)
690 E_Config_Dialog_View *v;
691 E_Config_Dialog_Data *cfdata;
694 v = E_NEW(E_Config_Dialog_View, 1);
696 cfdata = E_NEW(E_Config_Dialog_Data, 1);
702 cfdata->desktop = desktop;
703 if (cfdata->desktop) efreet_desktop_ref(cfdata->desktop);
704 if (exec) cfdata->exec = strdup(exec);
705 cfdata->error = exe_error;
706 cfdata->read = exe_read;
707 cfdata->event = *exe_event;
709 v->create_cfdata = _create_data;
710 v->free_cfdata = _free_data;
711 v->basic.create_widgets = _basic_create_widgets;
712 v->advanced.create_widgets = _advanced_create_widgets;
714 con = e_container_current_get(e_manager_current_get());
715 /* Create The Dialog */
716 e_config_dialog_new(con, _("Application Execution Error"),
717 "E", "_e_exec_error_exit_dialog",
722 _fill_data(E_Config_Dialog_Data *cfdata)
729 snprintf(buf, sizeof(buf), _("%s stopped running unexpectedly."), cfdata->desktop->name);
731 snprintf(buf, sizeof(buf), _("%s stopped running unexpectedly."), cfdata->exec);
732 cfdata->label = strdup(buf);
734 if ((cfdata->event.exited) && (!cfdata->exit))
736 snprintf(buf, sizeof(buf),
737 _("An exit code of %i was returned from %s."),
738 cfdata->event.exit_code, cfdata->exec);
739 cfdata->exit = strdup(buf);
741 if ((cfdata->event.signalled) && (!cfdata->signal))
743 if (cfdata->event.exit_signal == SIGINT)
744 snprintf(buf, sizeof(buf),
745 _("%s was interrupted by an Interrupt Signal."),
747 else if (cfdata->event.exit_signal == SIGQUIT)
748 snprintf(buf, sizeof(buf), _("%s was interrupted by a Quit Signal."),
750 else if (cfdata->event.exit_signal == SIGABRT)
751 snprintf(buf, sizeof(buf),
752 _("%s was interrupted by an Abort Signal."), cfdata->exec);
753 else if (cfdata->event.exit_signal == SIGFPE)
754 snprintf(buf, sizeof(buf),
755 _("%s was interrupted by a Floating Point Error."),
757 else if (cfdata->event.exit_signal == SIGKILL)
758 snprintf(buf, sizeof(buf),
759 _("%s was interrupted by an Uninterruptable Kill Signal."),
761 else if (cfdata->event.exit_signal == SIGSEGV)
762 snprintf(buf, sizeof(buf),
763 _("%s was interrupted by a Segmentation Fault."),
765 else if (cfdata->event.exit_signal == SIGPIPE)
766 snprintf(buf, sizeof(buf),
767 _("%s was interrupted by a Broken Pipe."), cfdata->exec);
768 else if (cfdata->event.exit_signal == SIGTERM)
769 snprintf(buf, sizeof(buf),
770 _("%s was interrupted by a Termination Signal."),
772 else if (cfdata->event.exit_signal == SIGBUS)
773 snprintf(buf, sizeof(buf),
774 _("%s was interrupted by a Bus Error."), cfdata->exec);
776 snprintf(buf, sizeof(buf),
777 _("%s was interrupted by the signal number %i."),
778 cfdata->exec, cfdata->event.exit_signal);
779 cfdata->signal = strdup(buf);
780 /* FIXME: Add sigchld_info stuff
784 * int si_signo; Signal number
785 * int si_errno; An errno value
786 * int si_code; Signal code
787 * pid_t si_pid; Sending process ID
788 * uid_t si_uid; Real user ID of sending process
789 * int si_status; Exit value or signal
790 * clock_t si_utime; User time consumed
791 * clock_t si_stime; System time consumed
792 * sigval_t si_value; Signal value
793 * int si_int; POSIX.1b signal
794 * void * si_ptr; POSIX.1b signal
795 * void * si_addr; Memory location which caused fault
796 * int si_band; Band event
797 * int si_fd; File descriptor
804 _create_data(E_Config_Dialog *cfd)
806 E_Config_Dialog_Data *cfdata;
814 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
816 if (cfdata->error) ecore_exe_event_data_free(cfdata->error);
817 if (cfdata->read) ecore_exe_event_data_free(cfdata->read);
819 if (cfdata->desktop) efreet_desktop_free(cfdata->desktop);
821 E_FREE(cfdata->exec);
822 E_FREE(cfdata->signal);
823 E_FREE(cfdata->exit);
824 E_FREE(cfdata->label);
829 _dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines)
831 Evas_Object *obj, *os;
833 char *trunc_note = _("***The remaining output has been truncated. Save the output to view.***\n");
834 int tlen, max_lines, i;
836 os = e_widget_framelist_add(evas, _(title), 0);
838 obj = e_widget_textblock_add(evas);
841 for (i = 0; lines[i].line; i++)
843 tlen += lines[i].size + 1;
844 /* When the program output is extraordinarily long, it can cause
845 * significant delays during text rendering. Limit to a fixed
846 * number of characters. */
847 if (tlen > MAX_OUTPUT_CHARACTERS)
849 tlen -= lines[i].size + 1;
850 tlen += strlen(trunc_note);
855 text = alloca(tlen + 1);
858 for (i = 0; i < max_lines; i++)
860 strcat(text, lines[i].line);
864 /* Append the warning about truncated output. */
865 if (lines[max_lines].line) strcat(text, trunc_note);
867 e_widget_textblock_plain_set(obj, text);
868 e_widget_size_min_set(obj, 240, 120);
870 e_widget_framelist_object_append(os, obj);
876 _basic_create_widgets(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
879 int error_length = 0;
880 Evas_Object *o, *ob, *os;
884 o = e_widget_list_add(evas, 0, 0);
886 ob = e_widget_label_add(evas, cfdata->label);
887 e_widget_list_object_append(o, ob, 1, 1, 0.5);
889 if (cfdata->error) error_length = cfdata->error->size;
892 os = _dialog_scrolltext_create(evas, _("Error Logs"),
893 cfdata->error->lines);
894 e_widget_list_object_append(o, os, 1, 1, 0.5);
898 ob = e_widget_label_add(evas, _("There was no error message."));
899 e_widget_list_object_append(o, ob, 1, 1, 0.5);
902 ob = e_widget_button_add(evas, _("Save This Message"), "system-run",
903 _dialog_save_cb, NULL, cfdata);
904 e_widget_list_object_append(o, ob, 0, 0, 0.5);
907 snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
908 e_user_homedir_get(), cfdata->desktop->name);
910 snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
911 e_user_homedir_get(), "Error");
912 ob = e_widget_label_add(evas, buf);
913 e_widget_list_object_append(o, ob, 1, 1, 0.5);
919 _advanced_create_widgets(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
923 int error_length = 0;
924 Evas_Object *o, *of, *ob, *ot;
928 o = e_widget_list_add(evas, 0, 0);
929 ot = e_widget_table_add(evas, 0);
931 ob = e_widget_label_add(evas, cfdata->label);
932 e_widget_list_object_append(o, ob, 1, 1, 0.5);
936 of = e_widget_framelist_add(evas, _("Error Information"), 0);
937 ob = e_widget_label_add(evas, _(cfdata->exit));
938 e_widget_framelist_object_append(of, ob);
939 e_widget_list_object_append(o, of, 1, 1, 0.5);
944 of = e_widget_framelist_add(evas, _("Error Signal Information"), 0);
945 ob = e_widget_label_add(evas, _(cfdata->signal));
946 e_widget_framelist_object_append(of, ob);
947 e_widget_list_object_append(o, of, 1, 1, 0.5);
950 if (cfdata->read) read_length = cfdata->read->size;
954 of = _dialog_scrolltext_create(evas, _("Output Data"),
955 cfdata->read->lines);
956 /* FIXME: Add stdout "start". */
957 /* FIXME: Add stdout "end". */
961 of = e_widget_framelist_add(evas, _("Output Data"), 0);
962 ob = e_widget_label_add(evas, _("There was no output."));
963 e_widget_framelist_object_append(of, ob);
965 e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
967 if (cfdata->error) error_length = cfdata->error->size;
970 of = _dialog_scrolltext_create(evas, _("Error Logs"),
971 cfdata->error->lines);
972 /* FIXME: Add stderr "start". */
973 /* FIXME: Add stderr "end". */
977 of = e_widget_framelist_add(evas, _("Error Logs"), 0);
978 ob = e_widget_label_add(evas, _("There was no error message."));
979 e_widget_framelist_object_append(of, ob);
981 e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1);
983 e_widget_list_object_append(o, ot, 1, 1, 0.5);
985 ob = e_widget_button_add(evas, _("Save This Message"), "system-run",
986 _dialog_save_cb, NULL, cfdata);
987 e_widget_list_object_append(o, ob, 0, 0, 0.5);
990 snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
991 e_user_homedir_get(), cfdata->desktop->name);
993 snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
994 e_user_homedir_get(), "Error");
995 ob = e_widget_label_add(evas, buf);
996 e_widget_list_object_append(o, ob, 1, 1, 0.5);
1002 _dialog_save_cb(void *data __UNUSED__, void *data2)
1004 E_Config_Dialog_Data *cfdata;
1009 int read_length = 0;
1014 if (cfdata->desktop)
1015 snprintf(buf, sizeof(buf), "%s/%s.log", e_user_homedir_get(),
1016 e_util_filename_escape(cfdata->desktop->name));
1018 snprintf(buf, sizeof(buf), "%s/%s.log", e_user_homedir_get(),
1020 f = fopen(buf, "w");
1025 snprintf(buffer, sizeof(buffer), "Error Information:\n\t%s\n\n",
1027 fwrite(buffer, sizeof(char), strlen(buffer), f);
1031 snprintf(buffer, sizeof(buffer), "Error Signal Information:\n\t%s\n\n",
1033 fwrite(buffer, sizeof(char), strlen(buffer), f);
1036 if (cfdata->read) read_length = cfdata->read->size;
1041 for (i = 0; cfdata->read->lines[i].line; i++)
1042 tlen += cfdata->read->lines[i].size + 2;
1043 text = alloca(tlen + 1);
1045 for (i = 0; cfdata->read->lines[i].line; i++)
1048 strcat(text, cfdata->read->lines[i].line);
1051 snprintf(buffer, sizeof(buffer), "Output Data:\n%s\n\n", text);
1052 fwrite(buffer, sizeof(char), strlen(buffer), f);
1056 snprintf(buffer, sizeof(buffer), "Output Data:\n\tThere was no output\n\n");
1057 fwrite(buffer, sizeof(char), strlen(buffer), f);
1060 /* Reusing this var */
1062 if (cfdata->error) read_length = cfdata->error->size;
1067 for (i = 0; cfdata->error->lines[i].line; i++)
1068 tlen += cfdata->error->lines[i].size + 1;
1069 text = alloca(tlen + 1);
1071 for (i = 0; cfdata->error->lines[i].line; i++)
1074 strcat(text, cfdata->error->lines[i].line);
1077 snprintf(buffer, sizeof(buffer), "Error Logs:\n%s\n", text);
1078 fwrite(buffer, sizeof(char), strlen(buffer), f);
1082 snprintf(buffer, sizeof(buffer), "Error Logs:\n\tThere was no error message\n");
1083 fwrite(buffer, sizeof(char), strlen(buffer), f);