From 4f62ef1b5821fc968a9f73c3fdf3ce7d37ff9584 Mon Sep 17 00:00:00 2001 From: John Zaitseff Date: Mon, 4 Jul 2011 12:41:30 +1000 Subject: [PATCH] Add simple functions to manage a stack of Curses windows --- src/intf.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/intf.h | 15 ++++- src/trader.c | 60 +++++++++-------- 3 files changed, 222 insertions(+), 30 deletions(-) diff --git a/src/intf.c b/src/intf.c index 471581b..f52f9c0 100644 --- a/src/intf.c +++ b/src/intf.c @@ -33,6 +33,35 @@ #include "utils.h" +/************************************************************************ +* Module constants and type declarations * +************************************************************************/ + +#define OUTBUFSIZE (1024) /* Output string buffer size */ + + +typedef struct txwin { + WINDOW *win; // Pointer to window structure + struct txwin *next; // Next window in stack + struct txwin *prev; // Previous window in stack +} txwin_t; + + +/************************************************************************ +* Global variable definitions * +************************************************************************/ + +WINDOW *curwin = NULL; // Top-most (current) window + + +/************************************************************************ +* Module variables * +************************************************************************/ + +txwin_t *topwin = NULL; // Top-most txwin structure +txwin_t *firstwin = NULL; // First (bottom-most) txwin structure + + /************************************************************************ * Basic text input/output function definitions * ************************************************************************/ @@ -56,6 +85,10 @@ void init_screen (void) MIN_COLS, MIN_LINES); } + curwin = stdscr; + topwin = NULL; + firstwin = NULL; + noecho(); curs_set(CURS_INVISIBLE); raw(); @@ -95,9 +128,153 @@ void init_screen (void) void end_screen (void) { + delalltxwin(); + clear(); refresh(); endwin(); + + curwin = NULL; +} + + +/*----------------------------------------------------------------------- + Function: newtxwin - Create a new window, inserted into window stack + Arguments: nlines - Number of lines in new window + ncols - Number of columns in new window + begin_y - Starting line number (global coordinates) + begin_x - Starting column number (global coordinates) + Returns: WINDOW * - Pointer to new window structure + + This function creates a window (using the Curses newwin() function) and + places it top-most in the stack of windows managed by this module. A + pointer to the new window is returned; the global variable "curwin" + also points to this new window. Please note that wrefresh() is NOT + called on the new window. +*/ + +WINDOW *newtxwin (int nlines, int ncols, int begin_y, int begin_x) +{ + WINDOW *win; + txwin_t *nw; + + + win = newwin(nlines, ncols, begin_y, begin_x); + if (win == NULL) { + return NULL; + } + + nw = malloc(sizeof(txwin_t)); + if (nw == NULL) { + delwin(win); + return NULL; + } + + nw->win = win; + nw->next = NULL; + nw->prev = topwin; + + if (topwin != NULL) { + topwin->next = nw; + } + + topwin = nw; + curwin = win; + + if (firstwin == NULL) { + firstwin = nw; + } + + return win; +} + + +/*----------------------------------------------------------------------- + Function: deltxwin - Delete the top-most window in window stack + Arguments: (none) + Returns: int - OK if all well, ERR if not + + This function deletes the top-most window in the stack of windows + managed by this module. ERR is returned if there is no such window, or + if delwin() fails. Please note that the actual screen is NOT + refreshed: a call to txrefresh() should follow this one. This allows + multiple windows to be deleted without screen flashing. +*/ + +int deltxwin (void) +{ + txwin_t *cur, *prev; + int r; + + + if (topwin == NULL) { + return ERR; + } + + cur = topwin; + prev = topwin->prev; + topwin = prev; + + if (prev != NULL) { + prev->next = NULL; + curwin = prev->win; + } else { + firstwin = NULL; + curwin = stdscr; + } + + r = delwin(cur->win); + free(cur); + + return r; +} + + +/*----------------------------------------------------------------------- + Function: delalltxwin - Delete all windows in the window stack + Arguments: (none) + Returns: int - OK is always returned + + This function deletes all windows in the stack of windows managed by + this module. After calling this function, the global variable "curwin" + points to "stdscr", the only window for which output is now permitted. + Please note that the screen is NOT refreshed; a call to txrefresh() + should follow this one if appropriate. +*/ + +int delalltxwin (void) +{ + while (topwin != NULL) { + deltxwin(); + } + + return OK; +} + + +/*----------------------------------------------------------------------- + Function: txrefresh - Redraw all windows in the window stack + Arguments: (none) + Returns: int - OK if all well, ERR if not + + This function redraws (refreshes) all windows in the stack of windows + managed by this module. Windows are refreshed from bottom (first) to + top (last). The result of doupdate() is returned. +*/ + +int txrefresh (void) +{ + txwin_t *p; + + touchwin(stdscr); + wnoutrefresh(stdscr); + + for (p = firstwin; p != NULL; p = p->next) { + touchwin(p->win); + wnoutrefresh(p->win); + } + + return doupdate(); } diff --git a/src/intf.h b/src/intf.h index 2291481..38ca37d 100644 --- a/src/intf.h +++ b/src/intf.h @@ -54,8 +54,6 @@ #define COL_OFFSET ((COLS - MIN_COLS) / 2) /* Window offsets */ #define LINE_OFFSET (0) -#define OUTBUFSIZE (1024) /* Output string buffer size */ - // Colour pairs used in Star Traders enum color_pairs { @@ -68,6 +66,13 @@ enum color_pairs { }; +/************************************************************************ +* Global variable declarations * +************************************************************************/ + +extern WINDOW *curwin; // Top-most (current) window + + /************************************************************************ * Basic text input/output function declarations * ************************************************************************/ @@ -75,6 +80,12 @@ enum color_pairs { extern void init_screen (void); extern void end_screen (void); +// Simplified panel-like window functions +extern WINDOW *newtxwin (int nlines, int ncols, int begin_y, int begin_x); +extern int deltxwin (void); +extern int delalltxwin (void); +extern int txrefresh (void); + extern int center (WINDOW *win, const bool clrline, const char *format, ...) __attribute__((format (printf, 3, 4))); diff --git a/src/trader.c b/src/trader.c index 4174389..95849e0 100644 --- a/src/trader.c +++ b/src/trader.c @@ -64,56 +64,60 @@ int main (int argc, char *argv[]) // Testing... init_screen(); - printw("Program name: %s\n", program_name()); - printw("Home directory: %s\n", home_directory()); - printw("Data directory: %s\n", data_directory()); - printw("Game filename: %s (%d)\n", game_filename(game_num), game_num); + wprintw(curwin, "Program name: %s\n", program_name()); + wprintw(curwin, "Home directory: %s\n", home_directory()); + wprintw(curwin, "Data directory: %s\n", data_directory()); + wprintw(curwin, "Game filename: %s (%d)\n", game_filename(game_num), game_num); - printw("Cols x Lines: %d x %d\n", COLS, LINES); - printw("Colours, pairs: %d, %d\n", COLORS, COLOR_PAIRS); + wprintw(curwin, "Cols x Lines: %d x %d\n", COLS, LINES); + wprintw(curwin, "Colours, pairs: %d, %d\n", COLORS, COLOR_PAIRS); - refresh(); + wrefresh(curwin); curs_set(CURS_VERYVISIBLE); - WINDOW *w1, *w2; + newtxwin(WIN_LINES - 7, WIN_COLS, LINE_OFFSET + 7, COL_OFFSET + 0); + wbkgd(curwin, COLOR_PAIR(WHITE_ON_BLUE)); + box(curwin, 0, 0); + wrefresh(curwin); - w1 = newwin(WIN_LINES - 7, WIN_COLS, LINE_OFFSET + 7, COL_OFFSET + 0); - wbkgd(w1, COLOR_PAIR(WHITE_ON_BLUE)); - box(w1, 0, 0); - wrefresh(w1); + newtxwin(WIN_LINES - 9, WIN_COLS - 8, LINE_OFFSET + 8, COL_OFFSET + 4); + wbkgd(curwin, COLOR_PAIR(WHITE_ON_BLUE)); - w2 = newwin(WIN_LINES - 9, WIN_COLS - 8, LINE_OFFSET + 8, COL_OFFSET + 4); - wbkgd(w2, COLOR_PAIR(WHITE_ON_BLUE)); + wattrset(curwin, has_colors() ? COLOR_PAIR(WHITE_ON_RED) | A_BOLD : A_REVERSE | A_BOLD); + center(curwin, true, "Type some keys (^C to exit):"); + wattrset(curwin, A_NORMAL); - wattrset(w2, has_colors() ? COLOR_PAIR(WHITE_ON_RED) | A_BOLD : A_REVERSE | A_BOLD); - center(w2, true, "Type some keys (^C to exit):"); - wattrset(w2, A_NORMAL); + wrefresh(curwin); - wrefresh(w2); - - scrollok(w2, true); - keypad(w2, true); - meta(w2, true); - wtimeout(w2, -1); + scrollok(curwin, true); + keypad(curwin, true); + meta(curwin, true); + wtimeout(curwin, -1); int c = 0; - while ((c = wgetch(w2)) != 3) { + while ((c = wgetch(curwin)) != 3) { if ((c >= 0) && (c < 32)) { - wprintw(w2, "0%03o ^%c ", c, c + '@'); + wprintw(curwin, "0%03o ^%c ", c, c + '@'); } else if ((c >= 32) && (c < 127)) { - wprintw(w2, "0%03o %c ", c, c); + wprintw(curwin, "0%03o %c ", c, c); } else { - wprintw(w2, "0%05o ", c); + wprintw(curwin, "0%05o ", c); } if (c == 0x1C) { err_exit("You pressed ^%c!", c + '@'); } - wrefresh(w2); + wrefresh(curwin); } + deltxwin(); + txrefresh(); + + mvwprintw(curwin, 1, 2, "All OK: "); + wgetch(curwin); + end_screen(); return EXIT_SUCCESS;