Rewrite the entire code-base

The following changes are focused upon:
- Modularity
- Doing away with globals
- No heap allocations
- Better command line interface
- Switch from Xlib to XCB
- More verbose type definitions
- Implement a single-file config by utilising X-macros
This commit is contained in:
Utkarsh Verma
2023-10-24 08:44:31 +05:30
parent 2773129533
commit bc84d094cd
30 changed files with 918 additions and 396 deletions

24
include/block.h Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include <bits/stdint-uintn.h>
#include <stdbool.h>
#include <sys/types.h>
#include "config.h"
#include "util.h"
typedef struct {
const char *const command;
const unsigned int interval;
const int signal;
int pipe[PIPE_FD_COUNT];
char output[MAX_BLOCK_OUTPUT_LENGTH * UTF8_MAX_BYTE_COUNT + 1];
pid_t fork_pid;
} block;
int block_init(block *const block);
int block_deinit(block *const block);
int block_execute(block *const block, const uint8_t button);
int block_update(block *const block);
bool block_must_run(const block *const block, const unsigned int time);

10
include/cli.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include <stdbool.h>
typedef struct {
bool is_debug_mode;
} cli_arguments;
int cli_init(cli_arguments* const args, const char* const argv[],
const int argc);

14
include/main.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include <signal.h>
#include "block.h"
#include "config.h"
#include "util.h"
// Utilise C's adjacent string concatenation to count the number of blocks.
#define X(...) "."
extern block blocks[LEN(BLOCKS(X)) - 1];
#undef X
#define REFRESH_SIGNAL SIGUSR1

22
include/signal-handler.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <bits/types/sigset_t.h>
#include "timer.h"
typedef sigset_t signal_set;
typedef int (*signal_refresh_callback)(void);
typedef int (*signal_timer_callback)(timer* const timer);
typedef struct {
int fd;
const signal_refresh_callback refresh_callback;
const signal_timer_callback timer_callback;
} signal_handler;
signal_handler signal_handler_new(
const signal_refresh_callback refresh_callback,
const signal_timer_callback timer_callback);
int signal_handler_init(signal_handler* const handler);
int signal_handler_deinit(signal_handler* const handler);
int signal_handler_process(signal_handler* const handler, timer* const timer);

25
include/status.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include <stdbool.h>
#include "block.h"
#include "config.h"
#include "main.h"
#include "util.h"
#include "x11.h"
typedef struct {
#define STATUS_LENGTH \
((LEN(blocks) * (MEMBER_LENGTH(block, output) - 1) + CLICKABLE_BLOCKS) + \
(LEN(blocks) - 1 + LEADING_DELIMITER + TRAILING_DELIMITER) * \
(LEN(DELIMITER) - 1) + \
1)
char current[STATUS_LENGTH];
char previous[STATUS_LENGTH];
#undef STATUS_LENGTH
} status;
status status_new(void);
bool status_update(status* const status);
int status_write(const status* const status, const bool is_debug_mode,
x11_connection* const connection);

14
include/timer.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include <signal.h>
#define TIMER_SIGNAL SIGALRM
typedef struct {
unsigned int time;
const unsigned int tick;
const unsigned int reset_value;
} timer;
timer timer_new(void);
int timer_arm(timer *const timer);

22
include/util.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <stddef.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define LEN(arr) (sizeof(arr) / sizeof(arr[0]))
#define BIT(n) (1 << (n))
#define MEMBER_SIZE(type, member) sizeof(((type*)NULL)->member)
#define MEMBER_LENGTH(type, member) \
(MEMBER_SIZE(type, member) / MEMBER_SIZE(type, member[0]))
#define UTF8_MAX_BYTE_COUNT 4
enum pipe_fd_index {
READ_END,
WRITE_END,
PIPE_FD_COUNT,
};
unsigned int gcd(unsigned int a, unsigned int b);
size_t truncate_utf8_string(char* const buffer, const size_t size,
const size_t char_limit);

22
include/watcher.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <stdbool.h>
#include <sys/poll.h>
#include "main.h"
#include "util.h"
typedef enum {
SIGNAL_FD = LEN(blocks),
WATCHER_FD_COUNT,
} watcher_fd_index;
typedef struct pollfd watcher_fd;
typedef struct {
watcher_fd fds[WATCHER_FD_COUNT];
} watcher;
int watcher_init(watcher *const watcher, const int signal_fd);
int watcher_poll(watcher *const watcher, const int timeout_ms);
bool watcher_fd_is_readable(const watcher_fd *const watcher_fd);

10
include/x11.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include <xcb/xcb.h>
typedef xcb_connection_t x11_connection;
x11_connection* x11_connection_open(void);
void x11_connection_close(x11_connection* const connection);
int x11_set_root_name(x11_connection* const connection,
const char* const name);