diff options
Diffstat (limited to 'ncurses-5.9/c++/cursesw.cc')
-rw-r--r-- | ncurses-5.9/c++/cursesw.cc | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/ncurses-5.9/c++/cursesw.cc b/ncurses-5.9/c++/cursesw.cc new file mode 100644 index 0000000..426f99c --- /dev/null +++ b/ncurses-5.9/c++/cursesw.cc @@ -0,0 +1,468 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 2007-2008,2009 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/* + * Authors: + * Thomas E. Dickey + * Juergen Pfeifer + * + * The NCursesWindow class was originally based on a file written by + * Eric Newton, later modified by Ulrich Drepper and Anatoly Ivasyuk. + * However, aside from the compatible interface definition, no trace + * of the original code remains in this version: it consists only of + * changes introduced since 1995. + */ + +#include "internal.h" +#include "cursesw.h" + +MODULE_ID("$Id$") + +#define COLORS_NEED_INITIALIZATION -1 +#define COLORS_NOT_INITIALIZED 0 +#define COLORS_MONOCHROME 1 +#define COLORS_ARE_REALLY_THERE 2 + +#define HaveColors() (colorInitialized == COLORS_ARE_REALLY_THERE) + +// declare static variables for the class +long NCursesWindow::count = 0L; +bool NCursesWindow::b_initialized = FALSE; + +int +NCursesWindow::scanw(const char* fmt, ...) +{ + int result = ERR; + + va_list args; + va_start(args, fmt); + result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args); + va_end(args); + + return result; +} + + +int +NCursesWindow::scanw(int y, int x, const char* fmt, ...) +{ + int result = ERR; + + if (::wmove(w, y, x) != ERR) { + va_list args; + va_start(args, fmt); + result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args); + va_end(args); + } + return result; +} + + +int +NCursesWindow::scanw(const char* fmt, va_list args) +{ + int result = ERR; + + result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args); + + return result; +} + + +int +NCursesWindow::scanw(int y, int x, const char* fmt, va_list args) +{ + int result = ERR; + + if (::wmove(w, y, x) != ERR) { + result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args); + } + return result; +} + + +int +NCursesWindow::printw(const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + int result = ::vw_printw(w, fmt, args); + va_end(args); + return result; +} + + +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) { + result = ::vw_printw(w, fmt, args); + } + va_end(args); + return result; +} + + +int +NCursesWindow::printw(const char * fmt, va_list args) +{ + int result = ::vw_printw(w, fmt, args); + return result; +} + + +int +NCursesWindow::printw(int y, int x, const char * fmt, va_list args) +{ + int result = ::wmove(w, y, x); + if (result == OK) { + result = ::vw_printw(w, fmt, args); + } + return result; +} + + +void +NCursesWindow::set_keyboard(void) +{ + keypad(TRUE); + meta(TRUE); +} + +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(); + } +} + +void +NCursesWindow::constructing() +{ + initialize(); + ++count; +} + +NCursesWindow::NCursesWindow() + : w(0), alloced(FALSE), par(0), subwins(0), sib(0) +{ + constructing(); + + w = static_cast<WINDOW *>(0); + set_keyboard(); +} + +NCursesWindow::NCursesWindow(int nlines, int ncols, int begin_y, int begin_x) + : w(0), alloced(TRUE), par(0), subwins(0), sib(0) +{ + constructing(); + + w = ::newwin(nlines, ncols, begin_y, begin_x); + if (w == 0) { + err_handler("Cannot construct window"); + } + set_keyboard(); +} + +NCursesWindow::NCursesWindow(WINDOW* window) + : w(0), alloced(FALSE), par(0), subwins(0), sib(0) +{ + constructing(); + + // We used to use a reference on the "window" parameter, but we cannot do + // that with an opaque pointer (see NCURSES_OPAQUE). If the parameter was + // "::stdscr", that is first set via the "constructing() call, and is null + // up to that point. So we allow a null pointer here as meaning the "same" + // as "::stdscr". + w = window ? window : ::stdscr; + set_keyboard(); +} + +NCursesWindow::NCursesWindow(NCursesWindow& win, int ny, int nx, + int begin_y, int begin_x, char absrel) + : w(0), alloced(TRUE), par(0), subwins(0), sib(0) +{ + constructing(); + if (absrel == 'a') { // absolute origin + begin_y -= win.begy(); + begin_x -= win.begx(); + } + + // Link this window into its parent's list of subwindows. + // We use derwin(), since this also works for pads. + w = ::derwin(win.w, ny, nx, begin_y, begin_x); + if (w == 0) { + err_handler("Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; +} + +NCursesWindow::NCursesWindow(NCursesWindow& win, + bool do_box NCURSES_PARAM_INIT(TRUE)) + : w(0), alloced(TRUE), par(0), subwins(0), sib(0) +{ + constructing(); + int myHeight = win.height(); + int myWidth = win.width(); + w = :: derwin(win.w, myHeight - 2, myWidth - 2, 1, 1); + if (w == 0) { + err_handler("Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; + subwins = 0; + + if (do_box) { + win.box(); + win.touchwin(); + } +} + +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; + +NCursesWindow::NCursesWindow(WINDOW *win, int ncols) + : w(0), alloced(FALSE), par(0), subwins(0), sib(0) +{ + initialize(); + w = win; +} + +int _nc_xx_ripoff_init(WINDOW *w, int ncols) +{ + int res = ERR; + + RIPOFFINIT init = *prip++; + if (init) { + res = init(*(new NCursesWindow(w,ncols))); + } + return res; +} + +int NCursesWindow::ripoffline(int ripoff_lines, + int (*init)(NCursesWindow& win)) +{ + int code = ::_nc_ripoffline(ripoff_lines,_nc_xx_ripoff_init); + if (code == OK && init && ripoff_lines) { + R_INIT[r_init_idx++] = init; + } + return code; +} + +bool +NCursesWindow::isDescendant(NCursesWindow& win) +{ + bool result = FALSE; + + for (NCursesWindow* p = subwins; p != NULL; p = p->sib) { + if (p == &win || p->isDescendant(win)) { + result = TRUE; + break; + } + } + return result; +} + +void +NCursesWindow::kill_subwindows() +{ + NCursesWindow* p = subwins; + + subwins = 0; + while (p != 0) { + NCursesWindow* q = p->sib; + p->kill_subwindows(); + if (p->alloced) { + if (p->w != 0) + ::delwin(p->w); + } + delete p; + p = q; + } +} + + +NCursesWindow::~NCursesWindow() +{ + kill_subwindows(); + + if (par != 0) { + // Remove this window from the parent's list of subwindows. + NCursesWindow * next = par->subwins; + NCursesWindow * prev = 0; + while (next != 0) { + if (next == this) { + if (prev != 0) { + prev->sib = next->sib; + } else { + par->subwins = next->sib; + } + break; + } + prev = next; + next = next->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::getPair() const +{ + return static_cast<short>(PAIR_NUMBER(getattrs(w))); +} + +short +NCursesWindow::getcolor(int getback) const +{ + short fore, back; + + if (HaveColors()) { + if (::pair_content(getPair(), &fore, &back) == ERR) + 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() +{ + return (HaveColors()) ? COLORS : 1; +} + +short +NCursesWindow::getcolor() const +{ + return (HaveColors()) ? getPair() : 0; +} + +int +NCursesWindow::setpalette(short fore, short back, short pair) +{ + return (HaveColors()) ? ::init_pair(pair, fore, back) : OK; +} + +int +NCursesWindow::setpalette(short fore, short back) +{ + return setpalette(fore, back, getPair()); +} + + +int +NCursesWindow::setcolor(short pair) +{ + if (HaveColors()) { + if ((pair < 1) || (pair > COLOR_PAIRS)) + err_handler("Can't set color pair"); + + attroff(A_COLOR); + attrset(COLOR_PAIR(pair)); + } + return OK; +} + +#if HAVE_HAS_KEY +bool NCursesWindow::has_mouse() const +{ + return ((::has_key(KEY_MOUSE) || ::has_mouse()) + ? TRUE : FALSE); +} +#endif |