Path: blob/master/Utilities/cmpdcurses/pdcurses/initscr.c
3153 views
/* PDCurses */12#include <curspriv.h>34/*man-start**************************************************************56initscr7-------89### Synopsis1011WINDOW *initscr(void);12WINDOW *Xinitscr(int argc, char **argv);13int endwin(void);14bool isendwin(void);15SCREEN *newterm(const char *type, FILE *outfd, FILE *infd);16SCREEN *set_term(SCREEN *new);17void delscreen(SCREEN *sp);1819int resize_term(int nlines, int ncols);20bool is_termresized(void);21const char *curses_version(void);22void PDC_get_version(PDC_VERSION *ver);2324int set_tabsize(int tabsize);2526### Description2728initscr() should be the first curses routine called. It will29initialize all curses data structures, and arrange that the first30call to refresh() will clear the screen. In case of error, initscr()31will write a message to standard error and end the program.3233endwin() should be called before exiting or escaping from curses mode34temporarily. It will restore tty modes, move the cursor to the lower35left corner of the screen and reset the terminal into the proper36non-visual mode. To resume curses after a temporary escape, call37refresh() or doupdate().3839isendwin() returns TRUE if endwin() has been called without a40subsequent refresh, unless SP is NULL.4142In some implementations of curses, newterm() allows the use of43multiple terminals. Here, it's just an alternative interface for44initscr(). It always returns SP, or NULL.4546delscreen() frees the memory allocated by newterm() or initscr(),47since it's not freed by endwin(). This function is usually not48needed. In PDCurses, the parameter must be the value of SP, and49delscreen() sets SP to NULL.5051set_term() does nothing meaningful in PDCurses, but is included for52compatibility with other curses implementations.5354resize_term() is effectively two functions: When called with nonzero55values for nlines and ncols, it attempts to resize the screen to the56given size. When called with (0, 0), it merely adjusts the internal57structures to match the current size after the screen is resized by58the user. On the currently supported platforms, SDL, Windows console,59and X11 allow user resizing, while DOS, OS/2, SDL and Windows console60allow programmatic resizing. If you want to support user resizing,61you should check for getch() returning KEY_RESIZE, and/or call62is_termresized() at appropriate times; if either condition occurs,63call resize_term(0, 0). Then, with either user or programmatic64resizing, you'll have to resize any windows you've created, as65appropriate; resize_term() only handles stdscr and curscr.6667is_termresized() returns TRUE if the curses screen has been resized68by the user, and a call to resize_term() is needed. Checking for69KEY_RESIZE is generally preferable, unless you're not handling the70keyboard.7172curses_version() returns a string describing the version of PDCurses.7374PDC_get_version() fills a PDC_VERSION structure provided by the user75with more detailed version info (see curses.h).7677set_tabsize() sets the tab interval, stored in TABSIZE.7879### Return Value8081All functions return NULL on error, except endwin(), which always82returns OK, and resize_term(), which returns either OK or ERR.8384### Portability85X/Open ncurses NetBSD86initscr Y Y Y87endwin Y Y Y88isendwin Y Y Y89newterm Y Y Y90set_term Y Y Y91delscreen Y Y Y92resize_term - Y Y93set_tabsize - Y Y94curses_version - Y -95is_termresized - - -9697**man-end****************************************************************/9899#include <stdlib.h>100101char ttytype[128];102103const char *_curses_notice = "PDCurses " PDC_VERDOT " - " __DATE__;104105SCREEN *SP = (SCREEN*)NULL; /* curses variables */106WINDOW *curscr = (WINDOW *)NULL; /* the current screen image */107WINDOW *stdscr = (WINDOW *)NULL; /* the default screen window */108109int LINES = 0; /* current terminal height */110int COLS = 0; /* current terminal width */111int TABSIZE = 8;112113MOUSE_STATUS Mouse_status;114115extern RIPPEDOFFLINE linesripped[5];116extern char linesrippedoff;117118WINDOW *initscr(void)119{120int i;121122PDC_LOG(("initscr() - called\n"));123124if (SP && SP->alive)125return NULL;126127SP = calloc(1, sizeof(SCREEN));128if (!SP)129return NULL;130131if (PDC_scr_open() == ERR)132{133fprintf(stderr, "initscr(): Unable to create SP\n");134exit(8);135}136137SP->autocr = TRUE; /* cr -> lf by default */138SP->raw_out = FALSE; /* tty I/O modes */139SP->raw_inp = FALSE; /* tty I/O modes */140SP->cbreak = TRUE;141SP->key_modifiers = 0L;142SP->return_key_modifiers = FALSE;143SP->echo = TRUE;144SP->visibility = 1;145SP->resized = FALSE;146SP->_trap_mbe = 0L;147SP->linesrippedoff = 0;148SP->linesrippedoffontop = 0;149SP->delaytenths = 0;150SP->line_color = -1;151SP->lastscr = (WINDOW *)NULL;152SP->dbfp = NULL;153SP->color_started = FALSE;154SP->dirty = FALSE;155SP->sel_start = -1;156SP->sel_end = -1;157158SP->orig_cursor = PDC_get_cursor_mode();159160LINES = SP->lines = PDC_get_rows();161COLS = SP->cols = PDC_get_columns();162163if (LINES < 2 || COLS < 2)164{165fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",166LINES, COLS);167exit(4);168}169170curscr = newwin(LINES, COLS, 0, 0);171if (!curscr)172{173fprintf(stderr, "initscr(): Unable to create curscr.\n");174exit(2);175}176177SP->lastscr = newwin(LINES, COLS, 0, 0);178if (!SP->lastscr)179{180fprintf(stderr, "initscr(): Unable to create SP->lastscr.\n");181exit(2);182}183184wattrset(SP->lastscr, (chtype)(-1));185werase(SP->lastscr);186187PDC_slk_initialize();188LINES -= SP->slklines;189190/* We have to sort out ripped off lines here, and reduce the height191of stdscr by the number of lines ripped off */192193for (i = 0; i < linesrippedoff; i++)194{195if (linesripped[i].line < 0)196(*linesripped[i].init)(newwin(1, COLS, LINES - 1, 0), COLS);197else198(*linesripped[i].init)(newwin(1, COLS,199SP->linesrippedoffontop++, 0), COLS);200201SP->linesrippedoff++;202LINES--;203}204205linesrippedoff = 0;206207stdscr = newwin(LINES, COLS, SP->linesrippedoffontop, 0);208if (!stdscr)209{210fprintf(stderr, "initscr(): Unable to create stdscr.\n");211exit(1);212}213214wclrtobot(stdscr);215216/* If preserving the existing screen, don't allow a screen clear */217218if (SP->_preserve)219{220untouchwin(curscr);221untouchwin(stdscr);222stdscr->_clear = FALSE;223curscr->_clear = FALSE;224}225else226curscr->_clear = TRUE;227228SP->atrtab = calloc(PDC_COLOR_PAIRS, sizeof(PDC_PAIR));229if (!SP->atrtab)230return NULL;231PDC_init_atrtab(); /* set up default colors */232233MOUSE_X_POS = MOUSE_Y_POS = -1;234BUTTON_STATUS(1) = BUTTON_RELEASED;235BUTTON_STATUS(2) = BUTTON_RELEASED;236BUTTON_STATUS(3) = BUTTON_RELEASED;237Mouse_status.changes = 0;238239SP->alive = TRUE;240241def_shell_mode();242243sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname());244245SP->c_buffer = malloc(_INBUFSIZ * sizeof(int));246if (!SP->c_buffer)247return NULL;248SP->c_pindex = 0;249SP->c_gindex = 1;250251SP->c_ungch = malloc(NUNGETCH * sizeof(int));252if (!SP->c_ungch)253return NULL;254SP->c_ungind = 0;255SP->c_ungmax = NUNGETCH;256257return stdscr;258}259260#ifdef XCURSES261WINDOW *Xinitscr(int argc, char **argv)262{263PDC_LOG(("Xinitscr() - called\n"));264265PDC_set_args(argc, argv);266return initscr();267}268#endif269270int endwin(void)271{272PDC_LOG(("endwin() - called\n"));273274/* Allow temporary exit from curses using endwin() */275276def_prog_mode();277PDC_scr_close();278279SP->alive = FALSE;280281return OK;282}283284bool isendwin(void)285{286PDC_LOG(("isendwin() - called\n"));287288return SP ? !(SP->alive) : FALSE;289}290291SCREEN *newterm(const char *type, FILE *outfd, FILE *infd)292{293PDC_LOG(("newterm() - called\n"));294295return initscr() ? SP : NULL;296}297298SCREEN *set_term(SCREEN *new)299{300PDC_LOG(("set_term() - called\n"));301302/* We only support one screen */303304return (new == SP) ? SP : NULL;305}306307void delscreen(SCREEN *sp)308{309PDC_LOG(("delscreen() - called\n"));310311if (!SP || sp != SP)312return;313314free(SP->c_ungch);315free(SP->c_buffer);316free(SP->atrtab);317318PDC_slk_free(); /* free the soft label keys, if needed */319320delwin(stdscr);321delwin(curscr);322delwin(SP->lastscr);323stdscr = (WINDOW *)NULL;324curscr = (WINDOW *)NULL;325SP->lastscr = (WINDOW *)NULL;326327SP->alive = FALSE;328329PDC_scr_free();330331free(SP);332SP = (SCREEN *)NULL;333}334335int resize_term(int nlines, int ncols)336{337PDC_LOG(("resize_term() - called: nlines %d\n", nlines));338339if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)340return ERR;341342SP->resized = FALSE;343344SP->lines = PDC_get_rows();345LINES = SP->lines - SP->linesrippedoff - SP->slklines;346SP->cols = COLS = PDC_get_columns();347348if (SP->cursrow >= SP->lines)349SP->cursrow = SP->lines - 1;350if (SP->curscol >= SP->cols)351SP->curscol = SP->cols - 1;352353if (wresize(curscr, SP->lines, SP->cols) == ERR ||354wresize(stdscr, LINES, COLS) == ERR ||355wresize(SP->lastscr, SP->lines, SP->cols) == ERR)356return ERR;357358werase(SP->lastscr);359curscr->_clear = TRUE;360361if (SP->slk_winptr)362{363if (wresize(SP->slk_winptr, SP->slklines, COLS) == ERR)364return ERR;365366wmove(SP->slk_winptr, 0, 0);367wclrtobot(SP->slk_winptr);368PDC_slk_initialize();369slk_noutrefresh();370}371372touchwin(stdscr);373wnoutrefresh(stdscr);374375return OK;376}377378bool is_termresized(void)379{380PDC_LOG(("is_termresized() - called\n"));381382return SP->resized;383}384385const char *curses_version(void)386{387return _curses_notice;388}389390void PDC_get_version(PDC_VERSION *ver)391{392if (!ver)393return;394395ver->flags = 0396#ifdef PDCDEBUG397| PDC_VFLAG_DEBUG398#endif399#ifdef PDC_WIDE400| PDC_VFLAG_WIDE401#endif402#ifdef PDC_FORCE_UTF8403| PDC_VFLAG_UTF8404#endif405#ifdef PDC_DLL_BUILD406| PDC_VFLAG_DLL407#endif408#ifdef PDC_RGB409| PDC_VFLAG_RGB410#endif411;412413ver->build = PDC_BUILD;414ver->major = PDC_VER_MAJOR;415ver->minor = PDC_VER_MINOR;416ver->csize = sizeof(chtype);417ver->bsize = sizeof(bool);418}419420int set_tabsize(int tabsize)421{422PDC_LOG(("set_tabsize() - called: tabsize %d\n", tabsize));423424if (tabsize < 1)425return ERR;426427TABSIZE = tabsize;428429return OK;430}431432433