|
|
|
@ -1,6 +1,12 @@ |
|
|
|
|
#include <e.h> |
|
|
|
|
#include "process.h" |
|
|
|
|
|
|
|
|
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) |
|
|
|
|
# include <sys/types.h> |
|
|
|
|
# include <sys/sysctl.h> |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static int64_t _mem_total; |
|
|
|
|
static Eina_List *_clients = NULL; |
|
|
|
|
static Ecore_Timer *_clients_timer = NULL; |
|
|
|
|
|
|
|
|
@ -11,12 +17,41 @@ struct _Proc_Stats |
|
|
|
|
{ |
|
|
|
|
E_Client *client; |
|
|
|
|
Evas_Object *obj; |
|
|
|
|
Evas_Object *obj_swallow; |
|
|
|
|
pid_t pid; |
|
|
|
|
uint64_t mem_size; |
|
|
|
|
uint64_t cpu_time; |
|
|
|
|
uint64_t cpu_time_prev; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_memory_total(void) |
|
|
|
|
{ |
|
|
|
|
#if defined(__linux__) |
|
|
|
|
char line[256]; |
|
|
|
|
FILE *f = fopen("/proc/meminfo", "r"); |
|
|
|
|
if (!f) return; |
|
|
|
|
|
|
|
|
|
while (fgets(line, sizeof(line), f) != NULL) |
|
|
|
|
{ |
|
|
|
|
if (!strncmp("MemTotal:", line, 9)) |
|
|
|
|
{ |
|
|
|
|
char *p, *t; |
|
|
|
|
p = strchr(line, ':') + 1; |
|
|
|
|
while (isspace(*p)) p++; |
|
|
|
|
t = strtok(p, " "); |
|
|
|
|
_mem_total = atoll(t) * 1024; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
fclose(f); |
|
|
|
|
#else |
|
|
|
|
size_t len = sizeof(_mem_total); |
|
|
|
|
int mib[5] = { CTL_HW, HW_PHYSMEM, 0, 0, 0 }; |
|
|
|
|
sysctl(mib, 2, &_mem_total, &len, NULL, 0); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static Eina_Bool |
|
|
|
|
_proc_stats_item_exists(E_Client *ec) |
|
|
|
|
{ |
|
|
|
@ -31,14 +66,24 @@ _proc_stats_item_exists(E_Client *ec) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_proc_stats_client_del_cb(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) |
|
|
|
|
_proc_stats_item_del(Proc_Stats *item) |
|
|
|
|
{ |
|
|
|
|
edje_object_signal_emit(item->obj, "e,state,procstats,off", "e"); |
|
|
|
|
evas_object_del(item->obj_swallow); |
|
|
|
|
free(item); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_proc_stats_client_del_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) |
|
|
|
|
{ |
|
|
|
|
edje_object_signal_emit(obj, "e,state,procstats,off", "e"); |
|
|
|
|
Proc_Stats *item = data; |
|
|
|
|
_proc_stats_item_del(item); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_proc_stats_item_add(E_Client *ec) |
|
|
|
|
{ |
|
|
|
|
Evas_Object *tb, *pb; |
|
|
|
|
Evas_Object *o; |
|
|
|
|
Proc_Stats *item; |
|
|
|
|
|
|
|
|
@ -51,25 +96,38 @@ _proc_stats_item_add(E_Client *ec) |
|
|
|
|
e_theme_edje_object_set(o, "base/theme/borders", |
|
|
|
|
"e/widgets/border/default/border"); |
|
|
|
|
|
|
|
|
|
if (!edje_object_part_exists(o, "e.procstats.text")) return; |
|
|
|
|
if (!edje_object_part_exists(o, "e.procstats.swallow")) return; |
|
|
|
|
|
|
|
|
|
tb = elm_table_add(e_comp->elm); |
|
|
|
|
evas_object_show(tb); |
|
|
|
|
|
|
|
|
|
pb = elm_progressbar_add(e_comp->elm); |
|
|
|
|
elm_progressbar_span_size_set(pb, 60); |
|
|
|
|
evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, EVAS_HINT_FILL); |
|
|
|
|
evas_object_show(pb); |
|
|
|
|
elm_table_pack(tb, pb, 0, 0, 1, 1); |
|
|
|
|
evas_object_data_set(tb, "pb_cpu", pb); |
|
|
|
|
|
|
|
|
|
pb = elm_progressbar_add(e_comp->elm); |
|
|
|
|
elm_progressbar_span_size_set(pb, 100); |
|
|
|
|
evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, EVAS_HINT_FILL); |
|
|
|
|
evas_object_show(pb); |
|
|
|
|
elm_table_pack(tb, pb, 1, 0, 1, 1); |
|
|
|
|
evas_object_data_set(tb, "pb_mem", pb); |
|
|
|
|
|
|
|
|
|
item = calloc(1, sizeof(Proc_Stats)); |
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(item); |
|
|
|
|
item->pid = ec->netwm.pid; |
|
|
|
|
item->client = ec; |
|
|
|
|
item->obj = ec->frame_object; |
|
|
|
|
item->obj_swallow = tb; |
|
|
|
|
|
|
|
|
|
edje_object_signal_emit(item->obj, "e,state,procstats,on", "e"); |
|
|
|
|
evas_object_event_callback_add(item->obj, EVAS_CALLBACK_DEL, _proc_stats_client_del_cb, NULL); |
|
|
|
|
edje_object_part_swallow(ec->frame_object, "e.procstats.swallow", tb); |
|
|
|
|
edje_object_signal_emit(ec->frame_object, "e,state,procstats,on", "e"); |
|
|
|
|
|
|
|
|
|
_clients = eina_list_append(_clients, item); |
|
|
|
|
} |
|
|
|
|
evas_object_event_callback_add(item->obj, EVAS_CALLBACK_DEL, _proc_stats_client_del_cb, item); |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_proc_stats_item_del(Proc_Stats *item) |
|
|
|
|
{ |
|
|
|
|
edje_object_signal_emit(item->obj, "e,state,procstats,off", "e"); |
|
|
|
|
free(item); |
|
|
|
|
_clients = eina_list_append(_clients, item); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -118,27 +176,55 @@ _proc_stats_item_children_update(Eina_List *children, Proc_Stats *item) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const char * |
|
|
|
|
_size_format(unsigned long long bytes) |
|
|
|
|
{ |
|
|
|
|
const char *units = "BKMGTPEZY"; |
|
|
|
|
unsigned long powi = 1; |
|
|
|
|
unsigned long long value; |
|
|
|
|
unsigned int precision = 2, powj = 1; |
|
|
|
|
|
|
|
|
|
value = bytes; |
|
|
|
|
while (value > 1024) |
|
|
|
|
{ |
|
|
|
|
if ((value / 1024) < powi) break; |
|
|
|
|
powi *= 1024; |
|
|
|
|
++units; |
|
|
|
|
if (units[1] == '\0') break; |
|
|
|
|
} |
|
|
|
|
if (*units == 'B') precision = 0; |
|
|
|
|
while (precision > 0) |
|
|
|
|
{ |
|
|
|
|
powj *= 10; |
|
|
|
|
if ((value / powi) < powj) break; |
|
|
|
|
--precision; |
|
|
|
|
} |
|
|
|
|
return eina_slstr_printf("%1.*f%c", precision, (double) value / powi, *units); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
_proc_stats_item_display(Proc_Stats *item) |
|
|
|
|
{ |
|
|
|
|
Edje_Message_Int_Set *msg; |
|
|
|
|
int mem_size; |
|
|
|
|
Evas_Object *pb; |
|
|
|
|
double val = 0.0; |
|
|
|
|
|
|
|
|
|
if (item->cpu_time_prev > item->cpu_time) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (!item->cpu_time_prev) item->cpu_time_prev = item->cpu_time; |
|
|
|
|
|
|
|
|
|
mem_size = item->mem_size >> 10; |
|
|
|
|
msg = malloc(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3)); |
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(msg); |
|
|
|
|
msg->count = 4; |
|
|
|
|
msg->val[0] = eina_cpu_count(); |
|
|
|
|
msg->val[1] = (item->cpu_time - item->cpu_time_prev) / _TIMER_FREQ; |
|
|
|
|
msg->val[2] = mem_size; |
|
|
|
|
msg->val[3] = 0; |
|
|
|
|
edje_object_message_send(item->obj, EDJE_MESSAGE_INT_SET, 1, msg); |
|
|
|
|
free(msg); |
|
|
|
|
pb = evas_object_data_get(item->obj_swallow, "pb_cpu"); |
|
|
|
|
|
|
|
|
|
val = (item->cpu_time - item->cpu_time_prev) / _TIMER_FREQ; |
|
|
|
|
elm_progressbar_value_set(pb, val / 100.0); |
|
|
|
|
elm_object_part_text_set(pb, "elm.text.status", eina_slstr_printf("%1.0f %%", val)); |
|
|
|
|
|
|
|
|
|
pb = evas_object_data_get(item->obj_swallow, "pb_mem"); |
|
|
|
|
val = item->mem_size / (_mem_total / 100.0); |
|
|
|
|
elm_progressbar_value_set(pb, val / 100.0); |
|
|
|
|
elm_object_part_text_set(pb, "elm.text.status", |
|
|
|
|
eina_slstr_printf("%s/%s", _size_format(item->mem_size), |
|
|
|
|
_size_format(_mem_total))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -201,6 +287,7 @@ E_API E_Module_Api e_modapi = |
|
|
|
|
E_API int |
|
|
|
|
e_modapi_init(E_Module *m EINA_UNUSED) |
|
|
|
|
{ |
|
|
|
|
_memory_total(); |
|
|
|
|
_proc_stats_timer_cb(NULL); |
|
|
|
|
|
|
|
|
|
_clients_timer = ecore_timer_add(_TIMER_FREQ, _proc_stats_timer_cb, NULL); |
|
|
|
|