diff --git a/INSTALL b/INSTALL index 3cbfe67..0c1675c 100644 --- a/INSTALL +++ b/INSTALL @@ -37,7 +37,7 @@ The above will only work after at least the following is done: ** QUICK AND DIRTY HELP ** -------------------------- -How clean out the build and config and start fresh: +How to clean out the build and config and start fresh: rm -rf build diff --git a/README.md b/README.md index c799fbd..0d11ea3 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ and in creating apps based on the EFL suite. meson ninja -EFL latest release (>= 1.20.7) +EFL latest release (>= 1.22.0) libclang-dev (or llvm-clang-devel) ## Installation diff --git a/meson.build b/meson.build index a87744b..6c14be2 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'edi', 'c', - version : '0.7.99', + version : '0.7.1', default_options: [ 'c_std=gnu99', 'warning_level=2' ], meson_version : '>= 0.39.0') @@ -22,7 +22,7 @@ config_h.set_quoted('PACKAGE_DOC_DIR', join_paths(get_option('prefix'), get_opti config_h.set_quoted('EFL_BETA_API_SUPPORT' , '1') -elm = dependency('elementary', version : '>=1.21.1') +elm = dependency('elementary', version : '>=1.22.0') top_inc = include_directories('.') cc = meson.get_compiler('c') diff --git a/packaging/pkgbuild/PKGBUILD b/packaging/pkgbuild/PKGBUILD index 37d5872..0e8f961 100644 --- a/packaging/pkgbuild/PKGBUILD +++ b/packaging/pkgbuild/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Enlightenment Developers pkgname='edi-git' -pkgver=0.7.0.0001 +pkgver=0.7.1.0001 pkgrel=1 pkgdesc="Efl based IDE - GIT development snapshot" arch=('i686' 'x86_64' 'arm') diff --git a/src/bin/edi_consolepanel.c b/src/bin/edi_consolepanel.c index c760d3a..3f40208 100644 --- a/src/bin/edi_consolepanel.c +++ b/src/bin/edi_consolepanel.c @@ -380,11 +380,11 @@ void edi_consolepanel_add(Evas_Object *parent) evas_object_show(frame); widget = elm_code_widget_add(parent, code); - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); edi_theme_elm_code_set(widget, _edi_project_config->gui.theme); - elm_obj_code_widget_gravity_set(widget, 0.0, 1.0); + elm_code_widget_gravity_set(widget, 0.0, 1.0); efl_event_callback_add(widget, &ELM_CODE_EVENT_LINE_LOAD_DONE, _edi_consolepanel_line_cb, NULL); - efl_event_callback_add(widget, ELM_OBJ_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_consolepanel_clicked_cb, code); + efl_event_callback_add(widget, EFL_UI_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_consolepanel_clicked_cb, code); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); @@ -415,11 +415,11 @@ void edi_testpanel_add(Evas_Object *parent) evas_object_show(frame); widget = elm_code_widget_add(parent, code); - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); edi_theme_elm_code_set(widget, _edi_project_config->gui.theme); - elm_obj_code_widget_gravity_set(widget, 0.0, 1.0); + elm_code_widget_gravity_set(widget, 0.0, 1.0); efl_event_callback_add(widget, &ELM_CODE_EVENT_LINE_LOAD_DONE, _edi_testpanel_line_cb, NULL); - efl_event_callback_add(widget, ELM_OBJ_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_consolepanel_clicked_cb, code); + efl_event_callback_add(widget, EFL_UI_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_consolepanel_clicked_cb, code); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); diff --git a/src/bin/edi_debug.c b/src/bin/edi_debug.c index 3a9b855..a0ed3f4 100644 --- a/src/bin/edi_debug.c +++ b/src/bin/edi_debug.c @@ -2,21 +2,19 @@ # include "config.h" #endif -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined (__APPLE__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) #include #include #include #include #endif -#if defined(__OpenBSD__) - #include -#endif #include #include #include #include "edi_debug.h" +#include "edi_process.h" #include "edi_config.h" #include "edi_private.h" @@ -67,160 +65,77 @@ Edi_Debug_Tool *edi_debug_tool_get(const char *name) return &_debugger_tools[0]; } -#if defined(__FreeBSD__) || defined(__DragonFly__) -static long int -_sysctlfromname(const char *name, void *mib, int depth, size_t *len) +static int +_system_pid_max_get(void) { - long int result; + static int pid_max = 0; - if (sysctlnametomib(name, mib, len) < 0) return -1; - *len = sizeof(result); - if (sysctl(mib, depth, &result, len, NULL, 0) < 0) return -1; + if (pid_max > 0) + return pid_max; - return result; -} +#if defined(__linux__) + FILE *f; + char buf[128]; + size_t n; + + f = fopen("/proc/sys/kernel/pid_max", "r"); + if (f) + { + n = fread(buf, 1, sizeof(buf) - 1, f); + buf[n] = 0x00; + fclose(f); + pid_max = atoi(buf); + } +#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) + int mib[2] = { CTL_KERN, KERN_MAXPROC }; + size_t len = sizeof(pid_max); + sysctl(mib, 2, &pid_max, &len, NULL, 0); +#elif defined(PID_MAX) + pid_max = PID_MAX; #endif + if (pid_max <= 0) + pid_max = 99999; + + return pid_max; +} /* Get the process ID of the child process being debugged in *our* session */ int edi_debug_process_id(Edi_Debug *debugger) { - int my_pid, child_pid = -1; -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined (__APPLE__) || defined(__OpenBSD__) - struct kinfo_proc kp; - int mib[6]; - size_t len; - int max_pid, i; + Edi_Proc_Stats *p; + int pid_max, debugger_pid, child_pid = -1; + if (!debugger) return -1; if (!debugger->program_name) return -1; if (!debugger->exe) return -1; -#if defined(__FreeBSD__) || defined(__DragonFly__) - len = sizeof(max_pid); - max_pid = _sysctlfromname("kern.lastpid", mib, 2, &len); -#elif defined(PID_MAX) - max_pid = PID_MAX; -#else - max_pid = 99999; -#endif - my_pid = ecore_exe_pid_get(debugger->exe); + debugger_pid = ecore_exe_pid_get(debugger->exe); -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) - if (sysctlnametomib("kern.proc.pid", mib, &len) < 0) return -1; -#elif defined(__OpenBSD__) - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[4] = sizeof(struct kinfo_proc); - mib[5] = 1; -#endif + pid_max = _system_pid_max_get(); - for (i = my_pid; i <= max_pid; i++) + for (int i = 1; i <= pid_max; i++) { - mib[3] = i; - len = sizeof(kp); -#if defined(__OpenBSD__) - if (sysctl(mib, 6, &kp, &len, NULL, 0) == -1) continue; -#else - if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1) continue; -#endif - -#if defined(__FreeBSD__) || defined(__DragonFly__) - if (kp.ki_ppid != my_pid) continue; - if (strcmp(debugger->program_name, kp.ki_comm)) continue; - child_pid = kp.ki_pid; - if (kp.ki_stat == SRUN || kp.ki_stat == SSLEEP) - debugger->state = EDI_DEBUG_PROCESS_ACTIVE; - else - debugger->state = EDI_DEBUG_PROCESS_SLEEPING; -#elif defined(__OpenBSD__) - if (kp.p_ppid != my_pid) continue; - if (strcmp(debugger->program_name, kp.p_comm)) continue; - child_pid = kp.p_pid; - - if (kp.p_stat == SRUN || kp.p_stat == SSLEEP) - debugger->state = EDI_DEBUG_PROCESS_ACTIVE; - else - debugger->state = EDI_DEBUG_PROCESS_SLEEPING; -#else /* APPLE */ - if (kp.kp_proc.p_oppid != my_pid) continue; - if (strcmp(debugger->program_name, kp.kp_proc.p_comm)) continue; - child_pid = kp.kp_proc.p_pid; - if (kp.kp_proc.p_stat == SRUN || kp.kp_proc.p_stat == SSLEEP) - debugger->state = EDI_DEBUG_PROCESS_ACTIVE; - else - debugger->state = EDI_DEBUG_PROCESS_SLEEPING; -#endif - break; - } -#else - Eina_List *files, *l; - const char *temp_name; - char path[PATH_MAX]; - char buf[4096]; - char *p, *name, *end; - FILE *f; - int count, parent_pid, pid; - - if (!debugger->program_name) - return -1; - - if (!debugger->exe) return -1; - - my_pid = ecore_exe_pid_get(debugger->exe); - - files = ecore_file_ls("/proc"); - - EINA_LIST_FOREACH(files, l, name) - { - pid = atoi(name); - if (!pid) continue; - snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); - f = fopen(path, "r"); - if (!f) continue; - p = fgets(buf, sizeof(buf), f); - fclose(f); + p = edi_process_stats_by_pid(i); if (!p) continue; - temp_name = ecore_file_file_get(buf); - if (!strcmp(temp_name, debugger->program_name)) + + if (p->ppid == debugger_pid) { - parent_pid = 0; - // Match success - program name with pid. - child_pid = pid; - snprintf(path, sizeof(path), "/proc/%d/stat", pid); - f = fopen(path, "r"); - if (f) + if (!strcmp(debugger->program_name, p->command)) { - count = 0; - p = fgets(buf, sizeof(buf), f); - while (*p++ != '\0') - { - if (p[0] == ' ') { count++; p++; } - if (count == 2) - { - if (p[0] == 'S' || p[0] == 'R') - debugger->state = EDI_DEBUG_PROCESS_ACTIVE; - else - debugger->state = EDI_DEBUG_PROCESS_SLEEPING; - } - if (count == 3) break; - } - end = strchr(p, ' '); - if (end) - { - *end = '\0'; - // parent pid matches - right process. - parent_pid = atoi(p); - } - fclose(f); + child_pid = p->pid; + if (!strcmp(p->state, "RUN") ||!strcmp(p->state, "SLEEP")) + debugger->state = EDI_DEBUG_PROCESS_ACTIVE; + else + debugger->state = EDI_DEBUG_PROCESS_SLEEPING; } - if (parent_pid == my_pid) - break; } + + free(p); + + if (child_pid != -1) + break; } - if (files) - eina_list_free(files); -#endif return child_pid; } diff --git a/src/bin/edi_debugpanel.c b/src/bin/edi_debugpanel.c index 4c86d90..1361c64 100644 --- a/src/bin/edi_debugpanel.c +++ b/src/bin/edi_debugpanel.c @@ -197,11 +197,14 @@ _edi_debugpanel_button_start_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UN edi_debugpanel_start(_edi_project_config_debug_command_get()); } -static Eina_Bool -_edi_debug_active_check_cb(void *data EINA_UNUSED) +void +edi_debugpanel_active_check(void) { + Edi_Debug *debug; int pid; - Edi_Debug *debug = edi_debug_get(); + + debug = edi_debug_get(); + if (!debug) return; pid = ecore_exe_pid_get(debug->exe); if (pid == -1) @@ -212,16 +215,11 @@ _edi_debug_active_check_cb(void *data EINA_UNUSED) elm_object_disabled_set(_button_start, EINA_FALSE); elm_object_disabled_set(_button_int, EINA_TRUE); elm_object_disabled_set(_button_term, EINA_TRUE); - return ECORE_CALLBACK_RENEW; + return; } - if (!debug) - return ECORE_CALLBACK_RENEW; - pid = edi_debug_process_id(debug); _edi_debugpanel_icons_update(pid > 0 ? debug->state : 0); - - return ECORE_CALLBACK_RENEW; } void edi_debugpanel_stop(void) @@ -322,7 +320,6 @@ void edi_debugpanel_add(Evas_Object *parent) Evas_Object *ico_start, *ico_quit, *ico_int, *ico_term; Elm_Code_Widget *widget; Elm_Code *code; - Ecore_Timer *timer; frame = elm_frame_add(parent); elm_object_text_set(frame, _("Debug")); @@ -335,9 +332,9 @@ void edi_debugpanel_add(Evas_Object *parent) code = elm_code_create(); widget = elm_code_widget_add(parent, code); - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); edi_theme_elm_code_set(_info_widget, _edi_project_config->gui.theme); - elm_obj_code_widget_gravity_set(widget, 0.0, 1.0); + elm_code_widget_gravity_set(widget, 0.0, 1.0); efl_event_callback_add(widget, &ELM_CODE_EVENT_LINE_LOAD_DONE, _edi_debugpanel_line_cb, NULL); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); @@ -409,9 +406,6 @@ void edi_debugpanel_add(Evas_Object *parent) edi_debug_new(); - timer = ecore_timer_add(1.0, _edi_debug_active_check_cb, NULL); - (void) timer; - elm_box_pack_end(box, widget); elm_box_pack_end(box, table); evas_object_show(box); diff --git a/src/bin/edi_debugpanel.h b/src/bin/edi_debugpanel.h index 47b7547..e274411 100644 --- a/src/bin/edi_debugpanel.h +++ b/src/bin/edi_debugpanel.h @@ -47,6 +47,14 @@ void edi_debugpanel_start(const char *toolname); */ void edi_debugpanel_stop(); +/** + * Perform a poll to check the state of any debug session + * + * @ingroup UI + */ +void edi_debugpanel_active_check(void); + + /** * @} */ diff --git a/src/bin/edi_logpanel.c b/src/bin/edi_logpanel.c index 176ecc2..425caae 100644 --- a/src/bin/edi_logpanel.c +++ b/src/bin/edi_logpanel.c @@ -94,8 +94,8 @@ void edi_logpanel_add(Evas_Object *parent) code = elm_code_create(); widget = elm_code_widget_add(parent, code); edi_theme_elm_code_set(widget, _edi_project_config->gui.theme); - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); - elm_obj_code_widget_gravity_set(widget, 0.0, 1.0); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_gravity_set(widget, 0.0, 1.0); efl_event_callback_add(widget, &ELM_CODE_EVENT_LINE_LOAD_DONE, _edi_logpanel_line_cb, NULL); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index a4cb970..4751c8b 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -16,6 +16,7 @@ #include "edi_theme.h" #include "edi_filepanel.h" #include "edi_file.h" +#include "edi_process.h" #include "edi_logpanel.h" #include "edi_consolepanel.h" #include "edi_searchpanel.h" @@ -52,12 +53,64 @@ static Elm_Object_Item *_edi_selected_bottompanel; static Evas_Object *_edi_filepanel, *_edi_filepanel_icon; static Evas_Object *_edi_menu_undo, *_edi_menu_redo, *_edi_toolbar_undo, *_edi_toolbar_redo, *_edi_toolbar_build, *_edi_toolbar_test; -static Evas_Object *_edi_menu_build, *_edi_menu_clean, *_edi_menu_test; +static Evas_Object *_edi_menu_build, *_edi_menu_clean, *_edi_menu_test, *_edi_menu_run, *_edi_menu_terminate; static Evas_Object *_edi_menu_init, *_edi_menu_commit, *_edi_menu_push, *_edi_menu_pull, *_edi_menu_status, *_edi_menu_stash; static Evas_Object *_edi_menu_save, *_edi_toolbar_save; static Evas_Object *_edi_main_win, *_edi_main_box; +static Evas_Object *_edi_toolbar_run, *_edi_toolbar_terminate; int _edi_log_dom = -1; +static void +_edi_active_process_icons_set(Eina_Bool active) +{ + if (active) + { + elm_object_disabled_set(_edi_toolbar_run, EINA_TRUE); + elm_object_disabled_set(_edi_toolbar_terminate, EINA_FALSE); + elm_object_item_disabled_set(_edi_menu_run, EINA_TRUE); + elm_object_item_disabled_set(_edi_menu_terminate, EINA_FALSE); + } + else + { + elm_object_disabled_set(_edi_toolbar_run, EINA_FALSE); + elm_object_disabled_set(_edi_toolbar_terminate, EINA_TRUE); + elm_object_item_disabled_set(_edi_menu_run, EINA_FALSE); + elm_object_item_disabled_set(_edi_menu_terminate, EINA_TRUE); + } +} + +static Eina_Bool +_edi_active_process_check_cb(EINA_UNUSED void *data) +{ + Edi_Proc_Stats *stats; + pid_t pid; + + // Check debugpanel state. + edi_debugpanel_active_check(); + + pid = edi_exe_project_pid_get(); + if (pid == -1) + { + _edi_active_process_icons_set(EINA_FALSE); + return ECORE_CALLBACK_RENEW; + } + + stats = edi_process_stats_by_pid(pid); + if (!stats) + { + // Our process is not running, reset PID we + // track. + edi_exe_project_pid_reset(); + _edi_active_process_icons_set(EINA_FALSE); + return ECORE_CALLBACK_RENEW; + } + + free(stats); + + _edi_active_process_icons_set(EINA_TRUE); + + return ECORE_CALLBACK_RENEW; +} static void _edi_file_open_cb(const char *path, const char *type, Eina_Bool newwin) @@ -569,7 +622,7 @@ edi_launcher_config_missing() title = _("Unable to launch"); message = _("No launch binary found, please configure in Settings."); - edi_screens_settings_message(_edi_main_win, title, message); + edi_screens_settings_message(_edi_main_win, EDI_SETTINGS_TAB_BUILDS, title, message); } void @@ -580,7 +633,7 @@ edi_debug_exe_missing(void) title = _("Unable to launch debugger"); message = _("No debug binary found, please check system configuration and Settings."); - edi_screens_settings_message(_edi_main_win, title, message); + edi_screens_settings_message(_edi_main_win, EDI_SETTINGS_TAB_BUILDS, title, message); } static void @@ -592,7 +645,7 @@ _edi_project_credentials_missing() title = _("Missing user information"); message = _("No user information found, please configure in Settings."); - edi_screens_settings_message(_edi_main_win, title, message); + edi_screens_settings_message(_edi_main_win, EDI_SETTINGS_TAB_PROJECT, title, message); } static Eina_Bool @@ -722,6 +775,15 @@ _edi_launcher_run(Edi_Project_Config_Launch *launch) edi_builder_run(launch->path, launch->args); } +static void +_edi_launcher_terminate(void) +{ + pid_t pid = edi_exe_project_pid_get(); + if (pid == -1) return; + + kill(pid, SIGKILL); +} + static void _edi_build_menu_items_disabled_set(Eina_Bool state) { @@ -831,6 +893,12 @@ _tb_debug_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i _edi_debug_project(); } +static void +_tb_terminate_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + _edi_launcher_terminate(); +} + static void _tb_about_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { @@ -840,7 +908,7 @@ _tb_about_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i static void _tb_settings_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - edi_settings_show(_edi_main_win); + edi_settings_show(_edi_main_win, EDI_SETTINGS_TAB_DISPLAY); } static void @@ -907,7 +975,7 @@ static void _edi_menu_settings_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - edi_settings_show(_edi_main_win); + edi_settings_show(_edi_main_win, EDI_SETTINGS_TAB_DISPLAY); } static void @@ -1037,6 +1105,13 @@ _edi_menu_run_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, _edi_launcher_run(&_edi_project_config->launch); } +static void +_edi_menu_terminate_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + _edi_launcher_terminate(); +} + static void _edi_menu_clean_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) @@ -1227,9 +1302,11 @@ _edi_menu_setup(Evas_Object *win) menu_it = elm_menu_item_add(menu, NULL, NULL, _("Build"), NULL, NULL); _edi_menu_build = elm_menu_item_add(menu, menu_it, "system-run", _("Build"), _edi_menu_build_cb, NULL); _edi_menu_test = elm_menu_item_add(menu, menu_it, "media-record", _("Test"), _edi_menu_test_cb, NULL); - elm_menu_item_add(menu, menu_it, "media-playback-start", _("Run"), _edi_menu_run_cb, NULL); _edi_menu_clean = elm_menu_item_add(menu, menu_it, "edit-clear", _("Clean"), _edi_menu_clean_cb, NULL); elm_menu_item_separator_add(menu, menu_it); + _edi_menu_run = elm_menu_item_add(menu, menu_it, "media-playback-start", _("Run"), _edi_menu_run_cb, NULL); + _edi_menu_terminate = elm_menu_item_add(menu, menu_it, "media-playback-stop", _("Terminate"), _edi_menu_terminate_cb, NULL); + elm_menu_item_separator_add(menu, menu_it); elm_menu_item_add(menu, menu_it, "utilities-terminal", _("Debugger"), _edi_menu_debug_cb, NULL); elm_menu_item_add(menu, menu_it, "applications-electronics", _("Memcheck"), _edi_menu_memcheck_cb, NULL); @@ -1304,7 +1381,10 @@ edi_toolbar_setup(Evas_Object *parent) _edi_toolbar_build = _edi_toolbar_item_add(tb, "system-run", _("Build"), _tb_build_cb); _edi_toolbar_test = _edi_toolbar_item_add(tb, "media-record", _("Test"), _tb_test_cb); - _edi_toolbar_item_add(tb, "media-playback-start", _("Run"), _tb_run_cb); + tb_it = elm_toolbar_item_append(tb, "separator", "", NULL, NULL); + elm_toolbar_item_separator_set(tb_it, EINA_TRUE); + _edi_toolbar_run =_edi_toolbar_item_add(tb, "media-playback-start", _("Run"), _tb_run_cb); + _edi_toolbar_terminate = _edi_toolbar_item_add(tb, "media-playback-stop", _("Terminate"), _tb_terminate_cb); _edi_toolbar_item_add(tb, "utilities-terminal", _("Debug"), _tb_debug_cb); tb_it = elm_toolbar_item_append(tb, "separator", "", NULL, NULL); @@ -1581,6 +1661,7 @@ edi_open(const char *inputpath) ecore_event_handler_add(EDI_EVENT_TAB_CHANGED, _edi_tab_changed, NULL); ecore_event_handler_add(EDI_EVENT_FILE_CHANGED, _edi_file_changed, NULL); ecore_event_handler_add(EDI_EVENT_FILE_SAVED, _edi_file_saved, NULL); + ecore_timer_add(1.0, _edi_active_process_check_cb, NULL); ERR("Loaded project at %s", path); evas_object_resize(win, _edi_project_config->gui.width * elm_config_scale_get(), diff --git a/src/bin/edi_scm_ui.c b/src/bin/edi_scm_ui.c index 947d876..9f74a34 100644 --- a/src/bin/edi_scm_ui.c +++ b/src/bin/edi_scm_ui.c @@ -774,9 +774,9 @@ edi_scm_ui_add(Evas_Object *parent) pd->code = code = elm_code_create(); entry = elm_code_widget_add(cbox, code); elm_code_parser_standard_add(code, ELM_CODE_PARSER_STANDARD_DIFF); - elm_obj_code_widget_gravity_set(entry, 0.0, 0.0); - elm_obj_code_widget_editable_set(entry, EINA_FALSE); - elm_obj_code_widget_line_numbers_set(entry, EINA_FALSE); + elm_code_widget_gravity_set(entry, 0.0, 0.0); + elm_code_widget_editable_set(entry, EINA_FALSE); + elm_code_widget_line_numbers_set(entry, EINA_FALSE); evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(entry); diff --git a/src/bin/edi_searchpanel.c b/src/bin/edi_searchpanel.c index e615ed5..cbcd5c0 100644 --- a/src/bin/edi_searchpanel.c +++ b/src/bin/edi_searchpanel.c @@ -585,9 +585,9 @@ edi_searchpanel_add(Evas_Object *parent) code = elm_code_create(); widget = elm_code_widget_add(parent, code); edi_theme_elm_code_set(widget, _edi_project_config->gui.theme); - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); - elm_obj_code_widget_gravity_set(widget, 0.0, 1.0); - efl_event_callback_add(widget, ELM_OBJ_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_searchpanel_line_clicked_cb, NULL); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_gravity_set(widget, 0.0, 1.0); + efl_event_callback_add(widget, EFL_UI_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_searchpanel_line_clicked_cb, NULL); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(widget); @@ -672,10 +672,10 @@ edi_taskspanel_add(Evas_Object *parent) code = elm_code_create(); widget = elm_code_widget_add(parent, code); edi_theme_elm_code_set(widget, _edi_project_config->gui.theme); - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); - elm_obj_code_widget_gravity_set(widget, 0.0, 1.0); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_gravity_set(widget, 0.0, 1.0); efl_event_callback_add(widget, &ELM_CODE_EVENT_LINE_LOAD_DONE, _edi_taskspanel_line_cb, NULL); - efl_event_callback_add(widget, ELM_OBJ_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_taskspanel_line_clicked_cb, NULL); + efl_event_callback_add(widget, EFL_UI_CODE_WIDGET_EVENT_LINE_CLICKED, _edi_taskspanel_line_clicked_cb, NULL); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(widget); diff --git a/src/bin/edi_theme.c b/src/bin/edi_theme.c index 88d2017..8a5e6d2 100644 --- a/src/bin/edi_theme.c +++ b/src/bin/edi_theme.c @@ -14,7 +14,7 @@ static Eina_List *_edi_themes = NULL; // we are hooking into Efl for now... -Efl_Ui_Theme_Apply efl_ui_widget_theme_apply(Eo *obj); +Eina_Error efl_ui_widget_theme_apply(Eo *obj); void edi_theme_window_alpha_set(void) diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index 2b470d3..3777aad 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -1202,13 +1202,13 @@ _edi_editor_config_changed(void *data, int type EINA_UNUSED, void *event EINA_UN code->config.trim_whitespace = _edi_config->trim_whitespace; - elm_obj_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); + elm_code_widget_font_set(widget, _edi_project_config->font.name, _edi_project_config->font.size); edi_theme_elm_code_alpha_set(widget); edi_theme_elm_code_set(widget, _edi_project_config->gui.theme); - elm_obj_code_widget_show_whitespace_set(widget, _edi_project_config->gui.show_whitespace); - elm_obj_code_widget_tab_inserts_spaces_set(widget, _edi_project_config->gui.tab_inserts_spaces); - elm_obj_code_widget_line_width_marker_set(widget, _edi_project_config->gui.width_marker); - elm_obj_code_widget_tabstop_set(widget, _edi_project_config->gui.tabstop); + elm_code_widget_show_whitespace_set(widget, _edi_project_config->gui.show_whitespace); + elm_code_widget_tab_inserts_spaces_set(widget, _edi_project_config->gui.tab_inserts_spaces); + elm_code_widget_line_width_marker_set(widget, _edi_project_config->gui.width_marker); + elm_code_widget_tabstop_set(widget, _edi_project_config->gui.tabstop); return ECORE_CALLBACK_RENEW; } diff --git a/src/bin/screens/edi_screens.c b/src/bin/screens/edi_screens.c index 04e77ee..eafa025 100644 --- a/src/bin/screens/edi_screens.c +++ b/src/bin/screens/edi_screens.c @@ -14,6 +14,12 @@ static void _edi_screens_popup_cancel_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { + Edi_Settings_Tab *default_tab; + + default_tab = evas_object_data_get((Evas_Object *) data, "default_tab"); + if (default_tab) + free(default_tab); + evas_object_del((Evas_Object *) data); } @@ -129,16 +135,20 @@ static void _edi_screens_settings_display_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) { - Evas_Object *parent = evas_object_data_get(obj, "parent"); + Evas_Object *parent; + Edi_Settings_Tab type; + parent = evas_object_data_get(obj, "parent"); + type = *((Edi_Settings_Tab *) evas_object_data_get((Evas_Object *) data, "default_tab")); evas_object_del((Evas_Object *) data); - edi_settings_show(parent); + edi_settings_show(parent, type); } -void edi_screens_settings_message(Evas_Object *parent, const char *title, const char *message) +void edi_screens_settings_message(Evas_Object *parent, Edi_Settings_Tab type, const char *title, const char *message) { Evas_Object *popup, *frame, *table, *box, *icon, *sep, *label, *button; + Edi_Settings_Tab *default_tab; popup = elm_popup_add(parent); elm_object_part_text_set(popup, "title,text", title); @@ -182,6 +192,14 @@ void edi_screens_settings_message(Evas_Object *parent, const char *title, const elm_object_text_set(button, _("Settings")); elm_object_part_content_set(popup, "button2", button); evas_object_data_set(button, "parent", parent); + + default_tab = malloc(sizeof(Edi_Settings_Tab)); + if (default_tab) + { + *default_tab = type; + evas_object_data_set(popup, "default_tab", default_tab); + } + evas_object_smart_callback_add(button, "clicked", _edi_screens_settings_display_cb, popup); evas_object_show(popup); diff --git a/src/bin/screens/edi_screens.h b/src/bin/screens/edi_screens.h index 590b191..42e2e8d 100644 --- a/src/bin/screens/edi_screens.h +++ b/src/bin/screens/edi_screens.h @@ -22,6 +22,14 @@ extern "C" { * */ +typedef enum _Edi_Settings_Tab +{ + EDI_SETTINGS_TAB_DISPLAY = 0, + EDI_SETTINGS_TAB_PROJECT = 1, + EDI_SETTINGS_TAB_BUILDS = 2, + EDI_SETTINGS_TAB_BEHAVIOUR = 3, +} Edi_Settings_Tab; + /** * Initialise a new Edi welcome window and display it. * @@ -56,7 +64,7 @@ Evas_Object *edi_about_show(Evas_Object *mainwin); * * @ingroup UI */ -Evas_Object *edi_settings_show(Evas_Object *mainwin); +Evas_Object *edi_settings_show(Evas_Object *mainwin, Edi_Settings_Tab type); /** * Return a pointer to the settings window. @@ -104,12 +112,13 @@ void edi_screens_message(Evas_Object *parent, const char *title, const char *mes * Create an information dialogue with additional button to settings. * * @param parent The parent object to display the dialogue in. + * @param type The type of tab to be opened in the settings window. * @param title The title for the popup. * @param message The text to be displayed in the popup. * * @ingroup UI */ -void edi_screens_settings_message(Evas_Object *parent, const char *title, const char *message); +void edi_screens_settings_message(Evas_Object *parent, Edi_Settings_Tab type, const char *title, const char *message); /** * Send a desktop notification message to the window manager. diff --git a/src/bin/screens/edi_settings.c b/src/bin/screens/edi_settings.c index 65130de..3f27f2f 100644 --- a/src/bin/screens/edi_settings.c +++ b/src/bin/screens/edi_settings.c @@ -139,10 +139,10 @@ _edi_settings_font_preview_add(Evas_Object *parent, const char *font_name, int f elm_code_file_line_append(code->file, FONT_PREVIEW, 35, NULL); widget = elm_code_widget_add(parent, code); - elm_obj_code_widget_font_set(widget, font_name, font_size); - elm_obj_code_widget_line_numbers_set(widget, EINA_TRUE); - elm_obj_code_widget_editable_set(widget, EINA_FALSE); - elm_obj_code_widget_policy_set(widget, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + elm_code_widget_font_set(widget, font_name, font_size); + elm_code_widget_line_numbers_set(widget, EINA_TRUE); + elm_code_widget_editable_set(widget, EINA_FALSE); + elm_code_widget_policy_set(widget, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(widget); @@ -852,10 +852,11 @@ edi_settings_win_get(void) } Evas_Object * -edi_settings_show(Evas_Object *mainwin) +edi_settings_show(Evas_Object *mainwin, Edi_Settings_Tab type) { Evas_Object *win, *bg, *table, *naviframe, *tb; Elm_Object_Item *tb_it, *default_it; + Elm_Object_Item *it_project, *it_display, *it_behaviour, *it_builds; if (edi_settings_win_get()) return NULL; @@ -908,18 +909,34 @@ edi_settings_show(Evas_Object *mainwin) _edi_settings_behaviour_create(naviframe), NULL); elm_naviframe_item_title_enabled_set(_edi_settings_behaviour, EINA_FALSE, EINA_FALSE); - - elm_toolbar_item_append(tb, "applications-development", _("Project"),_edi_settings_category_cb, _edi_settings_project); - default_it = elm_toolbar_item_append(tb, "preferences-desktop", _("Display"), - _edi_settings_category_cb, _edi_settings_display); - elm_toolbar_item_append(tb, "system-run", "Builds", - _edi_settings_category_cb, _edi_settings_builds); + it_project = elm_toolbar_item_append(tb, "applications-development", _("Project"),_edi_settings_category_cb, _edi_settings_project); + it_display = elm_toolbar_item_append(tb, "preferences-desktop", _("Display"), _edi_settings_category_cb, _edi_settings_display); + it_builds = elm_toolbar_item_append(tb, "system-run", _("Builds"), _edi_settings_category_cb, _edi_settings_builds); tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL); elm_toolbar_item_separator_set(tb_it, EINA_TRUE); elm_toolbar_item_append(tb, "application-internet", _("Global"), NULL, NULL); - elm_toolbar_item_append(tb, "preferences-other", _("Behaviour"), - _edi_settings_category_cb, _edi_settings_behaviour); + elm_object_item_disabled_set(tb, EINA_TRUE); + + it_behaviour = elm_toolbar_item_append(tb, "preferences-other", _("Behaviour"), + _edi_settings_category_cb, _edi_settings_behaviour); + + switch (type) + { + case EDI_SETTINGS_TAB_DISPLAY: + default_it = it_display; + break; + case EDI_SETTINGS_TAB_PROJECT: + default_it = it_project; + break; + case EDI_SETTINGS_TAB_BEHAVIOUR: + default_it = it_behaviour; + break; + case EDI_SETTINGS_TAB_BUILDS: + default_it = it_builds; + break; + } + elm_toolbar_item_selected_set(default_it, EINA_TRUE); evas_object_show(naviframe); diff --git a/src/bin/screens/edi_settings_font.c b/src/bin/screens/edi_settings_font.c index 44dbffb..f1bce4d 100644 --- a/src/bin/screens/edi_settings_font.c +++ b/src/bin/screens/edi_settings_font.c @@ -37,10 +37,10 @@ _edi_settings_font_preview_add(Evas_Object *parent, const char *font_name, int f elm_code_file_line_append(code->file, FONT_PREVIEW, 35, NULL); widget = elm_code_widget_add(parent, code); - elm_obj_code_widget_font_set(widget, font_name, font_size); - elm_obj_code_widget_line_numbers_set(widget, EINA_TRUE); - elm_obj_code_widget_editable_set(widget, EINA_FALSE); - elm_obj_code_widget_policy_set(widget, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + elm_code_widget_font_set(widget, font_name, font_size); + elm_code_widget_line_numbers_set(widget, EINA_TRUE); + elm_code_widget_editable_set(widget, EINA_FALSE); + elm_code_widget_policy_set(widget, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); evas_object_size_hint_weight_set(widget, 0.5, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(widget); diff --git a/src/lib/edi_build_provider_cargo.c b/src/lib/edi_build_provider_cargo.c index dcf2ee1..0e61036 100644 --- a/src/lib/edi_build_provider_cargo.c +++ b/src/lib/edi_build_provider_cargo.c @@ -26,7 +26,7 @@ _relative_path_exists(const char *base, const char *relative) static void _exec_cmd(const char *cmd) { - ecore_exe_pipe_run(cmd, + edi_exe_project_run(cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); diff --git a/src/lib/edi_build_provider_cmake.c b/src/lib/edi_build_provider_cmake.c index f43e43d..fe3f18d 100644 --- a/src/lib/edi_build_provider_cmake.c +++ b/src/lib/edi_build_provider_cmake.c @@ -76,7 +76,7 @@ _cmake_run(const char *path, const char *args) if (!args) { - ecore_exe_pipe_run(path, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + edi_exe_project_run(path, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); @@ -87,7 +87,7 @@ _cmake_run(const char *path, const char *args) full_cmd = malloc(sizeof(char) * (full_len + 1)); snprintf(full_cmd, full_len + 2, "%s %s", path, args); - ecore_exe_pipe_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + edi_exe_project_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); diff --git a/src/lib/edi_build_provider_go.c b/src/lib/edi_build_provider_go.c index 119010b..8dc5e98 100644 --- a/src/lib/edi_build_provider_go.c +++ b/src/lib/edi_build_provider_go.c @@ -69,22 +69,40 @@ _go_test(void) static void _go_run(const char *path EINA_UNUSED, const char *args EINA_UNUSED) { + const char *ext; char *full_cmd; - int full_len; + int full_len, flags; if (!path) return; + if (chdir(edi_project_get()) !=0) ERR("Could not chdir"); full_len = strlen(path) + 8; if (args) full_len += strlen(args); - full_cmd = malloc(sizeof(char) * (full_len + 1)); - snprintf(full_cmd, full_len + 1, "go run %s %s", path, args?args:""); - ecore_exe_pipe_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | - ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | - ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); + full_cmd = malloc(sizeof(char) * (full_len + 1)); + + flags = ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | + ECORE_EXE_PIPE_WRITE; + + ext = strrchr(path, '.'); + + // We may want to run a binary or via the go command. + // Simple and quicker to test for file extension. + if (ext && !strcasecmp(ext, ".go")) + { + snprintf(full_cmd, full_len + 1, "go run %s %s", path, args?args:""); + flags |= ECORE_EXE_USE_SH; + } + else + { + snprintf(full_cmd, full_len + 1, "%s", path); + } + + edi_exe_project_run(full_cmd, flags, NULL); free(full_cmd); } diff --git a/src/lib/edi_build_provider_make.c b/src/lib/edi_build_provider_make.c index d62b7ad..968af54 100644 --- a/src/lib/edi_build_provider_make.c +++ b/src/lib/edi_build_provider_make.c @@ -143,7 +143,7 @@ _make_run(const char *path, const char *args) if (!args) { - ecore_exe_pipe_run(path, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + edi_exe_project_run(path, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); @@ -154,7 +154,7 @@ _make_run(const char *path, const char *args) full_cmd = malloc(sizeof(char) * (full_len + 1)); snprintf(full_cmd, full_len + 1, "%s %s", path, args); - ecore_exe_pipe_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + edi_exe_project_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); diff --git a/src/lib/edi_build_provider_meson.c b/src/lib/edi_build_provider_meson.c index 48fb9a2..fc4bdf3 100644 --- a/src/lib/edi_build_provider_meson.c +++ b/src/lib/edi_build_provider_meson.c @@ -147,7 +147,8 @@ _meson_run(const char *path, const char *args) if (args) cmd = eina_slstr_printf("%s %s", path, args); else cmd = path; - ecore_exe_pipe_run(cmd, + + edi_exe_project_run(cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE /*| ECORE_EXE_USE_SH*/, md); diff --git a/src/lib/edi_build_provider_python.c b/src/lib/edi_build_provider_python.c index 3993e0e..80e282a 100644 --- a/src/lib/edi_build_provider_python.c +++ b/src/lib/edi_build_provider_python.c @@ -26,7 +26,7 @@ _relative_path_exists(const char *base, const char *relative) static void _exec_cmd(const char *cmd) { - ecore_exe_pipe_run(cmd, + edi_exe_project_run(cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); diff --git a/src/lib/edi_exe.c b/src/lib/edi_exe.c index 07ecb7d..c080838 100644 --- a/src/lib/edi_exe.c +++ b/src/lib/edi_exe.c @@ -184,3 +184,29 @@ edi_exe_response(const char *command) return out; } + +static pid_t _project_pid = -1; + +void +edi_exe_project_pid_reset() +{ + _project_pid = -1; +} + +pid_t +edi_exe_project_pid_get(void) +{ + return _project_pid; +} + +pid_t +edi_exe_project_run(const char *command, int flags, void *data) +{ + Ecore_Exe *exe; + + exe = ecore_exe_pipe_run(command, flags, data); + + _project_pid = ecore_exe_pid_get(exe); + + return _project_pid; +} diff --git a/src/lib/edi_exe.h b/src/lib/edi_exe.h index 2dec603..9bd1ce0 100644 --- a/src/lib/edi_exe.h +++ b/src/lib/edi_exe.h @@ -62,6 +62,31 @@ EAPI void edi_exe_notify(const char *name, const char *command); */ EAPI Eina_Bool edi_exe_notify_handle(const char *name, void ((*func)(int, void *)), void *data); +/** + * This function launches the project application binary. Used for monitoring a running + * process state. It's a wrapper for ecore_exe_run but is necessary to keep track of any + * instance of program being ran. + * + * @param command The command to execute. + * @param flags The ECORE_EXE flags to execute with. + * @param data Data to be passed to ecore_exe_run. + * + * @return PID of the process after executing. + */ +EAPI pid_t edi_exe_project_run(const char *command, int flags, void *data); + +/** + * Returns the PID of the project executable if running. + * + * @return PID if the process exists else -1. + */ +EAPI pid_t edi_exe_project_pid_get(void); + +/** + * Reset the project PID to inactive state. + */ +EAPI void edi_exe_project_pid_reset(void); + /** * @} */ diff --git a/src/lib/edi_process.c b/src/lib/edi_process.c new file mode 100644 index 0000000..991ad17 --- /dev/null +++ b/src/lib/edi_process.c @@ -0,0 +1,335 @@ +#if defined(__MACH__) && defined(__APPLE__) +# define __MacOS__ +#endif + +#if defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) +# include +# include +# include +# include +#endif + +#if defined(__OpenBSD__) +# include +# include +# include +# include +# include +#endif + +#if defined(__MacOS__) +# include +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "edi_process.h" +#include +#include +#include + +static const char * +_process_state_name(char state) +{ + const char *statename = NULL; +#if defined(__linux__) + + switch (state) + { + case 'D': + statename = "DSLEEP"; + break; + + case 'I': + statename = "IDLE"; + break; + + case 'R': + statename = "RUN"; + break; + + case 'S': + statename = "SLEEP"; + break; + + case 'T': + case 't': + statename = "STOP"; + break; + + case 'X': + statename = "DEAD"; + break; + + case 'Z': + statename = "ZOMB"; + break; + } +#else + switch (state) + { + case SIDL: + statename = "IDLE"; + break; + + case SRUN: + statename = "RUN"; + break; + + case SSLEEP: + statename = "SLEEP"; + break; + + case SSTOP: + statename = "STOP"; + break; + +#if !defined(__MacOS__) +#if !defined(__OpenBSD__) + case SWAIT: + statename = "WAIT"; + break; + + case SLOCK: + statename = "LOCK"; + break; + +#endif + case SZOMB: + statename = "ZOMB"; + break; + +#endif +#if defined(__OpenBSD__) + case SDEAD: + statename = "DEAD"; + break; + + case SONPROC: + statename = "ONPROC"; + break; +#endif + } +#endif + return statename; +} + +#if defined(__linux__) + +static unsigned long +_parse_line(const char *line) +{ + char *p, *tok; + + p = strchr(line, ':') + 1; + while (isspace(*p)) + p++; + tok = strtok(p, " "); + + return atol(tok); +} + +Edi_Proc_Stats * +edi_process_stats_by_pid(int pid) +{ + FILE *f; + char path[PATH_MAX]; + char line[4096]; + char state, program_name[1024]; + int res, dummy, utime, stime, cutime, cstime, uid, psr, ppid; + unsigned int mem_size, mem_rss, pri, nice, numthreads; + + snprintf(path, sizeof(path), "/proc/%d/stat", pid); + if (!ecore_file_exists(path)) + return NULL; + + f = fopen(path, "r"); + if (!f) return NULL; + + if (fgets(line, sizeof(line), f)) + { + char *end, *start = strchr(line, '(') + 1; + end = strchr(line, ')'); + strncpy(program_name, start, end - start); + program_name[end - start] = '\0'; + + res = sscanf(end + 2, "%c %d %d %d %d %d %u %u %u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d %d %d %d %u %d %d %d %d %d %d %d %d %d", + &state, &ppid, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &utime, &stime, &cutime, &cstime, + &pri, &nice, &numthreads, &dummy, &dummy, &mem_size, &mem_rss, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, + &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &psr, &dummy, &dummy, &dummy, &dummy, &dummy); + } + fclose(f); + + if (res != 42) return NULL; + + snprintf(path, sizeof(path), "/proc/%d/status", pid); + + f = fopen(path, "r"); + if (!f) return NULL; + + while ((fgets(line, sizeof(line), f)) != NULL) + { + if (!strncmp(line, "Uid:", 4)) + { + uid = _parse_line(line); + break; + } + } + fclose(f); + + Edi_Proc_Stats *p = calloc(1, sizeof(Edi_Proc_Stats)); + p->pid = pid; + p->ppid = ppid; + p->uid = uid; + p->cpu_id = psr; + snprintf(p->command, sizeof(p->command), "%s", program_name); + p->state = _process_state_name(state); + p->cpu_time = utime + stime; + p->mem_size = mem_size; + p->mem_rss = mem_rss * getpagesize(); + p->priority = pri; + p->nice = nice; + p->numthreads = numthreads; + + return p; +} + +#endif + +#if defined(__OpenBSD__) + +Edi_Proc_Stats * +edi_process_stats_by_pid(int pid) +{ + struct kinfo_proc *kp; + kvm_t *kern; + char errbuf[4096]; + int count, pagesize, pid_count; + + kern = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + if (!kern) return NULL; + + kp = kvm_getprocs(kern, KERN_PROC_PID, pid, sizeof(*kp), &count); + if (!kp) return NULL; + + if (count == 0) return NULL; + pagesize = getpagesize(); + + Edi_Proc_Stats *p = malloc(sizeof(Edi_Proc_Stats)); + p->pid = kp->p_pid; + p->ppid = kp->p_ppid; + p->uid = kp->p_uid; + p->cpu_id = kp->p_cpuid; + snprintf(p->command, sizeof(p->command), "%s", kp->p_comm); + p->state = _process_state_name(kp->p_stat); + p->cpu_time = kp->p_uticks + kp->p_sticks + kp->p_iticks; + p->mem_size = (kp->p_vm_tsize * pagesize) + (kp->p_vm_dsize * pagesize) + (kp->p_vm_ssize * pagesize); + p->mem_rss = kp->p_vm_rssize * pagesize; + p->priority = kp->p_priority - PZERO; + p->nice = kp->p_nice - NZERO; + p->numthreads = -1; + + kp = kvm_getprocs(kern, KERN_PROC_SHOW_THREADS, 0, sizeof(*kp), &pid_count); + + for (int i = 0; i < pid_count; i++) + { + if (kp[i].p_pid == p->pid) + p->numthreads++; + } + + kvm_close(kern); + + return p; +} + +#endif + +#if defined(__MacOS__) +Edi_Proc_Stats * +edi_process_stats_by_pid(int pid) +{ + struct kinfo_proc kp; + struct proc_taskallinfo taskinfo; + struct proc_workqueueinfo workqueue; + size_t size; + + size = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &taskinfo, sizeof(taskinfo)); + if (size != sizeof(taskinfo)) + return NULL; + + size = proc_pidinfo(pid, PROC_PIDWORKQUEUEINFO, 0, &workqueue, sizeof(workqueue)); + if (size != sizeof(workqueue)) + return NULL; + + Edi_Proc_Stats *p = calloc(1, sizeof(Edi_Proc_Stats)); + p->pid = pid; + p->ppid = taskinfo.pbsd.pbi_ppid; + p->uid = taskinfo.pbsd.pbi_uid; + p->cpu_id = workqueue.pwq_nthreads; + snprintf(p->command, sizeof(p->command), "%s", taskinfo.pbsd.pbi_comm); + p->cpu_time = taskinfo.ptinfo.pti_total_user + taskinfo.ptinfo.pti_total_system; + p->cpu_time /= 10000000; + p->state = _process_state_name(taskinfo.pbsd.pbi_status); + p->mem_size = taskinfo.ptinfo.pti_virtual_size; + p->mem_rss = taskinfo.ptinfo.pti_resident_size; + p->priority = taskinfo.ptinfo.pti_priority; + p->nice = taskinfo.pbsd.pbi_nice; + p->numthreads = taskinfo.ptinfo.pti_threadnum; + + return p; +} + +#endif + +#if defined(__FreeBSD__) || defined(__DragonFly__) +Edi_Proc_Stats * +edi_process_stats_by_pid(int pid) +{ + struct rusage *usage; + struct kinfo_proc kp; + int mib[4]; + size_t len; + int pagesize = getpagesize(); + + len = sizeof(int); + if (sysctlnametomib("kern.proc.pid", mib, &len) == -1) + return NULL; + + mib[3] = pid; + + len = sizeof(kp); + if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1) + return NULL; + + Edi_Proc_Stats *p = calloc(1, sizeof(Edi_Proc_Stats)); + p->pid = kp.ki_pid; + p->ppid = kp.ki_ppid; + p->uid = kp.ki_uid; + snprintf(p->command, sizeof(p->command), "%s", kp.ki_comm); + p->cpu_id = kp.ki_oncpu; + if (p->cpu_id == -1) + p->cpu_id = kp.ki_lastcpu; + + usage = &kp.ki_rusage; + + p->cpu_time = (usage->ru_utime.tv_sec * 1000000) + usage->ru_utime.tv_usec + (usage->ru_stime.tv_sec * 1000000) + usage->ru_stime.tv_usec; + p->cpu_time /= 10000; + p->state = _process_state_name(kp.ki_stat); + p->mem_size = kp.ki_size; + p->mem_rss = kp.ki_rssize * pagesize; + p->nice = kp.ki_nice = NZERO; + p->priority = kp.ki_pri.pri_level - PZERO; + p->numthreads = kp.ki_numthreads; + + return p; +} + +#endif + + diff --git a/src/lib/edi_process.h b/src/lib/edi_process.h new file mode 100644 index 0000000..bf8842d --- /dev/null +++ b/src/lib/edi_process.h @@ -0,0 +1,61 @@ +#ifndef __EDI_PROCESS_H__ +#define __EDI_PROCESS_H__ + +/** + * @file + * @brief Routines for querying processes. + */ + +/** + * @brief Querying Processes + * @defgroup Proc + * + * @{ + * + * Query processes. + * + */ + +#include +#include +#include + +#if !defined(PID_MAX) +# define PID_MAX 99999 +#endif + +#define CMD_NAME_MAX 8192 + +typedef struct _Edi_Proc_Stats +{ + pid_t pid; + pid_t ppid; + uid_t uid; + int8_t nice; + int8_t priority; + int cpu_id; + int32_t numthreads; + int64_t mem_size; + int64_t mem_rss; + double cpu_usage; + char command[CMD_NAME_MAX]; + const char *state; + + long cpu_time; +} Edi_Proc_Stats; + +/** + * Query a process for its current state. + * + * @param pid The process ID to query. + * + * @return Pointer to object containing the process information or NULL if non-existent. + */ +Edi_Proc_Stats *edi_process_stats_by_pid(int pid); + + +/** + * @} + */ + +#endif diff --git a/src/lib/meson.build b/src/lib/meson.build index ca5f978..5001a49 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -17,6 +17,8 @@ src = files([ 'edi_exe.h', 'edi_path.c', 'edi_path.h', + 'edi_process.c', + 'edi_process.h', 'edi_private.h', 'edi_scm.c', 'edi_scm.h',