Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlexMeter: Add FlexMeter functionality #1571

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CRT.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[FAILED_READ] = A_BOLD | ColorPair(Red, Black),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = A_BOLD | ColorPair(Cyan, Black),
[FLEX] = A_BOLD | ColorPair(Cyan, Black),
[BATTERY] = A_BOLD | ColorPair(Cyan, Black),
[LARGE_NUMBER] = A_BOLD | ColorPair(Red, Black),
[METER_SHADOW] = A_BOLD | ColorPairGrayBlack,
Expand Down Expand Up @@ -247,6 +248,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[FAILED_READ] = A_BOLD,
[PAUSED] = A_BOLD | A_REVERSE,
[UPTIME] = A_BOLD,
[FLEX] = A_BOLD,
[BATTERY] = A_BOLD,
[LARGE_NUMBER] = A_BOLD,
[METER_SHADOW] = A_DIM,
Expand Down Expand Up @@ -365,6 +367,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[FAILED_READ] = ColorPair(Red, White),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = ColorPair(Yellow, White),
[FLEX] = ColorPair(Yellow, White),
[BATTERY] = ColorPair(Yellow, White),
[LARGE_NUMBER] = ColorPair(Red, White),
[METER_SHADOW] = ColorPair(Blue, White),
Expand Down Expand Up @@ -483,6 +486,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[FAILED_READ] = ColorPair(Red, Black),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = ColorPair(Yellow, Black),
[FLEX] = ColorPair(Yellow, Black),
[BATTERY] = ColorPair(Yellow, Black),
[LARGE_NUMBER] = ColorPair(Red, Black),
[METER_SHADOW] = A_BOLD | ColorPairGrayBlack,
Expand Down Expand Up @@ -601,6 +605,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[FAILED_READ] = A_BOLD | ColorPair(Red, Blue),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = A_BOLD | ColorPair(Yellow, Blue),
[FLEX] = A_BOLD | ColorPair(Yellow, Blue),
[BATTERY] = A_BOLD | ColorPair(Yellow, Blue),
[LARGE_NUMBER] = A_BOLD | ColorPair(Red, Blue),
[METER_SHADOW] = ColorPair(Cyan, Blue),
Expand Down Expand Up @@ -719,6 +724,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[FAILED_READ] = A_BOLD | ColorPair(Red, Black),
[PAUSED] = A_BOLD | ColorPair(Yellow, Green),
[UPTIME] = ColorPair(Green, Black),
[FLEX] = ColorPair(Green, Black),
[BATTERY] = ColorPair(Green, Black),
[LARGE_NUMBER] = A_BOLD | ColorPair(Red, Black),
[METER_SHADOW] = A_BOLD | ColorPairGrayBlack,
Expand Down
1 change: 1 addition & 0 deletions CRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ typedef enum ColorElements_ {
DYNAMIC_MAGENTA,
DYNAMIC_YELLOW,
DYNAMIC_WHITE,
FLEX,
LAST_COLORELEMENT
} ColorElements;

Expand Down
225 changes: 225 additions & 0 deletions FlexMeter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
htop - FlexMeter.c
(C) 2021 Stoyan Bogdanov
(C) 2021 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

#include "config.h"
#include "FlexMeter.h"
#include <time.h>
#include <sys/time.h>
#include <dirent.h>
#include "CRT.h"
#include "Object.h"
//#include "ProcessList.h"

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

#define FLEX_CFG_FOLDER ".config/htop/FlexMeter"

typedef struct {
char name[80];
char command[2048];
char type[80];
char caption[80];
char uiName[80];
uint8_t done;
}_flex_meter;


_flex_meter meter_list[30];

int meter_list_idx=0;
static int meters_count=0;

static const int DateMeter_attributes[] = {
FLEX
};

MeterClass * FlexMeter_class = NULL;

int check_for_meters(void);

static int parse_input(char * line)
{
int l=0;

if (!strncmp(line,"name=",5))
{
strcpy(meter_list[meters_count].uiName,line+5);
l = strlen(meter_list[meters_count].uiName);
meter_list[meters_count].uiName[l-1] = '\0';
}
else if (!strncmp(line,"command=",7))
{
strcpy(meter_list[meters_count].command,line+8);
l = strlen(meter_list[meters_count].command);
meter_list[meters_count].command[l-1] = '\0';
}
else if (!strncmp(line,"caption=",7))
{
strcpy(meter_list[meters_count].caption,line+9);
l = strlen(meter_list[meters_count].caption);
meter_list[meters_count].caption[l-1] = '\0';
}
else if (!strncmp(line,"type=",5))
{
strcpy(meter_list[meters_count].type,line+6);
l = strlen(meter_list[meters_count].type);
meter_list[meters_count].type[l-1] = '\0';
}
else
{
return -1;
}

return 0;
}

static int load_config(char * file)
{
int ret=0;
char buff[2048];
memset(buff,0,2048);
FILE *fp = fopen( file , "r");
while( NULL != fgets(buff, 2048, fp) )
{
parse_input(buff);
memset(buff,0,2048);
}

fclose(fp);
return ret;
}

int check_for_meters(void)
{
char path[400];
DIR *d;
struct dirent *dir;
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
char home[120];
sprintf(home,"%s/%s",homedir,FLEX_CFG_FOLDER);
d = opendir(home);
if (d) {
while ((dir = readdir(d)) != NULL) {
if ( dir->d_name[0]!='.' && strcmp(".",dir->d_name) && strcmp("..",dir->d_name))
{
strcpy(meter_list[meters_count].name,dir->d_name);
memset(path,0,80);
sprintf(path,"%s/%s",home,dir->d_name);
if( 0 != load_config(path) )
{
break;
}
if ( meters_count < MAX_METERS_COUNT )
{
meters_count++;
}
else
{
break; // go out we reach the limit
}
}
}
closedir(d);
}
else
{
if (0 == mkdir(home,0777))
{
char template [4][40] =
{
"name=template",
"command=echo \"`uptime`\"",
"type=TEXT_METERMODE",
"caption=\"UPTIME\""
};

char template_filename[500];
sprintf(template_filename,"%s/%s",home,".Template");
FILE * fp = fopen(template_filename,"w");
if (fp != NULL )
{
for (int i=0; i<4; i++)
{
fprintf(fp,"%s\n",template[i]);
}
}
}
}
return meters_count;
}

static void FlexMeter_updateValues(Meter* this)
{
for (int i =0 ; i < meters_count; i++)
{
if (this->m_ptr == &FlexMeter_class[i] )
{
char buff[256]={0};
memset(buff,0,256);
if ( meter_list[i].command[0] != 0 )
{
FILE* fd = popen(meter_list[i].command, "r");
if (fd)
{
if ( fgets(buff, 256, fd) == NULL ) pclose(fd);
else pclose(fd);
}
if( buff[0] != 0 )
{
int l = strlen(buff);
buff[l-1] = '\0';
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%s",buff);
}
}
}
}
}

const MeterClass FlexMeter_class_template = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.updateValues = FlexMeter_updateValues,
.defaultMode = TEXT_METERMODE,
.maxItems = 1,
.total = 100,
.attributes = DateMeter_attributes,
.name = NULL,
.uiName = NULL,
.caption = NULL,
};

int load_flex_modules(void)
{
uint8_t meters_num = check_for_meters();
if (FlexMeter_class == NULL && meters_num!=0)
{
FlexMeter_class = (MeterClass*) xCalloc(meters_num,sizeof(MeterClass));
for (uint8_t i=0 ; i<meters_num;i++)
{
memcpy(&FlexMeter_class[i],&FlexMeter_class_template,sizeof(MeterClass));

char * p = (char * ) xCalloc(1,strlen(meter_list[i].name));
memcpy(p,meter_list[i].name,strlen(meter_list[i].name));
FlexMeter_class[i].name = (const char *) p;

p = (char * ) xCalloc(1,strlen(meter_list[i].uiName));
memcpy(p,meter_list[i].uiName,strlen(meter_list[i].uiName));
FlexMeter_class[i].uiName = (const char *) p;

p = (char * ) xCalloc(1,strlen(meter_list[i].caption));
memcpy(p,meter_list[i].caption,strlen(meter_list[i].caption));
FlexMeter_class[i].caption = (const char *) p;
}
}
return (int)meters_num;
}
19 changes: 19 additions & 0 deletions FlexMeter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef HEADER_FlexMeter
#define HEADER_FlexMeter
/*
htop - FlexMeter.c
(C) 2021 Stoyan Bogdanov
(C) 2021 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

#include "Meter.h"

#define METERS_LIST_SIZE 30
#define MAX_METERS_COUNT METERS_LIST_SIZE-1

extern MeterClass *FlexMeter_class ;
int load_flex_modules(void);

#endif
10 changes: 9 additions & 1 deletion Header.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ in the source distribution for its full text.
#include "ProvideCurses.h"
#include "Settings.h"
#include "XUtils.h"

#include "FlexMeter.h"

Header* Header_new(Machine* host, HeaderLayout hLayout) {
Header* this = xCalloc(1, sizeof(Header));
Expand Down Expand Up @@ -121,6 +121,14 @@ void Header_populateFromSettings(Header* this) {
const Settings* settings = this->host->settings;
Header_setLayout(this, settings->hLayout);

int num=load_flex_modules();
int platform_size=0;

for (platform_size =0; Platform_meterTypes[platform_size]!=NULL ;platform_size++);
for (int i =0; i<num ;i++) Platform_meterTypes[platform_size+i]=FlexMeter_class+i;

Platform_meterTypes[platform_size+num]=NULL;

Header_forEachColumn(this, col) {
const MeterColumnSetting* colSettings = &settings->hColumns[col];
Vector_prune(this->columns[col]);
Expand Down
6 changes: 4 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ myhtopsources = \
UptimeMeter.c \
UsersTable.c \
Vector.c \
XUtils.c
XUtils.c \
FlexMeter.c

myhtopheaders = \
Action.h \
Expand Down Expand Up @@ -163,7 +164,8 @@ myhtopheaders = \
UptimeMeter.h \
UsersTable.h \
Vector.h \
XUtils.h
XUtils.h \
FlexMeter.h

# Linux
# -----
Expand Down
1 change: 1 addition & 0 deletions Meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ Meter* Meter_new(const Machine* host, unsigned int param, const MeterClass* type
this->values = type->maxItems ? xCalloc(type->maxItems, sizeof(double)) : NULL;
this->total = type->total;
this->caption = xStrdup(type->caption);
this->m_ptr = type;
if (Meter_initFn(this)) {
Meter_init(this);
}
Expand Down
9 changes: 5 additions & 4 deletions Meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ typedef struct MeterClass_ {
const MeterModeId defaultMode;
const double total;
const int* const attributes;
const char* const name; /* internal name of the meter, must not contain any space */
const char* const uiName; /* display name in header setup menu */
const char* const caption; /* prefix in the actual header */
const char* name; /* internal name of the meter, must not contain any space */
const char* uiName; /* display name in header setup menu */
const char* caption; /* prefix in the actual header */
const char* const description; /* optional meter description in header setup menu */
const uint8_t maxItems;
const bool isMultiColumn; /* whether the meter draws multiple sub-columns (defaults to false) */
Expand Down Expand Up @@ -102,8 +102,9 @@ typedef struct GraphData_ {
struct Meter_ {
Object super;
Meter_Draw draw;
const Machine* host;

const Machine* host;
const MeterClass * m_ptr;
char* caption;
MeterModeId mode;
unsigned int param;
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ AM_INIT_AUTOMAKE([-Wall std-options subdir-objects])

# ----------------------------------------------------------------------

AC_DEFINE([MAX_PLATFORM_METERS], [100], [Set max meters for number])

# ----------------------------------------------------------------------
# Checks for platform.
Expand Down
Loading