diff options
Diffstat (limited to 'gnu/lib/libg++/g++-include/CursesW.cc')
-rw-r--r-- | gnu/lib/libg++/g++-include/CursesW.cc | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/gnu/lib/libg++/g++-include/CursesW.cc b/gnu/lib/libg++/g++-include/CursesW.cc new file mode 100644 index 00000000000..9533f691556 --- /dev/null +++ b/gnu/lib/libg++/g++-include/CursesW.cc @@ -0,0 +1,255 @@ +/* +Copyright (C) 1989, 1992 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. +*/ +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stdio.h> +#include <stdarg.h> +#include <builtin.h> +#include <values.h> +#ifndef _OLD_STREAMS +#include <strstream.h> +//#include <ioprivate.h> +#endif +// Include CurseW.h and/or curses.h *after* iostream includes, +// because curses.h defines a clear macro that conflicts with iostream. Sigh. +#include <CursesW.h> + +#if _G_HAVE_CURSES + +int CursesWindow::count = 0; + +/* + * C++ interface to curses library. + * + */ + +#if !defined(_IO_MAGIC) && !defined(HAVE_VSCANF) &&!defined vsscanf +extern "C" int _doscan(FILE *, const char*, va_list args); + +static int vsscanf(char *buf, const char * fmt, va_list args) +{ + FILE b; +#ifdef _IOSTRG + b._flag = _IOREAD|_IOSTRG; +#else + b._flag = _IOREAD; +#endif + b._base = (unsigned char*)buf; + b._ptr = (unsigned char*)buf; + b._cnt = BUFSIZ; + return _doscan(&b, fmt, args); +} +#endif + +/* + * varargs functions are handled conservatively: + * They interface directly into the underlying + * _doscan, _doprnt and/or vfprintf routines rather than + * assume that such things are handled compatibly in the curses library + */ + +int CursesWindow::scanw(const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); +#ifdef VMS + int result = wscanw(w , fmt , args); +#else /* NOT VMS */ + char buf[BUFSIZ]; + int result = wgetstr(w, buf); + if (result == OK) { + +#ifdef _IO_MAGIC /* GNU iostreams */ + strstreambuf ss(buf, BUFSIZ); + result = ss.vscan(fmt, args); +#else + result = vsscanf(buf, fmt, args); +#endif + } +#endif /* !VMS */ + va_end(args); + return result; +} + +int CursesWindow::mvscanw(int y, int x, const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + int result = wmove(w, y, x); + if (result == OK) +#ifdef VMS + result=wscanw(w , fmt , args); +#else /* !VMS */ + { + result = wgetstr(w, buf); + if (result == OK) { +#ifdef _IO_MAGIC /* GNU iostreams */ + strstreambuf ss(buf, BUFSIZ); + result = ss.vscan(fmt, args); +#else + result = vsscanf(buf, fmt, args); +#endif + } + } +#endif /* !VMS */ + va_end(args); + return result; +} + +int CursesWindow::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 CursesWindow::mvprintw(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; +} + +CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x) +{ + if (count==0) + initscr(); + + w = newwin(lines, cols, begin_y, begin_x); + if (w == 0) + { + (*lib_error_handler)("CursesWindow", "Cannot construct window"); + } + + alloced = 1; + subwins = par = sib = 0; + count++; +} + +CursesWindow::CursesWindow(WINDOW* &window) +{ + if (count==0) + initscr(); + + w = window; + alloced = 0; + subwins = par = sib = 0; + count++; +} + +CursesWindow::CursesWindow(CursesWindow& win, int l, int c, + int by, int bx, char absrel) +{ + + if (absrel == 'r') // relative origin + { + by += win.begy(); + bx += win.begx(); + } + + // Even though we treat subwindows as a tree, the standard curses + // library needs the `subwin' call to link to the root in + // order to correctly perform refreshes, etc. + + CursesWindow* root = &win; + while (root->par != 0) root = root->par; + + w = subwin(root->w, l, c, by, bx); + if (w == 0) + { + (*lib_error_handler)("CursesWindow", "Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; + subwins = 0; + alloced = 1; + count++; +} + + +void CursesWindow::kill_subwindows() +{ + for (CursesWindow* p = subwins; p != 0; p = p->sib) + { + p->kill_subwindows(); + if (p->alloced) + { + if (p->w != 0) + ::delwin(p->w); + p->alloced = 0; + } + p->w = 0; // cause a run-time error if anyone attempts to use... + } +} + +CursesWindow::~CursesWindow() +{ + kill_subwindows(); + + if (par != 0) // Snip us from the parent's list of subwindows. + { + CursesWindow * win = par->subwins; + CursesWindow * 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); + + --count; + if (count == 0) + endwin(); + else if (count < 0) // cannot happen! + { + (*lib_error_handler)("CursesWindow", "Too many windows destroyed"); + } +} + +#endif /* _G_HAVE_CURSES */ |