Nahrány soubory do „rcbar“
This commit is contained in:
commit
3821ae9d5c
2 changed files with 388 additions and 0 deletions
22
rcbar/Makefile
Normal file
22
rcbar/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
CC = gcc
|
||||
#CFLAGS = -Wall -pedantic -Werror -std=c99
|
||||
CFLAGS = -Wall -pedantic
|
||||
target = rcbar
|
||||
source = main.c
|
||||
release = -O2
|
||||
debug = -g
|
||||
valgrind = -ggdb3
|
||||
|
||||
$(target): Makefile $(source)
|
||||
# @echo "sestavuji"
|
||||
$(CC) -o $(target) $(source) $(release) $(CFLAGS)
|
||||
|
||||
.PHONY : clean
|
||||
clean:
|
||||
# @echo "provadim clean"
|
||||
rm -f $(target)
|
||||
|
||||
install: $(target)
|
||||
@echo "Instaluji"
|
||||
cp -f $(target) /usr/local/bin
|
||||
sync
|
366
rcbar/main.c
Normal file
366
rcbar/main.c
Normal file
|
@ -0,0 +1,366 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MODULE_DATA_SIZE 64
|
||||
#define MODULE_BLOCK_SIZE 1024
|
||||
|
||||
#define BLOCK_CLOCK "clock"
|
||||
#define BLOCK_VOLUME "volume"
|
||||
#define BLOCK_MEMORY "memory"
|
||||
|
||||
#define MODID_CLOCK 1
|
||||
#define MODID_VOLUME 2
|
||||
#define MODID_MEMORY 3
|
||||
|
||||
#define PARAM_CLOCK_LONG 1
|
||||
|
||||
typedef struct module_ {
|
||||
timer_t timer;
|
||||
int interval;
|
||||
char bufdata[MODULE_DATA_SIZE];
|
||||
char bufblock[MODULE_BLOCK_SIZE];
|
||||
char colorbg[16];
|
||||
char colorfg[16];
|
||||
uint64_t id;
|
||||
uint64_t params;
|
||||
} module_t;
|
||||
|
||||
typedef struct appdata_
|
||||
{
|
||||
module_t** modules;
|
||||
size_t mod_count;
|
||||
pthread_mutex_t mutex;
|
||||
} appdata_t;
|
||||
|
||||
static appdata_t* _data;
|
||||
|
||||
static module_t* add_module(appdata_t* data);
|
||||
static void init_modules(appdata_t* data);
|
||||
static void module_start(module_t* module);
|
||||
static void on_timer(union sigval timer_data);
|
||||
static void module_stop(module_t* module);
|
||||
static void cleanup(void);
|
||||
static void fatal_exit(const char* msg);
|
||||
static int update_module(module_t* m);
|
||||
static void send_header(void);
|
||||
static void send_data(void);
|
||||
static void* thread_func_read(void* arg);
|
||||
static int update_memory(module_t* mod);
|
||||
static int update_clock(module_t* m);
|
||||
static int update_volume(module_t* m);
|
||||
static int_fast8_t get_button_number(const char* buff);
|
||||
static module_t* find_first_module_type(appdata_t* data, uint64_t t);
|
||||
static int command_to_buffer(const char* cmd, char* outbuff, size_t buffsize);
|
||||
|
||||
static void cleanup(void) {
|
||||
for (size_t i = 0; i < _data->mod_count; ++i)
|
||||
module_stop(_data->modules[i]);
|
||||
}
|
||||
|
||||
static void fatal_exit(const char* msg) {
|
||||
if (!msg)
|
||||
perror(msg);
|
||||
cleanup();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int_fast8_t get_button_number(const char* buff) {
|
||||
char* pbut = strstr(buff, "\"button\":");
|
||||
if (NULL == pbut)
|
||||
return -1;
|
||||
pbut += 8;
|
||||
while (0 != pbut) {
|
||||
if (*pbut >= '0' && *pbut <= '9') {
|
||||
return (int_fast8_t)(*pbut - '0');
|
||||
}
|
||||
++pbut;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void on_click_clock(module_t* m, const char* buffer) {
|
||||
int_fast8_t butn = get_button_number(buffer);
|
||||
if (butn >= 2)
|
||||
system("foot -e tty-clock");
|
||||
else
|
||||
m->params ^= PARAM_CLOCK_LONG;
|
||||
send_data();
|
||||
}
|
||||
|
||||
static module_t* find_first_module_type(appdata_t* data, uint64_t t) {
|
||||
for (size_t i = 0; i < data->mod_count; ++i) {
|
||||
if (data->modules[i]->id == t)
|
||||
return data->modules[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int command_to_buffer(const char* cmd, char* outbuff, size_t buffsize) {
|
||||
FILE* pf = popen(cmd, "r");
|
||||
if (!pf) {
|
||||
strcpy(outbuff, "ERR");
|
||||
return -1;
|
||||
}
|
||||
int retval = 1;
|
||||
if (!feof(pf)) {
|
||||
if (fgets(outbuff, buffsize, pf) != NULL) {
|
||||
if (strlen(outbuff) > 0) {
|
||||
if (*(outbuff+strlen(outbuff)-1) == '\n')
|
||||
*(outbuff+strlen(outbuff)-1) = 0;
|
||||
}
|
||||
else
|
||||
retval = 0;
|
||||
}
|
||||
else
|
||||
retval = -1;
|
||||
}
|
||||
pclose(pf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void* thread_func_read(void* arg) {
|
||||
char buffer[1024];
|
||||
appdata_t* data = (appdata_t*)arg;
|
||||
module_t* m;
|
||||
while (1) {
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL)
|
||||
break;
|
||||
if (strstr(buffer, BLOCK_CLOCK) != NULL) {
|
||||
m = find_first_module_type(data, MODID_CLOCK);
|
||||
if (m)
|
||||
on_click_clock(m, buffer);
|
||||
}
|
||||
else if (strstr(buffer, BLOCK_MEMORY) != NULL) {
|
||||
system("foot -e htop");
|
||||
}
|
||||
else if (strstr(buffer, BLOCK_VOLUME) != NULL) {
|
||||
system("pavucontrol");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void get_module_block(module_t* module, const char* block_name) {
|
||||
strcpy(module->bufblock, "{\"name\":\"");
|
||||
strcat(module->bufblock, block_name);
|
||||
strcat(module->bufblock, "\",\"full_text\":\"");
|
||||
strcat(module->bufblock, module->bufdata);
|
||||
/* strcat(data->clock->bufblock, "\",\"short_text\":\"");
|
||||
strcat(data->clock->bufblock, data->clock->bufdata);*/
|
||||
strcat(module->bufblock, "\", \"background\":\"");
|
||||
strcat(module->bufblock, module->colorbg);
|
||||
strcat(module->bufblock, "\",\"color\":\"");
|
||||
strcat(module->bufblock, module->colorfg);
|
||||
strcat(module->bufblock, "\"}");
|
||||
}
|
||||
|
||||
static int update_clock(module_t* m) {
|
||||
if (NULL == m)
|
||||
return 0;
|
||||
char buff[MODULE_DATA_SIZE];
|
||||
time_t time_now = time(NULL);
|
||||
if (m->params & PARAM_CLOCK_LONG)
|
||||
strftime(buff, sizeof(buff), "%H:%M:%S, %a %d.%m.%Y",
|
||||
localtime((const time_t*)&time_now));
|
||||
else
|
||||
strftime(buff, sizeof(buff), "%H:%M:%S",
|
||||
localtime((const time_t*)&time_now));
|
||||
if (strcmp(buff, m->bufdata) == 0)
|
||||
return 0;
|
||||
strcpy(m->bufdata, buff);
|
||||
get_module_block(m, BLOCK_CLOCK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int update_volume(module_t* m) {
|
||||
if (NULL == m)
|
||||
return 0;
|
||||
char buff[MODULE_DATA_SIZE];
|
||||
int retv = command_to_buffer("show-volume.sh", buff, sizeof(buff));
|
||||
if (retv <= 0)
|
||||
return -1;
|
||||
if (strcmp(buff, m->bufdata) == 0)
|
||||
return 0;
|
||||
strcpy(m->bufdata, buff);
|
||||
get_module_block(m, BLOCK_VOLUME);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int update_memory(module_t* mod) {
|
||||
if (NULL == mod)
|
||||
return 0;
|
||||
FILE* pfile = fopen("/proc/meminfo", "r");
|
||||
if (NULL == pfile) {
|
||||
return 0;
|
||||
}
|
||||
char line[256];
|
||||
unsigned int mem_total;
|
||||
unsigned int mem_avail;
|
||||
unsigned int swap_total;
|
||||
unsigned int swap_free;
|
||||
unsigned int end = 0;
|
||||
while (fgets(line, sizeof(line), pfile)) {
|
||||
if (sscanf(line, "MemTotal: %u kB", &mem_total) == 1) {
|
||||
end |= 1;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "MemAvailable: %u kB", &mem_avail) == 1) {
|
||||
end |= 2;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "SwapTotal: %u kB", &swap_total) == 1) {
|
||||
end |= 4;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "SwapFree: %u kB", &swap_free) == 1) {
|
||||
end |= 8;
|
||||
continue;
|
||||
}
|
||||
if (0xF == end)
|
||||
break;
|
||||
}
|
||||
fclose(pfile);
|
||||
char buff[MODULE_DATA_SIZE];
|
||||
sprintf(buff, "%.2f - %.2f GiB",
|
||||
(double)(mem_total - mem_avail) / (1024 * 1024),
|
||||
(double)(swap_total - swap_free) / (1024 * 1024));
|
||||
if (strcmp(buff, mod->bufdata) == 0)
|
||||
return 0;
|
||||
strcpy(mod->bufdata, buff);
|
||||
get_module_block(mod, BLOCK_MEMORY);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static module_t* add_module(appdata_t* data) {
|
||||
if (0 == data->mod_count) {
|
||||
data->modules = (module_t**)malloc(sizeof(module_t*));
|
||||
} else {
|
||||
data->modules = (module_t**)realloc(data->modules,
|
||||
(data->mod_count + 1) * sizeof(module_t*));
|
||||
}
|
||||
if (NULL == data->modules)
|
||||
abort();
|
||||
data->modules[data->mod_count] = (module_t*)malloc(sizeof(module_t));
|
||||
if (NULL == data->modules[data->mod_count])
|
||||
abort();
|
||||
memset(data->modules[data->mod_count], 0, sizeof(module_t));
|
||||
++data->mod_count;
|
||||
return data->modules[data->mod_count - 1];
|
||||
}
|
||||
|
||||
static int update_module(module_t* m) {
|
||||
if (m->id == MODID_MEMORY)
|
||||
return update_memory(m);
|
||||
else if (m->id == MODID_CLOCK) {
|
||||
return update_clock(m);
|
||||
}
|
||||
else if (m->id == MODID_VOLUME) {
|
||||
return update_volume(m);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_header(void) {
|
||||
puts("{ \"version\": 1, \"click_events\":true }");
|
||||
puts("[ []");
|
||||
}
|
||||
|
||||
static void send_data(void) {
|
||||
pthread_mutex_lock(&(_data->mutex));
|
||||
printf(",[");
|
||||
|
||||
for (size_t i = 0; i < _data->mod_count; ++i) {
|
||||
if (i > 0)
|
||||
printf(",");
|
||||
printf(_data->modules[i]->bufblock);
|
||||
}
|
||||
printf("]\n");
|
||||
fflush(stdout);
|
||||
pthread_mutex_unlock(&(_data->mutex));
|
||||
}
|
||||
|
||||
static void on_timer(union sigval timer_data) {
|
||||
int need_refresh = update_module((module_t*)timer_data.sival_ptr);
|
||||
if (need_refresh)
|
||||
send_data();
|
||||
}
|
||||
|
||||
static void module_start(module_t* module) {
|
||||
struct sigevent sev;
|
||||
struct itimerspec its;
|
||||
memset(&sev, 0, sizeof(sev));
|
||||
sev.sigev_notify = SIGEV_THREAD;
|
||||
sev.sigev_notify_function = &on_timer;
|
||||
sev.sigev_value.sival_ptr = module;
|
||||
if (-1 == timer_create(CLOCK_REALTIME, &sev, &(module->timer))) {
|
||||
fatal_exit("timer_create");
|
||||
}
|
||||
its.it_value.tv_sec = 0;
|
||||
its.it_value.tv_nsec = 10;
|
||||
its.it_interval.tv_sec = module->interval;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
if (-1 == timer_settime(module->timer, 0, &its, NULL))
|
||||
fatal_exit("timer_settime");
|
||||
}
|
||||
|
||||
static void module_stop(module_t* module) {
|
||||
if (NULL == module)
|
||||
return;
|
||||
if (0 != timer_delete(module->timer))
|
||||
fatal_exit("timer_stop");
|
||||
}
|
||||
|
||||
static void init_modules(appdata_t* data) {
|
||||
module_t* module;
|
||||
module = add_module(data);
|
||||
module->id = MODID_MEMORY;
|
||||
strcpy(module->colorbg, "#3c3c3cff");
|
||||
strcpy(module->colorfg, "#d0ffd0ff");
|
||||
module->interval = 2;
|
||||
|
||||
module = add_module(data);
|
||||
module->id = MODID_VOLUME;
|
||||
strcpy(module->colorbg, "#3c3c3cff");
|
||||
strcpy(module->colorfg, "#e0e0ffff");
|
||||
module->interval = 1;
|
||||
|
||||
module = add_module(data);
|
||||
module->id = MODID_CLOCK;
|
||||
strcpy(module->colorbg, "#3c3c3cff");
|
||||
strcpy(module->colorfg, "#f0f0f0ff");
|
||||
module->interval = 1;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int iret;
|
||||
pthread_t thread_read;
|
||||
appdata_t data;
|
||||
_data = &data;
|
||||
memset(&data, 0, sizeof(appdata_t));
|
||||
data.mod_count = 0;
|
||||
init_modules(&data);
|
||||
pthread_mutex_init(&data.mutex, NULL);
|
||||
iret = pthread_create(&thread_read, NULL, &thread_func_read, (void*)&data);
|
||||
if (0 != iret)
|
||||
return EXIT_FAILURE;
|
||||
send_header();
|
||||
for (size_t i = 0; i < data.mod_count; ++i) {
|
||||
module_start(data.modules[i]);
|
||||
update_module(data.modules[i]);
|
||||
}
|
||||
while (1) {
|
||||
pause();
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in a new issue