dwmblocks

Kris's build of dwmblocks
git clone git clone https://git.krisyotam.com/krisyotam/dwmblocks.git
Log | Files | Refs | README | LICENSE

main.c (4252B)


      1 #include "main.h"
      2 
      3 #include <errno.h>
      4 #include <stdbool.h>
      5 #include <stddef.h>
      6 
      7 #include "block.h"
      8 #include "cli.h"
      9 #include "config.h"
     10 #include "signal-handler.h"
     11 #include "status.h"
     12 #include "timer.h"
     13 #include "util.h"
     14 #include "watcher.h"
     15 #include "x11.h"
     16 
     17 static int init_blocks(block *const blocks, const unsigned short block_count) {
     18     for (unsigned short i = 0; i < block_count; ++i) {
     19         block *const block = &blocks[i];
     20         if (block_init(block) != 0) {
     21             return 1;
     22         }
     23     }
     24 
     25     return 0;
     26 }
     27 
     28 static int deinit_blocks(block *const blocks,
     29                          const unsigned short block_count) {
     30     for (unsigned short i = 0; i < block_count; ++i) {
     31         block *const block = &blocks[i];
     32         if (block_deinit(block) != 0) {
     33             return 1;
     34         }
     35     }
     36 
     37     return 0;
     38 }
     39 
     40 static int execute_blocks(block *const blocks,
     41                           const unsigned short block_count,
     42                           const timer *const timer) {
     43     for (unsigned short i = 0; i < block_count; ++i) {
     44         block *const block = &blocks[i];
     45         if (!timer_must_run_block(timer, block)) {
     46             continue;
     47         }
     48 
     49         if (block_execute(&blocks[i], 0) != 0) {
     50             return 1;
     51         }
     52     }
     53 
     54     return 0;
     55 }
     56 
     57 static int trigger_event(block *const blocks, const unsigned short block_count,
     58                          timer *const timer) {
     59     if (execute_blocks(blocks, block_count, timer) != 0) {
     60         return 1;
     61     }
     62 
     63     if (timer_arm(timer) != 0) {
     64         return 1;
     65     }
     66 
     67     return 0;
     68 }
     69 
     70 static int refresh_callback(block *const blocks,
     71                             const unsigned short block_count) {
     72     if (execute_blocks(blocks, block_count, NULL) != 0) {
     73         return 1;
     74     }
     75 
     76     return 0;
     77 }
     78 
     79 static int event_loop(block *const blocks, const unsigned short block_count,
     80                       const bool is_debug_mode,
     81                       x11_connection *const connection,
     82                       signal_handler *const signal_handler) {
     83     timer timer = timer_new(blocks, block_count);
     84 
     85     // Kickstart the event loop with an initial execution.
     86     if (trigger_event(blocks, block_count, &timer) != 0) {
     87         return 1;
     88     }
     89 
     90     watcher watcher;
     91     if (watcher_init(&watcher, blocks, block_count, signal_handler->fd) != 0) {
     92         return 1;
     93     }
     94 
     95     status status = status_new(blocks, block_count);
     96     bool is_alive = true;
     97     while (is_alive) {
     98         if (watcher_poll(&watcher, -1) != 0) {
     99             return 1;
    100         }
    101 
    102         if (watcher.got_signal) {
    103             is_alive = signal_handler_process(signal_handler, &timer) == 0;
    104         }
    105 
    106         for (unsigned short i = 0; i < watcher.active_block_count; ++i) {
    107             (void)block_update(&blocks[watcher.active_blocks[i]]);
    108         }
    109 
    110         const bool has_status_changed = status_update(&status);
    111         if (has_status_changed &&
    112             status_write(&status, is_debug_mode, connection) != 0) {
    113             return 1;
    114         }
    115     }
    116 
    117     return 0;
    118 }
    119 
    120 int main(const int argc, const char *const argv[]) {
    121     const cli_arguments cli_args = cli_parse_arguments(argv, argc);
    122     if (errno != 0) {
    123         return 1;
    124     }
    125 
    126     x11_connection *const connection = x11_connection_open();
    127     if (connection == NULL) {
    128         return 1;
    129     }
    130 
    131 #define BLOCK(icon, command, interval, signal) \
    132     block_new(icon, command, interval, signal),
    133     block blocks[BLOCK_COUNT] = {BLOCKS(BLOCK)};
    134 #undef BLOCK
    135     const unsigned short block_count = LEN(blocks);
    136 
    137     int status = 0;
    138     if (init_blocks(blocks, block_count) != 0) {
    139         status = 1;
    140         goto x11_close;
    141     }
    142 
    143     signal_handler signal_handler = signal_handler_new(
    144         blocks, block_count, refresh_callback, trigger_event);
    145     if (signal_handler_init(&signal_handler) != 0) {
    146         status = 1;
    147         goto deinit_blocks;
    148     }
    149 
    150     if (event_loop(blocks, block_count, cli_args.is_debug_mode, connection,
    151                    &signal_handler) != 0) {
    152         status = 1;
    153     }
    154 
    155     if (signal_handler_deinit(&signal_handler) != 0) {
    156         status = 1;
    157     }
    158 
    159 deinit_blocks:
    160     if (deinit_blocks(blocks, block_count) != 0) {
    161         status = 1;
    162     }
    163 
    164 x11_close:
    165     x11_connection_close(connection);
    166 
    167     return status;
    168 }