xref: /386bsd/usr/src/lib/libg++/libg++/CursesW.cc (revision a2142627)
1 /*
2 Copyright (C) 1989 Free Software Foundation
3     written by Eric Newton (newton@rocky.oswego.edu)
4 
5 This file is part of GNU CC.
6 
7 GNU CC is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY.  No author or distributor
9 accepts responsibility to anyone for the consequences of using it
10 or for whether it serves any particular purpose or works at all,
11 unless he says so in writing.  Refer to the GNU CC General Public
12 License for full details.
13 
14 Everyone is granted permission to copy, modify and redistribute
15 GNU CC, but only under the conditions described in the
16 GNU CC General Public License.   A copy of this license is
17 supposed to have been given to you along with GNU CC so you
18 can know your rights and responsibilities.  It should be in a
19 file named COPYING.  Among other things, the copyright notice
20 and this notice must be preserved on all copies.
21 */
22 #ifdef __GNUG__
23 #pragma implementation
24 #endif
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <builtin.h>
28 #include <values.h>
29 #include <CursesW.h>
30 
31 extern "C" int _sscans(WINDOW*, const char*, va_list);
32 
33 /*
34  * C++ interface to curses library.
35  *
36  */
37 
38 /*
39  * varargs functions are handled conservatively:
40  * They interface directly into the underlying
41  * _doscan, _doprnt and/or vfprintf routines rather than
42  * assume that such things are handled compatibly in the curses library
43  */
44 
scanw(const char * fmt,...)45 int CursesWindow::scanw(const char * fmt, ...)
46 {
47   va_list args;
48   va_start(args, fmt);
49 #if 1 /* bsd */
50   int result = _sscans(w, fmt, args);
51 #else
52 #ifdef VMS
53   int result = wscanw(w , fmt , args);
54 #else
55   char buf[BUFSIZ];
56   int result = wgetstr(w, buf);
57   if (result == OK) {
58 #ifndef HAVE_VSCANF
59       FILE b;
60       b._flag = _IOREAD|_IOSTRG;
61       b._base = buf;
62       b._ptr = buf;
63       b._cnt = BUFSIZ;
64       result = _doscan(&b, fmt, args);
65 #else
66       result = vsscanf(buf, fmt, args);
67 #endif
68 #endif
69   }
70 #endif
71   va_end(args);
72   return result;
73 }
74 
mvscanw(int y,int x,const char * fmt,...)75 int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
76 {
77   va_list args;
78   va_start(args, fmt);
79 #ifndef VMS
80   char buf[BUFSIZ];
81   int result = wmove(w, y, x);
82   if (result == OK)
83 #if 1 /* bsd */
84   result = _sscans(w, fmt, args);
85 #else
86 #ifdef VMS
87   result=wscanw(w , fmt , args);
88 #else
89   {
90     result = wgetstr(w, buf);
91     if (result == OK) {
92 #ifndef HAVE_VSCANF
93 	FILE b;
94 	b._flag = _IOREAD|_IOSTRG;
95 	b._base = buf;
96 	b._ptr = buf;
97 	b._cnt = BUFSIZ;
98 	result = _doscan(&b, fmt, args);
99 #else
100 	result = vsscanf(buf, fmt, args);
101 #endif
102 #endif
103     }
104   }
105 #endif
106 #endif
107   va_end(args);
108   return result;
109 }
110 
printw(const char * fmt,...)111 int CursesWindow::printw(const char * fmt, ...)
112 {
113   va_list args;
114   va_start(args, fmt);
115   char buf[BUFSIZ];
116 #ifndef HAVE_VPRINTF
117   FILE b;
118   b._flag = _IOWRT|_IOSTRG;
119   b._ptr = buf;
120   b._cnt = BUFSIZ;
121   _doprnt(fmt, args, &b);
122   putc('\0', &b);
123 #else
124   vsprintf(buf, fmt, args);
125 #endif
126   va_end(args);
127   return waddstr(w, buf);
128 }
129 
130 
mvprintw(int y,int x,const char * fmt,...)131 int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
132 {
133   va_list args;
134   va_start(args, fmt);
135   char buf[BUFSIZ];
136   int result = wmove(w, y, x);
137   if (result == OK)
138   {
139 #ifndef HAVE_VPRINTF
140     FILE b;
141     b._flag = _IOWRT|_IOSTRG;
142     b._ptr = buf;
143     b._cnt = BUFSIZ;
144     _doprnt(fmt, args, &b);
145     putc('\0', &b);
146 #else
147     vsprintf(buf, fmt, args);
148 #endif
149     result = waddstr(w, buf);
150   }
151   va_end(args);
152   return result;
153 }
154 
CursesWindow(int lines,int cols,int begin_y,int begin_x)155 CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
156 {
157   if (count==0)
158     initscr();
159 
160   w = newwin(lines, cols, begin_y, begin_x);
161   if (w == 0)
162   {
163     (*lib_error_handler)("CursesWindow", "Cannot construct window");
164   }
165 
166   alloced = 1;
167   subwins = par = sib = 0;
168   count++;
169 }
170 
CursesWindow(WINDOW * & window)171 CursesWindow::CursesWindow(WINDOW* &window)
172 {
173   if (count==0)
174     initscr();
175 
176   w = window;
177   alloced = 0;
178   subwins = par = sib = 0;
179   count++;
180 }
181 
CursesWindow(CursesWindow & win,int l,int c,int by,int bx,char absrel)182 CursesWindow::CursesWindow(CursesWindow& win, int l, int c,
183                            int by, int bx, char absrel)
184 {
185 
186   if (absrel == 'r') // relative origin
187   {
188     by += win.begy();
189     bx += win.begx();
190   }
191 
192   // Even though we treat subwindows as a tree, the standard curses
193   // library needs the `subwin' call to link to the root in
194   // order to correctly perform refreshes, etc.
195 
196   CursesWindow* root = &win;
197   while (root->par != 0) root = root->par;
198 
199   w = subwin(root->w, l, c, by, bx);
200   if (w == 0)
201   {
202     (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
203   }
204 
205   par = &win;
206   sib = win.subwins;
207   win.subwins = this;
208   subwins = 0;
209   alloced = 1;
210   count++;
211 }
212 
213 
kill_subwindows()214 void CursesWindow::kill_subwindows()
215 {
216   for (CursesWindow* p = subwins; p != 0; p = p->sib)
217   {
218     p->kill_subwindows();
219     if (p->alloced)
220     {
221       if (p->w != 0)
222         ::delwin(p->w);
223       p->alloced = 0;
224     }
225     p->w = 0; // cause a run-time error if anyone attempts to use...
226   }
227 }
228 
~CursesWindow()229 CursesWindow::~CursesWindow()
230 {
231   kill_subwindows();
232 
233   if (par != 0)   // Snip us from the parent's list of subwindows.
234   {
235     CursesWindow * win = par->subwins;
236     CursesWindow * trail = 0;
237     for (;;)
238     {
239       if (win == 0)
240         break;
241       else if (win == this)
242       {
243         if (trail != 0)
244           trail->sib = win->sib;
245         else
246           par->subwins = win->sib;
247         break;
248       }
249       else
250       {
251         trail = win;
252         win = win->sib;
253       }
254     }
255   }
256 
257   if (alloced && w != 0)
258     delwin(w);
259 
260   --count;
261   if (count == 0)
262     endwin();
263   else if (count < 0) // cannot happen!
264   {
265     (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
266   }
267 }
268