/* Copyright 2022 g.uwu@tutanota.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "./main.h" #include #include #include #define true 1 #define false 0 enum {SECS_TO_SLEEP = 0, NSEC_TO_SLEEP = 250000000}; struct notcurses *_nc; void cleanup() { notcurses_stop(_nc); } uint mimicks[10][5][3] = { // 0 { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }, // 1 { { 1, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, { 1, 1, 1 } }, // 2 { { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 } }, // 3 { { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } }, // 4 { { 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 } }, // 5 { { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } }, // 6 { { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }, // 7 { { 1, 1, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 0 }, { 0, 1, 0 } }, // 8 { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }, // 9 { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } } }; int rows; int cols; int midr; int midc; uint stop = false; void *notcurses_thread(void *_) { uint32_t input = 0; ncinput ni; while ((input = notcurses_get(_nc, 0, &ni)) != (uint32_t)-1) { if (ni.evtype == NCTYPE_RELEASE) continue; if (input == 'q') { stop = true; break; } if (ni.id == NCKEY_RESIZE) { unsigned dimx, dimy, oldx, oldy; notcurses_term_dim_yx(_nc, &dimy, &dimx); ncplane_dim_yx(notcurses_stdplane(_nc), &oldy, &oldx); notcurses_refresh(_nc, &dimy, &dimx); rows = dimy - 1; cols = dimx - 1; midr = rows / 2; midc = cols / 2; } } return NULL; } int main(int argc, char **argv) { struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP}; setlocale(LC_ALL, "C"); struct notcurses* nc = notcurses_init(NULL, stdout); _nc = nc; notcurses_enter_alternate_screen(nc); atexit(cleanup); rows = LINES - 1; cols = COLS - 1; midr = rows / 2; midc = cols / 2; cbreak(); noecho(); pthread_t thread_id; pthread_create(&thread_id, NULL, notcurses_thread, NULL); while (!stop) { time_t *t = (time_t *)malloc(sizeof(time_t) + 1); time(t); struct tm *lc = localtime(t); // hourul:minul:sec int hour = lc->tm_hour; int hourl = hour % 10; int houru = (hour - hourl) / 10; int min = lc->tm_min; int minl = min % 10; int minu = (min - minl) / 10; int sec = lc->tm_sec; ncplane_erase(notcurses_stdplane(nc)); ncplane_set_fg_rgb(notcurses_stdplane(nc), 0x777777); ncplane_putchar_yx(notcurses_stdplane(nc), midr - 1, midc, '|'); ncplane_putchar_yx(notcurses_stdplane(nc), midr + 0, midc, '|'); ncplane_putchar_yx(notcurses_stdplane(nc), midr + 1, midc, '|'); struct bignumber_t *bn_houru = bignumber(00, houru); drawbignumber(bn_houru, sec, midc - 20, midr - 2, notcurses_stdplane(nc)); free(bn_houru); struct bignumber_t *bn_hourl = bignumber(15, hourl); drawbignumber(bn_hourl, sec, midc - 10, midr - 2, notcurses_stdplane(nc)); free(bn_hourl); struct bignumber_t *bn_minu = bignumber(30, minu); drawbignumber(bn_minu, sec, midc + 3, midr - 2, notcurses_stdplane(nc)); free(bn_minu); struct bignumber_t *bn_minl = bignumber(45, minl); drawbignumber(bn_minl, sec, midc + 13, midr - 2, notcurses_stdplane(nc)); free(bn_minl); refresh(); notcurses_render(nc); free(t); nanosleep(&request, &remaining); } pthread_kill(thread_id, SIGKILL); return 0; } struct bignumber_t *bignumber(int start, uint mimick) { struct bignumber_t *bn = (struct bignumber_t *)malloc(sizeof(struct bignumber_t) + 1); uint i = start; for (int x = 0; x < 3; x++) for (int y = 0; y < 5; y++) bn->matrix[y][x] = i, i++; bn->mimick = mimick; return bn; } void drawbignumber(struct bignumber_t *bn, int sec, int startx, int starty, struct ncplane *plane) { for (int x = 0; x < 3; x++) { for (int y = 0; y < 5; y++) { struct string *padded_num = pad_int(bn->matrix[y][x], 2, 2); uint currentSec = (uint)sec == bn->matrix[y][x]; uint partOfMimick = mimicks[bn->mimick][y][x]; ncplane_set_bg_alpha(plane, NCALPHA_TRANSPARENT); ncplane_set_fg_alpha(plane, NCALPHA_OPAQUE); uint32_t bg = ncplane_bg_rgb(plane); uint32_t fg = ncplane_fg_rgb(plane); if (partOfMimick) ncplane_set_fg_rgb(plane, 0xCCCCCC), ncplane_set_styles(plane, 0x0002u); else ncplane_set_fg_rgb(plane, 0x555555); if (currentSec) ncplane_set_bg_rgb(plane, 0xFFFFFF), ncplane_set_fg_rgb(plane, 0x333333), ncplane_set_bg_alpha(plane, NCALPHA_OPAQUE); ncplane_putstr_yx(plane, starty + y, startx + (x * 3), padded_num->s); ncplane_set_styles(plane, 0x0000); ncplane_set_bg_rgb(plane, bg); ncplane_set_fg_rgb(plane, fg); ncplane_set_bg_alpha(plane, NCALPHA_TRANSPARENT); ncplane_set_fg_alpha(plane, NCALPHA_OPAQUE); free_string(padded_num); } } } // pad_uint struct string *pad_int(int n, uint pad, uint maxsize) { struct string *str = (struct string *)malloc(sizeof (struct string) + 1); maxsize++; str->s = (char *)malloc((sizeof(char) * maxsize) + 1); str->length = 0; memset(str->s, 0, maxsize); // Figure out how many place values are in n int _n = abs(n); uint places = 1; for (uint i = 0; i < pad; i++) { if (_n >= 10) { _n /= 10; places++; } else break; } char *padding = (char *)malloc((sizeof(char) * pad) + 2); for (uint i = 0; i < pad + 1; i++) padding[i] = '0'; uint required_padding = pad - places; if (required_padding > pad) required_padding = 0; // Negative value if (n < 0) { required_padding++; padding[0] = '-'; } snprintf(str->s, maxsize, "%*.*s%i%c", 0, required_padding, padding, abs(n), 0); free(padding); for (uint i = 0; i < maxsize + 1; i++) { if (str->s[i] == 0) { str->length = i; break; } } return str; } // alloc_string struct string *alloc_string(uint l) { struct string *s = (struct string *)malloc(sizeof(struct string) + 1); s->s = (char *)malloc(l + 1); s->length = l; memset(s->s, 0, l); return s; } // free_string void free_string(struct string *s) { free(s->s); free(s); }