#include #include #include #include "_ncurses.h" #include "ncrswrap.h" #include "ncurses.h" #include "node.h" #include "tree.h" volatile sig_atomic_t got_winch = 0; void handle_SIGWINCH(int sig) { // endwin(); // Needs to be called after an endwin() so ncurses will initialize // itself with the new terminal dimensions. got_winch = 1; } /* * If ncurses is configured to supply its own SIGWINCH handler, * - on receipt of a SIGWINCH, the handler sets a flag * - which is tested in wgetch(3X), doupdate(3X) and restartterm(3X), * - in turn, calling the resizeterm function, * - which ungetch's a KEY_RESIZE which will be read on the next call to * wgetch. REF: `man resizeterm(3x)` */ static void bind_SIGWINCH(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handle_SIGWINCH; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; /* Restart functions if interrupted by handler */ if (sigaction(SIGWINCH, &sa, NULL) == -1) { perror("bind_SIGWINCH"); exit(2); } } int ct_init(struct ct_tree **const tree) { // bind_SIGWINCH(); /* Initialise NCurses Library & Root Node */ init_ncurses(); init_tree(tree); return EXIT_SUCCESS; } void ct_redraw(void) { /* TODO: hide doupdate() behind some other method */ /* flush ncurses virtual screen -> physical screen */ doupdate(); } /* Recursively search the tree for update requests. * Returns: * 0 - success (no action required) * 1 - success (request: redraw the screen) */ static int __update_rec(struct ct_node *const node) { int result = 0; struct ct_dims *dims; if (node->flags & NFLAG_RESIZE) { /* TODO: the child has requested a resizing, but resize_node() * TODO: wastes CPU time resizing itself! */ dims = IS_ROOT_NODE(node) ? termdims() : dup_dims(node->surface->dims); resize_node(node, dims); node->flags &= ~NFLAG_RESIZE; result = 1; } if (node->surface->updatereq) { // TODO: is this necessary or does mvresize_win do this for us? wnoutrefresh(node->surface->win); node->surface->updatereq = 0; } for (int i = 0; i < node->cindex; i++) { result |= __update_rec(node->child[i]); } return result; } void ct_update(struct ct_tree *const tree) { // WARNING: update_rec does not flush the screen, wgetch will do that for us if (__update_rec(tree->root)) { doupdate(); // redrawwin(curscr); // wrefresh(curscr); } } void ct_process(struct ct_tree *const tree) { const int key = wgetch(curscr); // int key = -1; /* ncurses binds a SIGWINCH handler if SIGWINCH has SIG_DFL disposition * when initscr(3x) is called. This handler emits KEY_RESIZE (decimal 410) to * stdin. REF: manpages -> resizeterm(3x) initscr(3x) wgetch(3x) */ switch (key) { case -1: // wclear(tree->root->surface->win); // mvwprintw(tree->root->surface->win, 0, 0, " \r-1\n"); // wrefresh(tree->root->surface->win); break; case KEY_RESIZE: // got_winch = 1; tree->root->flags |= NFLAG_RESIZE; break; default: // wclear(tree->root->surface->win); // mvwprintw(tree->root->surface->win, 0, 0, " \r%d\n", key); // wrefresh(tree->root->surface->win); break; } // if (got_winch == 1) { // tree->root->flags |= NFLAG_RESIZE; // got_winch = 0; // } // if (__update_rec(tree->root)) { // ct_redraw(); // } }