First commit

This commit is contained in:
Alastair Poole 2018-06-04 11:11:21 +01:00
commit de2818a394
11 changed files with 3481 additions and 0 deletions

26
LICENSE Normal file
View File

@ -0,0 +1,26 @@
Copyright (c) 2018, Al Poole <netstar@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# esysinfo
System Information (EFL)
This is a process monitor.
Currently have full engines for Linux, FreeBSD, OpenBSD and MacOS.

22
makefile Normal file
View File

@ -0,0 +1,22 @@
LIBS=
OSNAME := $(shell uname -s)
ifeq ($(OSNAME), OpenBSD)
LIBS += -lkvm
LDFLAGS += -I/usr/local/include -L/usr/local/lib -L/usr/X11R6/lib
endif
export CFLAGS = -g -ggdb3 -O
export PKGS = eina elementary
export LIBS
export LDFLAGS
default:
$(MAKE) -C src
clean:
$(MAKE) -C src clean

59
src/main.c Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2018. Alastair Poole <netstar@gmail.com>
See LICENSE file for details.
*/
#include "process.h"
#include "system.h"
#include "ui.h"
static void
_win_del_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
evas_object_del(obj);
ecore_main_loop_quit();
}
static Evas_Object *
_win_add(void)
{
Evas_Object *win, *icon;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_util_standard_add("esysinfo", "esysinfo");
icon = elm_icon_add(win);
elm_icon_standard_set(icon, "system-preferences");
elm_win_icon_object_set(win, icon);
evas_object_resize(win, 768 * elm_config_scale_get(), 420 * elm_config_scale_get());
evas_object_smart_callback_add(win, "delete,request", _win_del_cb, NULL);
elm_win_title_set(win, "System Information");
return win;
}
int
main(int argc, char **argv)
{
Evas_Object *win;
eina_init();
ecore_init();
elm_init(argc, argv);
win = _win_add();
ui_add(win);
elm_win_center(win, EINA_TRUE, EINA_TRUE);
evas_object_show(win);
ecore_main_loop_begin();
eina_shutdown();
ecore_shutdown();
elm_shutdown();
return 0;
}

24
src/makefile Normal file
View File

@ -0,0 +1,24 @@
TARGET = ../esysinfo
OBJECTS = system.o process.o ui.o main.o
default: $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(OBJECTS) $(shell pkg-config --libs $(PKGS)) $(LIBS) $(LDFLAGS) -o $@
main.o: main.c
$(CC) -c $(CFLAGS) $(shell pkg-config --cflags $(PKGS)) main.c -o $@
system.o: system.c
$(CC) -c $(CFLAGS) system.c -o $@
process.o: process.c
$(CC) -c $(CFLAGS) $(shell pkg-config --cflags $(PKGS)) process.c -o $@
ui.o: ui.c
$(CC) -c $(CFLAGS) $(shell pkg-config --cflags $(PKGS)) ui.c -o $@
clean:
-rm $(OBJECTS)
-rm $(TARGET)

568
src/process.c Normal file
View File

@ -0,0 +1,568 @@
#if defined(__MACH__) && defined(__APPLE__)
# define __MacOS__
#endif
#if defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
# include <sys/types.h>
# include <sys/sysctl.h>
# include <sys/user.h>
# include <sys/proc.h>
#endif
#if defined(__OpenBSD__)
# include <kvm.h>
# include <limits.h>
# include <sys/proc.h>
# include <sys/param.h>
# include <sys/resource.h>
#endif
#if defined(__MacOS__)
# include <libproc.h>
# include <sys/proc_info.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <limits.h>
#include "process.h"
#include <Eina.h>
#include <Ecore.h>
#include <Ecore_File.h>
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);
}
static Eina_List *
_process_list_linux_get(void)
{
char *name;
Eina_List *files, *list = NULL;
FILE *f;
char path[PATH_MAX], line[4096], program_name[1024], state;
int pid, res, utime, stime, cutime, cstime, uid, psr, pri, nice, numthreads;
unsigned int mem_size, mem_rss;
int pagesize = getpagesize();
files = ecore_file_ls("/proc");
EINA_LIST_FREE(files, name)
{
pid = atoi(name);
free(name);
if (!pid) continue;
snprintf(path, sizeof(path), "/proc/%d/stat", pid);
f = fopen(path, "r");
if (!f) continue;
if (fgets(line, sizeof(line), f))
{
int dummy;
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, &dummy, &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) continue;
snprintf(path, sizeof(path), "/proc/%d/status", pid);
f = fopen(path, "r");
if (!f) continue;
while ((fgets(line, sizeof(line), f)) != NULL)
{
if (!strncmp(line, "Uid:", 4))
{
uid = _parse_line(line);
break;
}
}
fclose(f);
Proc_Stats *p = calloc(1, sizeof(Proc_Stats));
p->pid = pid;
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 * pagesize;
p->nice = nice;
p->priority = pri;
p->numthreads = numthreads;
list = eina_list_append(list, p);
}
if (files)
eina_list_free(files);
return list;
}
Proc_Stats *
proc_info_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;
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, &dummy, &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);
Proc_Stats *p = calloc(1, sizeof(Proc_Stats));
p->pid = pid;
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__)
Proc_Stats *
proc_info_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();
Proc_Stats *p = malloc(sizeof(Proc_Stats));
p->pid = kp->p_pid;
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;
}
static Eina_List *
_process_list_openbsd_get(void)
{
struct kinfo_proc *kp;
Proc_Stats *p;
char errbuf[4096];
kvm_t *kern;
int pid_count, pagesize;
Eina_List *l, *list = NULL;
kern = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (!kern) return NULL;
kp = kvm_getprocs(kern, KERN_PROC_ALL, 0, sizeof(*kp), &pid_count);
if (!kp) return NULL;
pagesize = getpagesize();
for (int i = 0; i < pid_count; i++)
{
p = malloc(sizeof(Proc_Stats));
p->pid = kp[i].p_pid;
p->uid = kp[i].p_uid;
p->cpu_id = kp[i].p_cpuid;
snprintf(p->command, sizeof(p->command), "%s", kp[i].p_comm);
p->state = _process_state_name(kp[i].p_stat);
p->cpu_time = kp[i].p_uticks + kp[i].p_sticks + kp[i].p_iticks;
p->mem_size = (kp[i].p_vm_tsize * pagesize) + (kp[i].p_vm_dsize * pagesize) + (kp[i].p_vm_ssize * pagesize);
p->mem_rss = kp[i].p_vm_rssize * pagesize;
p->priority = kp[i].p_priority - PZERO;
p->nice = kp[i].p_nice - NZERO;
p->numthreads = -1;
list = eina_list_append(list, p);
}
kp = kvm_getprocs(kern, KERN_PROC_SHOW_THREADS, 0, sizeof(*kp), &pid_count);
EINA_LIST_FOREACH (list, l, p)
{
for (int i = 0; i < pid_count; i++)
{
if (kp[i].p_pid == p->pid)
p->numthreads++;
}
}
kvm_close(kern);
return list;
}
#endif
#if defined(__MacOS__)
static Eina_List *
_process_list_macos_get(void)
{
Eina_List *list = NULL;
for (int i = 1; i <= PID_MAX; i++)
{
struct proc_taskallinfo taskinfo;
int size = proc_pidinfo(i, PROC_PIDTASKALLINFO, 0, &taskinfo, sizeof(taskinfo));
if (size != sizeof(taskinfo)) continue;
Proc_Stats *p = calloc(1, sizeof(Proc_Stats));
p->pid = i;
p->uid = taskinfo.pbsd.pbi_uid;
p->cpu_id = -1;
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;
list = eina_list_append(list, p);
}
return list;
}
Proc_Stats *
proc_info_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;
Proc_Stats *p = calloc(1, sizeof(Proc_Stats));
p->pid = pid;
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__)
static Eina_List *
_process_list_freebsd_get(void)
{
Eina_List *list;
struct rusage *usage;
struct kinfo_proc kp;
int mib[4];
size_t len;
int pagesize = getpagesize();
list = NULL;
len = sizeof(int);
if (sysctlnametomib("kern.proc.pid", mib, &len) == -1)
return NULL;
for (int i = 1; i <= PID_MAX; i++)
{
mib[3] = i;
len = sizeof(kp);
if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
{
continue;
}
if (kp.ki_flag & P_SYSTEM)
continue;
Proc_Stats *p = calloc(1, sizeof(Proc_Stats));
p->pid = kp.ki_pid;
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;
list = eina_list_append(list, p);
}
return list;
}
Proc_Stats *
proc_info_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;
Proc_Stats *p = calloc(1, sizeof(Proc_Stats));
p->pid = kp.ki_pid;
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
Eina_List *
proc_info_all_get(void)
{
Eina_List *processes;
#if defined(__linux__)
processes = _process_list_linux_get();
#elif defined(__FreeBSD__) || defined(__DragonFly__)
processes = _process_list_freebsd_get();
#elif defined(__MacOS__)
processes = _process_list_macos_get();
#elif defined(__OpenBSD__)
processes = _process_list_openbsd_get();
#else
processes = NULL;
#endif
return processes;
}

69
src/process.h Normal file
View File

@ -0,0 +1,69 @@
#ifndef __PROC_H__
#define __PROC_H__
/**
* @file
* @brief Routines for querying processes.
*/
/**
* @brief Querying Processes
* @defgroup Proc
*
* @{
*
* Query processes.
*
*/
#include <Eina.h>
#include <stdint.h>
#include <unistd.h>
#if !defined(PID_MAX)
# define PID_MAX 99999
#endif
#define CMD_NAME_MAX 256
typedef struct _Proc_Stats
{
pid_t pid;
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;
// Not used yet in UI.
long cpu_time;
} Proc_Stats;
/**
* Query a full list of running processes and return a list.
*
* @return A list of proc_t members for all processes.
*/
Eina_List *
proc_info_all_get(void);
/**
* Query a process for its current state.
*
* @param pid The process ID to query.
*
* @return A proc_t pointer containing the process information.
*/
Proc_Stats *
proc_info_by_pid(int pid);
/**
* @}
*/
#endif

1184
src/system.c Normal file

File diff suppressed because it is too large Load Diff

7
src/system.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef __SYSTEM_H__
#define __SYSTEM_H__
int
system_cpu_memory_get(double *percent_cpu, long *memory_total, long *memory_used);
#endif

1401
src/ui.c Normal file

File diff suppressed because it is too large Load Diff

114
src/ui.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef __UI_H__
#define __UI_H__
#include <Elementary.h>
typedef enum
{
PROCESS_INFO_FIELD_PID,
PROCESS_INFO_FIELD_UID,
PROCESS_INFO_FIELD_SIZE,
PROCESS_INFO_FIELD_RSS,
PROCESS_INFO_FIELD_COMMAND,
PROCESS_INFO_FIELD_STATE,
PROCESS_INFO_FIELD_CPU_USAGE,
// Not displayed in the main UI.
PROCESS_INFO_FIELD_NICE,
PROCESS_INFO_FIELD_PRI,
PROCESS_INFO_FIELD_CPU,
PROCESS_INFO_FIELD_THREADS,
// Not used yet in UI.
PROCESS_INFO_FIELD_CPU_TIME,
} Proc_Stats_Field;
#define PROCESS_INFO_FIELDS 7
typedef enum
{
SORT_BY_NONE,
SORT_BY_PID,
SORT_BY_UID,
SORT_BY_NICE,
SORT_BY_PRI,
SORT_BY_CPU,
SORT_BY_THREADS,
SORT_BY_SIZE,
SORT_BY_RSS,
SORT_BY_CMD,
SORT_BY_STATE,
SORT_BY_CPU_USAGE,
} Sort_Type;
typedef struct Ui
{
Evas_Object *win;
Evas_Object *panel;
Evas_Object *scroller;
Evas_Object *progress_cpu;
Evas_Object *progress_mem;
Evas_Object *entry_pid;
Evas_Object *entry_uid;
Evas_Object *entry_size;
Evas_Object *entry_rss;
Evas_Object *entry_cmd;
Evas_Object *entry_state;
Evas_Object *entry_cpu_usage;
Evas_Object *btn_pid;
Evas_Object *btn_uid;
Evas_Object *btn_size;
Evas_Object *btn_rss;
Evas_Object *btn_cmd;
Evas_Object *btn_state;
Evas_Object *btn_cpu_usage;
Evas_Object *entry_pid_cmd;
Evas_Object *entry_pid_user;
Evas_Object *entry_pid_pid;
Evas_Object *entry_pid_uid;
Evas_Object *entry_pid_cpu;
Evas_Object *entry_pid_threads;
Evas_Object *entry_pid_size;
Evas_Object *entry_pid_rss;
Evas_Object *entry_pid_nice;
Evas_Object *entry_pid_pri;
Evas_Object *entry_pid_state;
Evas_Object *entry_pid_cpu_usage;
Ecore_Timer *timer_pid;
pid_t selected_pid;
pid_t program_pid;
#define TEXT_FIELD_MAX 65535
char *fields[PROCESS_INFO_FIELDS];
Evas_Object *list_pid;
Eina_Bool first_run;
int64_t cpu_times[PID_MAX];
int64_t pid_cpu_time;
int poll_delay;
Sort_Type sort_type;
Eina_Bool sort_reverse;
Eina_Bool panel_visible;
} Ui;
typedef struct Sys_Stats
{
int cpu_count;
double cpu_usage;
long mem_total;
long mem_used;
} Sys_Stats;
void
ui_add(Evas_Object *win);
#endif