X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=c%2B%2B%2Fcursesw.cc;h=905a7b52c20d9a5a0536af4fd9744efc0ddf3e30;hp=d1354425666537994e5fb9343a86d983f4361f4b;hb=46722468f47c2b77b3987729b4bcf2321cccfd01;hpb=3a9b6a3bf0269231bef7de74757a910dedd04e0c diff --git a/c++/cursesw.cc b/c++/cursesw.cc index d1354425..905a7b52 100644 --- a/c++/cursesw.cc +++ b/c++/cursesw.cc @@ -19,66 +19,91 @@ 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) + modified by Juergen Pfeifer + Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en */ #include "internal.h" - -MODULE_ID("$Id: cursesw.cc,v 1.5 1997/05/05 20:04:59 tom Exp $") - -#pragma implementation - #include "cursesw.h" +MODULE_ID("$Id: cursesw.cc,v 1.25 2002/07/06 15:47:52 juergen 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 -int NCursesWindow::count = 0; +long NCursesWindow::count = 0L; +bool NCursesWindow::b_initialized = FALSE; + +/* + * The ncurses library has a fallback for vsscanf(), which may work... + */ +#if !(USE_STRSTREAM_VSCAN || USE_STRSTREAM_VSCAN_CAST) +# undef USE_STDIO_VSCAN +# define USE_STDIO_VSCAN 1 +#endif + +#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); + int result = ERR; char buf[BUFSIZ]; - int result = wgetstr(w, buf); - if (result == OK) { - strstreambuf ss(buf, BUFSIZ); - result = ss.vscan(fmt, args); + + if (::wgetnstr(w, buf, sizeof(buf)) != ERR) { + va_list args; + va_start(args, fmt); +#if USE_STDIO_VSCAN + if (::vsscanf(buf, fmt, args) != -1) + result = OK; +#elif USE_STRSTREAM_VSCAN /* powerpc, os390 */ + strstreambuf ss(buf, sizeof(buf)); + if (ss.vscan(fmt, args) != -1) + result = OK; +#elif USE_STRSTREAM_VSCAN_CAST /* pre-gcc 3.0 */ + strstreambuf ss(buf, sizeof(buf)); + if (ss.vscan(fmt, (_IO_va_list)args) != -1) + result = OK; +#endif + va_end(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); + int result = ERR; 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, args); + + if (::wmove(w, y, x) != ERR) { + if (::wgetnstr(w, buf, sizeof(buf)) != ERR) { + va_list args; + va_start(args, fmt); +#if USE_STDIO_VSCAN + if (::vsscanf(buf, fmt, args) != -1) + result = OK; +#elif USE_STRSTREAM_VSCAN /* powerpc, os390 */ + strstreambuf ss(buf, sizeof(buf)); + if (ss.vscan(fmt, args) != -1) + result = OK; +#elif USE_STRSTREAM_VSCAN_CAST /* pre-gcc 3.0 */ + strstreambuf ss(buf, sizeof(buf)); + if (ss.vscan(fmt, (_IO_va_list)args) != -1) + result = OK; +#endif + va_end(args); } } - va_end(args); return result; -#else - return ERR; -#endif } @@ -88,7 +113,7 @@ NCursesWindow::printw(const char * fmt, ...) va_list args; va_start(args, fmt); char buf[BUFSIZ]; - vsprintf(buf, fmt, args); + ::vsprintf(buf, fmt, args); va_end(args); return waddstr(w, buf); } @@ -99,10 +124,10 @@ NCursesWindow::printw(int y, int x, const char * fmt, ...) { va_list args; va_start(args, fmt); - int result = wmove(w, y, x); + int result = ::wmove(w, y, x); if (result == OK) { char buf[BUFSIZ]; - vsprintf(buf, fmt, args); + ::vsprintf(buf, fmt, args); result = waddstr(w, buf); } va_end(args); @@ -113,10 +138,9 @@ NCursesWindow::printw(int y, int x, const char * fmt, ...) void NCursesWindow::init(void) { - noecho(); - cbreak(); leaveok(0); keypad(1); + meta(1); } void @@ -127,19 +151,31 @@ NCursesWindow::err_handler(const char *msg) const THROWS(NCursesException) void NCursesWindow::initialize() { - ::initscr(); - if (colorInitialized==COLORS_NEED_INITIALIZATION) { - colorInitialized=COLORS_NOT_INITIALIZED; - count++; - useColors(); - count--; + if (!b_initialized) { + ::initscr(); + b_initialized = TRUE; + if (colorInitialized==COLORS_NEED_INITIALIZATION) { + colorInitialized=COLORS_NOT_INITIALIZED; + useColors(); + } + ::noecho(); + ::cbreak(); } } +NCursesWindow::NCursesWindow() { + 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 (count==0) - initialize(); + initialize(); w = ::newwin(lines, cols, begin_y, begin_x); if (w == 0) { @@ -147,40 +183,36 @@ NCursesWindow::NCursesWindow(int lines, int cols, int begin_y, int begin_x) } init(); - alloced = 1; + alloced = TRUE; subwins = par = sib = 0; count++; } NCursesWindow::NCursesWindow(WINDOW* &window) { - if (count==0) - initialize(); - + initialize(); + w = window; init(); - alloced = 0; + alloced = FALSE; subwins = par = sib = 0; count++; } - NCursesWindow::NCursesWindow(NCursesWindow& win, int l, int c, - int by, int bx, char absrel) + int begin_y, int begin_x, char absrel) { - if (absrel == 'r') { // relative origin - by += win.begy(); - bx += win.begx(); + initialize(); + 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 root in + // library needs the `subwin' call to link to the parent in // order to correctly perform refreshes, etc. - - NCursesWindow* root = &win; - while (root->par != 0) root = root->par; - - w = subwin(root->w, l, c, by, bx); + // 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"); } @@ -189,10 +221,78 @@ NCursesWindow::NCursesWindow(NCursesWindow& win, int l, int c, sib = win.subwins; win.subwins = this; subwins = 0; - alloced = 1; + alloced = TRUE; count++; } +NCursesWindow::NCursesWindow(NCursesWindow& win, + bool do_box NCURSES_PARAM_INIT(TRUE)) +{ + initialize(); + w = :: derwin(win.w,win.height()-2,win.width()-2,1,1); + if (w == 0) { + err_handler("Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; + subwins = 0; + alloced = TRUE; + count++; + + 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; + +extern "C" int _nc_ripoffline(int,int (*init)(WINDOW*,int)); + +NCursesWindow::NCursesWindow(WINDOW *win, int cols) { + initialize(); + 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) { @@ -214,7 +314,7 @@ NCursesWindow::kill_subwindows() if (p->alloced) { if (p->w != 0) ::delwin(p->w); - p->alloced = 0; + p->alloced = FALSE; } p->w = 0; // cause a run-time error if anyone attempts to use... } @@ -245,13 +345,16 @@ NCursesWindow::~NCursesWindow() } if (alloced && w != 0) - delwin(w); + ::delwin(w); - --count; - if (count == 0) - endwin(); - else if (count < 0) { // cannot happen! + if (alloced) { + --count; + if (count == 0) { + ::endwin(); + } + else if (count < 0) { // cannot happen! err_handler("Too many windows destroyed"); + } } } @@ -263,10 +366,10 @@ int NCursesWindow::colorInitialized = COLORS_NOT_INITIALIZED; void NCursesWindow::useColors(void) { - if (colorInitialized == COLORS_NOT_INITIALIZED) { - if (count>0) { - if (has_colors()) { - start_color(); + if (colorInitialized == COLORS_NOT_INITIALIZED) { + if (b_initialized) { + if (::has_colors()) { + ::start_color(); colorInitialized = COLORS_ARE_REALLY_THERE; } else @@ -278,12 +381,12 @@ NCursesWindow::useColors(void) } short -NCursesWindow::getcolor(int getback) const +NCursesWindow::getcolor(int getback) const { short fore, back; if (colorInitialized==COLORS_ARE_REALLY_THERE) { - if (pair_content(PAIR_NUMBER(w->_attrs), &fore, &back)) + if (::pair_content((short)PAIR_NUMBER(w->_attrs), &fore, &back)) err_handler("Can't get color pair"); } else { @@ -303,7 +406,7 @@ int NCursesWindow::NumberOfColors() } short -NCursesWindow::getcolor() const +NCursesWindow::getcolor() const { if (colorInitialized==COLORS_ARE_REALLY_THERE) return PAIR_NUMBER(w->_attrs); @@ -315,7 +418,7 @@ int NCursesWindow::setpalette(short fore, short back, short pair) { if (colorInitialized==COLORS_ARE_REALLY_THERE) - return init_pair(pair, fore, back); + return ::init_pair(pair, fore, back); else return OK; } @@ -324,7 +427,7 @@ int NCursesWindow::setpalette(short fore, short back) { if (colorInitialized==COLORS_ARE_REALLY_THERE) - return setpalette(fore, back, PAIR_NUMBER(w->_attrs)); + return setpalette(fore, back, (short)PAIR_NUMBER(w->_attrs)); else return OK; } @@ -336,9 +439,18 @@ 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; } + +#if HAVE_HAS_KEY +extern "C" int _nc_has_mouse(void); + +bool NCursesWindow::has_mouse() const { + return ((::has_key(KEY_MOUSE) || ::_nc_has_mouse()) + ? TRUE : FALSE); +} +#endif