1 // * this is for making emacs happy: -*-Mode: C++;-*-
2 /****************************************************************************
3 * Copyright (c) 2007-2008,2009 Free Software Foundation, Inc. *
5 * Permission is hereby granted, free of charge, to any person obtaining a *
6 * copy of this software and associated documentation files (the *
7 * "Software"), to deal in the Software without restriction, including *
8 * without limitation the rights to use, copy, modify, merge, publish, *
9 * distribute, distribute with modifications, sublicense, and/or sell *
10 * copies of the Software, and to permit persons to whom the Software is *
11 * furnished to do so, subject to the following conditions: *
13 * The above copyright notice and this permission notice shall be included *
14 * in all copies or substantial portions of the Software. *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
24 * Except as contained in this notice, the name(s) of the above copyright *
25 * holders shall not be used in advertising or otherwise to promote the *
26 * sale, use or other dealings in this Software without prior written *
28 ****************************************************************************/
35 * The NCursesWindow class was originally based on a file written by
36 * Eric Newton, later modified by Ulrich Drepper and Anatoly Ivasyuk.
37 * However, aside from the compatible interface definition, no trace
38 * of the original code remains in this version: it consists only of
39 * changes introduced since 1995.
45 MODULE_ID("$Id: cursesw.cc,v 1.51 2009/03/28 21:31:37 tom Exp $")
47 #define COLORS_NEED_INITIALIZATION -1
48 #define COLORS_NOT_INITIALIZED 0
49 #define COLORS_MONOCHROME 1
50 #define COLORS_ARE_REALLY_THERE 2
52 #define HaveColors() (colorInitialized == COLORS_ARE_REALLY_THERE)
54 // declare static variables for the class
55 long NCursesWindow::count
= 0L;
56 bool NCursesWindow::b_initialized
= FALSE
;
59 NCursesWindow::scanw(const char* fmt
, ...)
65 result
= ::vw_scanw (w
, const_cast<NCURSES_CONST
char *>(fmt
), args
);
73 NCursesWindow::scanw(int y
, int x
, const char* fmt
, ...)
77 if (::wmove(w
, y
, x
) != ERR
) {
80 result
= ::vw_scanw (w
, const_cast<NCURSES_CONST
char *>(fmt
), args
);
88 NCursesWindow::scanw(const char* fmt
, va_list args
)
92 result
= ::vw_scanw (w
, const_cast<NCURSES_CONST
char *>(fmt
), args
);
99 NCursesWindow::scanw(int y
, int x
, const char* fmt
, va_list args
)
103 if (::wmove(w
, y
, x
) != ERR
) {
104 result
= ::vw_scanw (w
, const_cast<NCURSES_CONST
char *>(fmt
), args
);
111 NCursesWindow::printw(const char * fmt
, ...)
115 int result
= ::vw_printw(w
, fmt
, args
);
122 NCursesWindow::printw(int y
, int x
, const char * fmt
, ...)
126 int result
= ::wmove(w
, y
, x
);
128 result
= ::vw_printw(w
, fmt
, args
);
136 NCursesWindow::printw(const char * fmt
, va_list args
)
138 int result
= ::vw_printw(w
, fmt
, args
);
144 NCursesWindow::printw(int y
, int x
, const char * fmt
, va_list args
)
146 int result
= ::wmove(w
, y
, x
);
148 result
= ::vw_printw(w
, fmt
, args
);
155 NCursesWindow::set_keyboard(void)
162 NCursesWindow::err_handler(const char *msg
) const THROWS(NCursesException
)
164 THROW(new NCursesException(msg
));
168 NCursesWindow::initialize()
170 if (!b_initialized
) {
172 b_initialized
= TRUE
;
173 if (colorInitialized
== COLORS_NEED_INITIALIZATION
) {
174 colorInitialized
= COLORS_NOT_INITIALIZED
;
183 NCursesWindow::constructing()
189 NCursesWindow::NCursesWindow()
190 : w(0), alloced(FALSE
), par(0), subwins(0), sib(0)
194 w
= static_cast<WINDOW
*>(0);
198 NCursesWindow::NCursesWindow(int nlines
, int ncols
, int begin_y
, int begin_x
)
199 : w(0), alloced(TRUE
), par(0), subwins(0), sib(0)
203 w
= ::newwin(nlines
, ncols
, begin_y
, begin_x
);
205 err_handler("Cannot construct window");
210 NCursesWindow::NCursesWindow(WINDOW
* window
)
211 : w(0), alloced(FALSE
), par(0), subwins(0), sib(0)
215 // We used to use a reference on the "window" parameter, but we cannot do
216 // that with an opaque pointer (see NCURSES_OPAQUE). If the parameter was
217 // "::stdscr", that is first set via the "constructing() call, and is null
218 // up to that point. So we allow a null pointer here as meaning the "same"
220 w
= window
? window
: ::stdscr
;
224 NCursesWindow::NCursesWindow(NCursesWindow
& win
, int ny
, int nx
,
225 int begin_y
, int begin_x
, char absrel
)
226 : w(0), alloced(TRUE
), par(0), subwins(0), sib(0)
229 if (absrel
== 'a') { // absolute origin
230 begin_y
-= win
.begy();
231 begin_x
-= win
.begx();
234 // Link this window into its parent's list of subwindows.
235 // We use derwin(), since this also works for pads.
236 w
= ::derwin(win
.w
, ny
, nx
, begin_y
, begin_x
);
238 err_handler("Cannot construct subwindow");
246 NCursesWindow::NCursesWindow(NCursesWindow
& win
,
247 bool do_box
NCURSES_PARAM_INIT(TRUE
))
248 : w(0), alloced(TRUE
), par(0), subwins(0), sib(0)
251 int myHeight
= win
.height();
252 int myWidth
= win
.width();
253 w
= :: derwin(win
.w
, myHeight
- 2, myWidth
- 2, 1, 1);
255 err_handler("Cannot construct subwindow");
269 NCursesWindow
NCursesWindow::Clone()
271 WINDOW
*d
= ::dupwin(w
);
280 typedef int (*RIPOFFINIT
)(NCursesWindow
&);
281 static RIPOFFINIT R_INIT
[5]; // There can't be more
282 static int r_init_idx
= 0;
283 static RIPOFFINIT
* prip
= R_INIT
;
285 NCursesWindow::NCursesWindow(WINDOW
*win
, int ncols
)
286 : w(0), alloced(FALSE
), par(0), subwins(0), sib(0)
292 int _nc_xx_ripoff_init(WINDOW
*w
, int ncols
)
296 RIPOFFINIT init
= *prip
++;
298 res
= init(*(new NCursesWindow(w
,ncols
)));
303 int NCursesWindow::ripoffline(int ripoff_lines
,
304 int (*init
)(NCursesWindow
& win
))
306 int code
= ::_nc_ripoffline(ripoff_lines
,_nc_xx_ripoff_init
);
307 if (code
== OK
&& init
&& ripoff_lines
) {
308 R_INIT
[r_init_idx
++] = init
;
314 NCursesWindow::isDescendant(NCursesWindow
& win
)
318 for (NCursesWindow
* p
= subwins
; p
!= NULL
; p
= p
->sib
) {
319 if (p
== &win
|| p
->isDescendant(win
)) {
328 NCursesWindow::kill_subwindows()
330 NCursesWindow
* p
= subwins
;
334 NCursesWindow
* q
= p
->sib
;
335 p
->kill_subwindows();
346 NCursesWindow::~NCursesWindow()
351 // Remove this window from the parent's list of subwindows.
352 NCursesWindow
* next
= par
->subwins
;
353 NCursesWindow
* prev
= 0;
357 prev
->sib
= next
->sib
;
359 par
->subwins
= next
->sib
;
368 if (alloced
&& w
!= 0)
375 } else if (count
< 0) { // cannot happen!
376 err_handler("Too many windows destroyed");
381 // ---------------------------------------------------------------------
384 int NCursesWindow::colorInitialized
= COLORS_NOT_INITIALIZED
;
387 NCursesWindow::useColors(void)
389 if (colorInitialized
== COLORS_NOT_INITIALIZED
) {
391 if (::has_colors()) {
393 colorInitialized
= COLORS_ARE_REALLY_THERE
;
395 colorInitialized
= COLORS_MONOCHROME
;
398 colorInitialized
= COLORS_NEED_INITIALIZATION
;
404 NCursesWindow::getPair() const
406 return static_cast<short>(PAIR_NUMBER(getattrs(w
)));
410 NCursesWindow::getcolor(int getback
) const
415 if (::pair_content(getPair(), &fore
, &back
) == ERR
)
416 err_handler("Can't get color pair");
418 // Monochrome means white on black
422 return getback
? back
: fore
;
425 int NCursesWindow::NumberOfColors()
427 return (HaveColors()) ? COLORS
: 1;
431 NCursesWindow::getcolor() const
433 return (HaveColors()) ? getPair() : 0;
437 NCursesWindow::setpalette(short fore
, short back
, short pair
)
439 return (HaveColors()) ? ::init_pair(pair
, fore
, back
) : OK
;
443 NCursesWindow::setpalette(short fore
, short back
)
445 return setpalette(fore
, back
, getPair());
450 NCursesWindow::setcolor(short pair
)
453 if ((pair
< 1) || (pair
> COLOR_PAIRS
))
454 err_handler("Can't set color pair");
457 attrset(COLOR_PAIR(pair
));
463 bool NCursesWindow::has_mouse() const
465 return ((::has_key(KEY_MOUSE
) || ::has_mouse())