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