summaryrefslogtreecommitdiff
path: root/lib/libcurses++
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1999-05-09 00:21:16 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1999-05-09 00:21:16 +0000
commit9891bec8eb3d751912a9139b6552c207025c8aa5 (patch)
tree76b682f1ecbece1e7fa034747e7f8c77ba1634c6 /lib/libcurses++
parent71e21992ce3a04e37b129906f21d13e1b4e3571a (diff)
c++ clasess for ncurses
Diffstat (limited to 'lib/libcurses++')
-rw-r--r--lib/libcurses++/Makefile20
-rw-r--r--lib/libcurses++/README-first58
-rw-r--r--lib/libcurses++/cursesapp.cc146
-rw-r--r--lib/libcurses++/cursesapp.h163
-rw-r--r--lib/libcurses++/cursesf.cc423
-rw-r--r--lib/libcurses++/cursesf.h823
-rw-r--r--lib/libcurses++/cursesm.cc379
-rw-r--r--lib/libcurses++/cursesm.h592
-rw-r--r--lib/libcurses++/cursesmain.cc51
-rw-r--r--lib/libcurses++/cursesp.cc123
-rw-r--r--lib/libcurses++/cursesp.h186
-rw-r--r--lib/libcurses++/cursesw.cc420
-rw-r--r--lib/libcurses++/cursesw.h1262
-rw-r--r--lib/libcurses++/cursslk.cc121
-rw-r--r--lib/libcurses++/cursslk.h205
-rw-r--r--lib/libcurses++/demo.cc405
-rw-r--r--lib/libcurses++/etip.h248
-rw-r--r--lib/libcurses++/internal.h47
18 files changed, 5672 insertions, 0 deletions
diff --git a/lib/libcurses++/Makefile b/lib/libcurses++/Makefile
new file mode 100644
index 00000000000..9ca9b1f5a43
--- /dev/null
+++ b/lib/libcurses++/Makefile
@@ -0,0 +1,20 @@
+# $OpenBSD: Makefile,v 1.1 1999/05/09 00:21:14 millert Exp $
+
+# Uncomment this to enable tracing in libcurses
+#CURSESTRACE=-DTRACE
+
+LIB= curses++
+SRCS= cursesapp.cc cursesf.cc cursesm.cc cursesmain.cc cursesp.cc \
+ cursesw.cc cursslk.cc
+HEADERS=cursesapp.h cursesf.h cursesm.h cursesp.h cursesw.h etip.h cursslk.h
+
+CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../libcurses ${CURSESTRACE}
+
+includes:
+ @for i in ${HEADERS}; do \
+ cmp -s ${DESTDIR}/usr/include/g++/$$i ${.CURDIR}/$$i || \
+ ${INSTALL} ${INSTALL_COPY} -m 444 -o $(BINOWN) -g $(BINGRP) \
+ ${.CURDIR}/$$i ${DESTDIR}/usr/include/g++/$$i; \
+ done
+
+.include <bsd.lib.mk>
diff --git a/lib/libcurses++/README-first b/lib/libcurses++/README-first
new file mode 100644
index 00000000000..b3b0b9d8f71
--- /dev/null
+++ b/lib/libcurses++/README-first
@@ -0,0 +1,58 @@
+ C++ interface to ncurses routines
+-----------------------------------------------------------------------
+
+This directory contains the source code for several C++ classes which
+ease the use of writing ncurses-based programs. The code is derived
+from the libg++ CursesWindow class but enhanced for ncurses.
+
+The classes simplify the use of window specific functions by
+encapsulating them in the window object. Function overloading is
+used in order to narrow the interface. E.g. you don't have the
+distinction between `printw' and `mvprintw' anymore.
+
+A second benefit is the removal of all #defines which are included in
+the curses.h file. This is a steady cause of trouble because many
+common identifiers are used. Instead now all #defines are inline
+functions which also allows strict type checking of arguments.
+
+The next enhancement is color support. It was originally provided by a
+derived class. This caused some trouble if you think about Panels or
+Menus and Forms with colors. We decided to put color support into the
+base class so that any derived class may use color support also.
+The implementation chosen here is directed to unrestricted use
+of mixes of color and monochrome windows. The original NCursesColorWindow
+class is maintained for compatibility reasons.
+
+The last point to mention is the support of other packages that are
+distributed with the ncurses package: the panels library, the menu library
+and the form library. This support is provided by the NCursesPanel class,
+which is also derived from the NCursesWindow class and the NCursesMenu
+and NCursesForm classes which are derived from NCursesPanel. This allows
+building interfaces with windows.
+
+Please see the example program for a quick introduction.
+
+Note that at this point, there is no documentation for these classes.
+Hopefully some will be written in the not too distant future. For now,
+to find out how to use the classes, read the code and the example program.
+
+Suggestions for enhancements and contributions of code (and docs) are
+welcome. Please let us know which functionality you miss.
+
+ ATTENTION LINUX USERS: There is currently some discussion of
+ replacing the BSD curses in the Linux libc with ncurses. If
+ this is done we could perhaps include these classes in the Linux
+ libg++ replacing the original CursesWindow class (and renaming it
+ to CursesWindow). This could be done because NCursesWindow can
+ be made easily to a superset of the CursesWindow class.
+
+
+Original author:
+ Eric Newton <newton@rocky.oswego.edu> for FSF's libg++
+
+Authors of first ncurses based release (NCursesWindow, NCursesPanel):
+ Ulrich Drepper <drepper@ira.uka.de>
+ and Anatoly Ivasyuk <anatoly@nick.csh.rit.edu>
+
+Author of this release:
+ Juergen Pfeifer <Juergen.Pfeifer@T-Online.de>
diff --git a/lib/libcurses++/cursesapp.cc b/lib/libcurses++/cursesapp.cc
new file mode 100644
index 00000000000..503de0936cf
--- /dev/null
+++ b/lib/libcurses++/cursesapp.cc
@@ -0,0 +1,146 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+#include "cursesapp.h"
+#include "internal.h"
+
+MODULE_ID("$Id: cursesapp.cc,v 1.1 1999/05/09 00:21:14 millert Exp $")
+
+void
+NCursesApplication::init(bool bColors) {
+ if (bColors)
+ NCursesWindow::useColors();
+
+ if (Root_Window->colors() > 1) {
+ b_Colors = TRUE;
+ Root_Window->setcolor(1);
+ Root_Window->setpalette(COLOR_YELLOW,COLOR_BLUE);
+ Root_Window->setcolor(2);
+ Root_Window->setpalette(COLOR_CYAN,COLOR_BLUE);
+ Root_Window->setcolor(3);
+ Root_Window->setpalette(COLOR_BLACK,COLOR_BLUE);
+ Root_Window->setcolor(4);
+ Root_Window->setpalette(COLOR_BLACK,COLOR_CYAN);
+ Root_Window->setcolor(5);
+ Root_Window->setpalette(COLOR_BLUE,COLOR_YELLOW);
+ Root_Window->setcolor(6);
+ Root_Window->setpalette(COLOR_BLACK,COLOR_GREEN);
+ }
+ else
+ b_Colors = FALSE;
+
+ Root_Window->bkgd(' '|window_backgrounds());
+}
+
+NCursesApplication* NCursesApplication::theApp = 0;
+NCursesWindow* NCursesApplication::titleWindow = 0;
+NCursesApplication::SLK_Link* NCursesApplication::slk_stack = 0;
+
+NCursesApplication::~NCursesApplication() {
+ Soft_Label_Key_Set* S;
+
+ delete titleWindow;
+ while( (S=top()) ) {
+ pop();
+ delete S;
+ }
+ delete Root_Window;
+ ::endwin();
+}
+
+int NCursesApplication::rinit(NCursesWindow& w) {
+ titleWindow = &w;
+ return OK;
+}
+
+void NCursesApplication::push(Soft_Label_Key_Set& S) {
+ SLK_Link* L = new SLK_Link;
+ assert(L);
+ L->prev = slk_stack;
+ L->SLKs = &S;
+ slk_stack = L;
+ if (Root_Window)
+ S.show();
+}
+
+bool NCursesApplication::pop() {
+ if (slk_stack) {
+ SLK_Link* L = slk_stack;
+ slk_stack = slk_stack->prev;
+ delete L;
+ if (Root_Window && top())
+ top()->show();
+ }
+ return (slk_stack ? FALSE : TRUE);
+}
+
+Soft_Label_Key_Set* NCursesApplication::top() const {
+ if (slk_stack)
+ return slk_stack->SLKs;
+ else
+ return (Soft_Label_Key_Set*)0;
+}
+
+int NCursesApplication::operator()(void) {
+ bool bColors = b_Colors;
+ Soft_Label_Key_Set* S;
+
+ int ts = titlesize();
+ if (ts>0)
+ NCursesWindow::ripoffline(ts,rinit);
+ Soft_Label_Key_Set::Label_Layout fmt = useSLKs();
+ if (fmt!=Soft_Label_Key_Set::None) {
+ S = new Soft_Label_Key_Set(fmt);
+ assert(S);
+ init_labels(*S);
+ }
+
+ Root_Window = new NCursesWindow(::stdscr);
+ init(bColors);
+
+ if (ts>0)
+ title();
+ if (fmt!=Soft_Label_Key_Set::None) {
+ push(*S);
+ }
+
+ return run();
+}
+
+NCursesApplication::NCursesApplication(bool bColors) {
+ b_Colors = bColors;
+ if (theApp)
+ THROW(new NCursesException("Application object already created."));
+ else
+ theApp = this;
+}
diff --git a/lib/libcurses++/cursesapp.h b/lib/libcurses++/cursesapp.h
new file mode 100644
index 00000000000..a1b6aee62b1
--- /dev/null
+++ b/lib/libcurses++/cursesapp.h
@@ -0,0 +1,163 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+// $Id: cursesapp.h,v 1.1 1999/05/09 00:21:14 millert Exp $
+
+#ifndef _CURSESAPP_H
+#define _CURSESAPP_H
+
+#include <cursslk.h>
+
+class NCursesApplication {
+public:
+ typedef struct _slk_link { // This structure is used to maintain
+ struct _slk_link* prev; // a stack of SLKs
+ Soft_Label_Key_Set* SLKs;
+ } SLK_Link;
+private:
+ static int rinit(NCursesWindow& w); // Internal Init function for title
+ static NCursesApplication* theApp; // Global ref. to the application
+
+ static SLK_Link* slk_stack;
+
+protected:
+ static NCursesWindow* titleWindow; // The Title Window (if any)
+
+ bool b_Colors; // Is this a color application?
+ NCursesWindow* Root_Window; // This is the stdscr equiv.
+
+ // Initialization of attributes;
+ // Rewrite this in your derived class if you prefer other settings
+ virtual void init(bool bColors);
+
+ // The number of lines for the title window. Default is no title window
+ // You may rewrite this in your derived class
+ virtual int titlesize() const {
+ return 0;
+ }
+
+ // This method is called to put something into the title window initially
+ // You may rewrite this in your derived class
+ virtual void title() {
+ }
+
+ // The layout used for the Soft Label Keys. Default is to have no SLKs.
+ // You may rewrite this in your derived class
+ virtual Soft_Label_Key_Set::Label_Layout useSLKs() const {
+ return Soft_Label_Key_Set::None;
+ }
+
+ // This method is called to initialize the SLKs. Default is nothing.
+ // You may rewrite this in your derived class
+ virtual void init_labels(Soft_Label_Key_Set& S) const {
+ }
+
+ // Your derived class must implement this method. The return value must
+ // be the exit value of your application.
+ virtual int run() = 0;
+
+
+ // The constructor is protected, so you may use it in your derived
+ // class constructor. The argument tells whether or not you want colors.
+ NCursesApplication(bool wantColors = FALSE);
+
+public:
+ virtual ~NCursesApplication();
+
+ // Get a pointer to the current application object
+ static NCursesApplication* getApplication() {
+ return theApp;
+ }
+
+ // This method runs the application and returns its exit value
+ int operator()(void);
+
+ // Process the commandline arguments. The default implementation simply
+ // ignores them. Your derived class may rewrite this.
+ virtual void handleArgs(int argc, char* argv[]) {
+ }
+
+ // Does this application use colors?
+ inline bool useColors() const {
+ return b_Colors;
+ }
+
+ // Push the Key Set S onto the SLK Stack. S then becomes the current set
+ // of Soft Labelled Keys.
+ void push(Soft_Label_Key_Set& S);
+
+ // Throw away the current set of SLKs and make the previous one the
+ // new current set.
+ bool pop();
+
+ // Retrieve the current set of Soft Labelled Keys.
+ Soft_Label_Key_Set* top() const;
+
+ // Attributes to use for menu and forms foregrounds
+ virtual chtype foregrounds() const {
+ return b_Colors ? COLOR_PAIR(1) : A_BOLD;
+ }
+
+ // Attributes to use for menu and forms backgrounds
+ virtual chtype backgrounds() const {
+ return b_Colors ? COLOR_PAIR(2) : A_NORMAL;
+ }
+
+ // Attributes to use for inactive (menu) elements
+ virtual chtype inactives() const {
+ return b_Colors ? (COLOR_PAIR(3)|A_DIM) : A_DIM;
+ }
+
+ // Attributes to use for (form) labels and SLKs
+ virtual chtype labels() const {
+ return b_Colors ? COLOR_PAIR(4) : A_NORMAL;
+ }
+
+ // Attributes to use for form backgrounds
+ virtual chtype dialog_backgrounds() const {
+ return b_Colors ? COLOR_PAIR(4) : A_NORMAL;
+ }
+
+ // Attributes to use as default for (form) window backgrounds
+ virtual chtype window_backgrounds() const {
+ return b_Colors ? COLOR_PAIR(5) : A_NORMAL;
+ }
+
+ // Attributes to use for the title window
+ virtual chtype screen_titles() const {
+ return b_Colors ? COLOR_PAIR(6) : A_BOLD;
+ }
+
+};
+
+#endif // _CURSESAPP_H
diff --git a/lib/libcurses++/cursesf.cc b/lib/libcurses++/cursesf.cc
new file mode 100644
index 00000000000..aa34bd724e4
--- /dev/null
+++ b/lib/libcurses++/cursesf.cc
@@ -0,0 +1,423 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+#include "cursesf.h"
+#include "cursesapp.h"
+#include "internal.h"
+
+MODULE_ID("$Id: cursesf.cc,v 1.1 1999/05/09 00:21:14 millert Exp $")
+
+NCursesFormField::~NCursesFormField () {
+ if (field)
+ OnError(::free_field (field));
+}
+
+/* Construct a FIELD* array from an array of NCursesFormField
+ * objects.
+ */
+FIELD**
+NCursesForm::mapFields(NCursesFormField* nfields[]) {
+ int fieldCount = 0,lcv;
+
+ assert(nfields);
+
+ for (lcv=0; nfields[lcv]->field; ++lcv)
+ ++fieldCount;
+
+ FIELD** fields = new FIELD*[fieldCount + 1];
+
+ for (lcv=0;nfields[lcv]->field;++lcv) {
+ fields[lcv] = nfields[lcv]->field;
+ }
+ fields[lcv] = NULL;
+
+ my_fields = nfields;
+
+ if (form)
+ delete[] ::form_fields(form);
+ return fields;
+}
+
+void NCursesForm::setDefaultAttributes() {
+ NCursesApplication* S = NCursesApplication::getApplication();
+
+ int n = count();
+ if (n > 0) {
+ for(int i=0; i<n; i++) {
+ NCursesFormField* f = (*this)[i];
+ if ((f->options() & (O_EDIT|O_ACTIVE))==(O_EDIT|O_ACTIVE)) {
+ if (S) {
+ f->set_foreground(S->foregrounds());
+ f->set_background(S->backgrounds());
+ }
+ f->set_pad_character('_');
+ }
+ else {
+ if (S)
+ f->set_background(S->labels());
+ }
+ }
+ }
+
+ if (S) {
+ bkgd(' '|S->dialog_backgrounds());
+ if (sub)
+ sub->bkgd(' '|S->dialog_backgrounds());
+ }
+}
+
+void
+NCursesForm::InitForm(NCursesFormField* nfields[],
+ bool with_frame,
+ bool autoDelete_Fields) {
+ int mrows, mcols;
+
+ keypad(TRUE);
+ meta(TRUE);
+
+ b_framed = with_frame;
+ b_autoDelete = autoDelete_Fields;
+
+ form = (FORM*)0;
+ form = ::new_form(mapFields(nfields));
+ if (!form)
+ OnError (E_SYSTEM_ERROR);
+
+ UserHook* hook = new UserHook;
+ hook->m_user = NULL;
+ hook->m_back = this;
+ hook->m_owner = form;
+ ::set_form_userptr(form,(void*)hook);
+
+ ::set_form_init (form, NCursesForm::frm_init);
+ ::set_form_term (form, NCursesForm::frm_term);
+ ::set_field_init (form, NCursesForm::fld_init);
+ ::set_field_term (form, NCursesForm::fld_term);
+
+ scale(mrows, mcols);
+ ::set_form_win(form, w);
+
+ if (with_frame) {
+ if ((mrows > height()-2) || (mcols > width()-2))
+ OnError(E_NO_ROOM);
+ sub = new NCursesWindow(*this,mrows,mcols,1,1,'r');
+ ::set_form_sub(form, sub->w);
+ b_sub_owner = TRUE;
+ }
+ else {
+ sub = (NCursesWindow*)0;
+ b_sub_owner = FALSE;
+ }
+ options_on(O_NL_OVERLOAD);
+ setDefaultAttributes();
+}
+
+NCursesForm::~NCursesForm() {
+ UserHook* hook = (UserHook*)::form_userptr(form);
+ delete hook;
+ if (b_sub_owner) {
+ delete sub;
+ ::set_form_sub(form,(WINDOW *)0);
+ }
+ if (form) {
+ FIELD** fields = ::form_fields(form);
+ int cnt = count();
+
+ OnError(::set_form_fields(form,(FIELD**)0));
+
+ if (b_autoDelete) {
+ if (cnt>0) {
+ for (int i=0; i <= cnt; i++)
+ delete my_fields[i];
+ }
+ delete[] my_fields;
+ }
+
+ ::free_form(form);
+ // It's essential to do this after free_form()
+ delete[] fields;
+ }
+}
+
+void
+NCursesForm::setSubWindow(NCursesWindow& nsub) {
+ if (!isDescendant(nsub))
+ OnError(E_SYSTEM_ERROR);
+ else {
+ if (b_sub_owner)
+ delete sub;
+ sub = &nsub;
+ ::set_form_sub(form,sub->w);
+ }
+}
+
+/* Internal hook functions. They will route the hook
+ * calls to virtual methods of the NCursesForm class,
+ * so in C++ providing a hook is done simply by
+ * implementing a virtual method in a derived class
+ */
+void
+NCursesForm::frm_init(FORM *f) {
+ getHook(f)->On_Form_Init();
+}
+
+void
+NCursesForm::frm_term(FORM *f) {
+ getHook(f)->On_Form_Termination();
+}
+
+void
+NCursesForm::fld_init(FORM *f) {
+ NCursesForm* F = getHook(f);
+ F->On_Field_Init (*(F->current_field ()));
+}
+
+void
+NCursesForm::fld_term(FORM *f) {
+ NCursesForm* F = getHook(f);
+ F->On_Field_Termination (*(F->current_field ()));
+}
+
+void
+NCursesForm::On_Form_Init() {
+}
+
+void
+NCursesForm::On_Form_Termination() {
+}
+
+void
+NCursesForm::On_Field_Init(NCursesFormField& field) {
+}
+
+void
+NCursesForm::On_Field_Termination(NCursesFormField& field) {
+}
+
+// call the form driver and do basic error checking.
+int
+NCursesForm::driver (int c) {
+ int res = ::form_driver (form, c);
+ switch (res) {
+ case E_OK:
+ case E_REQUEST_DENIED:
+ case E_INVALID_FIELD:
+ case E_UNKNOWN_COMMAND:
+ break;
+ default:
+ OnError (res);
+ }
+ return (res);
+}
+
+void NCursesForm::On_Request_Denied(int c) const {
+ beep();
+}
+
+void NCursesForm::On_Invalid_Field(int c) const {
+ beep();
+}
+
+void NCursesForm::On_Unknown_Command(int c) const {
+ beep();
+}
+
+static const int CMD_QUIT = MAX_COMMAND + 1;
+
+NCursesFormField*
+NCursesForm::operator()(void) {
+ int drvCmnd;
+ int err;
+ int c;
+
+ post();
+ show();
+ refresh();
+
+ while (((drvCmnd = virtualize((c=getch()))) != CMD_QUIT)) {
+ switch((err=driver(drvCmnd))) {
+ case E_REQUEST_DENIED:
+ On_Request_Denied(c);
+ break;
+ case E_INVALID_FIELD:
+ On_Invalid_Field(c);
+ break;
+ case E_UNKNOWN_COMMAND:
+ On_Unknown_Command(c);
+ break;
+ case E_OK:
+ break;
+ default:
+ OnError(err);
+ }
+ }
+
+ unpost();
+ hide();
+ refresh();
+ return my_fields[::field_index (::current_field (form))];
+}
+
+// Provide a default key virtualization. Translate the keyboard
+// code c into a form request code.
+// The default implementation provides a hopefully straightforward
+// mapping for the most common keystrokes and form requests.
+int
+NCursesForm::virtualize(int c) {
+ switch(c) {
+
+ case KEY_HOME : return(REQ_FIRST_FIELD);
+ case KEY_END : return(REQ_LAST_FIELD);
+
+ case KEY_DOWN : return(REQ_DOWN_CHAR);
+ case KEY_UP : return(REQ_UP_CHAR);
+ case KEY_LEFT : return(REQ_PREV_CHAR);
+ case KEY_RIGHT : return(REQ_NEXT_CHAR);
+
+ case KEY_NPAGE : return(REQ_NEXT_PAGE);
+ case KEY_PPAGE : return(REQ_PREV_PAGE);
+
+ case KEY_BACKSPACE : return(REQ_DEL_PREV);
+ case KEY_ENTER : return(REQ_NEW_LINE);
+ case KEY_CLEAR : return(REQ_CLR_FIELD);
+
+ case CTRL('X') : return(CMD_QUIT); // eXit
+
+ case CTRL('F') : return(REQ_NEXT_FIELD); // Forward
+ case CTRL('B') : return(REQ_PREV_FIELD); // Backward
+ case CTRL('L') : return(REQ_LEFT_FIELD); // Left
+ case CTRL('R') : return(REQ_RIGHT_FIELD); // Right
+ case CTRL('U') : return(REQ_UP_FIELD); // Up
+ case CTRL('D') : return(REQ_DOWN_FIELD); // Down
+
+ case CTRL('W') : return(REQ_NEXT_WORD);
+ case CTRL('T') : return(REQ_PREV_WORD);
+
+ case CTRL('A') : return(REQ_BEG_FIELD);
+ case CTRL('E') : return(REQ_END_FIELD);
+
+ case CTRL('I') : return(REQ_INS_CHAR);
+ case CTRL('M') :
+ case CTRL('J') : return(REQ_NEW_LINE);
+ case CTRL('O') : return(REQ_INS_LINE);
+ case CTRL('V') : return(REQ_DEL_CHAR);
+ case CTRL('H') : return(REQ_DEL_PREV);
+ case CTRL('Y') : return(REQ_DEL_LINE);
+ case CTRL('G') : return(REQ_DEL_WORD);
+ case CTRL('K') : return(REQ_CLR_EOF);
+
+ case CTRL('N') : return(REQ_NEXT_CHOICE);
+ case CTRL('P') : return(REQ_PREV_CHOICE);
+
+ default:
+ return(c);
+ }
+}
+//
+// -------------------------------------------------------------------------
+// User Defined Fieldtypes
+// -------------------------------------------------------------------------
+//
+bool UserDefinedFieldType::fcheck(FIELD *f, const void *u) {
+ NCursesFormField* F = (NCursesFormField*)u;
+ assert(F);
+ UserDefinedFieldType* udf = (UserDefinedFieldType*)(F->fieldtype());
+ assert(udf);
+ return udf->field_check(*F);
+}
+
+bool UserDefinedFieldType::ccheck(int c, const void *u) {
+ NCursesFormField* F = (NCursesFormField*)u;
+ assert(F);
+ UserDefinedFieldType* udf =
+ (UserDefinedFieldType*)(F->fieldtype());
+ assert(udf);
+ return udf->char_check(c);
+}
+
+void* UserDefinedFieldType::makearg(va_list* va) {
+ return va_arg(*va,NCursesFormField*);
+}
+
+FIELDTYPE* UserDefinedFieldType::generic_fieldtype =
+ ::new_fieldtype(UserDefinedFieldType::fcheck,
+ UserDefinedFieldType::ccheck);
+
+FIELDTYPE* UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice =
+ ::new_fieldtype(UserDefinedFieldType::fcheck,
+ UserDefinedFieldType::ccheck);
+
+bool UserDefinedFieldType_With_Choice::next_choice(FIELD *f, const void *u) {
+ NCursesFormField* F = (NCursesFormField*)u;
+ assert(F);
+ UserDefinedFieldType_With_Choice* udf =
+ (UserDefinedFieldType_With_Choice*)(F->fieldtype());
+ assert(udf);
+ return udf->next(*F);
+}
+
+bool UserDefinedFieldType_With_Choice::prev_choice(FIELD *f, const void *u) {
+ NCursesFormField* F = (NCursesFormField*)u;
+ assert(F);
+ UserDefinedFieldType_With_Choice* udf =
+ (UserDefinedFieldType_With_Choice*)(F->fieldtype());
+ assert(udf);
+ return udf->previous(*F);
+}
+
+class UDF_Init {
+private:
+ int code;
+ static UDF_Init* I;
+public:
+ UDF_Init() {
+ code = ::set_fieldtype_arg(UserDefinedFieldType::generic_fieldtype,
+ UserDefinedFieldType::makearg,
+ NULL,
+ NULL);
+ if (code==E_OK)
+ code = ::set_fieldtype_arg
+ (UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice,
+ UserDefinedFieldType::makearg,
+ NULL,
+ NULL);
+ if (code==E_OK)
+ code = ::set_fieldtype_choice
+ (UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice,
+ UserDefinedFieldType_With_Choice::next_choice,
+ UserDefinedFieldType_With_Choice::prev_choice);
+ }
+};
+
+UDF_Init* UDF_Init::I = new UDF_Init();
+
diff --git a/lib/libcurses++/cursesf.h b/lib/libcurses++/cursesf.h
new file mode 100644
index 00000000000..3ff38999683
--- /dev/null
+++ b/lib/libcurses++/cursesf.h
@@ -0,0 +1,823 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+// $Id: cursesf.h,v 1.1 1999/05/09 00:21:14 millert Exp $
+
+#ifndef _CURSESF_H
+#define _CURSESF_H
+
+#include <cursesp.h>
+
+extern "C" {
+# include <form.h>
+}
+//
+// -------------------------------------------------------------------------
+// The abstract base class for buitin and user defined Fieldtypes.
+// -------------------------------------------------------------------------
+//
+class NCursesFormField; // forward declaration
+
+// Class to represent builtin field types as well as C++ written new
+// fieldtypes (see classes UserDefineFieldType...
+class NCursesFieldType {
+ friend class NCursesFormField;
+
+protected:
+ FIELDTYPE* fieldtype;
+
+ inline void OnError(int err) const THROWS(NCursesFormException) {
+ if (err!=E_OK)
+ THROW(new NCursesFormException (err));
+ }
+
+ NCursesFieldType(FIELDTYPE *f) : fieldtype(f) {
+ }
+
+ virtual ~NCursesFieldType() {}
+
+ // Set the fields f fieldtype to this one.
+ virtual void set(NCursesFormField& f) = 0;
+
+public:
+ NCursesFieldType() : fieldtype((FIELDTYPE*)0) {
+ }
+};
+
+//
+// -------------------------------------------------------------------------
+// The class representing a forms field, wrapping the lowlevel FIELD struct
+// -------------------------------------------------------------------------
+//
+class NCursesFormField {
+ friend class NCursesForm;
+
+protected:
+ FIELD *field; // lowlevel structure
+ NCursesFieldType* ftype; // Associated field type
+
+ // Error handler
+ inline void OnError (int err) const THROWS(NCursesFormException) {
+ if (err != E_OK)
+ THROW(new NCursesFormException (err));
+ }
+
+public:
+ // Create a 'Null' field. Can be used to delimit a field list
+ NCursesFormField()
+ : field((FIELD*)0), ftype((NCursesFieldType*)0) {
+ }
+
+ // Create a new field
+ NCursesFormField (int rows,
+ int cols,
+ int first_row = 0,
+ int first_col = 0,
+ int offscreen_rows = 0,
+ int additional_buffers = 0)
+ : ftype((NCursesFieldType*)0) {
+ field = ::new_field(rows,cols,first_row,first_col,
+ offscreen_rows, additional_buffers);
+ if (!field)
+ OnError(errno);
+ }
+
+ virtual ~NCursesFormField ();
+
+ // Duplicate the field at a new position
+ inline NCursesFormField* dup(int first_row, int first_col) {
+ NCursesFormField* f = new NCursesFormField();
+ if (!f)
+ OnError(E_SYSTEM_ERROR);
+ else {
+ f->ftype = ftype;
+ f->field = ::dup_field(field,first_row,first_col);
+ if (!f->field)
+ OnError(errno);
+ }
+ return f;
+ }
+
+ // Link the field to a new location
+ inline NCursesFormField* link(int first_row, int first_col) {
+ NCursesFormField* f = new NCursesFormField();
+ if (!f)
+ OnError(E_SYSTEM_ERROR);
+ else {
+ f->ftype = ftype;
+ f->field = ::link_field(field,first_row,first_col);
+ if (!f->field)
+ OnError(errno);
+ }
+ return f;
+ }
+
+ // Get the lowlevel field representation
+ inline FIELD* get_field() const {
+ return field;
+ }
+
+ // Retrieve info about the field
+ inline void info(int& rows, int& cols,
+ int& first_row, int& first_col,
+ int& offscreen_rows, int& additional_buffers) const {
+ OnError(::field_info(field, &rows, &cols,
+ &first_row, &first_col,
+ &offscreen_rows, &additional_buffers));
+ }
+
+ // Retrieve info about the fields dynamic properties.
+ inline void dynamic_info(int& dynamic_rows, int& dynamic_cols,
+ int& max_growth) const {
+ OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols,
+ &max_growth));
+ }
+
+ // For a dynamic field you may set the maximum growth limit.
+ // A zero means unlimited growth.
+ inline void set_maximum_growth(int growth = 0) {
+ OnError(::set_max_field(field,growth));
+ }
+
+ // Move the field to a new position
+ inline void move(int row, int col) {
+ OnError(::move_field(field,row,col));
+ }
+
+ // Mark the field to start a new page
+ inline void new_page(bool pageFlag = FALSE) {
+ OnError(::set_new_page(field,pageFlag));
+ }
+
+ // Retrieve whether or not the field starts a new page.
+ inline bool is_new_page() const {
+ return ::new_page(field);
+ }
+
+ // Set the justification for the field
+ inline void set_justification(int just) {
+ OnError(::set_field_just(field,just));
+ }
+
+ // Retrieve the fields justification
+ inline int justification() const {
+ return ::field_just(field);
+ }
+ // Set the foreground attribute for the field
+ inline void set_foreground(chtype fore) {
+ OnError(::set_field_fore(field,fore));
+ }
+
+ // Retrieve the fields foreground attribute
+ inline chtype fore() const {
+ return ::field_fore(field);
+ }
+
+ // Set the background attribute for the field
+ inline void set_background(chtype back) {
+ OnError(::set_field_back(field,back));
+ }
+
+ // Retrieve the fields background attribute
+ inline chtype back() const {
+ return ::field_back(field);
+ }
+
+ // Set the padding character for the field
+ inline void set_pad_character(int pad) {
+ OnError(::set_field_pad(field,pad));
+ }
+
+ // Retrieve the fields padding character
+ inline int pad() const {
+ return ::field_pad(field);
+ }
+
+ // Switch on the fields options
+ inline void options_on (Field_Options options) {
+ OnError (::field_opts_on (field, options));
+ }
+
+ // Switch off the fields options
+ inline void options_off (Field_Options options) {
+ OnError (::field_opts_off (field, options));
+ }
+
+ // Retrieve the fields options
+ inline Field_Options options () const {
+ return ::field_opts (field);
+ }
+
+ // Set the fields options
+ inline void set_options (Field_Options options) {
+ OnError (::set_field_opts (field, options));
+ }
+
+ // Mark the field as changed
+ inline void set_changed(bool changeFlag = TRUE) {
+ OnError(::set_field_status(field,changeFlag));
+ }
+
+ // Test whether or not the field is marked as changed
+ inline bool changed() const {
+ return ::field_status(field);
+ }
+
+ // Return the index of the field in the field array of a form
+ // or -1 if the field is not associated to a form
+ inline int (index)() const {
+ return ::field_index(field);
+ }
+
+ // Store a value in a fields buffer. The default buffer is nr. 0
+ inline void set_value(const char *val, int buffer = 0) {
+ OnError(::set_field_buffer(field,buffer,val));
+ }
+
+ // Retrieve the value of a fields buffer. The defaukt buffer is nr. 0
+ inline char* value(int buffer = 0) const {
+ return ::field_buffer(field,buffer);
+ }
+
+ // Set the validation type of the field.
+ inline void set_fieldtype(NCursesFieldType& f) {
+ ftype = &f;
+ f.set(*this); // A good friend may do that...
+ }
+
+ // Retrieve the validation type of the field.
+ inline NCursesFieldType* fieldtype() const {
+ return ftype;
+ }
+
+};
+
+//
+// -------------------------------------------------------------------------
+// The class representing a form, wrapping the lowlevel FORM struct
+// -------------------------------------------------------------------------
+//
+class NCursesForm : public NCursesPanel {
+protected:
+ FORM* form; // the lowlevel structure
+
+private:
+ NCursesWindow* sub; // the subwindow object
+ bool b_sub_owner; // is this our own subwindow?
+ bool b_framed; // has the form a border?
+ bool b_autoDelete; // Delete fields when deleting form?
+
+ NCursesFormField** my_fields; // The array of fields for this form
+
+ // This structure is used for the form's user data field to link the
+ // FORM* to the C++ object and to provide extra space for a user pointer.
+ typedef struct {
+ void* m_user; // the pointer for the user's data
+ const NCursesForm* m_back; // backward pointer to C++ object
+ const FORM* m_owner;
+ } UserHook;
+
+ // Get the backward pointer to the C++ object from a FORM
+ static inline NCursesForm* getHook(const FORM *f) {
+ UserHook* hook = (UserHook*)::form_userptr(f);
+ assert(hook && hook->m_owner==f);
+ return (NCursesForm*)(hook->m_back);
+ }
+
+ // This are the built-in hook functions in this C++ binding. In C++ we use
+ // virtual member functions (see below On_..._Init and On_..._Termination)
+ // to provide this functionality in an object oriented manner.
+ static void frm_init(FORM *);
+ static void frm_term(FORM *);
+ static void fld_init(FORM *);
+ static void fld_term(FORM *);
+
+ // Calculate FIELD* array for the menu
+ FIELD** mapFields(NCursesFormField* nfields[]);
+
+protected:
+ // internal routines
+ inline void set_user(void *user) {
+ UserHook* uptr = (UserHook*)::form_userptr (form);
+ assert (uptr && uptr->m_back==this && uptr->m_owner==form);
+ uptr->m_user = user;
+ }
+
+ inline void *get_user() {
+ UserHook* uptr = (UserHook*)::form_userptr (form);
+ assert (uptr && uptr->m_back==this && uptr->m_owner==form);
+ return uptr->m_user;
+ }
+
+ void InitForm (NCursesFormField* Fields[],
+ bool with_frame,
+ bool autoDeleteFields);
+
+ inline void OnError (int err) const THROWS(NCursesFormException) {
+ if (err != E_OK)
+ THROW(new NCursesFormException (err));
+ }
+
+ // this wraps the form_driver call.
+ virtual int driver (int c) ;
+
+ // 'Internal' constructor, builds an object without association to a
+ // field array.
+ NCursesForm( int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0)
+ : NCursesPanel(lines,cols,begin_y,begin_x),
+ form ((FORM*)0) {
+ }
+
+public:
+ // Create form for the default panel.
+ NCursesForm (NCursesFormField* Fields[],
+ bool with_frame=FALSE, // reserve space for a frame?
+ bool autoDelete_Fields=FALSE) // do automatic cleanup?
+ : NCursesPanel() {
+ InitForm(Fields, with_frame, autoDelete_Fields);
+ }
+
+ // Create a form in a panel with the given position and size.
+ NCursesForm (NCursesFormField* Fields[],
+ int lines,
+ int cols,
+ int begin_y,
+ int begin_x,
+ bool with_frame=FALSE, // reserve space for a frame?
+ bool autoDelete_Fields=FALSE) // do automatic cleanup?
+ : NCursesPanel(lines, cols, begin_y, begin_x) {
+ InitForm(Fields, with_frame, autoDelete_Fields);
+ }
+
+ virtual ~NCursesForm();
+
+ // Set the default attributes for the form
+ virtual void setDefaultAttributes();
+
+ // Retrieve current field of the form.
+ inline NCursesFormField* current_field() const {
+ return my_fields[::field_index(::current_field(form))];
+ }
+
+ // Set the forms subwindow
+ void setSubWindow(NCursesWindow& sub);
+
+ // Set these fields for the form
+ inline void setFields(NCursesFormField* Fields[]) {
+ OnError(::set_form_fields(form,mapFields(Fields)));
+ }
+
+ // Remove the form from the screen
+ inline void unpost (void) {
+ OnError (::unpost_form (form));
+ }
+
+ // Post the form to the screen if flag is true, unpost it otherwise
+ inline void post(bool flag = TRUE) {
+ OnError (flag ? ::post_form(form) : ::unpost_form (form));
+ }
+
+ // Decorations
+ inline void frame(const char *title=NULL, const char* btitle=NULL) {
+ if (b_framed)
+ NCursesPanel::frame(title,btitle);
+ else
+ OnError(E_SYSTEM_ERROR);
+ }
+
+ inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
+ if (b_framed)
+ NCursesPanel::boldframe(title,btitle);
+ else
+ OnError(E_SYSTEM_ERROR);
+ }
+
+ inline void label(const char *topLabel, const char *bottomLabel) {
+ if (b_framed)
+ NCursesPanel::label(topLabel,bottomLabel);
+ else
+ OnError(E_SYSTEM_ERROR);
+ }
+
+ // -----
+ // Hooks
+ // -----
+
+ // Called after the form gets repositioned in its window.
+ // This is especially true if the form is posted.
+ virtual void On_Form_Init();
+
+ // Called before the form gets repositioned in its window.
+ // This is especially true if the form is unposted.
+ virtual void On_Form_Termination();
+
+ // Called after the field became the current field
+ virtual void On_Field_Init(NCursesFormField& field);
+
+ // Called before this field is left as current field.
+ virtual void On_Field_Termination(NCursesFormField& field);
+
+ // Calculate required window size for the form.
+ void scale(int& rows, int& cols) const {
+ OnError(::scale_form(form,&rows,&cols));
+ }
+
+ // Retrieve number of fields in the form.
+ int count() const {
+ return ::field_count(form);
+ }
+
+ // Make the page the current page of the form.
+ void set_page(int page) {
+ OnError(::set_form_page(form,page));
+ }
+
+ // Retrieve current page number
+ int page() const {
+ return ::form_page(form);
+ }
+
+ // Switch on the forms options
+ inline void options_on (Form_Options options) {
+ OnError (::form_opts_on (form, options));
+ }
+
+ // Switch off the forms options
+ inline void options_off (Form_Options options) {
+ OnError (::form_opts_off (form, options));
+ }
+
+ // Retrieve the forms options
+ inline Form_Options options () const {
+ return ::form_opts (form);
+ }
+
+ // Set the forms options
+ inline void set_options (Form_Options options) {
+ OnError (::set_form_opts (form, options));
+ }
+
+ // Are there more data in the current field after the data shown
+ inline bool data_ahead() const {
+ return ::data_ahead(form);
+ }
+
+ // Are there more data in the current field before the data shown
+ inline bool data_behind() const {
+ return ::data_behind(form);
+ }
+
+ // Position the cursor to the current field
+ inline void position_cursor () {
+ OnError (::pos_form_cursor (form));
+ }
+ // Set the current field
+ inline void set_current(NCursesFormField& F) {
+ OnError (::set_current_field(form, F.field));
+ }
+
+ // Provide a default key virtualization. Translate the keyboard
+ // code c into a form request code.
+ // The default implementation provides a hopefully straightforward
+ // mapping for the most common keystrokes and form requests.
+ virtual int virtualize(int c);
+
+ // Operators
+ inline NCursesFormField* operator[](int i) const {
+ if ( (i < 0) || (i >= ::field_count (form)) )
+ OnError (E_BAD_ARGUMENT);
+ return my_fields[i];
+ }
+
+ // Perform the menu's operation
+ // Return the field where you left the form.
+ virtual NCursesFormField* operator()(void);
+
+ // Exception handlers. The default is a Beep.
+ virtual void On_Request_Denied(int c) const;
+ virtual void On_Invalid_Field(int c) const;
+ virtual void On_Unknown_Command(int c) const;
+
+};
+
+//
+// -------------------------------------------------------------------------
+// This is the typical C++ typesafe way to allow to attach
+// user data to a field of a form. Its assumed that the user
+// data belongs to some class T. Use T as template argument
+// to create a UserField.
+// -------------------------------------------------------------------------
+template<class T> class NCursesUserField : public NCursesFormField
+{
+public:
+ NCursesUserField (int rows,
+ int cols,
+ int first_row = 0,
+ int first_col = 0,
+ const T* p_UserData = (T*)0,
+ int offscreen_rows = 0,
+ int additional_buffers = 0)
+ : NCursesFormField (rows, cols,
+ first_row, first_col,
+ offscreen_rows, additional_buffers) {
+ if (field)
+ OnError(::set_field_userptr(field,(void *)p_UserData));
+ }
+
+ virtual ~NCursesUserField() {};
+
+ inline const T* UserData (void) const {
+ return (const T*)::field_userptr (field);
+ }
+
+ inline virtual void setUserData(const T* p_UserData) {
+ if (field)
+ OnError (::set_field_userptr (field, (void *)p_UserData));
+ }
+};
+//
+// -------------------------------------------------------------------------
+// The same mechanism is used to attach user data to a form
+// -------------------------------------------------------------------------
+//
+template<class T> class NCursesUserForm : public NCursesForm
+{
+protected:
+ // 'Internal' constructor, builds an object without association to a
+ // field array.
+ NCursesUserForm( int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0,
+ const T* p_UserData = (T*)0)
+ : NCursesForm(lines,cols,begin_y,begin_x) {
+ if (form)
+ set_user ((void *)p_UserData);
+ }
+
+public:
+ NCursesUserForm (NCursesFormField Fields[],
+ bool with_frame=FALSE,
+ bool autoDelete_Fields=FALSE)
+ : NCursesForm (Fields, with_frame, autoDelete_Fields) {
+ };
+
+ NCursesUserForm (NCursesFormField Fields[],
+ const T* p_UserData = (T*)0,
+ bool with_frame=FALSE,
+ bool autoDelete_Fields=FALSE)
+ : NCursesForm (Fields, with_frame, autoDelete_Fields) {
+ if (form)
+ set_user ((void *)p_UserData);
+ };
+
+ NCursesUserForm (NCursesFormField Fields[],
+ int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0,
+ const T* p_UserData = (T*)0,
+ bool with_frame=FALSE,
+ bool autoDelete_Fields=FALSE)
+ : NCursesForm (Fields, lines, cols, begin_y, begin_x,
+ with_frame, autoDelete_Fields) {
+ if (form)
+ set_user ((void *)p_UserData);
+ };
+
+ virtual ~NCursesUserForm() {
+ };
+
+ inline T* UserData (void) const {
+ return (T*)get_user ();
+ };
+
+ inline virtual void setUserData (const T* p_UserData) {
+ if (form)
+ set_user ((void *)p_UserData);
+ }
+
+};
+//
+// -------------------------------------------------------------------------
+// Builtin Fieldtypes
+// -------------------------------------------------------------------------
+//
+class Alpha_Field : public NCursesFieldType {
+private:
+ int min_field_width;
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
+ }
+
+public:
+ Alpha_Field(int width)
+ : NCursesFieldType(TYPE_ALPHA),
+ min_field_width(width) {
+ }
+};
+
+class Alphanumeric_Field : public NCursesFieldType {
+private:
+ int min_field_width;
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
+ }
+
+public:
+ Alphanumeric_Field(int width)
+ : NCursesFieldType(TYPE_ALNUM),
+ min_field_width(width) {
+ }
+};
+
+class Integer_Field : public NCursesFieldType {
+private:
+ int precision;
+ long lower_limit, upper_limit;
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,
+ precision,lower_limit,upper_limit));
+ }
+
+public:
+ Integer_Field(int prec, long low=0L, long high=0L)
+ : NCursesFieldType(TYPE_INTEGER),
+ precision(prec), lower_limit(low), upper_limit(high) {
+ }
+};
+
+class Numeric_Field : public NCursesFieldType {
+private:
+ int precision;
+ double lower_limit, upper_limit;
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,
+ precision,lower_limit,upper_limit));
+ }
+
+public:
+ Numeric_Field(int prec, double low=0.0, double high=0.0)
+ : NCursesFieldType(TYPE_NUMERIC),
+ precision(prec), lower_limit(low), upper_limit(high) {
+ }
+};
+
+class Regular_Expression_Field : public NCursesFieldType {
+private:
+ char* regex;
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,regex));
+ }
+
+public:
+ Regular_Expression_Field(const char *expr)
+ : NCursesFieldType(TYPE_REGEXP) {
+ regex = new char[1+::strlen(expr)];
+ (strcpy)(regex,expr);
+ }
+
+ ~Regular_Expression_Field() {
+ delete[] regex;
+ }
+};
+
+class Enumeration_Field : public NCursesFieldType {
+private:
+ char** list;
+ int case_sensitive;
+ int non_unique_matches;
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,
+ list,case_sensitive,non_unique_matches));
+ }
+public:
+ Enumeration_Field(char* enums[],
+ bool case_sens=FALSE,
+ bool non_unique=FALSE)
+ : NCursesFieldType(TYPE_ENUM),
+ list(enums),
+ case_sensitive(case_sens?-1:0),
+ non_unique_matches(non_unique?-1:0) {
+ }
+};
+
+class IPV4_Address_Field : public NCursesFieldType {
+private:
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype));
+ }
+
+public:
+ IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
+ }
+};
+//
+// -------------------------------------------------------------------------
+// Abstract base class for User-Defined Fieldtypes
+// -------------------------------------------------------------------------
+//
+class UserDefinedFieldType : public NCursesFieldType {
+ friend class UDF_Init; // Internal helper to set up statics
+private:
+ // For all C++ defined fieldtypes we need only one generic lowlevel
+ // FIELDTYPE* element.
+ static FIELDTYPE* generic_fieldtype;
+
+protected:
+ // This are the functions required by the low level libforms functions
+ // to construct a fieldtype.
+ static bool fcheck(FIELD *, const void*);
+ static bool ccheck(int c, const void *);
+ static void* makearg(va_list*);
+
+ void set(NCursesFormField& f) {
+ OnError(::set_field_type(f.get_field(),fieldtype,&f));
+ }
+
+protected:
+ // Redefine this function to do a field validation. The argument
+ // is a reference to the field you should validate.
+ virtual bool field_check(NCursesFormField& f) = 0;
+
+ // Redefine this function to do a character validation. The argument
+ // is the character to be validated.
+ virtual bool char_check (int c) = 0;
+
+public:
+ UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) {
+ }
+};
+//
+// -------------------------------------------------------------------------
+// Abstract base class for User-Defined Fieldtypes with Choice functions
+// -------------------------------------------------------------------------
+//
+class UserDefinedFieldType_With_Choice : public UserDefinedFieldType {
+ friend class UDF_Init; // Internal helper to set up statics
+private:
+ // For all C++ defined fieldtypes with choice functions we need only one
+ // generic lowlevel FIELDTYPE* element.
+ static FIELDTYPE* generic_fieldtype_with_choice;
+
+ // This are the functions required by the low level libforms functions
+ // to construct a fieldtype with choice functions.
+ static bool next_choice(FIELD*, const void *);
+ static bool prev_choice(FIELD*, const void *);
+
+protected:
+ // Redefine this function to do the retrieval of the next choice value.
+ // The argument is a reference to the field tobe examined.
+ virtual bool next (NCursesFormField& f) = 0;
+
+ // Redefine this function to do the retrieval of the previous choice value.
+ // The argument is a reference to the field tobe examined.
+ virtual bool previous(NCursesFormField& f) = 0;
+
+public:
+ UserDefinedFieldType_With_Choice() {
+ fieldtype = generic_fieldtype_with_choice;
+ }
+};
+
+#endif // _CURSESF_H
+
diff --git a/lib/libcurses++/cursesm.cc b/lib/libcurses++/cursesm.cc
new file mode 100644
index 00000000000..02ee75c8c56
--- /dev/null
+++ b/lib/libcurses++/cursesm.cc
@@ -0,0 +1,379 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+#include "cursesm.h"
+#include "cursesapp.h"
+#include "internal.h"
+
+MODULE_ID("$Id: cursesm.cc,v 1.1 1999/05/09 00:21:14 millert Exp $")
+
+NCursesMenuItem::~NCursesMenuItem() {
+ if (item)
+ OnError(::free_item(item));
+}
+
+bool
+NCursesMenuItem::action() {
+ return FALSE;
+};
+
+NCursesMenuCallbackItem::~NCursesMenuCallbackItem() {
+}
+
+bool
+NCursesMenuCallbackItem::action() {
+ if (p_fct)
+ return p_fct (*this);
+ else
+ return FALSE;
+}
+
+/* Internal hook functions. They will route the hook
+ * calls to virtual methods of the NCursesMenu class,
+ * so in C++ providing a hook is done simply by
+ * implementing a virtual method in a derived class
+ */
+void
+NCursesMenu::mnu_init(MENU *m) {
+ getHook(m)->On_Menu_Init();
+}
+
+void
+NCursesMenu::mnu_term(MENU *m) {
+ getHook(m)->On_Menu_Termination();
+}
+
+void
+NCursesMenu::itm_init(MENU *m) {
+ NCursesMenu* M = getHook(m);
+ M->On_Item_Init (*(M->current_item ()));
+}
+
+void
+NCursesMenu::itm_term(MENU *m) {
+ NCursesMenu* M = getHook(m);
+ M->On_Item_Termination (*(M->current_item ()));
+}
+
+/* Construct an ITEM* array from an array of NCursesMenuItem
+ * objects.
+ */
+ITEM**
+NCursesMenu::mapItems(NCursesMenuItem* nitems[]) {
+ int itemCount = 0,lcv;
+
+ for (lcv=0; nitems[lcv]->item; ++lcv)
+ ++itemCount;
+
+ ITEM** items = new ITEM*[itemCount + 1];
+
+ for (lcv=0;nitems[lcv]->item;++lcv) {
+ items[lcv] = nitems[lcv]->item;
+ }
+ items[lcv] = NULL;
+
+ my_items = nitems;
+
+ if (menu)
+ delete[] ::menu_items(menu);
+ return items;
+}
+
+void
+NCursesMenu::InitMenu(NCursesMenuItem* nitems[],
+ bool with_frame,
+ bool autoDelete_Items) {
+ int mrows, mcols;
+
+ keypad(TRUE);
+ meta(TRUE);
+
+ b_framed = with_frame;
+ b_autoDelete = autoDelete_Items;
+
+ menu = (MENU*)0;
+ menu = ::new_menu(mapItems(nitems));
+ if (!menu)
+ OnError (E_SYSTEM_ERROR);
+
+ UserHook* hook = new UserHook;
+ hook->m_user = NULL;
+ hook->m_back = this;
+ hook->m_owner = menu;
+ ::set_menu_userptr(menu,(void*)hook);
+
+ ::set_menu_init (menu, NCursesMenu::mnu_init);
+ ::set_menu_term (menu, NCursesMenu::mnu_term);
+ ::set_item_init (menu, NCursesMenu::itm_init);
+ ::set_item_term (menu, NCursesMenu::itm_term);
+
+ scale(mrows, mcols);
+ ::set_menu_win(menu, w);
+
+ if (with_frame) {
+ if ((mrows > height()-2) || (mcols > width()-2))
+ OnError(E_NO_ROOM);
+ sub = new NCursesWindow(*this,mrows,mcols,1,1,'r');
+ ::set_menu_sub(menu, sub->w);
+ b_sub_owner = TRUE;
+ }
+ else {
+ sub = (NCursesWindow*)0;
+ b_sub_owner = FALSE;
+ }
+ setDefaultAttributes();
+}
+
+void
+NCursesMenu::setDefaultAttributes() {
+ NCursesApplication* S = NCursesApplication::getApplication();
+ if (S) {
+ ::set_menu_fore(menu, S->foregrounds());
+ ::set_menu_back(menu, S->backgrounds());
+ ::set_menu_grey(menu, S->inactives());
+ }
+}
+
+NCursesMenu::~NCursesMenu() {
+ UserHook* hook = (UserHook*)::menu_userptr(menu);
+ delete hook;
+ if (b_sub_owner) {
+ delete sub;
+ ::set_menu_sub(menu,(WINDOW *)0);
+ }
+ if (menu) {
+ ITEM** itms = ::menu_items(menu);
+ int cnt = count();
+
+ OnError(::set_menu_items(menu,(ITEM**)0));
+
+ if (b_autoDelete) {
+ if (cnt>0) {
+ for (int i=0; i <= cnt; i++)
+ delete my_items[i];
+ }
+ delete[] my_items;
+ }
+
+ ::free_menu(menu);
+ // It's essential to do this after free_menu()
+ delete[] itms;
+ }
+}
+
+void
+NCursesMenu::setSubWindow(NCursesWindow& nsub) {
+ if (!isDescendant(nsub))
+ OnError(E_SYSTEM_ERROR);
+ else {
+ if (b_sub_owner)
+ delete sub;
+ sub = &nsub;
+ ::set_menu_sub(menu,sub->w);
+ }
+}
+
+bool
+NCursesMenu::set_pattern (const char *pat) {
+ int res = ::set_menu_pattern (menu, pat);
+ switch(res) {
+ case E_OK:
+ break;
+ case E_NO_MATCH:
+ return FALSE;
+ default:
+ OnError (res);
+ }
+ return TRUE;
+}
+
+// call the menu driver and do basic error checking.
+int
+NCursesMenu::driver (int c) {
+ int res = ::menu_driver (menu, c);
+ switch (res) {
+ case E_OK:
+ case E_REQUEST_DENIED:
+ case E_NOT_SELECTABLE:
+ case E_UNKNOWN_COMMAND:
+ case E_NO_MATCH:
+ break;
+ default:
+ OnError (res);
+ }
+ return (res);
+}
+
+static const int CMD_QUIT = MAX_COMMAND + 1;
+static const int CMD_ACTION = MAX_COMMAND + 2;
+//
+// -------------------------------------------------------------------------
+// Provide a default key virtualization. Translate the keyboard
+// code c into a menu request code.
+// The default implementation provides a hopefully straightforward
+// mapping for the most common keystrokes and menu requests.
+// -------------------------------------------------------------------------
+int
+NCursesMenu::virtualize(int c) {
+ switch(c) {
+ case CTRL('X') : return(CMD_QUIT); // eXit
+
+ case KEY_DOWN : return(REQ_DOWN_ITEM);
+ case CTRL('N') : return(REQ_NEXT_ITEM); // Next
+ case KEY_UP : return(REQ_UP_ITEM);
+ case CTRL('P') : return(REQ_PREV_ITEM); // Previous
+
+ case CTRL('U') : return(REQ_SCR_ULINE); // Up
+ case CTRL('D') : return(REQ_SCR_DLINE); // Down
+ case CTRL('F') : return(REQ_SCR_DPAGE); // Forward
+ case CTRL('B') : return(REQ_SCR_UPAGE); // Backward
+
+ case CTRL('Y') : return(REQ_CLEAR_PATTERN);
+ case CTRL('H') : return(REQ_BACK_PATTERN);
+ case CTRL('A') : return(REQ_NEXT_MATCH);
+ case CTRL('E') : return(REQ_PREV_MATCH);
+ case CTRL('T') : return(REQ_TOGGLE_ITEM);
+
+ case CTRL('J') :
+ case CTRL('M') : return(CMD_ACTION);
+
+ case KEY_HOME : return(REQ_FIRST_ITEM);
+ case KEY_LEFT : return(REQ_LEFT_ITEM);
+ case KEY_RIGHT : return(REQ_RIGHT_ITEM);
+ case KEY_END : return(REQ_LAST_ITEM);
+ case KEY_BACKSPACE : return(REQ_BACK_PATTERN);
+ case KEY_NPAGE : return(REQ_SCR_DPAGE);
+ case KEY_PPAGE : return(REQ_SCR_UPAGE);
+
+ default:
+ return(c);
+ }
+}
+
+NCursesMenuItem*
+NCursesMenu::operator()(void) {
+ int drvCmnd;
+ int err;
+ int c;
+ bool b_action = FALSE;
+
+ post();
+ show();
+ refresh();
+
+ while (!b_action && ((drvCmnd = virtualize((c=getch()))) != CMD_QUIT)) {
+
+ switch((err=driver(drvCmnd))) {
+ case E_REQUEST_DENIED:
+ On_Request_Denied(c);
+ break;
+ case E_NOT_SELECTABLE:
+ On_Not_Selectable(c);
+ break;
+ case E_UNKNOWN_COMMAND:
+ if (drvCmnd == CMD_ACTION) {
+ if (options() & O_ONEVALUE) {
+ NCursesMenuItem* itm = current_item();
+ assert(itm);
+ if (itm->options() & O_SELECTABLE)
+ b_action = itm->action();
+ else
+ On_Not_Selectable(c);
+ }
+ else {
+ int n = count();
+ for(int i=0; i<n; i++) {
+ NCursesMenuItem* itm = my_items[i];
+ if (itm->value()) {
+ b_action |= itm->action();
+ }
+ }
+ }
+ } else
+ On_Unknown_Command(c);
+ break;
+ case E_NO_MATCH:
+ On_No_Match(c);
+ break;
+ case E_OK:
+ break;
+ default:
+ OnError(err);
+ }
+ }
+
+ unpost();
+ hide();
+ refresh();
+ if (options() & O_ONEVALUE)
+ return my_items[::item_index (::current_item (menu))];
+ else
+ return NULL;
+}
+
+void
+NCursesMenu::On_Menu_Init() {
+}
+
+void
+NCursesMenu::On_Menu_Termination() {
+}
+
+void
+NCursesMenu::On_Item_Init(NCursesMenuItem& item) {
+}
+
+void
+NCursesMenu::On_Item_Termination(NCursesMenuItem& item) {
+}
+
+void
+NCursesMenu::On_Request_Denied(int c) const {
+ beep();
+}
+
+void
+NCursesMenu::On_Not_Selectable(int c) const {
+ beep();
+}
+
+void
+NCursesMenu::On_No_Match(int c) const {
+ beep();
+}
+
+void
+NCursesMenu::On_Unknown_Command(int c) const {
+ beep();
+}
+
diff --git a/lib/libcurses++/cursesm.h b/lib/libcurses++/cursesm.h
new file mode 100644
index 00000000000..1aa15628466
--- /dev/null
+++ b/lib/libcurses++/cursesm.h
@@ -0,0 +1,592 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+// $Id: cursesm.h,v 1.1 1999/05/09 00:21:14 millert Exp $
+
+#ifndef _CURSESM_H
+#define _CURSESM_H
+
+#include <cursesp.h>
+
+extern "C" {
+# include <menu.h>
+}
+//
+// -------------------------------------------------------------------------
+// This wraps the ITEM type of <menu.h>
+// -------------------------------------------------------------------------
+//
+class NCursesMenuItem {
+ friend class NCursesMenu;
+
+protected:
+ ITEM *item;
+
+ inline void OnError (int err) const THROWS(NCursesMenuException) {
+ if (err != E_OK)
+ THROW(new NCursesMenuException (err));
+ }
+
+public:
+ NCursesMenuItem (const char* p_name = NULL,
+ const char* p_descript = NULL ) {
+ item = p_name ? ::new_item (p_name, p_descript) : (ITEM*)0;
+ if (p_name && !item)
+ OnError (E_SYSTEM_ERROR);
+ }
+ // Create an item. If you pass both parameters as NULL, a delimiting
+ // item is constructed which can be used to terminate a list of
+ // NCursesMenu objects.
+
+ virtual ~NCursesMenuItem ();
+ // Release the items memory
+
+ inline const char* name () const {
+ return ::item_name (item);
+ }
+ // Name of the item
+
+ inline const char* description () const {
+ return ::item_description (item);
+ }
+ // Description of the item
+
+ inline int (index) (void) const {
+ return ::item_index (item);
+ }
+ // Index of the item in an item array (or -1)
+
+ inline void options_on (Item_Options options) {
+ OnError (::item_opts_on (item, options));
+ }
+ // Switch on the items options
+
+ inline void options_off (Item_Options options) {
+ OnError (::item_opts_off (item, options));
+ }
+ // Switch off the item's option
+
+ inline Item_Options options () const {
+ return ::item_opts (item);
+ }
+ // Retrieve the items options
+
+ inline void set_options (Item_Options options) {
+ OnError (::set_item_opts (item, options));
+ }
+ // Set the items options
+
+ inline void set_value (bool f) {
+ OnError (::set_item_value (item,f));
+ }
+ // Set/Reset the items selection state
+
+ inline bool value () const {
+ return ::item_value (item);
+ }
+ // Retrieve the items selection state
+
+ inline bool visible () const {
+ return ::item_visible (item);
+ }
+ // Retrieve visibility of the item
+
+ virtual bool action();
+ // Perform an action associated with this item; you may use this in an
+ // user supplied driver for a menu; you may derive from this class and
+ // overload action() to supply items with different actions.
+ // If an action returns true, the menu will be exited. The default action
+ // is to do nothing.
+};
+
+// Prototype for an items callback function.
+typedef bool ITEMCALLBACK(NCursesMenuItem&);
+
+// If you don't like to create a child class for individual items to
+// overload action(), you may use this class and provide a callback
+// function pointer for items.
+class NCursesMenuCallbackItem : public NCursesMenuItem {
+private:
+ const ITEMCALLBACK* p_fct;
+
+public:
+ NCursesMenuCallbackItem(const ITEMCALLBACK* fct = NULL,
+ const char* p_name = NULL,
+ const char* p_descript = NULL )
+ : NCursesMenuItem (p_name, p_descript),
+ p_fct (fct) {
+ }
+
+ virtual ~NCursesMenuCallbackItem();
+
+ bool action();
+};
+//
+// -------------------------------------------------------------------------
+// This wraps the MENU type of <menu.h>
+// -------------------------------------------------------------------------
+//
+class NCursesMenu : public NCursesPanel {
+protected:
+ MENU *menu;
+
+private:
+ NCursesWindow* sub; // the subwindow object
+ bool b_sub_owner; // is this our own subwindow?
+ bool b_framed; // has the menu a border?
+ bool b_autoDelete; // Delete items when deleting menu?
+
+ NCursesMenuItem** my_items; // The array of items for this menu
+
+ // This structure is used for the menu's user data field to link the
+ // MENU* to the C++ object and to provide extra space for a user pointer.
+ typedef struct {
+ void* m_user; // the pointer for the user's data
+ const NCursesMenu* m_back; // backward pointer to C++ object
+ const MENU* m_owner;
+ } UserHook;
+
+ // Get the backward pointer to the C++ object from a MENU
+ static inline NCursesMenu* getHook(const MENU *m) {
+ UserHook* hook = (UserHook*)::menu_userptr(m);
+ assert(hook && hook->m_owner==m);
+ return (NCursesMenu*)(hook->m_back);
+ }
+
+ // This are the built-in hook functions in this C++ binding. In C++ we use
+ // virtual member functions (see below On_..._Init and On_..._Termination)
+ // to provide this functionality in an object oriented manner.
+ static void mnu_init(MENU *);
+ static void mnu_term(MENU *);
+ static void itm_init(MENU *);
+ static void itm_term(MENU *);
+
+ // Calculate ITEM* array for the menu
+ ITEM** mapItems(NCursesMenuItem* nitems[]);
+
+protected:
+ // internal routines
+ inline void set_user(void *user) {
+ UserHook* uptr = (UserHook*)::menu_userptr (menu);
+ assert (uptr && uptr->m_back==this && uptr->m_owner==menu);
+ uptr->m_user = user;
+ }
+
+ inline void *get_user() {
+ UserHook* uptr = (UserHook*)::menu_userptr (menu);
+ assert (uptr && uptr->m_back==this && uptr->m_owner==menu);
+ return uptr->m_user;
+ }
+
+ void InitMenu (NCursesMenuItem* menu[],
+ bool with_frame,
+ bool autoDeleteItems);
+
+ inline void OnError (int err) const THROWS(NCursesMenuException) {
+ if (err != E_OK)
+ THROW(new NCursesMenuException (this, err));
+ }
+
+ // this wraps the menu_driver call.
+ virtual int driver (int c) ;
+
+ // 'Internal' constructor to create a menu without association to
+ // an array of items.
+ NCursesMenu( int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0)
+ : NCursesPanel(lines,cols,begin_y,begin_x),
+ menu ((MENU*)0) {
+ }
+
+public:
+ // Make a full window size menu
+ NCursesMenu (NCursesMenuItem* Items[],
+ bool with_frame=FALSE, // Reserve space for a frame?
+ bool autoDelete_Items=FALSE) // Autocleanup of Items?
+ : NCursesPanel() {
+ InitMenu(Items, with_frame, autoDelete_Items);
+ }
+
+ // Make a menu with a window of this size.
+ NCursesMenu (NCursesMenuItem* Items[],
+ int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0,
+ bool with_frame=FALSE, // Reserve space for a frame?
+ bool autoDelete_Items=FALSE) // Autocleanup of Items?
+ : NCursesPanel(lines, cols, begin_y, begin_x) {
+ InitMenu(Items, with_frame, autoDelete_Items);
+ }
+
+ virtual ~NCursesMenu ();
+
+ // Retrieve the menus subwindow
+ inline NCursesWindow& subWindow() const {
+ assert(sub!=NULL);
+ return *sub;
+ }
+
+ // Set the menus subwindow
+ void setSubWindow(NCursesWindow& sub);
+
+ // Set these items for the menu
+ inline void setItems(NCursesMenuItem* Items[]) {
+ OnError(::set_menu_items(menu,mapItems(Items)));
+ }
+
+ // Remove the menu from the screen
+ inline void unpost (void) {
+ OnError (::unpost_menu (menu));
+ }
+
+ // Post the menu to the screen if flag is true, unpost it otherwise
+ inline void post(bool flag = TRUE) {
+ flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
+ }
+
+ // Get the numer of rows and columns for this menu
+ inline void scale (int& mrows, int& mcols) const {
+ OnError (::scale_menu (menu, &mrows, &mcols));
+ }
+
+ // Set the format of this menu
+ inline void set_format(int mrows, int mcols) {
+ OnError (::set_menu_format(menu, mrows, mcols));
+ }
+
+ // Get the format of this menu
+ inline void menu_format(int& rows,int& cols) {
+ ::menu_format(menu,&rows,&cols);
+ }
+
+ // Items of the menu
+ inline NCursesMenuItem* items() const {
+ return *my_items;
+ }
+
+ // Get the number of items in this menu
+ inline int count() const {
+ return ::item_count(menu);
+ }
+
+ // Get the current item (i.e. the one the cursor is located)
+ inline NCursesMenuItem* current_item() const {
+ return my_items[::item_index(::current_item(menu))];
+ }
+
+ // Get the marker string
+ inline const char* mark() const {
+ return ::menu_mark(menu);
+ }
+
+ // Set the marker string
+ inline void set_mark(const char *mark) {
+ OnError (::set_menu_mark (menu, mark));
+ }
+
+ // Get the name of the request code c
+ inline static const char* request_name(int c) {
+ return ::menu_request_name(c);
+ }
+
+ // Get the current pattern
+ inline char* pattern() const {
+ return ::menu_pattern(menu);
+ }
+
+ // true if there is a pattern match, false otherwise.
+ bool set_pattern (const char *pat);
+
+ // set the default attributes for the menu
+ // i.e. set fore, back and grey attribute
+ virtual void setDefaultAttributes();
+
+ // Get the menus background attributes
+ inline chtype back() const {
+ return ::menu_back(menu);
+ }
+
+ // Get the menus foreground attributes
+ inline chtype fore() const {
+ return ::menu_fore(menu);
+ }
+
+ // Get the menus grey attributes (used for unselectable items)
+ inline chtype grey() const {
+ return ::menu_grey(menu);
+ }
+
+ // Set the menus background attributes
+ inline chtype set_background(chtype a) {
+ return ::set_menu_back(menu,a);
+ }
+
+ // Set the menus foreground attributes
+ inline chtype set_foreground(chtype a) {
+ return ::set_menu_fore(menu,a);
+ }
+
+ // Set the menus grey attributes (used for unselectable items)
+ inline chtype set_grey(chtype a) {
+ return ::set_menu_grey(menu,a);
+ }
+
+ inline void options_on (Menu_Options opts) {
+ OnError (::menu_opts_on (menu,opts));
+ }
+
+ inline void options_off(Menu_Options opts) {
+ OnError (::menu_opts_off(menu,opts));
+ }
+
+ inline Menu_Options options() const {
+ return ::menu_opts(menu);
+ }
+
+ inline void set_options (Menu_Options opts) {
+ OnError (::set_menu_opts (menu,opts));
+ }
+
+ inline int pad() const {
+ return ::menu_pad(menu);
+ }
+
+ inline void set_pad (int padch) {
+ OnError (::set_menu_pad (menu, padch));
+ }
+
+ // Position the cursor to the current item
+ inline void position_cursor () const {
+ OnError (::pos_menu_cursor (menu));
+ }
+
+ // Set the current item
+ inline void set_current(NCursesMenuItem& I) {
+ OnError (::set_current_item(menu, I.item));
+ }
+
+ // Get the current top row of the menu
+ inline int top_row (void) const {
+ return ::top_row (menu);
+ }
+
+ // Set the current top row of the menu
+ inline void set_top_row (int row) {
+ OnError (::set_top_row (menu, row));
+ }
+
+ // spacing control
+ // Set the spacing for the menu
+ inline void setSpacing(int spc_description,
+ int spc_rows,
+ int spc_columns) {
+ OnError(::set_menu_spacing(menu,
+ spc_description,
+ spc_rows,
+ spc_columns));
+ }
+
+ // Get the spacing info for the menu
+ inline void Spacing(int& spc_description,
+ int& spc_rows,
+ int& spc_columns) const {
+ OnError(::menu_spacing(menu,
+ &spc_description,
+ &spc_rows,
+ &spc_columns));
+ }
+
+ // Decorations
+ inline void frame(const char *title=NULL, const char* btitle=NULL) {
+ if (b_framed)
+ NCursesPanel::frame(title,btitle);
+ else
+ OnError(E_SYSTEM_ERROR);
+ }
+
+ inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
+ if (b_framed)
+ NCursesPanel::boldframe(title,btitle);
+ else
+ OnError(E_SYSTEM_ERROR);
+ }
+
+ inline void label(const char *topLabel, const char *bottomLabel) {
+ if (b_framed)
+ NCursesPanel::label(topLabel,bottomLabel);
+ else
+ OnError(E_SYSTEM_ERROR);
+ }
+
+ // -----
+ // Hooks
+ // -----
+
+ // Called after the menu gets repositioned in its window.
+ // This is especially true if the menu is posted.
+ virtual void On_Menu_Init();
+
+ // Called before the menu gets repositioned in its window.
+ // This is especially true if the menu is unposted.
+ virtual void On_Menu_Termination();
+
+ // Called after the item became the current item
+ virtual void On_Item_Init(NCursesMenuItem& item);
+
+ // Called before this item is left as current item.
+ virtual void On_Item_Termination(NCursesMenuItem& item);
+
+ // Provide a default key virtualization. Translate the keyboard
+ // code c into a menu request code.
+ // The default implementation provides a hopefully straightforward
+ // mapping for the most common keystrokes and menu requests.
+ virtual int virtualize(int c);
+
+
+ // Operators
+ inline NCursesMenuItem* operator[](int i) const {
+ if ( (i < 0) || (i >= ::item_count (menu)) )
+ OnError (E_BAD_ARGUMENT);
+ return (my_items[i]);
+ }
+
+ // Perform the menu's operation
+ // Return the item where you left the selection mark for a single
+ // selection menu, or NULL for a multivalued menu.
+ virtual NCursesMenuItem* operator()(void);
+
+ // --------------------
+ // Exception handlers
+ // Called by operator()
+ // --------------------
+
+ // Called if the request is denied
+ virtual void On_Request_Denied(int c) const;
+
+ // Called if the item is not selectable
+ virtual void On_Not_Selectable(int c) const;
+
+ // Called if pattern doesn't match
+ virtual void On_No_Match(int c) const;
+
+ // Called if the command is unknown
+ virtual void On_Unknown_Command(int c) const;
+
+};
+//
+// -------------------------------------------------------------------------
+// This is the typical C++ typesafe way to allow to attach
+// user data to an item of a menu. Its assumed that the user
+// data belongs to some class T. Use T as template argument
+// to create a UserItem.
+// -------------------------------------------------------------------------
+//
+template<class T> class NCursesUserItem : public NCursesMenuItem
+{
+public:
+ NCursesUserItem (const char* p_name,
+ const char* p_descript = NULL,
+ const T* p_UserData = (T*)0)
+ : NCursesMenuItem (p_name, p_descript) {
+ if (item)
+ OnError (::set_item_userptr (item, (void *)p_UserData));
+ };
+
+ virtual ~NCursesUserItem() {};
+
+ inline const T* UserData (void) const {
+ return (const T*)::item_userptr (item);
+ };
+
+ inline virtual void setUserData(const T* p_UserData) {
+ if (item)
+ OnError (::set_item_userptr (item, (void *)p_UserData));
+ }
+};
+//
+// -------------------------------------------------------------------------
+// The same mechanism is used to attach user data to a menu
+// -------------------------------------------------------------------------
+//
+template<class T> class NCursesUserMenu : public NCursesMenu
+{
+protected:
+ NCursesUserMenu( int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0,
+ const T* p_UserData = (T*)0)
+ : NCursesMenu(lines,cols,begin_y,begin_x) {
+ if (menu)
+ set_user ((void *)p_UserData);
+ }
+
+public:
+ NCursesUserMenu (NCursesMenuItem Items[],
+ const T* p_UserData = (T*)0,
+ bool with_frame=FALSE,
+ bool autoDelete_Items=FALSE)
+ : NCursesMenu (Items, with_frame, autoDelete_Items) {
+ if (menu)
+ set_user ((void *)p_UserData);
+ };
+
+ NCursesUserMenu (NCursesMenuItem Items[],
+ int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0,
+ const T* p_UserData = (T*)0,
+ bool with_frame=FALSE)
+ : NCursesMenu (Items, lines, cols, begin_y, begin_x, with_frame) {
+ if (menu)
+ set_user ((void *)p_UserData);
+ };
+
+ virtual ~NCursesUserMenu() {
+ };
+
+ inline T* UserData (void) const {
+ return (T*)get_user ();
+ };
+
+ inline virtual void setUserData (const T* p_UserData) {
+ if (menu)
+ set_user ((void *)p_UserData);
+ }
+};
+
+#endif // _CURSESM_H
diff --git a/lib/libcurses++/cursesmain.cc b/lib/libcurses++/cursesmain.cc
new file mode 100644
index 00000000000..d3cb692c8bf
--- /dev/null
+++ b/lib/libcurses++/cursesmain.cc
@@ -0,0 +1,51 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+#include "cursesapp.h"
+#include "internal.h"
+
+MODULE_ID("$Id: cursesmain.cc,v 1.1 1999/05/09 00:21:14 millert Exp $")
+
+/* This is the default implementation of main() for a NCursesApplication.
+ * You only have to instantiate a static NCursesApplication object in your
+ * main application source file and link this module with your application.
+ */
+int main(int argc, char* argv[])
+{
+ NCursesApplication* A = NCursesApplication::getApplication();
+ if (!A)
+ return(1);
+ A->handleArgs(argc,argv);
+ ::endwin();
+ return((*A)());
+}
diff --git a/lib/libcurses++/cursesp.cc b/lib/libcurses++/cursesp.cc
new file mode 100644
index 00000000000..46314f0df79
--- /dev/null
+++ b/lib/libcurses++/cursesp.cc
@@ -0,0 +1,123 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1993,1997 *
+ ****************************************************************************/
+
+#include "cursesp.h"
+#include "internal.h"
+
+MODULE_ID("$Id: cursesp.cc,v 1.1 1999/05/09 00:21:14 millert Exp $")
+
+NCursesPanel* NCursesPanel::dummy = (NCursesPanel*)0;
+
+void NCursesPanel::init() {
+ p = ::new_panel(w);
+ if (!p)
+ OnError(ERR);
+
+ UserHook* hook = new UserHook;
+ hook->m_user = NULL;
+ hook->m_back = this;
+ hook->m_owner = p;
+ ::set_panel_userptr(p, (void *)hook);
+}
+
+NCursesPanel::~NCursesPanel() {
+ UserHook* hook = (UserHook*)::panel_userptr(p);
+ assert(hook && hook->m_back==this && hook->m_owner==p);
+ delete hook;
+ ::del_panel(p);
+ ::update_panels();
+}
+
+void
+NCursesPanel::redraw() {
+ PANEL *pan;
+
+ pan = ::panel_above(NULL);
+ while (pan) {
+ ::touchwin(panel_window(pan));
+ pan = ::panel_above(pan);
+ }
+ ::update_panels();
+ ::doupdate();
+}
+
+int
+NCursesPanel::refresh() {
+ ::update_panels();
+ return doupdate();
+}
+
+int
+NCursesPanel::noutrefresh() {
+ ::update_panels();
+ return OK;
+}
+
+void
+NCursesPanel::boldframe(const char *title, const char* btitle) {
+ standout();
+ frame(title, btitle);
+ standend();
+}
+
+void
+NCursesPanel::frame(const char *title,const char *btitle) {
+ int err = OK;
+ if (!title && !btitle) {
+ err = box();
+ }
+ else {
+ err = box();
+ if (err==OK)
+ label(title,btitle);
+ }
+ OnError(err);
+}
+
+void
+NCursesPanel::label(const char *tLabel, const char *bLabel) {
+ if (tLabel)
+ centertext(0,tLabel);
+ if (bLabel)
+ centertext(maxy(),bLabel);
+}
+
+void
+NCursesPanel::centertext(int row,const char *label) {
+ if (label) {
+ int x = (maxx() - strlen(label)) / 2;
+ if (x<0)
+ x=0;
+ OnError(addstr(row, x, label, width()));
+ }
+}
diff --git a/lib/libcurses++/cursesp.h b/lib/libcurses++/cursesp.h
new file mode 100644
index 00000000000..3ea4bf87a35
--- /dev/null
+++ b/lib/libcurses++/cursesp.h
@@ -0,0 +1,186 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+#ifndef _CURSESP_H
+#define _CURSESP_H
+
+// $Id: cursesp.h,v 1.1 1999/05/09 00:21:15 millert Exp $
+
+#include <cursesw.h>
+
+extern "C" {
+# include <panel.h>
+}
+
+class NCursesPanel : public NCursesWindow {
+protected:
+ PANEL *p;
+ static NCursesPanel *dummy;
+
+private:
+ // This structure is used for the panel's user data field to link the
+ // PANEL* to the C++ object and to provide extra space for a user pointer.
+ typedef struct {
+ void* m_user; // the pointer for the user's data
+ const NCursesPanel* m_back; // backward pointer to C++ object
+ const PANEL* m_owner; // the panel itself
+ } UserHook;
+
+ void init(); // Initialize the panel object
+
+protected:
+ void set_user(void *user) {
+ UserHook* uptr = (UserHook*)::panel_userptr (p);
+ assert (uptr && uptr->m_back==this && uptr->m_owner==p);
+ uptr->m_user = user;
+ }
+ // Set the user pointer of the panel.
+
+ void *get_user() {
+ UserHook* uptr = (UserHook*)::panel_userptr (p);
+ assert (uptr && uptr->m_back==this && uptr->m_owner==p);
+ return uptr->m_user;
+ }
+
+ void OnError (int err) const THROWS((NCursesPanelException)) {
+ if (err==ERR)
+ THROW(new NCursesPanelException (this, err));
+ }
+ // If err is equal to the curses error indicator ERR, an error handler
+ // is called.
+
+public:
+ NCursesPanel(int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0)
+ : NCursesWindow(lines,cols,begin_y,begin_x) {
+ init();
+ }
+ // Create a panel with this size starting at the requested position.
+
+ NCursesPanel() : NCursesWindow(::stdscr) { init(); }
+ // This constructor creates the default Panel associated with the
+ // ::stdscr window
+
+ virtual ~NCursesPanel();
+
+ // basic manipulation
+ inline void hide() {
+ OnError (::hide_panel(p));
+ }
+ // Hide the panel. It stays in the stack but becomes invisible.
+
+ inline void show() {
+ OnError (::show_panel(p));
+ }
+ // Show the panel, i.e. make it visible.
+
+ inline void top() {
+ OnError (::top_panel(p));
+ }
+ // Make this panel the top panel in the stack.
+
+ inline void bottom() {
+ OnError (::bottom_panel(p));
+ }
+ // Make this panel the bottom panel in the stack.
+ // N.B.: The panel associated with ::stdscr is always on the bottom. So
+ // actually bottom() makes the panel the first above ::stdscr.
+
+ inline int mvwin(int y, int x) {
+ OnError(::move_panel(p, y, x));
+ return OK;
+ }
+
+ inline bool hidden() const {
+ return (::panel_hidden (p) ? TRUE : FALSE);
+ }
+ // Return TRUE if the panel is hidden, FALSE otherwise.
+
+/* The functions panel_above() and panel_below() are not reflected in
+ the NCursesPanel class. The reason for this is, that we cannot
+ assume that a panel retrieved by those operations is one wrapped
+ by a C++ class. Although this situation might be handled, we also
+ need a reverse mapping from PANEL to NCursesPanel which needs some
+ redesign of the low level stuff. At the moment, we define them in the
+ interface but they will always produce an error. */
+ inline NCursesPanel& above() const {
+ OnError(ERR);
+ return *dummy;
+ }
+
+ inline NCursesPanel& below() const {
+ OnError(ERR);
+ return *dummy;
+ }
+
+ // Those two are rewrites of the corresponding virtual members of
+ // NCursesWindow
+ int refresh();
+ // Propagate all panel changes to the virtual screen and update the
+ // physical screen.
+
+ int noutrefresh();
+ // Propagate all panel changes to the virtual screen.
+
+ static void redraw();
+ // Redraw all panels.
+
+ // decorations
+ virtual void frame(const char* title=NULL,
+ const char* btitle=NULL);
+ // Put a frame around the panel and put the title centered in the top line
+ // and btitle in the bottom line.
+
+ virtual void boldframe(const char* title=NULL,
+ const char* btitle=NULL);
+ // Same as frame(), but use highlighted attributes.
+
+ virtual void label(const char* topLabel,
+ const char* bottomLabel);
+ // Put the title centered in the top line and btitle in the bottom line.
+
+ virtual void centertext(int row,const char* label);
+ // Put the label text centered in the specified row.
+};
+
+/* We use templates to provide a typesafe mechanism to associate
+ * user data with a panel. A NCursesUserPanel<T> is a panel
+ * associated with some user data of type T.
+ */
+template<class T> class NCursesUserPanel : public NCursesPanel
+{
+public:
+ NCursesUserPanel (int lines,
+ int cols,
+ int begin_y = 0,
+ int begin_x = 0,
+ const T* p_UserData = (T*)0)
+ : NCursesPanel (lines, cols, begin_y, begin_x) {
+ if (p)
+ set_user ((void *)p_UserData);
+ };
+ // This creates an user panel of the requested size with associated
+ // user data pointed to by p_UserData.
+
+ NCursesUserPanel(const T* p_UserData = (T*)0) : NCursesPanel() {
+ if (p)
+ set_user((void *)p_UserData);
+ };
+ // This creates an user panel associated with the ::stdscr and user data
+ // pointed to by p_UserData.
+
+ virtual ~NCursesUserPanel() {};
+
+ T* UserData (void) const {
+ return (T*)get_user ();
+ };
+ // Retrieve the user data associated with the panel.
+
+ virtual void setUserData (const T* p_UserData) {
+ if (p)
+ set_user ((void *)p_UserData);
+ }
+ // Associate the user panel with the user data pointed to by p_UserData.
+};
+
+#endif // _CURSESP_H
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;
+}
diff --git a/lib/libcurses++/cursesw.h b/lib/libcurses++/cursesw.h
new file mode 100644
index 00000000000..830416dd373
--- /dev/null
+++ b/lib/libcurses++/cursesw.h
@@ -0,0 +1,1262 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+#ifndef _CURSESW_H
+#define _CURSESW_H
+
+// $Id: cursesw.h,v 1.1 1999/05/09 00:21:15 millert Exp $
+
+#include <etip.h>
+#include <stdio.h>
+#include <stdarg.h>
+#ifdef __MWERKS__
+/* This is a bogus check, stringstream is actually ANSI C++ standard,
+ * but old compilers like GCC don't have it, and new compilers like Metrowerks
+ * don't have strstream
+ */
+#include <sstream>
+#else
+#include <strstream.h>
+#endif
+
+extern "C" {
+# include <curses.h>
+}
+
+/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro.
+ Undefine it here, because NCursesWindow uses lines as a method. */
+#undef lines
+
+/* "Convert" macros to inlines. We'll define it as another symbol to avoid
+ * conflict with library symbols.
+ */
+#undef UNDEF
+#define UNDEF(name) CUR_ ##name
+
+#ifdef addch
+inline int UNDEF(addch)(chtype ch) { return addch(ch); }
+#undef addch
+#define addch UNDEF(addch)
+#endif
+
+#ifdef echochar
+inline int UNDEF(echochar)(chtype ch) { return echochar(ch); }
+#undef echochar
+#define echochar UNDEF(echochar)
+#endif
+
+#ifdef insdelln
+inline int UNDEF(insdelln)(int n) { return insdelln(n); }
+#undef insdelln
+#define insdelln UNDEF(insdelln)
+#endif
+
+#ifdef addstr
+/* The (char*) cast is to hack around missing const's */
+inline int UNDEF(addstr)(const char * str) { return addstr((char*)str); }
+#undef addstr
+#define addstr UNDEF(addstr)
+#endif
+
+#ifdef attron
+inline int UNDEF(attron)(chtype at) { return attron(at); }
+#undef attron
+#define attron UNDEF(attron)
+#endif
+
+#ifdef attroff
+inline int UNDEF(attroff)(chtype at) { return attroff(at); }
+#undef attroff
+#define attroff UNDEF(attroff)
+#endif
+
+#ifdef attrset
+inline chtype UNDEF(attrset)(chtype at) { return attrset(at); }
+#undef attrset
+#define attrset UNDEF(attrset)
+#endif
+
+#ifdef color_set
+inline chtype UNDEF(color_set)(short p,void* opts) { return color_set(p,opts); }
+#undef color_set
+#define color_set UNDEF(color_set)
+#endif
+
+#ifdef border
+inline int UNDEF(border)(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br)
+{ return border(ls,rs,ts,bs,tl,tr,bl,br); }
+#undef border
+#define border UNDEF(border)
+#endif
+
+#ifdef box
+inline int UNDEF(box)(WINDOW *win, int v, int h) { return box(win, v, h); }
+#undef box
+#define box UNDEF(box)
+#endif
+
+#ifdef mvwhline
+inline int UNDEF(mvwhline)(WINDOW *win,int y,int x,chtype c,int n) {
+ return mvwhline(win,y,x,c,n); }
+#undef mvwhline
+#define mvwhline UNDEF(mvwhline)
+#endif
+
+#ifdef mvwvline
+inline int UNDEF(mvwvline)(WINDOW *win,int y,int x,chtype c,int n) {
+ return mvwvline(win,y,x,c,n); }
+#undef mvwvline
+#define mvwvline UNDEF(mvwvline)
+#endif
+
+#ifdef clear
+inline int UNDEF(clear)() { return clear(); }
+#undef clear
+#define clear UNDEF(clear)
+#endif
+
+#ifdef clearok
+inline int UNDEF(clearok)(WINDOW* win, bool bf) { return clearok(win, bf); }
+#undef clearok
+#define clearok UNDEF(clearok)
+#else
+extern "C" int clearok(WINDOW*, bool);
+#endif
+
+#ifdef clrtobot
+inline int UNDEF(clrtobot)() { return clrtobot(); }
+#undef clrtobot
+#define clrtobot UNDEF(clrtobot)
+#endif
+
+#ifdef clrtoeol
+inline int UNDEF(clrtoeol)() { return clrtoeol(); }
+#undef clrtoeol
+#define clrtoeol UNDEF(clrtoeol)
+#endif
+
+#ifdef delch
+inline int UNDEF(delch)() { return delch(); }
+#undef delch
+#define delch UNDEF(delch)
+#endif
+
+#ifdef deleteln
+inline int UNDEF(deleteln)() { return deleteln(); }
+#undef deleteln
+#define deleteln UNDEF(deleteln)
+#endif
+
+#ifdef erase
+inline int UNDEF(erase)() { return erase(); }
+#undef erase
+#define erase UNDEF(erase)
+#endif
+
+#ifdef flushok
+inline int UNDEF(flushok)(WINDOW* _win, bool _bf) {
+ return flushok(_win, _bf); }
+#undef flushok
+#define flushok UNDEF(flushok)
+#else
+#define _no_flushok
+#endif
+
+#ifdef getch
+inline int UNDEF(getch)() { return getch(); }
+#undef getch
+#define getch UNDEF(getch)
+#endif
+
+#ifdef getstr
+inline int UNDEF(getstr)(char *_str) { return getstr(_str); }
+#undef getstr
+#define getstr UNDEF(getstr)
+#endif
+
+#ifdef instr
+inline int UNDEF(instr)(char *_str) { return instr(_str); }
+#undef instr
+#define instr UNDEF(instr)
+#endif
+
+#ifdef innstr
+inline int UNDEF(innstr)(char *_str, int n) { return innstr(_str,n); }
+#undef innstr
+#define innstr UNDEF(innstr)
+#endif
+
+#ifdef mvwinnstr
+inline int UNDEF(mvwinnstr)(WINDOW *win, int y, int x, char *_str, int n) {
+ return mvwinnstr(win,y,x,_str,n); }
+#undef mvwinnstr
+#define mvwinnstr UNDEF(mvwinnstr)
+#endif
+
+#ifdef mvinnstr
+inline int UNDEF(mvinnstr)(int y, int x, char *_str, int n) {
+ return mvinnstr(y,x,_str,n); }
+#undef mvinnstr
+#define mvinnstr UNDEF(mvinnstr)
+#endif
+
+#ifdef winsstr
+inline int UNDEF(winsstr)(WINDOW *w, const char *_str) {
+ return winsstr(w,_str); }
+#undef winsstr
+#define winsstr UNDEF(winsstr)
+#endif
+
+#ifdef mvwinsstr
+inline int UNDEF(mvwinsstr)(WINDOW *w, int y, int x, const char *_str) {
+ return mvwinsstr(w,y,x,_str); }
+#undef mvwinsstr
+#define mvwinsstr UNDEF(mvwinsstr)
+#endif
+
+#ifdef insstr
+inline int UNDEF(insstr)(const char *_str) {
+ return insstr(_str); }
+#undef insstr
+#define insstr UNDEF(insstr)
+#endif
+
+#ifdef mvinsstr
+inline int UNDEF(mvinsstr)(int y, int x,const char *_str) {
+ return mvinsstr(y,x,_str); }
+#undef mvinsstr
+#define mvinsstr UNDEF(mvinsstr)
+#endif
+
+#ifdef insnstr
+inline int UNDEF(insnstr)(const char *_str, int n) {
+ return insnstr(_str,n); }
+#undef insnstr
+#define insnstr UNDEF(insnstr)
+#endif
+
+#ifdef mvwinsnstr
+inline int UNDEF(mvwinsnstr)(WINDOW *w, int y, int x,const char *_str, int n) {
+ return mvwinsnstr(w,y,x,_str,n); }
+#undef mvwinsnstr
+#define mvwinsnstr UNDEF(mvwinsnstr)
+#endif
+
+#ifdef mvinsnstr
+inline int UNDEF(mvinsnstr)(int y, int x,const char *_str, int n) {
+ return mvinsnstr(y,x,_str,n); }
+#undef mvinsnstr
+#define mvinsnstr UNDEF(mvinsnstr)
+#endif
+
+#ifdef getnstr
+inline int UNDEF(getnstr)(char *_str, int n) { return getnstr(_str,n); }
+#undef getnstr
+#define getnstr UNDEF(getnstr)
+#endif
+
+#ifdef getyx
+inline void UNDEF(getyx)(const WINDOW* win, int& y, int& x) {
+ getyx(win, y, x); }
+#undef getyx
+#define getyx UNDEF(getyx)
+#endif
+
+#ifdef getbegyx
+inline void UNDEF(getbegyx)(WINDOW* win, int& y, int& x) { getbegyx(win, y, x); }
+#undef getbegyx
+#define getbegyx UNDEF(getbegyx)
+#endif
+
+#ifdef getmaxyx
+inline void UNDEF(getmaxyx)(WINDOW* win, int& y, int& x) { getmaxyx(win, y, x); }
+#undef getmaxyx
+#define getmaxyx UNDEF(getmaxyx)
+#endif
+
+#ifdef hline
+inline int UNDEF(hline)(chtype ch, int n) { return hline(ch, n); }
+#undef hline
+#define hline UNDEF(hline)
+#endif
+
+#ifdef inch
+inline chtype UNDEF(inch)() { return inch(); }
+#undef inch
+#define inch UNDEF(inch)
+#endif
+
+#ifdef insch
+inline int UNDEF(insch)(char c) { return insch(c); }
+#undef insch
+#define insch UNDEF(insch)
+#endif
+
+#ifdef insertln
+inline int UNDEF(insertln)() { return insertln(); }
+#undef insertln
+#define insertln UNDEF(insertln)
+#endif
+
+#ifdef leaveok
+inline int UNDEF(leaveok)(WINDOW* win, bool bf) { return leaveok(win, bf); }
+#undef leaveok
+#define leaveok UNDEF(leaveok)
+#else
+extern "C" int leaveok(WINDOW* win, bool bf);
+#endif
+
+#ifdef move
+inline int UNDEF(move)(int x, int y) { return move(x, y); }
+#undef move
+#define move UNDEF(move)
+#endif
+
+#ifdef refresh
+inline int UNDEF(refresh)() { return refresh(); }
+#undef refresh
+#define refresh UNDEF(refresh)
+#endif
+
+#ifdef redrawwin
+inline int UNDEF(redrawwin)(WINDOW *win) { return redrawwin(win); }
+#undef redrawwin
+#define redrawwin UNDEF(redrawwin)
+#endif
+
+#ifdef scrl
+inline int UNDEF(scrl)(int l) { return scrl(l); }
+#undef scrl
+#define scrl UNDEF(scrl)
+#endif
+
+#ifdef scroll
+inline int UNDEF(scroll)(WINDOW *win) { return scroll(win); }
+#undef scroll
+#define scroll UNDEF(scroll)
+#endif
+
+#ifdef scrollok
+inline int UNDEF(scrollok)(WINDOW* win, bool bf) { return scrollok(win, bf); }
+#undef scrollok
+#define scrollok UNDEF(scrollok)
+#else
+#if defined(__NCURSES_H)
+extern "C" int scrollok(WINDOW*, bool);
+#else
+extern "C" int scrollok(WINDOW*, char);
+#endif
+#endif
+
+#ifdef setscrreg
+inline int UNDEF(setscrreg)(int t, int b) { return setscrreg(t, b); }
+#undef setscrreg
+#define setscrreg UNDEF(setscrreg)
+#endif
+
+#ifdef standend
+inline int UNDEF(standend)() { return standend(); }
+#undef standend
+#define standend UNDEF(standend)
+#endif
+
+#ifdef standout
+inline int UNDEF(standout)() { return standout(); }
+#undef standout
+#define standout UNDEF(standout)
+#endif
+
+#ifdef subpad
+inline WINDOW *UNDEF(subpad)(WINDOW *p, int l, int c, int y, int x)
+{ return derwin(p,l,c,y,x); }
+#undef subpad
+#define subpad UNDEF(subpad)
+#endif
+
+#ifdef timeout
+inline void UNDEF(timeout)(int delay) { timeout(delay); }
+#undef timeout
+#define timeout UNDEF(timeout)
+#endif
+
+#ifdef touchline
+inline int UNDEF(touchline)(WINDOW *win, int s, int c)
+{ return touchline(win,s,c); }
+#undef touchline
+#define touchline UNDEF(touchline)
+#endif
+
+#ifdef touchwin
+inline int UNDEF(touchwin)(WINDOW *win) { return touchwin(win); }
+#undef touchwin
+#define touchwin UNDEF(touchwin)
+#endif
+
+#ifdef untouchwin
+inline int UNDEF(untouchwin)(WINDOW *win) { return untouchwin(win); }
+#undef untouchwin
+#define untouchwin UNDEF(untouchwin)
+#endif
+
+#ifdef vline
+inline int UNDEF(vline)(chtype ch, int n) { return vline(ch, n); }
+#undef vline
+#define vline UNDEF(vline)
+#endif
+
+#ifdef waddstr
+inline int UNDEF(waddstr)(WINDOW *win, char *str) { return waddstr(win, str); }
+#undef waddstr
+#define waddstr UNDEF(waddstr)
+#endif
+
+#ifdef waddchstr
+inline int UNDEF(waddchstr)(WINDOW *win, chtype *at) { return waddchstr(win, at); }
+#undef waddchstr
+#define waddchstr UNDEF(waddchstr)
+#endif
+
+#ifdef wstandend
+inline int UNDEF(wstandend)(WINDOW *win) { return wstandend(win); }
+#undef wstandend
+#define wstandend UNDEF(wstandend)
+#endif
+
+#ifdef wstandout
+inline int UNDEF(wstandout)(WINDOW *win) { return wstandout(win); }
+#undef wstandout
+#define wstandout UNDEF(wstandout)
+#endif
+
+
+#ifdef wattroff
+inline int UNDEF(wattroff)(WINDOW *win, int att) { return wattroff(win, att); }
+#undef wattroff
+#define wattroff UNDEF(wattroff)
+#endif
+
+#ifdef chgat
+inline int UNDEF(chgat)(int n,attr_t attr, short color, const void *opts) {
+ return chgat(n,attr,color,opts); }
+#undef chgat
+#define chgat UNDEF(chgat)
+#endif
+
+#ifdef mvchgat
+inline int UNDEF(mvchgat)(int y, int x, int n,
+ attr_t attr, short color, const void *opts) {
+ return mvchgat(y,x,n,attr,color,opts); }
+#undef mvchgat
+#define mvchgat UNDEF(mvchgat)
+#endif
+
+#ifdef mvwchgat
+inline int UNDEF(mvwchgat)(WINDOW *win, int y, int x, int n,
+ attr_t attr, short color, const void *opts) {
+ return mvwchgat(win,y,x,n,attr,color,opts); }
+#undef mvwchgat
+#define mvwchgat UNDEF(mvwchgat)
+#endif
+
+#ifdef wattrset
+inline int UNDEF(wattrset)(WINDOW *win, int att) { return wattrset(win, att); }
+#undef wattrset
+#define wattrset UNDEF(wattrset)
+#endif
+
+#ifdef winch
+inline chtype UNDEF(winch)(const WINDOW* win) { return winch(win); }
+#undef winch
+#define winch UNDEF(winch)
+#endif
+
+#ifdef mvwaddch
+inline int UNDEF(mvwaddch)(WINDOW *win, int y, int x, const chtype ch)
+{ return mvwaddch(win, y, x, ch); }
+#undef mvwaddch
+#define mvwaddch UNDEF(mvwaddch)
+#endif
+
+#ifdef mvwaddchnstr
+inline int UNDEF(mvwaddchnstr)(WINDOW *win, int y, int x, chtype *str, int n)
+{ return mvwaddchnstr(win, y, x, str, n); }
+#undef mvwaddchnstr
+#define mvwaddchnstr UNDEF(mvwaddchnstr)
+#endif
+
+#ifdef mvwaddchstr
+inline int UNDEF(mvwaddchstr)(WINDOW *win, int y, int x, chtype *str)
+{ return mvwaddchstr(win, y, x, str); }
+#undef mvwaddchstr
+#define mvwaddchstr UNDEF(mvwaddchstr)
+#endif
+
+#ifdef addnstr
+inline int UNDEF(addnstr)(const char *str, int n)
+{ return addnstr((char*)str, n); }
+#undef addnstr
+#define addnstr UNDEF(addnstr)
+#endif
+
+#ifdef mvwaddnstr
+inline int UNDEF(mvwaddnstr)(WINDOW *win, int y, int x, const char *str, int n)
+{ return mvwaddnstr(win, y, x, (char*)str, n); }
+#undef mvwaddnstr
+#define mvwaddnstr UNDEF(mvwaddnstr)
+#endif
+
+#ifdef mvwaddstr
+inline int UNDEF(mvwaddstr)(WINDOW *win, int y, int x, const char * str)
+{ return mvwaddstr(win, y, x, (char*)str); }
+#undef mvwaddstr
+#define mvwaddstr UNDEF(mvwaddstr)
+#endif
+
+#ifdef mvwdelch
+inline int UNDEF(mvwdelch)(WINDOW *win, int y, int x)
+{ return mvwdelch(win, y, x); }
+#undef mvwdelch
+#define mvwdelch UNDEF(mvwdelch)
+#endif
+
+#ifdef mvwgetch
+inline int UNDEF(mvwgetch)(WINDOW *win, int y, int x) { return mvwgetch(win, y, x);}
+#undef mvwgetch
+#define mvwgetch UNDEF(mvwgetch)
+#endif
+
+#ifdef mvwgetstr
+inline int UNDEF(mvwgetstr)(WINDOW *win, int y, int x, char *str)
+{return mvwgetstr(win,y,x, str);}
+#undef mvwgetstr
+#define mvwgetstr UNDEF(mvwgetstr)
+#endif
+
+#ifdef mvwgetnstr
+inline int UNDEF(mvwgetnstr)(WINDOW *win, int y, int x, char *str, int n)
+{return mvwgetnstr(win,y,x, str,n);}
+#undef mvwgetnstr
+#define mvwgetnstr UNDEF(mvwgetnstr)
+#endif
+
+#ifdef mvwinch
+inline chtype UNDEF(mvwinch)(WINDOW *win, int y, int x) {
+ return mvwinch(win, y, x);}
+#undef mvwinch
+#define mvwinch UNDEF(mvwinch)
+#endif
+
+#ifdef mvwinsch
+inline int UNDEF(mvwinsch)(WINDOW *win, int y, int x, char c)
+{ return mvwinsch(win, y, x, c); }
+#undef mvwinsch
+#define mvwinsch UNDEF(mvwinsch)
+#endif
+
+#ifdef mvaddch
+inline int UNDEF(mvaddch)(int y, int x, chtype ch)
+{ return mvaddch(y, x, ch); }
+#undef mvaddch
+#define mvaddch UNDEF(mvaddch)
+#endif
+
+#ifdef mvaddnstr
+inline int UNDEF(mvaddnstr)(int y, int x, const char *str, int n)
+{ return mvaddnstr(y, x, (char*)str, n); }
+#undef mvaddnstr
+#define mvaddnstr UNDEF(mvaddnstr)
+#endif
+
+#ifdef mvaddstr
+inline int UNDEF(mvaddstr)(int y, int x, const char * str)
+{ return mvaddstr(y, x, (char*)str); }
+#undef mvaddstr
+#define mvaddstr UNDEF(mvaddstr)
+#endif
+
+#ifdef mvdelch
+inline int UNDEF(mvdelch)(int y, int x) { return mvdelch(y, x);}
+#undef mvdelch
+#define mvdelch UNDEF(mvdelch)
+#endif
+
+#ifdef mvgetch
+inline int UNDEF(mvgetch)(int y, int x) { return mvgetch(y, x);}
+#undef mvgetch
+#define mvgetch UNDEF(mvgetch)
+#endif
+
+#ifdef mvgetstr
+inline int UNDEF(mvgetstr)(int y, int x, char *str) {return mvgetstr(y, x, str);}
+#undef mvgetstr
+#define mvgetstr UNDEF(mvgetstr)
+#endif
+
+#ifdef mvgetnstr
+inline int UNDEF(mvgetnstr)(int y, int x, char *str, int n) {
+ return mvgetnstr(y, x, str,n);}
+#undef mvgetnstr
+#define mvgetnstr UNDEF(mvgetnstr)
+#endif
+
+#ifdef mvinch
+inline chtype UNDEF(mvinch)(int y, int x) { return mvinch(y, x);}
+#undef mvinch
+#define mvinch UNDEF(mvinch)
+#endif
+
+#ifdef mvinsch
+inline int UNDEF(mvinsch)(int y, int x, char c)
+{ return mvinsch(y, x, c); }
+#undef mvinsch
+#define mvinsch UNDEF(mvinsch)
+#endif
+
+#ifdef napms
+inline void UNDEF(napms)(unsigned long x) { napms(x); }
+#undef napms
+#define napms UNDEF(napms)
+#endif
+
+#ifdef fixterm
+inline int UNDEF(fixterm)(void) { return fixterm(); }
+#undef fixterm
+#define fixterm UNDEF(fixterm)
+#endif
+
+#ifdef resetterm
+inline int UNDEF(resetterm)(void) { return resetterm(); }
+#undef resetterm
+#define resetterm UNDEF(resetterm)
+#endif
+
+#ifdef saveterm
+inline int UNDEF(saveterm)(void) { return saveterm(); }
+#undef saveterm
+#define saveterm UNDEF(saveterm)
+#endif
+
+#ifdef crmode
+inline int UNDEF(crmode)(void) { return crmode(); }
+#undef crmode
+#define crmode UNDEF(crmode)
+#endif
+
+#ifdef nocrmode
+inline int UNDEF(nocrmode)(void) { return nocrmode(); }
+#undef nocrmode
+#define nocrmode UNDEF(nocrmode)
+#endif
+
+#ifdef getbkgd
+inline chtype UNDEF(getbkgd)(const WINDOW *win) { return getbkgd(win); }
+#undef getbkgd
+#define getbkgd UNDEF(getbkgd)
+#endif
+
+#ifdef bkgd
+inline int UNDEF(bkgd)(chtype ch) { return bkgd(ch); }
+#undef bkgd
+#define bkgd UNDEF(bkgd)
+#endif
+
+#ifdef bkgdset
+inline void UNDEF(bkgdset)(chtype ch) { bkgdset(ch); }
+#undef bkgdset
+#define bkgdset UNDEF(bkgdset)
+#endif
+
+/*
+ *
+ * C++ class for windows.
+ *
+ *
+ */
+
+class NCursesWindow
+{
+ friend class NCursesMenu;
+ friend class NCursesForm;
+
+private:
+ static bool b_initialized;
+ static void initialize();
+ static int ripoff_init(WINDOW *,int);
+
+ void init();
+
+ short getcolor(int getback) const;
+
+ static int setpalette(short fore, short back, short pair);
+ static int colorInitialized;
+
+ // This private constructor is only used during the initialization
+ // of windows generated by ripoffline() calls.
+ NCursesWindow(WINDOW* win, int cols);
+
+protected:
+ void err_handler(const char *) const THROWS(NCursesException);
+ // Signal an error with the given message text.
+
+ static long count; // count of all active windows:
+ // We rely on the c++ promise that
+ // all otherwise uninitialized
+ // static class vars are set to 0
+
+ WINDOW* w; // the curses WINDOW
+
+ bool alloced; // TRUE if we own the WINDOW
+
+ NCursesWindow* par; // parent, if subwindow
+ NCursesWindow* subwins; // head of subwindows list
+ NCursesWindow* sib; // next subwindow of parent
+
+ void kill_subwindows(); // disable all subwindows
+ // Destroy all subwindows.
+
+ /* Only for use by derived classes. They are then in charge to
+ fill the member variables correctly. */
+ NCursesWindow();
+
+public:
+ NCursesWindow(WINDOW* &window); // useful only for stdscr
+
+ NCursesWindow(int lines, // number of lines
+ int cols, // number of columns
+ int begin_y, // line origin
+ int begin_x); // col origin
+
+ NCursesWindow(NCursesWindow& par,// parent window
+ int lines, // number of lines
+ int cols, // number of columns
+ int begin_y, // absolute or relative
+ int begin_x, // origins:
+ char absrel = 'a');// if `a', by & bx are
+ // absolute screen pos, else if `r', they are relative to par origin
+
+ virtual ~NCursesWindow();
+
+ NCursesWindow Clone();
+ // Make an exact copy of the window.
+
+ // Initialization.
+ static void useColors(void);
+ // Call this routine very early if you want to have colors.
+
+ static int ripoffline(int ripoff_lines,
+ int (*init)(NCursesWindow& win));
+ // This function is used to generate a window of ripped-of lines.
+ // If the argument is positive, lines are removed from the top, if it
+ // is negative lines are removed from the bottom. This enhances the
+ // lowlevel ripoffline() function because it uses the internal
+ // implementation that allows to remove more than just a single line.
+ // This function must be called before any other ncurses function. The
+ // creation of the window is defered until ncurses gets initialized.
+ // The initialization function is then called.
+
+ // -------------------------------------------------------------------------
+ // terminal status
+ // -------------------------------------------------------------------------
+ int lines() const { return LINES; }
+ // Number of lines on terminal, *not* window
+
+ int cols() const { return COLS; }
+ // Number of cols on terminal, *not* window
+
+ int tabsize() const { return TABSIZE; }
+ // Size of a tab on terminal, *not* window
+
+ static int NumberOfColors();
+ // Number of available colors
+
+ int colors() const { return NumberOfColors(); }
+ // Number of available colors
+
+ // -------------------------------------------------------------------------
+ // window status
+ // -------------------------------------------------------------------------
+ int height() const { return maxy() + 1; }
+ // Number of lines in this window
+
+ int width() const { return maxx() + 1; }
+ // Number of columns in this window
+
+ int begx() const { return w->_begx; }
+ // Column of top left corner relative to stdscr
+
+ int begy() const { return w->_begy; }
+ // Line of top left corner relative to stdscr
+
+ int maxx() const { return w->_maxx; }
+ // Largest x coord in window
+
+ int maxy() const { return w->_maxy; }
+ // Largest y coord in window
+
+ short getcolor() const;
+ // Actual color pair
+
+ short foreground() const { return getcolor(0); }
+ // Actual foreground color
+
+ short background() const { return getcolor(1); }
+ // Actual background color
+
+ int setpalette(short fore, short back);
+ // Set color palette entry
+
+ int setcolor(short pair);
+ // Set actually used palette entry
+
+ // -------------------------------------------------------------------------
+ // window positioning
+ // -------------------------------------------------------------------------
+ virtual int mvwin(int begin_y, int begin_x) {
+ return ::mvwin(w,begin_y,begin_x); }
+ // Move window to new position with the new position as top left corner.
+ // This is virtual because it is redefined in NCursesPanel.
+
+ // -------------------------------------------------------------------------
+ // coordinate positioning
+ // -------------------------------------------------------------------------
+ int move(int y, int x) { return ::wmove(w, y, x); }
+ // Move cursor the this position
+
+ void getyx(int& y, int& x) const { ::getyx(w, y, x); }
+ // Get current position of the cursor
+
+ int mvcur(int oldrow, int oldcol, int newrow, int newcol) const {
+ return ::mvcur(oldrow, oldcol, newrow, newcol); }
+ // Perform lowlevel cursor motion that takes effect immediately.
+
+ // -------------------------------------------------------------------------
+ // input
+ // -------------------------------------------------------------------------
+ int getch() { return ::wgetch(w); }
+ // Get a keystroke from the window.
+
+ int getch(int y, int x) { return ::mvwgetch(w,y,x); }
+ // Move cursor to position and get a keystroke from the window
+
+ int getstr(char* str, int n=-1) {
+ return ::wgetnstr(w, str,n); }
+ // Read a series of characters into str until a newline or carriage return
+ // is received. Read at most n characters. If n is negative, the limit is
+ // ignored.
+
+ int getstr(int y, int x, char* str, int n=-1) {
+ return ::mvwgetnstr(w,y,x,str,n); }
+ // Move the cursor to the requested position and then perform the getstr()
+ // as described above.
+
+ int instr(char *s, int n=-1) { return ::winnstr(w,s,n); }
+ // Get a string of characters from the window into the buffer s. Retrieve
+ // at most n characters, if n is negative retrieve all characters up to the
+ // end of the current line. Attributes are stripped from the characters.
+
+ int instr(int y, int x, char *s, int n=-1) {
+ return ::mvwinnstr(w,y,x,s,n); }
+ // Move the cursor to the requested position and then perform the instr()
+ // as described above.
+
+ int scanw(const char* fmt, ...)
+ // Perform a scanw function from the window. This only works if you're
+ // using the GNU C++ compiler.
+#if __GNUG__ >= 2
+ __attribute__ ((format (scanf, 2, 3)));
+#else
+ ;
+#endif
+
+ int scanw(int y, int x, const char* fmt, ...)
+ // Move the cursor to the requested position and then perform a scanw
+ // from the window. This nly works if you're using the GNU C++ compiler.
+#if __GNUG__ >= 2
+ __attribute__ ((format (scanf, 4, 5)));
+#else
+ ;
+#endif
+
+ // -------------------------------------------------------------------------
+ // output
+ // -------------------------------------------------------------------------
+ int addch(const chtype ch) { return ::waddch(w, ch); }
+ // Put attributed character to the window.
+
+ int addch(int y, int x, const chtype ch) {
+ return ::mvwaddch(w,y,x,ch); }
+ // Move cursor to the requested position and then put attributed character
+ // to the window.
+
+ int echochar(const chtype ch) { return ::wechochar(w,ch); }
+ // Put attributed character to the window and refresh it immediately.
+
+ int addstr(const char* str, int n=-1) {
+ return ::waddnstr(w, (char*)str,n); }
+ // Write the string str to the window, stop writing if the terminating
+ // NUL or the limit n is reached. If n is negative, it is ignored.
+
+ int addstr(int y, int x, const char * str, int n=-1) {
+ return ::mvwaddnstr(w,y,x,(char*)str,n); }
+ // Move the cursor to the requested position and then perform the addstr
+ // as described above.
+
+ int printw(const char* fmt, ...)
+ // Do a formatted print to the window.
+#if __GNUG__ >= 2
+ __attribute__ ((format (printf, 2, 3)));
+#else
+ ;
+#endif
+
+ int printw(int y, int x, const char * fmt, ...)
+ // Move the cursor and then do a formatted print to the window.
+#if __GNUG__ >= 2
+ __attribute__ ((format (printf, 4, 5)));
+#else
+ ;
+#endif
+
+ chtype inch() const { return ::winch(w); }
+ // Retrieve attributed character under the current cursor position.
+
+ chtype inch(int y, int x) { return ::mvwinch(w,y,x); }
+ // Move cursor to requested position and then retrieve attributed character
+ // at this position.
+
+ int insch(chtype ch) { return ::winsch(w, ch); }
+ // Insert attributed character into the window before current cursor
+ // position.
+
+ int insch(int y, int x, chtype ch) {
+ return ::mvwinsch(w,y,x,ch); }
+ // Move cursor to requested position and then insert the attributed
+ // character before that position.
+
+ int insertln() { return ::winsdelln(w,1); }
+ // Insert an empty line above the current line.
+
+ int insdelln(int n=1) { return ::winsdelln(w,n); }
+ // If n>0 insert that many lines above the current line. If n<0 delete
+ // that many lines beginning with the current line.
+
+ int insstr(const char *s, int n=-1) {
+ return ::winsnstr(w,s,n); }
+ // Insert the string into the window before the current cursor position.
+ // Insert stops at end of string or when the limit n is reached. If n is
+ // negative, it is ignored.
+
+ int insstr(int y, int x, const char *s, int n=-1) {
+ return ::mvwinsnstr(w,y,x,s,n); }
+ // Move the cursor to the requested position and then perform the insstr()
+ // as described above.
+
+ int attron (chtype at) { return ::wattron (w, at); }
+ // Switch on the window attributes;
+
+ int attroff(chtype at) { return ::wattroff(w, at); }
+ // Switch off the window attributes;
+
+ int attrset(chtype at) { return ::wattrset(w, at); }
+ // Set the window attributes;
+
+ int color_set(short color_pair_number, void* opts=NULL) {
+ return ::wcolor_set(w, color_pair_number, opts); }
+ // Set the window color attribute;
+
+ int chgat(int n,attr_t attr, short color, const void *opts=NULL) {
+ return ::wchgat(w,n,attr,color,opts); }
+ // Change the attributes of the next n characters in the current line. If
+ // n is negative or greater than the number of remaining characters in the
+ // line, the attributes will be changed up to the end of the line.
+
+ int chgat(int y, int x,
+ int n,attr_t attr, short color, const void *opts=NULL) {
+ return ::mvwchgat(w,y,x,n,attr,color,opts); }
+ // Move the cursor to the requested position and then perform chgat() as
+ // described above.
+
+ // -------------------------------------------------------------------------
+ // background
+ // -------------------------------------------------------------------------
+ chtype getbkgd() const { return ::getbkgd(w); }
+ // Get current background setting.
+
+ int bkgd(const chtype ch) { return ::wbkgd(w,ch); }
+ // Set the background property and apply it to the window.
+
+ void bkgdset(chtype ch) { ::wbkgdset(w,ch); }
+ // Set the background property.
+
+ // -------------------------------------------------------------------------
+ // borders
+ // -------------------------------------------------------------------------
+ int box(chtype vert=0, chtype hor=0) {
+ return ::wborder(w, vert, vert, hor, hor, 0, 0 ,0, 0); }
+ // Draw a box around the window with the given vertical and horizontal
+ // drawing characters. If you specifiy a zero as character, curses will try
+ // to find a "nice" character.
+
+ int border(chtype left=0, chtype right=0,
+ chtype top =0, chtype bottom=0,
+ chtype top_left =0, chtype top_right=0,
+ chtype bottom_left =0, chtype bottom_right=0) {
+ return ::wborder(w,left,right,top,bottom,top_left,top_right,
+ bottom_left,bottom_right); }
+ // Draw a border around the window with the given characters for the
+ // various parts of the border. If you pass zero for a character, curses
+ // will try to find "nice" characters.
+
+ // -------------------------------------------------------------------------
+ // lines and boxes
+ // -------------------------------------------------------------------------
+ int hline(int len, chtype ch=0) { return ::whline(w, ch, len); }
+ // Draw a horizontal line of len characters with the given character. If
+ // you pass zero for the character, curses will try to find a "nice" one.
+
+ int hline(int y, int x, int len, chtype ch=0) {
+ return ::mvwhline(w,y,x,ch,len); }
+ // Move the cursor to the requested position and then draw a horizontal line.
+
+ int vline(int len, chtype ch=0) { return ::wvline(w, ch, len); }
+ // Draw a vertical line of len characters with the given character. If
+ // you pass zero for the character, curses will try to find a "nice" one.
+
+ int vline(int y, int x, int len, chtype ch=0) {
+ return ::mvwvline(w,y,x,ch,len); }
+ // Move the cursor to the requested position and then draw a vertical line.
+
+ // -------------------------------------------------------------------------
+ // erasure
+ // -------------------------------------------------------------------------
+ int erase() { return ::werase(w); }
+ // Erase the window.
+
+ int clear() { return ::wclear(w); }
+ // Clear the window.
+
+ int clearok(bool bf) { return ::clearok(w, bf); }
+ // Set/Reset the clear flag. If set, the next refresh() will clear the
+ // screen.
+
+ int clrtobot() { return ::wclrtobot(w); }
+ // Clear to the end of the window.
+
+ int clrtoeol() { return ::wclrtoeol(w); }
+ // Clear to the end of the line.
+
+ int delch() { return ::wdelch(w); }
+ // Delete character under the cursor.
+
+ int delch(int y, int x) { return ::mvwdelch(w,y,x); }
+ // Move cursor to requested position and delete the character under the
+ // cursor.
+
+ int deleteln() { return ::winsdelln(w,-1); }
+ // Delete the current line.
+
+ // -------------------------------------------------------------------------
+ // screen control
+ // -------------------------------------------------------------------------
+ int scroll(int amount=1) { return ::wscrl(w,amount); }
+ // Scroll amount lines. If amount is positive, scroll up, otherwise
+ // scroll down.
+
+ int scrollok(bool bf) { return ::scrollok(w, bf); }
+ // If bf is TRUE, window scrolls if cursor is moved off the bottom
+ // edge of the window or a scrolling region, otherwise the cursor is left
+ // at the bottom line.
+
+ int setscrreg(int from, int to) {
+ return ::wsetscrreg(w,from,to); }
+ // Define a soft scrolling region.
+
+ int idlok(bool bf) { return ::idlok(w, bf); }
+ // If bf is TRUE, use insert/delete line hardware support if possible.
+ // Otherwise do it in software.
+
+
+ void idcok(bool bf) { ::idcok(w, bf); }
+ // If bf is TRUE, use insert/delete character hardware support if possible.
+ // Otherwise do it in software.
+
+ int touchwin() { return ::wtouchln(w,0,height(),1); }
+ // Mark the whole window as modified.
+
+ int untouchwin() { return ::wtouchln(w,0,height(),0); }
+ // Mark the whole window as unmodified.
+
+ int touchln(int s, int cnt, bool changed=TRUE) {
+ return ::wtouchln(w,s,cnt,(int)(changed?1:0)); }
+ // Mark cnt lines beginning from line s as changed or unchanged, depending
+ // on the value of the changed flag.
+
+ bool is_linetouched(int line) const {
+ return (::is_linetouched(w,line) ? TRUE:FALSE); }
+ // Return TRUE if line is marked as changed, FALSE otherwise
+
+ bool is_wintouched() const {
+ return (::is_wintouched(w) ? TRUE:FALSE); }
+ // Return TRUE if window is marked as changed, FALSE otherwise
+
+ int leaveok(bool bf) { return ::leaveok(w, bf); }
+ // If bf is TRUE, curses will leave the cursor after an update whereever
+ // it is after the update.
+
+ int redrawln(int from, int n) { return ::wredrawln(w,from,n); }
+ // Redraw n lines starting from the requested line
+
+ int redrawwin() { return ::wredrawln(w,0,height()); }
+ // Redraw the whole window
+
+ int doupdate() { return ::doupdate(); }
+ // Do all outputs to make the physical screen looking like the virtual one
+
+ void syncdown() { ::wsyncdown(w); }
+ // Propagate the changes down to all descendant windows
+
+ void syncup() { ::wsyncup(w); }
+ // Propagate the changes up in the hierarchy
+
+ void cursyncup() { ::wcursyncup(w); }
+ // Position the cursor in all ancestor windows corresponding to our setting
+
+ int syncok(bool bf) { return ::syncok(w,bf); }
+ // If called with bf=TRUE, syncup() is called whenever the window is changed
+
+#ifndef _no_flushok
+ int flushok(bool bf) { return ::flushok(w, bf); }
+#endif
+
+ void immedok(bool bf) { ::immedok(w,bf); }
+ // If called with bf=TRUE, any change in the window will cause an
+ // automatic immediate refresh()
+
+ int keypad(bool bf) { return ::keypad(w, bf); }
+ // If called with bf=TRUE, the application will interpret function keys.
+
+ int meta(bool bf) { return ::meta(w,bf); }
+ // If called with bf=TRUE, keys may generate 8-Bit characters. Otherwise
+ // 7-Bit characters are generated.
+
+ int standout() { return ::wstandout(w); }
+ // Enable "standout" attributes
+
+ int standend() { return ::wstandend(w); }
+ // Disable "standout" attributes
+
+ // -------------------------------------------------------------------------
+ // The next two are virtual, because we redefine them in the
+ // NCursesPanel class.
+ // -------------------------------------------------------------------------
+ virtual int refresh() { return ::wrefresh(w); }
+ // Propagate the changes in this window to the virtual screen and call
+ // doupdate(). This is redefined in NCursesPanel.
+
+ virtual int noutrefresh() { return ::wnoutrefresh(w); }
+ // Propagate the changes in this window to the virtual screen. This is
+ // redefined in NCursesPanel.
+
+ // -------------------------------------------------------------------------
+ // multiple window control
+ // -------------------------------------------------------------------------
+ int overlay(NCursesWindow& win) {
+ return ::overlay(w, win.w); }
+ // Overlay this window over win.
+
+ int overwrite(NCursesWindow& win) {
+ return ::overwrite(w, win.w); }
+ // Overwrite win with this window.
+
+ int copywin(NCursesWindow& win,
+ int sminrow, int smincol,
+ int dminrow, int dmincol,
+ int dmaxrow, int dmaxcol, bool overlay=TRUE) {
+ return ::copywin(w,win.w,sminrow,smincol,dminrow,dmincol,
+ dmaxrow,dmaxcol,(int)(overlay?1:0)); }
+ // Overlay or overwrite the rectangle in win given by dminrow,dmincol,
+ // dmaxrow,dmaxcol with the rectangle in this window beginning at
+ // sminrow,smincol.
+
+ // -------------------------------------------------------------------------
+ // Mouse related
+ // -------------------------------------------------------------------------
+ bool has_mouse() const;
+ // Return TRUE if terminal supports a mouse, FALSE otherwise
+
+ // -------------------------------------------------------------------------
+ // traversal support
+ // -------------------------------------------------------------------------
+ NCursesWindow* child() { return subwins; }
+ // Get the first child window.
+
+ NCursesWindow* sibling() { return sib; }
+ // Get the next child of my parent.
+
+ NCursesWindow* parent() { return par; }
+ // Get my parent.
+
+ bool isDescendant(NCursesWindow& win);
+ // Return TRUE if win is a descendant of this.
+};
+
+// -------------------------------------------------------------------------
+// We leave this here for compatibility reasons.
+// -------------------------------------------------------------------------
+class NCursesColorWindow : public NCursesWindow {
+public:
+ NCursesColorWindow(WINDOW* &window) // useful only for stdscr
+ : NCursesWindow(window) {
+ useColors(); }
+
+ NCursesColorWindow(int lines, // number of lines
+ int cols, // number of columns
+ int begin_y, // line origin
+ int begin_x) // col origin
+ : NCursesWindow(lines,cols,begin_y,begin_x) {
+ useColors(); }
+
+ NCursesColorWindow(NCursesWindow& par,// parent window
+ int lines, // number of lines
+ int cols, // number of columns
+ int begin_y, // absolute or relative
+ int begin_x, // origins:
+ char absrel = 'a') // if `a', by & bx are
+ : NCursesWindow(par,lines,cols, // absolute screen pos,
+ begin_y,begin_x, // else if `r', they are
+ absrel ) { // relative to par origin
+ useColors(); }
+};
+
+class NCursesPad : public NCursesWindow {
+public:
+ NCursesPad(int lines, int cols);
+
+ int echochar(const chtype ch) { return ::pechochar(w,ch); }
+ // Put the attributed character onto the pad and immediately do a
+ // prefresh().
+
+ // For Pad's we reimplement refresh() and noutrefresh() to do nothing.
+ // You should call the versions with the argument list that are specific
+ // for Pad's.
+ int refresh() { return OK; };
+ int noutrefresh() { return OK; };
+
+ int refresh(int pminrow, int pmincol,
+ int sminrow, int smincol,
+ int smaxrow, int smaxcol) {
+ return ::prefresh(w,pminrow,pmincol,
+ sminrow,smincol,smaxrow,smaxcol);
+ }
+ // The coordinates sminrow,smincol,smaxrow,smaxcol describe a rectangle
+ // on the screen. <b>refresh</b> copies a rectangle of this size beginning
+ // with top left corner pminrow,pmincol onto the screen and calls doupdate().
+
+ int noutrefresh(int pminrow, int pmincol,
+ int sminrow, int smincol,
+ int smaxrow, int smaxcol) {
+ return ::pnoutrefresh(w,pminrow,pmincol,
+ sminrow,smincol,smaxrow,smaxcol);
+ }
+ // Does the same like refresh() but without calling doupdate().
+};
+
+#endif // _CURSESW_H
diff --git a/lib/libcurses++/cursslk.cc b/lib/libcurses++/cursslk.cc
new file mode 100644
index 00000000000..384d7e06ce0
--- /dev/null
+++ b/lib/libcurses++/cursslk.cc
@@ -0,0 +1,121 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+#include "cursslk.h"
+#include "cursesapp.h"
+#include "internal.h"
+
+MODULE_ID("$Id: cursslk.cc,v 1.1 1999/05/09 00:21:15 millert Exp $")
+
+void Soft_Label_Key_Set::Soft_Label_Key::operator=(char *text) {
+ delete[] label;
+ label = new char[1 + ::strlen(text)];
+ (strcpy)(label,text);
+}
+
+long Soft_Label_Key_Set::count = 0L;
+int Soft_Label_Key_Set::num_labels = 0;
+
+Soft_Label_Key_Set::Label_Layout
+ Soft_Label_Key_Set::format = None;
+
+void Soft_Label_Key_Set::init() {
+ slk_array = new Soft_Label_Key[num_labels];
+ for(int i=0; i < num_labels; i++) {
+ slk_array[i].num = i+1;
+ }
+ b_attrInit = FALSE;
+}
+
+Soft_Label_Key_Set::Soft_Label_Key_Set() {
+ if (format==None)
+ Error("No default SLK layout");
+ init();
+}
+
+Soft_Label_Key_Set::Soft_Label_Key_Set(Soft_Label_Key_Set::Label_Layout fmt) {
+ if (fmt==None)
+ Error("Invalid SLK Layout");
+ if (count++==0) {
+ format = fmt;
+ if (ERR == ::slk_init((int)fmt))
+ Error("slk_init");
+ num_labels = (fmt>=PC_Style?12:8);
+ }
+ else if (fmt!=format)
+ Error("All SLKs must have same layout");
+ init();
+}
+
+Soft_Label_Key_Set::~Soft_Label_Key_Set() {
+ if (!::isendwin())
+ clear();
+ delete[] slk_array;
+ count--;
+}
+
+Soft_Label_Key_Set::Soft_Label_Key& Soft_Label_Key_Set::operator[](int i) {
+ if (i<1 || i>num_labels)
+ Error("Invalid Label index");
+ return slk_array[i-1];
+}
+
+void Soft_Label_Key_Set::activate_label(int i, bool bf) {
+ if (!b_attrInit) {
+ NCursesApplication* A = NCursesApplication::getApplication();
+ if (A) attrset(A->labels());
+ b_attrInit = TRUE;
+ }
+ Soft_Label_Key& K = (*this)[i];
+ if (ERR==::slk_set(K.num,bf?K.label:"",K.format))
+ Error("slk_set");
+ noutrefresh();
+}
+
+void Soft_Label_Key_Set::activate_labels(bool bf) {
+ if (!b_attrInit) {
+ NCursesApplication* A = NCursesApplication::getApplication();
+ if (A) attrset(A->labels());
+ b_attrInit = TRUE;
+ }
+ for(int i=1; i <= num_labels; i++) {
+ Soft_Label_Key& K = (*this)[i];
+ if (ERR==::slk_set(K.num,bf?K.label:"",K.format))
+ Error("slk_set");
+ }
+ if (bf)
+ restore();
+ else
+ clear();
+ noutrefresh();
+}
diff --git a/lib/libcurses++/cursslk.h b/lib/libcurses++/cursslk.h
new file mode 100644
index 00000000000..3f789bb39c8
--- /dev/null
+++ b/lib/libcurses++/cursslk.h
@@ -0,0 +1,205 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+// $Id: cursslk.h,v 1.1 1999/05/09 00:21:15 millert Exp $
+
+#ifndef _CURSSLK_H
+#define _CURSSLK_H
+
+#include <cursesw.h>
+
+class Soft_Label_Key_Set {
+public:
+ // This inner class represents the attributes of a Soft Label Key (SLK)
+ class Soft_Label_Key {
+ friend class Soft_Label_Key_Set;
+ public:
+ typedef enum { Left=0, Center=1, Right=2 } Justification;
+
+ private:
+ char *label; // The Text of the Label
+ Justification format; // The Justification
+ int num; // The number of the Label
+
+ Soft_Label_Key() : label((char*)0),format(Left),num(-1) {
+ }
+
+ virtual ~Soft_Label_Key() {
+ delete[] label;
+ };
+
+ public:
+ // Set the text of the Label
+ void operator=(char *text);
+
+ // Set the Justification of the Label
+ inline void operator=(Justification just) {
+ format = just;
+ }
+
+ // Retrieve the text of the label
+ inline char* operator()(void) const {
+ return label;
+ }
+ };
+
+public:
+ typedef enum {
+ None = -1,
+ Three_Two_Three = 0,
+ Four_Four = 1,
+ PC_Style = 2,
+ PC_Style_With_Index = 3
+ } Label_Layout;
+
+private:
+ static long count; // Number of Key Sets
+ static Label_Layout format; // Layout of the Key Sets
+ static int num_labels; // Number Of Labels in Key Sets
+ bool b_attrInit; // Are attributes initialized
+
+ Soft_Label_Key *slk_array; // The array of SLK's
+
+ // Init the Key Set
+ void init();
+
+ // Activate or Deactivate Label# i, Label counting starts with 1!
+ void activate_label(int i, bool bf=TRUE);
+
+ // Activate of Deactivate all Labels
+ void activate_labels(bool bf);
+
+protected:
+ inline void Error (const char* msg) const THROWS(NCursesException) {
+ THROW(new NCursesException (msg));
+ }
+
+ // Remove SLK's from screen
+ void clear() {
+ if (ERR==::slk_clear())
+ Error("slk_clear");
+ }
+
+ // Restore them
+ void restore() {
+ if (ERR==::slk_restore())
+ Error("slk_restore");
+ }
+
+public:
+
+ // Construct a Key Set, use the most comfortable layout as default.
+ // You must create a Soft_Label_Key_Set before you create any object of
+ // the NCursesWindow, NCursesPanel or derived classes. (Actually before
+ // ::initscr() is called).
+ Soft_Label_Key_Set(Label_Layout fmt);
+
+ // This constructor assumes, that you already constructed a Key Set
+ // with a layout by the constructor above. This layout will be reused.
+ Soft_Label_Key_Set();
+
+ virtual ~Soft_Label_Key_Set();
+
+ // Get Label# i. Label counting starts with 1!
+ Soft_Label_Key& operator[](int i);
+
+ // Retrieve number of Labels
+ inline int labels() const { return num_labels; }
+
+ // Refresh the SLK portion of the screen
+ inline void refresh() {
+ if (ERR==::slk_refresh())
+ Error("slk_refresh");
+ }
+
+ // Mark the SLK portion of the screen for refresh, defer actual refresh
+ // until next update call.
+ inline void noutrefresh() {
+ if (ERR==::slk_noutrefresh())
+ Error("slk_noutrefresh");
+ }
+
+ // Mark the whole SLK portion of the screen as modified
+ inline void touch() {
+ if (ERR==::slk_touch())
+ Error("slk_touch");
+ }
+
+ // Activate Label# i
+ inline void show(int i) {
+ activate_label(i,FALSE);
+ activate_label(i,TRUE);
+ }
+
+ // Hide Label# i
+ inline void hide(int i) {
+ activate_label(i,FALSE);
+ }
+
+ // Show all Labels
+ inline void show() {
+ activate_labels(FALSE);
+ activate_labels(TRUE);
+ }
+
+ // Hide all Labels
+ inline void hide() {
+ activate_labels(FALSE);
+ }
+
+ inline void attron(attr_t attrs) {
+ if (ERR==::slk_attron(attrs))
+ Error("slk_attron");
+ }
+
+ inline void attroff(attr_t attrs) {
+ if (ERR==::slk_attroff(attrs))
+ Error("slk_attroff");
+ }
+
+ inline void attrset(attr_t attrs) {
+ if (ERR==::slk_attrset(attrs))
+ Error("slk_attrset");
+ }
+
+ inline void color(short color_pair_number) {
+ if (ERR==::slk_color(color_pair_number))
+ Error("slk_color");
+ }
+
+ inline attr_t attr() const {
+ return ::slk_attr();
+ }
+};
+
+#endif // _CURSSLK_H
diff --git a/lib/libcurses++/demo.cc b/lib/libcurses++/demo.cc
new file mode 100644
index 00000000000..d529eb386d1
--- /dev/null
+++ b/lib/libcurses++/demo.cc
@@ -0,0 +1,405 @@
+/*
+ * Silly demo program for the NCursesPanel class.
+ *
+ * written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
+ *
+ * Demo code for NCursesMenu and NCursesForm written by
+ * Juergen Pfeifer <Juergen.Pfeifer@T-Online.de>
+ *
+ * $Id: demo.cc,v 1.1 1999/05/09 00:21:15 millert Exp $
+ */
+
+#include "cursesapp.h"
+#include "cursesm.h"
+#include "cursesf.h"
+
+#if HAVE_LIBC_H
+# include <libc.h>
+#endif
+
+extern "C" unsigned int sleep(unsigned int);
+
+#undef index // needed for NeXT
+
+//
+// -------------------------------------------------------------------------
+//
+class SillyDemo
+{
+ public:
+ void run(int sleeptime) {
+
+ NCursesPanel *std = new NCursesPanel();
+
+ // Make a few small demo panels
+
+ NCursesPanel *u = new NCursesPanel(8,20,12,4);
+ NCursesPanel *v = new NCursesPanel(8,20,10,6);
+ NCursesPanel *w = new NCursesPanel(8,20,8,8);
+ NCursesPanel *x = new NCursesPanel(8,20,6,10);
+ NCursesPanel *y = new NCursesPanel(8,20,4,12);
+ NCursesPanel *z = new NCursesPanel(8,30,2,14);
+
+ // Draw something on the main screen, so we can see what happens
+ // when panels get moved or deleted.
+
+ std->box();
+ std->move(std->height()/2,1);
+ std->hline(std->width()-2);
+ std->move(1,std->width()/2);
+ std->vline(std->height()-2);
+ std->addch(0,std->width()/2,ACS_TTEE);
+ std->addch(std->height()-1,std->width()/2,ACS_BTEE);
+ std->addch(std->height()/2,0,ACS_LTEE);
+ std->addch(std->height()/2,std->width()-1,ACS_RTEE);
+ std->addch(std->height()/2,std->width()/2,ACS_PLUS);
+
+ // Draw frames with titles around panels so that we can see where
+ // the panels are located.
+ u->boldframe("Win U");
+ v->frame("Win V");
+ w->boldframe("Win W");
+ x->frame("Win X");
+ y->boldframe("Win Y");
+ z->frame("Win Z");
+ if (NCursesApplication::getApplication()->useColors()) {
+ u->bkgd(' '|COLOR_PAIR(1));
+ w->bkgd(' '|COLOR_PAIR(1));
+ y->bkgd(' '|COLOR_PAIR(1));
+ v->bkgd(' '|COLOR_PAIR(2));
+ x->bkgd(' '|COLOR_PAIR(2));
+ z->bkgd(' '|COLOR_PAIR(2));
+ }
+
+ // A refresh to any valid panel updates all panels and refreshes
+ // the screen. Using std is just convenient - We know it's always
+ // valid until the end of the program.
+
+ std->refresh();
+ sleep(sleeptime);
+
+ // Show what happens when panels are deleted and moved.
+
+ sleep(sleeptime);
+ delete u;
+ std->refresh();
+
+ sleep(sleeptime);
+ delete z;
+ std->refresh();
+
+ sleep(sleeptime);
+ delete v;
+ std->refresh();
+
+ // show how it looks when a panel moves
+ sleep(sleeptime);
+ y->mvwin(5,30);
+ std->refresh();
+
+ sleep(sleeptime);
+ delete y;
+ std->refresh();
+
+ // show how it looks when you raise a panel
+ sleep(sleeptime);
+ w->top();
+ std->refresh();
+
+ sleep(sleeptime);
+ delete w;
+ std->refresh();
+
+ sleep(sleeptime);
+ delete x;
+
+ std->clear();
+ std->refresh();
+
+ // Don't forget to clean up the main screen. Since this is the
+ // last thing using NCursesWindow, this has the effect of
+ // shutting down ncurses and restoring the terminal state.
+
+ sleep(sleeptime);
+ delete std;
+ }
+};
+
+class UserData
+{
+private:
+ int u;
+public:
+ UserData(int x) : u(x) {}
+ int sleeptime() const { return u; }
+};
+//
+// -------------------------------------------------------------------------
+//
+template<class T> class MyAction : public NCursesUserItem<T>
+{
+public:
+ MyAction (const char* p_name,
+ const T* p_UserData)
+ : NCursesUserItem<T>(p_name, (const char*)0, p_UserData)
+ {};
+
+ ~MyAction() {}
+
+ bool action() {
+ SillyDemo a;
+ a.run(NCursesUserItem<T>::UserData()->sleeptime());
+ return FALSE;
+ }
+};
+
+class QuitItem : public NCursesMenuItem
+{
+public:
+ QuitItem() : NCursesMenuItem("Quit") {
+ }
+
+ bool action() {
+ return TRUE;
+ }
+};
+//
+// -------------------------------------------------------------------------
+//
+class Label : public NCursesFormField
+{
+public:
+ Label(const char*title,
+ int row, int col)
+ : NCursesFormField(1,(int)::strlen(title),row,col) {
+ set_value(title);
+ options_off(O_EDIT|O_ACTIVE);
+ }
+};
+//
+// -------------------------------------------------------------------------
+//
+class MyFieldType : public UserDefinedFieldType {
+private:
+ int chk;
+protected:
+ bool field_check(NCursesFormField& f) {
+ return TRUE;
+ }
+ bool char_check(int c) {
+ return (c==chk?TRUE:FALSE);
+ }
+public:
+ MyFieldType(int x) : chk(x) {
+ }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestForm : public NCursesForm
+{
+private:
+ NCursesFormField** F;
+ MyFieldType* mft;
+ Integer_Field *ift;
+ Enumeration_Field *eft;
+
+ static char *weekdays[];
+
+public:
+ TestForm() : NCursesForm(13,51,(lines()-15)/2,(cols()-53)/2) {
+
+ F = new NCursesFormField*[10];
+ mft = new MyFieldType('X');
+ ift = new Integer_Field(0,1,10);
+ eft = new Enumeration_Field(weekdays);
+
+ F[0] = new Label("Demo Entry Form",0,16);
+ F[1] = new Label("Weekday Enum",2,1);
+ F[2] = new Label("Number(1-10)",2,21);
+ F[3] = new Label("Only 'X'",2,35);
+ F[4] = new Label("Multiline Field (Dynamic and Scrollable)",5,1);
+ F[5] = new NCursesFormField(1,18,3,1);
+ F[6] = new NCursesFormField(1,12,3,21);
+ F[7] = new NCursesFormField(1,12,3,35);
+ F[8] = new NCursesFormField(4,46,6,1,2);
+ F[9] = new NCursesFormField();
+
+ InitForm(F,TRUE,TRUE);
+ boldframe();
+
+ F[5]->set_fieldtype(*eft);
+ F[6]->set_fieldtype(*ift);
+
+ F[7]->set_fieldtype(*mft);
+ F[7]->set_maximum_growth(20); // max. 20 characters
+ F[7]->options_off(O_STATIC); // make field dynamic
+
+ F[8]->set_maximum_growth(10); // max. 10 lines
+ F[8]->options_off(O_STATIC); // make field dynamic
+ }
+
+ ~TestForm() {
+ delete mft;
+ delete ift;
+ delete eft;
+ }
+};
+
+char* TestForm::weekdays[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday", (char *)0 };
+//
+// -------------------------------------------------------------------------
+//
+class FormAction : public NCursesMenuItem
+{
+public:
+ FormAction(const char *s) : NCursesMenuItem(s) {
+ }
+
+ bool action() {
+ TestForm F;
+ Soft_Label_Key_Set* S = new Soft_Label_Key_Set;
+ for(int i=1; i <= S->labels(); i++) {
+ char buf[5];
+ ::sprintf(buf,"Frm%02d",i);
+ (*S)[i] = buf; // Text
+ (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+ }
+ NCursesApplication::getApplication()->push(*S);
+ F();
+ NCursesApplication::getApplication()->pop();
+ return FALSE;
+ }
+};
+//
+// -------------------------------------------------------------------------
+//
+class PassiveItem : public NCursesMenuItem {
+public:
+ PassiveItem(const char* text) : NCursesMenuItem(text) {
+ options_off(O_SELECTABLE);
+ }
+};
+//
+// -------------------------------------------------------------------------
+//
+class MyMenu : public NCursesMenu
+{
+private:
+ NCursesPanel* P;
+ NCursesMenuItem** I;
+ UserData *u;
+
+public:
+ MyMenu ()
+ : NCursesMenu (8, 8, (lines()-10)/2, (cols()-10)/2)
+ {
+ u = new UserData(1);
+ I = new NCursesMenuItem*[7];
+ I[0] = new PassiveItem("One");
+ I[1] = new PassiveItem("Two");
+ I[2] = new MyAction<UserData> ("Silly", u);
+ I[3] = new FormAction("Form");
+ I[4] = new PassiveItem("Five");
+ I[5] = new QuitItem();
+ I[6] = new NCursesMenuItem(); // Terminating empty item
+
+ InitMenu(I,TRUE,TRUE);
+
+ P = new NCursesPanel(1,6,LINES-1,1);
+ boldframe("Demo","Silly");
+ P->show();
+ }
+
+ ~MyMenu()
+ {
+ P->hide();
+ delete P;
+ delete u;
+ }
+
+ virtual void On_Menu_Init()
+ {
+ NCursesWindow W(::stdscr);
+ P->move(0,0);
+ P->clrtoeol();
+ for(int i=1; i<=count(); i++)
+ P->addch('0' + i);
+ P->bkgd(W.getbkgd());
+ refresh();
+ }
+
+ virtual void On_Menu_Termination()
+ {
+ P->move(0,0);
+ P->clrtoeol();
+ refresh();
+ }
+
+ virtual void On_Item_Init(NCursesMenuItem& item)
+ {
+ P->move(0,item.index());
+ P->attron(A_REVERSE);
+ P->printw("%1d",1+item.index());
+ P->attroff(A_REVERSE);
+ refresh();
+ }
+
+ virtual void On_Item_Termination(NCursesMenuItem& item)
+ {
+ P->move(0,item.index());
+ P->attroff(A_REVERSE);
+ P->printw("%1d",1+item.index());
+ refresh();
+ }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestApplication : public NCursesApplication {
+protected:
+ int titlesize() const { return 1; }
+ void title();
+ Soft_Label_Key_Set::Label_Layout useSLKs() const {
+ return Soft_Label_Key_Set::PC_Style_With_Index;
+ }
+ void init_labels(Soft_Label_Key_Set& S) const;
+
+public:
+ TestApplication() : NCursesApplication(TRUE) {
+ }
+
+ int run();
+};
+
+void TestApplication::init_labels(Soft_Label_Key_Set& S) const {
+ for(int i=1; i <= S.labels(); i++) {
+ char buf[5];
+ ::sprintf(buf,"Key%02d",i);
+ S[i] = buf; // Text
+ S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+ }
+}
+
+void TestApplication::title() {
+ const char * const title = "Simple C++ Binding Demo";
+ const int len = ::strlen(title);
+
+ titleWindow->bkgd(screen_titles());
+ titleWindow->addstr(0,(titleWindow->cols()-len)/2,title);
+ titleWindow->noutrefresh();
+}
+
+
+int TestApplication::run() {
+ MyMenu M;
+ M();
+ return 0;
+}
+
+//
+// -------------------------------------------------------------------------
+//
+static TestApplication Demo;
diff --git a/lib/libcurses++/etip.h b/lib/libcurses++/etip.h
new file mode 100644
index 00000000000..0e4b10c0462
--- /dev/null
+++ b/lib/libcurses++/etip.h
@@ -0,0 +1,248 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+// $Id: etip.h,v 1.1 1999/05/09 00:21:15 millert Exp $
+
+#ifndef _ETIP_H
+#define _ETIP_H
+
+// These are substituted at configure/build time
+#ifndef HAVE_BUILTIN_H
+# define HAVE_BUILTIN_H 1
+#endif
+
+#ifndef HAVE_TYPEINFO
+# define HAVE_TYPEINFO 1
+#endif
+
+#ifndef HAVE_VALUES_H
+# define HAVE_VALUES_H 0
+#endif
+
+#ifndef ETIP_NEEDS_MATH_H
+#define ETIP_NEEDS_MATH_H 0
+#endif
+
+#ifndef ETIP_NEEDS_MATH_EXCEPTION
+#define ETIP_NEEDS_MATH_EXCEPTION 0
+#endif
+
+#ifdef __GNUG__
+# if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8))
+# if HAVE_TYPEINFO
+# include <typeinfo>
+# endif
+# endif
+#endif
+
+#if defined(__GNUG__)
+# if HAVE_BUILTIN_H
+# if ETIP_NEEDS_MATH_H
+# if ETIP_NEEDS_MATH_EXCEPTION
+# undef exception
+# define exception math_exception
+# endif
+# include <math.h>
+# endif
+# undef exception
+# define exception builtin_exception
+# include <builtin.h>
+# undef exception
+# endif
+#elif defined (__SUNPRO_CC)
+# include <generic.h>
+# include <string.h>
+#else
+# include <string.h>
+#endif
+
+extern "C" {
+#if HAVE_VALUES_H
+# include <values.h>
+#endif
+
+#include <assert.h>
+#include <eti.h>
+#include <errno.h>
+}
+
+// Forward Declarations
+class NCursesPanel;
+class NCursesMenu;
+class NCursesForm;
+
+class NCursesException
+{
+public:
+ const char *message;
+ int errorno;
+
+ NCursesException (const char* msg, int err)
+ : message(msg), errorno (err)
+ {};
+
+ NCursesException (const char* msg)
+ : message(msg), errorno (E_SYSTEM_ERROR)
+ {};
+
+ virtual const char *classname() const {
+ return "NCursesWindow";
+ }
+};
+
+class NCursesPanelException : public NCursesException
+{
+public:
+ const NCursesPanel* p;
+
+ NCursesPanelException (const char *msg, int err) :
+ NCursesException (msg, err),
+ p ((NCursesPanel*)0)
+ {};
+
+ NCursesPanelException (const NCursesPanel* panel,
+ const char *msg,
+ int err) :
+ NCursesException (msg, err),
+ p (panel)
+ {};
+
+ NCursesPanelException (int err) :
+ NCursesException ("panel library error", err),
+ p ((NCursesPanel*)0)
+ {};
+
+ NCursesPanelException (const NCursesPanel* panel,
+ int err) :
+ NCursesException ("panel library error", err),
+ p (panel)
+ {};
+
+ virtual const char *classname() const {
+ return "NCursesPanel";
+ }
+
+};
+
+class NCursesMenuException : public NCursesException
+{
+public:
+ const NCursesMenu* m;
+
+ NCursesMenuException (const char *msg, int err) :
+ NCursesException (msg, err),
+ m ((NCursesMenu *)0)
+ {};
+
+ NCursesMenuException (const NCursesMenu* menu,
+ const char *msg,
+ int err) :
+ NCursesException (msg, err),
+ m (menu)
+ {};
+
+ NCursesMenuException (int err) :
+ NCursesException ("menu library error", err),
+ m ((NCursesMenu *)0)
+ {};
+
+ NCursesMenuException (const NCursesMenu* menu,
+ int err) :
+ NCursesException ("menu library error", err),
+ m (menu)
+ {};
+
+ virtual const char *classname() const {
+ return "NCursesMenu";
+ }
+
+};
+
+class NCursesFormException : public NCursesException
+{
+public:
+ const NCursesForm* f;
+
+ NCursesFormException (const char *msg, int err) :
+ NCursesException (msg, err),
+ f ((NCursesForm*)0)
+ {};
+
+ NCursesFormException (const NCursesForm* form,
+ const char *msg,
+ int err) :
+ NCursesException (msg, err),
+ f (form)
+ {};
+
+ NCursesFormException (int err) :
+ NCursesException ("form library error", err),
+ f ((NCursesForm*)0)
+ {};
+
+ NCursesFormException (const NCursesForm* form,
+ int err) :
+ NCursesException ("form library error", err),
+ f (form)
+ {};
+
+ virtual const char *classname() const {
+ return "NCursesForm";
+ }
+
+};
+
+#if !(defined(__GNUG__)||defined(__SUNPRO_CC))
+# include <iostream.h>
+ extern "C" void exit(int);
+#endif
+
+inline void THROW(const NCursesException *e) {
+#if defined(__GNUG__)
+# if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8))
+ (*lib_error_handler)(e?e->classname():"",e?e->message:"");
+#else
+ throw *e;
+#endif
+#elif defined(__SUNPRO_CC)
+ genericerror(1, ((e != 0) ? (char *)(e->message) : ""));
+#else
+ if (e)
+ cerr << e->message << endl;
+ exit(0);
+#endif
+}
+
+#define THROWS(s)
+
+#endif // _ETIP_H
diff --git a/lib/libcurses++/internal.h b/lib/libcurses++/internal.h
new file mode 100644
index 00000000000..ce5af0167da
--- /dev/null
+++ b/lib/libcurses++/internal.h
@@ -0,0 +1,47 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997 *
+ ****************************************************************************/
+
+// $Id: internal.h,v 1.1 1999/05/09 00:21:15 millert Exp $
+
+#ifndef _CPLUS_INTERNAL_H
+#define _CPLUS_INTERNAL_H 1
+
+#ifdef USE_RCS_IDS
+#define MODULE_ID(id) static const char Ident[] = id;
+#else
+#define MODULE_ID(id) /*nothing*/
+#endif
+
+#define CTRL(x) ((x) & 0x1f)
+
+#endif