diff --git a/Makefile b/Makefile index f6d7900..2f649d6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ TARGET = qtimer -LIBS = -lm +LIBS = -lm -lncurses -luiohook CC = gcc CFLAGS = -g -Wall diff --git a/timer.c b/timer.c index 2137eca..cdf22b5 100644 --- a/timer.c +++ b/timer.c @@ -1,7 +1,189 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -int main(char argc, char** argv) +#define NS_PER_S 1000000000 +#define K_START 1 +#define K_STOP 2 +#define K_PAUSE 3 +#define K_SPLIT 4 + +struct keymap { - printf("Hello, World!\n"); + uint16_t START; + uint16_t STOP; + uint16_t PAUSE; + uint16_t SPLIT; +}; + +char buf; +int pipefd[2]; +struct timespec start, finish, delta; +char *gameTitle, *catagoryTitle; +char *splitPath; +struct keymap km; + +bool timerActive; + +void loadKeymap(); +void startTimer(); +void stopTimer(); +void splitTimer(); +void handleInput(); + +void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td) +{ + td->tv_nsec = t2.tv_nsec - t1.tv_nsec; + td->tv_sec = t2.tv_sec - t1.tv_sec; + if (td->tv_sec > 0 && td->tv_nsec < 0) { + td->tv_nsec += NS_PER_S; + td->tv_sec--; + } else if (td->tv_sec < 0 && td->tv_nsec > 0) { + td->tv_nsec -= NS_PER_S; + td->tv_sec++; + } +} + +void add_timespec(struct timespec t1, struct timespec t2, struct timespec* td) +{ + td->tv_nsec = t2.tv_nsec + t1.tv_nsec; + td->tv_sec = t2.tv_sec + t1.tv_sec; + if (td->tv_nsec < 0) { + td->tv_nsec += NS_PER_S; + td->tv_sec++; + } +} + + +bool logger_proc(unsigned int level, const char *format, ...) { + return 0; +} +void dispatch_proc(uiohook_event * const event) { + switch (event->type) { + case EVENT_KEY_PRESSED: + if (event->data.keyboard.keycode == VC_R) + buf = K_START; + if (event->data.keyboard.keycode == VC_F) + buf = K_STOP; + if (event->data.keyboard.keycode == VC_D) + buf = K_PAUSE; + if (event->data.keyboard.keycode == VC_E) + buf = K_SPLIT; + write(pipefd[1], &buf, 1); + default: + break; + } +} + +void handleInput() +{ + if (read(pipefd[0], &buf, 1) == -1) + return; + switch(buf) { + case K_SPLIT: + splitTimer(); + break; + case K_START: + startTimer(); + break; + case K_STOP: + stopTimer(); + break; + case K_PAUSE: + break; + } +} + +void ncDisplay() +{ + erase(); + int minutes = (int)delta.tv_sec / 60; + int hours = minutes / 60; + printw("%2d:%02d:%02d.%ld\n", hours, minutes, (int)delta.tv_sec%60, delta.tv_nsec/1000000); + refresh(); +} + +void startTimer() +{ + if (timerActive) + return; + clock_gettime(CLOCK_REALTIME, &start); + timerActive = true; +} + +void stopTimer() +{ + if (!timerActive) + return; + timerActive = false; +} + +void splitTimer() +{ + +} + +void loadKeymap() +{ + char path[256]; + strcat(strcpy(path, getenv("HOME")), "/.config/qtimer"); + mkdir(path, 0777); + strcat(strcpy(path, getenv("HOME")), "/.config/qtimer/keymaps"); + mkdir(path, 0777); + strcat(strcpy(path, getenv("HOME")), "/.config/qtimer/keymaps/default"); + + FILE* fp = fopen(path, "r"); + + if (fp == NULL) { + fp = fopen(path, "w"); + fprintf(fp, "some text"); + fclose(fp); + } + km.START = VC_R; + km.STOP = VC_F; + km.PAUSE = VC_D; + km.SPLIT = VC_E; +} + +int main(int argc, char* argv[]) +{ + timerActive = false; + hook_set_logger_proc(&logger_proc); + hook_set_dispatch_proc(&dispatch_proc); + + //IPC pipe + pid_t cpid; + + pipe(pipefd); + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + loadKeymap(); + cpid = fork(); + + if (cpid == 0) { + close(pipefd[0]); + hook_run(); + } else { + close(pipefd[1]); + initscr(); + while(1) { + handleInput(); + if (timerActive) { + clock_gettime(CLOCK_REALTIME, &finish); + sub_timespec(start, finish, &delta); + } + ncDisplay(); + } + endwin(); + } return 0; }