diff options
Diffstat (limited to 'lib/libcurses++/cursesw.cc')
-rw-r--r-- | lib/libcurses++/cursesw.cc | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/lib/libcurses++/cursesw.cc b/lib/libcurses++/cursesw.cc new file mode 100644 index 00000000000..9fc64b64cbd --- /dev/null +++ b/lib/libcurses++/cursesw.cc @@ -0,0 +1,420 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- + +/* + Copyright (C) 1989 Free Software Foundation + written by Eric Newton (newton@rocky.oswego.edu) + + This file is part of the GNU C++ Library. This library is free + software; you can redistribute it and/or modify it under the terms of + the GNU Library General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. This library 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 Library General Public License for more details. + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + modified by Ulrich Drepper (drepper@karlsruhe.gmd.de) + and Anatoly Ivasyuk (anatoly@nick.csh.rit.edu) + + modified by Juergen Pfeifer (Juergen.Pfeifer@T-Online.de) +*/ + +#include "cursesw.h" +#include "internal.h" + +MODULE_ID("$Id: cursesw.cc,v 1.1 1999/05/09 00:21:15 millert Exp $") + +#define COLORS_NEED_INITIALIZATION -1 +#define COLORS_NOT_INITIALIZED 0 +#define COLORS_MONOCHROME 1 +#define COLORS_ARE_REALLY_THERE 2 + +// declare static variables for the class +long NCursesWindow::count = 0L; +bool NCursesWindow::b_initialized = FALSE; + +#if defined(__GNUG__) +# ifndef _IO_va_list +# define _IO_va_list char * +# endif +#endif + +int +NCursesWindow::scanw(const char* fmt, ...) +{ +#if defined(__GNUG__) + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + int result = wgetstr(w, buf); + if (result == OK) { + strstreambuf ss(buf, BUFSIZ); + result = ss.vscan(fmt, (_IO_va_list)args); + } + va_end(args); + return result; +#else + return ERR; +#endif +} + + +int +NCursesWindow::scanw(int y, int x, const char* fmt, ...) +{ +#if defined(__GNUG__) + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + int result = wmove(w, y, x); + if (result == OK) { + result = wgetstr(w, buf); + if (result == OK) { + strstreambuf ss(buf, BUFSIZ); + result = ss.vscan(fmt, (_IO_va_list)args); + } + } + va_end(args); + return result; +#else + return ERR; +#endif +} + + +int +NCursesWindow::printw(const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + vsprintf(buf, fmt, args); + va_end(args); + return waddstr(w, buf); +} + + +int +NCursesWindow::printw(int y, int x, const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + int result = wmove(w, y, x); + if (result == OK) { + char buf[BUFSIZ]; + vsprintf(buf, fmt, args); + result = waddstr(w, buf); + } + va_end(args); + return result; +} + + +void +NCursesWindow::init(void) +{ + leaveok(0); + keypad(1); + meta(1); +} + +void +NCursesWindow::err_handler(const char *msg) const THROWS(NCursesException) +{ + THROW(new NCursesException(msg)); +} + +void +NCursesWindow::initialize() { + if (!b_initialized) { + ::initscr(); + b_initialized = TRUE; + if (colorInitialized==COLORS_NEED_INITIALIZATION) { + colorInitialized=COLORS_NOT_INITIALIZED; + useColors(); + } + ::noecho(); + ::cbreak(); + } +} + +NCursesWindow::NCursesWindow() { + if (!b_initialized) + initialize(); + + w = (WINDOW *)0; + init(); + alloced = FALSE; + subwins = par = sib = 0; + count++; +} + +NCursesWindow::NCursesWindow(int lines, int cols, int begin_y, int begin_x) +{ + if (!b_initialized) + initialize(); + + w = ::newwin(lines, cols, begin_y, begin_x); + if (w == 0) { + err_handler("Cannot construct window"); + } + init(); + + alloced = TRUE; + subwins = par = sib = 0; + count++; +} + +NCursesWindow::NCursesWindow(WINDOW* &window) +{ + if (!b_initialized) + initialize(); + + w = window; + init(); + alloced = FALSE; + subwins = par = sib = 0; + count++; +} + +NCursesWindow::NCursesWindow(NCursesWindow& win, int l, int c, + int begin_y, int begin_x, char absrel) +{ + if (absrel == 'a') { // absolute origin + begin_y -= win.begy(); + begin_x -= win.begx(); + } + + // Even though we treat subwindows as a tree, the standard curses + // library needs the `subwin' call to link to the parent in + // order to correctly perform refreshes, etc. + // Friendly enough, this also works for pads. + w = ::derwin(win.w, l, c, begin_y, begin_x); + if (w == 0) { + err_handler("Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; + subwins = 0; + alloced = TRUE; + count++; +} + +NCursesWindow NCursesWindow::Clone() { + WINDOW *d = ::dupwin(w); + NCursesWindow W(d); + W.subwins = subwins; + W.sib = sib; + W.par = par; + W.alloced = alloced; + return W; +} + +typedef int (*RIPOFFINIT)(NCursesWindow&); +static RIPOFFINIT R_INIT[5]; // There can't be more +static int r_init_idx = 0; +static RIPOFFINIT* prip = R_INIT; + +extern "C" int _nc_ripoffline(int,int (*init)(WINDOW*,int)); + +NCursesWindow::NCursesWindow(WINDOW *win, int cols) { + w = win; + assert((w->_maxx+1)==cols); + alloced = FALSE; + subwins = par = sib = 0; +} + +int NCursesWindow::ripoff_init(WINDOW *w, int cols) +{ + int res = ERR; + + RIPOFFINIT init = *prip++; + if (init) { + NCursesWindow* W = new NCursesWindow(w,cols); + res = init(*W); + } + return res; +} + +int NCursesWindow::ripoffline(int ripoff_lines, + int (*init)(NCursesWindow& win)) { + int code = ::_nc_ripoffline(ripoff_lines,ripoff_init); + if (code==OK && init && ripoff_lines) { + R_INIT[r_init_idx++] = init; + } + return code; +} + +bool +NCursesWindow::isDescendant(NCursesWindow& win) { + for (NCursesWindow* p = subwins; p != NULL; p = p->sib) { + if (p==&win) + return TRUE; + else { + if (p->isDescendant(win)) + return TRUE; + } + } + return FALSE; +} + +void +NCursesWindow::kill_subwindows() +{ + for (NCursesWindow* p = subwins; p != 0; p = p->sib) { + p->kill_subwindows(); + if (p->alloced) { + if (p->w != 0) + ::delwin(p->w); + p->alloced = FALSE; + } + p->w = 0; // cause a run-time error if anyone attempts to use... + } +} + + +NCursesWindow::~NCursesWindow() +{ + kill_subwindows(); + + if (par != 0) { // Snip us from the parent's list of subwindows. + NCursesWindow * win = par->subwins; + NCursesWindow * trail = 0; + for (;;) { + if (win == 0) + break; + else if (win == this) { + if (trail != 0) + trail->sib = win->sib; + else + par->subwins = win->sib; + break; + } else { + trail = win; + win = win->sib; + } + } + } + + if (alloced && w != 0) + delwin(w); + + if (alloced) { + --count; + if (count == 0) { + ::endwin(); + } + else if (count < 0) { // cannot happen! + err_handler("Too many windows destroyed"); + } + } +} + +// --------------------------------------------------------------------- +// Color stuff +// +int NCursesWindow::colorInitialized = COLORS_NOT_INITIALIZED; + +void +NCursesWindow::useColors(void) +{ + if (colorInitialized == COLORS_NOT_INITIALIZED) { + if (b_initialized) { + if (::has_colors()) { + ::start_color(); + colorInitialized = COLORS_ARE_REALLY_THERE; + } + else + colorInitialized = COLORS_MONOCHROME; + } + else + colorInitialized = COLORS_NEED_INITIALIZATION; + } +} + +short +NCursesWindow::getcolor(int getback) const +{ + short fore, back; + + if (colorInitialized==COLORS_ARE_REALLY_THERE) { + if (pair_content(PAIR_NUMBER(w->_attrs), &fore, &back)) + err_handler("Can't get color pair"); + } + else { + // Monochrome means white on black + back = COLOR_BLACK; + fore = COLOR_WHITE; + } + return getback ? back : fore; +} + +int NCursesWindow::NumberOfColors() +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return COLORS; + else + return 1; // monochrome (actually there are two ;-) +} + +short +NCursesWindow::getcolor() const +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return PAIR_NUMBER(w->_attrs); + else + return 0; // we only have pair zero +} + +int +NCursesWindow::setpalette(short fore, short back, short pair) +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return init_pair(pair, fore, back); + else + return OK; +} + +int +NCursesWindow::setpalette(short fore, short back) +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return setpalette(fore, back, PAIR_NUMBER(w->_attrs)); + else + return OK; +} + + +int +NCursesWindow::setcolor(short pair) +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) { + if ((pair < 1) || (pair > COLOR_PAIRS)) + err_handler("Can't set color pair"); + + attroff(A_COLOR); + attrset(COLOR_PAIR(pair)); + } + return OK; +} + +extern "C" int _nc_has_mouse(void); + +bool NCursesWindow::has_mouse() const { + return ((::has_key(KEY_MOUSE) || ::_nc_has_mouse()) + ? TRUE : FALSE); +} + +NCursesPad::NCursesPad(int lines, int cols) : NCursesWindow() { + w = ::newpad(lines,cols); + if (w==(WINDOW*)0) { + count--; + err_handler("Cannot construct window"); + } + alloced = TRUE; +} |