libyui-ncurses  2.57.2
ncursesw.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: ncursesw.cc
20 
21  Author: Michael Andres <ma@suse.de>
22 
23 /-*/
24 
25 /*
26  Copyright (C) 1989 Free Software Foundation
27  written by Eric Newton (newton@rocky.oswego.edu)
28 
29  This file is part of the GNU C++ Library. This library is free
30  software; you can redistribute it and/or modify it under the terms of
31  the GNU Library General Public License as published by the Free
32  Software Foundation; either version 2 of the License, or (at your
33  option) any later version. This library is distributed in the hope
34  that it will be useful, but WITHOUT ANY WARRANTY; without even the
35  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
36  PURPOSE. See the GNU Library General Public License for more details.
37  You should have received a copy of the GNU Library General Public
38  License along with this library; if not, write to the Free Software
39  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
40 
41  modified by Ulrich Drepper (drepper@karlsruhe.gmd.de)
42  and Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
43 
44  modified by Juergen Pfeifer (Juergen.Pfeifer@T-Online.de)
45 */
46 
47 #include <iostream>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <ncursesw/term.h>
51 #undef line
52 #undef columns
53 
54 #define YUILogComponent "ncurses"
55 #include <yui/YUILog.h>
56 #include <yui/YUIException.h>
57 
58 #include "ncursesw.h"
59 #include "NCstring.h"
60 
61 
62 #define COLORS_NEED_INITIALIZATION -1
63 #define COLORS_NOT_INITIALIZED 0
64 #define COLORS_MONOCHROME 1
65 #define COLORS_ARE_REALLY_THERE 2
66 
67 //
68 // static class variables
69 //
70 long NCursesWindow::count = 0L;
71 bool NCursesWindow::b_initialized = FALSE;
72 
73 
74 
75 int
76 NCursesWindow::printw( const char * fmt, ... )
77 {
78  va_list args;
79  va_start( args, fmt );
80  char buf[BUFSIZ];
81  vsprintf( buf, fmt, args );
82  va_end( args );
83  return waddstr( w, buf );
84 }
85 
86 
87 int
88 NCursesWindow::printw( int y, int x, const char * fmt, ... )
89 {
90  va_list args;
91  va_start( args, fmt );
92  int result = wmove( w, y, x );
93 
94  if ( result == OK )
95  {
96  char buf[BUFSIZ];
97  vsprintf( buf, fmt, args );
98  result = waddstr( w, buf );
99  }
100 
101  va_end( args );
102 
103  return result;
104 }
105 
106 int
107 NCursesWindow::addwstr( int y, int x, const wchar_t * str, int n )
108 {
109  const std::wstring wstr( str );
110  std::string out;
111 
112  if ( NCstring::terminalEncoding() != "UTF-8" )
113  {
114  NCstring::RecodeFromWchar( wstr, NCstring::terminalEncoding(), &out );
115  return ::mvwaddnstr( w, y, x, out.c_str(), n );
116  }
117  else
118  return ::mvwaddnwstr( w, y, x, (wchar_t *) str, n );
119 
120 }
121 
122 
123 int
124 NCursesWindow::addwstr( const wchar_t* str, int n )
125 {
126  const std::wstring wstr( str );
127  std::string out;
128 
129  if ( NCstring::terminalEncoding() != "UTF-8" )
130  {
131  NCstring::RecodeFromWchar( wstr, NCstring::terminalEncoding(), &out );
132  return ::waddnstr( w, out.c_str(), n );
133  }
134  else
135  return ::waddnwstr( w, (wchar_t *) str, n );
136 }
137 
138 
139 int
140 NCursesWindow::in_wchar( int y, int x, cchar_t *combined )
141 {
142  int ret = mvwin_wch( w, y, x, combined );
143  combined->attr = combined->attr & ( A_CHARTEXT | A_ALTCHARSET );
144 
145 // libncurses6 enables ext_color from struct cchar_t (see curses.h).
146 // Set ext_color to 0 to respect the settings got from mvwin_wch (bnc#652240).
147 #ifdef NCURSES_EXT_COLORS
148  combined->ext_color = 0;
149 #endif
150  return ret;
151 }
152 
153 int
154 NCursesWindow::in_wchar( cchar_t *combined )
155 {
156  int ret = win_wch( w, combined );
157  combined->attr = combined->attr & ( A_CHARTEXT | A_ALTCHARSET );
158 // libncurses6 enables ext_color from struct cchar_t (see curses.h).
159 // Set ext_color to 0 to respect the settings got from win_wch (bnc#652240).
160 #ifdef NCURSES_EXT_COLORS
161  combined->ext_color = 0;
162 #endif
163  return ret;
164 }
165 
166 int
168 {
169  int ret = ERR;
170 
171  if ( NCstring::terminalEncoding() != "UTF-8" )
172  {
173  ret = addch( inchar( y, x ) );
174  }
175  else
176  {
177  cchar_t combined;
178  ret = in_wchar( y, x, &combined );
179 
180  if ( ret == OK )
181  {
182  ret = add_wch( &combined );
183  }
184  }
185 
186  return ret;
187 }
188 
189 int
190 NCursesWindow::add_attr_char()
191 {
192  int ret = ERR;
193 
194  if ( NCstring::terminalEncoding() != "UTF-8" )
195  {
196  ret = addch( inchar() );
197  }
198  else
199  {
200  cchar_t combined;
201  ret = in_wchar( &combined );
202 
203  if ( ret == OK )
204  {
205  ret = add_wch( &combined );
206  }
207  }
208 
209  return ret;
210 }
211 
212 void
213 NCursesWindow::init( void )
214 {
215  // Setting back_color_erase to FALSE was added because of bug #418613.
216  // This isn't necessary any longer because the kernel patch which
217  // has caused the bug was reverted (in SLES11-GM).
218 #if 0
219  static char * env;
220  if (!env && (env = ::getenv("TERM"))) {
221  if (::strncmp(env, "linux", 5) == 0)
222  back_color_erase = FALSE;
223  }
224 #endif
225  leaveok( 0 );
226  keypad( 1 );
227  meta( 1 );
228 }
229 
230 void
231 NCursesWindow::err_handler( const char *msg ) const THROWS( NCursesException )
232 {
233  THROW( new NCursesException( msg ) );
234 }
235 
236 void
237 NCursesWindow::initialize()
238 {
239  if ( !b_initialized )
240  {
241  //::initscr();
242  b_initialized = TRUE;
243 
244  if ( colorInitialized == COLORS_NEED_INITIALIZATION )
245  {
246  colorInitialized = COLORS_NOT_INITIALIZED;
247  useColors();
248  }
249 
250  ::noecho();
251 
252  ::cbreak();
253  }
254 }
255 
257  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
258 {
259  if ( !b_initialized )
260  initialize();
261 
262  w = static_cast<WINDOW *>(0);
263 
264  init();
265 
266  count++;
267 }
268 
269 NCursesWindow::NCursesWindow( int lines, int cols, int begin_y, int begin_x )
270  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
271 {
272  if ( !b_initialized )
273  initialize();
274 
275  if ( lines <= 0 )
276  lines = 1;
277 
278  if ( cols <= 0 )
279  cols = 1;
280 
281  if ( lines + begin_y > NCursesWindow::lines() )
282  lines = NCursesWindow::lines() - begin_y;
283 
284  if ( cols + begin_x > NCursesWindow::cols() )
285  cols = NCursesWindow::cols() - begin_x;
286 
287  // yuiDebug() << "Lines: " << lines << " Cols: " << cols << " y: " << begin_y << " x: " << begin_x << std::endl;
288 
289  w = ::newwin( lines, cols, begin_y, begin_x );
290 
291  if ( w == 0 )
292  {
293  err_handler( "Cannot construct window" );
294  }
295 
296  init();
297 
298  count++;
299 }
300 
302  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
303 {
304  if ( !b_initialized )
305  initialize();
306 
307  w = window ? window : ::stdscr;
308 
309  init();
310 
311  count++;
312 }
313 
315  int begin_y, int begin_x, char absrel )
316  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
317 {
318  if ( l <= 0 )
319  l = 1;
320 
321  if ( c <= 0 )
322  c = 1;
323 
324  if ( begin_y < 0 )
325  begin_y = 0;
326 
327  if ( begin_x < 0 )
328  begin_x = 0;
329 
330  if ( absrel == 'a' ) // absolute origin
331  {
332  begin_y -= win.begy();
333  begin_x -= win.begx();
334  }
335 
336  if ( l + begin_y > win.height() )
337  l = win.height() - begin_y;
338 
339  if ( c + begin_x > win.width() )
340  c = win.width() - begin_x;
341 
342  // Even though we treat subwindows as a tree, the standard curses
343  // library needs the `subwin' call to link to the parent in
344  // order to correctly perform refreshes, etc.
345  // Friendly enough, this also works for pads.
346  w = ::derwin( win.w, l, c, begin_y, begin_x );
347 
348  if ( w == 0 )
349  {
350  yuiError() << "NULL subwindow; throw " << wpos( begin_y, begin_x ) << wsze( l, c ) << std::endl;
351  YUI_THROW( YUIException( "NULL ncurses lowlevel subwindow" ) );
352  }
353 
354  // yuiDebug() << "created " << wpos(begin_y, begin_x) << wsze(l, c) << std::endl;
355 
356  par = &win;
357  sib = win.subwins;
358  win.subwins = this;
359  count++;
360 }
361 
363 {
364  WINDOW *d = ::dupwin( w );
365  NCursesWindow W( d );
366  W.subwins = subwins;
367  W.sib = sib;
368  W.par = par;
369  W.alloced = alloced;
370  return W;
371 }
372 
373 typedef int ( *RIPOFFINIT )( NCursesWindow& );
374 static RIPOFFINIT R_INIT[5]; // There can't be more
375 static int r_init_idx = 0;
376 static RIPOFFINIT* prip = R_INIT;
377 
378 
379 NCursesWindow::NCursesWindow( WINDOW *win, int cols )
380 {
381  w = win;
382  assert(( w->_maxx + 1 ) == cols );
383  alloced = FALSE;
384  subwins = par = sib = 0;
385 }
386 
387 int NCursesWindow::ripoff_init( WINDOW *w, int cols )
388 {
389  int res = ERR;
390 
391  RIPOFFINIT init = *prip++;
392 
393  if ( init )
394  {
395  NCursesWindow* W = new NCursesWindow( w, cols );
396  res = init( *W );
397  }
398 
399  return res;
400 }
401 
402 int NCursesWindow::ripoffline( int ripoff_lines,
403  int ( *init )( NCursesWindow& win ) )
404 {
405  int code = ::ripoffline( ripoff_lines, ripoff_init );
406 
407  if ( code == OK && init && ripoff_lines )
408  {
409  R_INIT[r_init_idx++] = init;
410  }
411 
412  return code;
413 }
414 
415 bool
417 {
418  for ( NCursesWindow* p = subwins; p != NULL; p = p->sib )
419  {
420  if ( p == &win )
421  return TRUE;
422  else
423  {
424  if ( p->isDescendant( win ) )
425  return TRUE;
426  }
427  }
428 
429  return FALSE;
430 }
431 
432 void
434 {
435  for ( NCursesWindow* p = subwins; p != 0; p = p->sib )
436  {
437  p->kill_subwindows();
438 
439  if ( p->alloced )
440  {
441  if ( p->w != 0 )
442  ::delwin( p->w );
443 
444  p->alloced = FALSE;
445  }
446 
447  p->w = 0; // cause a run-time error if anyone attempts to use...
448  }
449 }
450 
451 
453 {
454  kill_subwindows();
455 
456  if ( par != 0 ) // Snip us from the parent's list of subwindows.
457  {
458  NCursesWindow * win = par->subwins;
459  NCursesWindow * trail = 0;
460 
461  for ( ;; )
462  {
463  if ( win == 0 )
464  break;
465  else if ( win == this )
466  {
467  if ( trail != 0 )
468  trail->sib = win->sib;
469  else
470  par->subwins = win->sib;
471 
472  break;
473  }
474  else
475  {
476  trail = win;
477  win = win->sib;
478  }
479  }
480  }
481 
482  if ( alloced && w != 0 )
483  delwin( w );
484 
485  if ( alloced )
486  {
487  --count;
488 
489  if ( count == 0 )
490  {
491  ::endwin();
492  }
493  else if ( count < 0 ) // cannot happen!
494  {
495  err_handler( "Too many windows destroyed" );
496  }
497  }
498 }
499 
500 // ---------------------------------------------------------------------
501 // Color stuff
502 int NCursesWindow::colorInitialized = COLORS_NOT_INITIALIZED;
503 
504 void
506 {
507  if ( colorInitialized == COLORS_NOT_INITIALIZED )
508  {
509  if ( b_initialized )
510  {
511  if ( ::has_colors() )
512  {
513  ::start_color();
514  colorInitialized = COLORS_ARE_REALLY_THERE;
515  }
516  else
517  colorInitialized = COLORS_MONOCHROME;
518  }
519  else
520  colorInitialized = COLORS_NEED_INITIALIZATION;
521  }
522 }
523 
524 short
525 NCursesWindow::getcolor( int getback ) const
526 {
527  short fore, back;
528 
529  if ( colorInitialized == COLORS_ARE_REALLY_THERE )
530  {
531  if ( pair_content( PAIR_NUMBER( w->_attrs ), &fore, &back ) )
532  err_handler( "Can't get color pair" );
533  }
534  else
535  {
536  // Monochrome means white on black
537  back = COLOR_BLACK;
538  fore = COLOR_WHITE;
539  }
540 
541  return getback ? back : fore;
542 }
543 
545 {
546  if ( colorInitialized == COLORS_ARE_REALLY_THERE )
547  return COLORS;
548  else
549  return 1; // monochrome (actually there are two ;-)
550 }
551 
552 short
554 {
555  if ( colorInitialized == COLORS_ARE_REALLY_THERE )
556  return PAIR_NUMBER( w->_attrs );
557  else
558  return 0; // we only have pair zero
559 }
560 
561 int
562 NCursesWindow::setpalette( short fore, short back, short pair )
563 {
564  if ( colorInitialized == COLORS_ARE_REALLY_THERE )
565  return init_pair( pair, fore, back );
566  else
567  return OK;
568 }
569 
570 int
571 NCursesWindow::setpalette( short fore, short back )
572 {
573  if ( colorInitialized == COLORS_ARE_REALLY_THERE )
574  return setpalette( fore, back, PAIR_NUMBER( w->_attrs ) );
575  else
576  return OK;
577 }
578 
579 int
581 {
582  if ( colorInitialized == COLORS_ARE_REALLY_THERE )
583  {
584  if (( pair < 1 ) || ( pair > COLOR_PAIRS ) )
585  err_handler( "Can't std::set color pair" );
586 
587  attroff( A_COLOR );
588 
589  attrset( COLOR_PAIR( pair ) );
590  }
591 
592  return OK;
593 }
594 
596 {
597  return (( ::has_key( KEY_MOUSE ) || ::has_mouse() )
598  ? TRUE : FALSE );
599 }
600 
601 NCursesPad::NCursesPad( int lines, int cols ) : NCursesWindow()
602 {
603  if ( lines <= 0 )
604  lines = 1;
605 
606  if ( cols <= 0 )
607  cols = 1;
608 
609  w = ::newpad( lines, cols );
610 
611  if ( w == ( WINDOW* )0 )
612  {
613  count--;
614  err_handler( "Cannot construct window" );
615  }
616 
617  alloced = TRUE;
618 }
619 
620 
621 
622 int NCursesWindow::box( const wrect & dim )
623 {
624  wrect box_area( dim.intersectRelTo( area() ) );
625 
626  if ( box_area.Sze > 0 )
627  {
628  hline( box_area.Pos.L, box_area.Pos.C, box_area.Sze.W );
629  hline( box_area.Pos.L + box_area.Sze.H - 1, box_area.Pos.C, box_area.Sze.W );
630  vline( box_area.Pos.L, box_area.Pos.C, box_area.Sze.H );
631  vline( box_area.Pos.L, box_area.Pos.C + box_area.Sze.W - 1, box_area.Sze.H );
632 
633  addch( box_area.Pos.L + box_area.Sze.H - 1, box_area.Pos.C, ACS_LLCORNER );
634  addch( box_area.Pos.L, box_area.Pos.C + box_area.Sze.W - 1, ACS_URCORNER );
635  addch( box_area.Pos.L + box_area.Sze.H - 1, box_area.Pos.C + box_area.Sze.W - 1, ACS_LRCORNER );
636  addch( box_area.Pos.L, box_area.Pos.C, ACS_ULCORNER );
637  }
638 
639  return OK;
640 }
641 
642 
643 
644 // move subwin tree inside parent
645 int NCursesWindow::mvsubwin( NCursesWindow * sub, int begin_y, int begin_x )
646 {
647  int ret = ERR;
648 
649  if ( sub && sub->parent() )
650  {
651  sub->w->_parx = -1; // force ncurses to actually move the child
652  ret = ::mvderwin( sub->w, begin_y, begin_x );
653 
654  for ( NCursesWindow * ch = sub->child(); ch && ret == OK; ch = ch->sibling() )
655  {
656  ret = mvsubwin( ch, ch->w->_pary, ch->w->_parx );
657  }
658  }
659 
660  return ret;
661 }
662 
663 
664 
665 int NCursesWindow::resize( int lines, int columns )
666 {
667  if ( lines <= 0 )
668  lines = 1;
669 
670  if ( columns <= 0 )
671  columns = 1;
672 
673  return ::wresize( w, lines, columns );
674 }
675 
676 
677 std::ostream & operator<<( std::ostream & Stream, const NCursesWindow * Obj_Cv )
678 {
679  if ( Obj_Cv )
680  return Stream << *Obj_Cv;
681 
682  return Stream << "(NoNCWin)";
683 }
684 
685 
686 std::ostream & operator<<( std::ostream & Stream, const NCursesWindow & Obj_Cv )
687 {
688  return Stream << "NCWin(" << Obj_Cv.w
689  << wrect( wpos( Obj_Cv.begy(), Obj_Cv.begx() ),
690  wsze( Obj_Cv.height(), Obj_Cv.width() ) ) << ')';
691 }
NCursesWindow::lines
static int lines()
Number of lines on terminal, not window.
Definition: ncursesw.h:1044
NCursesWindow::addch
int addch(const char ch)
Put attributed character to the window.
Definition: ncursesw.h:1230
NCursesWindow::ripoffline
static int ripoffline(int ripoff_lines, int(*init)(NCursesWindow &win))
This function is used to generate a window of ripped-of lines.
Definition: ncursesw.cc:402
wsze
Screen dimension (screen size) in the order height, width: (H, W)
Definition: position.h:154
NCursesWindow::hline
int hline(int len, chtype ch=0)
Draw a horizontal line of len characters with the given character.
Definition: ncursesw.h:1487
NCursesWindow::attrset
int attrset(chtype at)
Set the window attributes;.
Definition: ncursesw.h:1412
NCursesWindow::sibling
NCursesWindow * sibling()
Get the next child of my parent.
Definition: ncursesw.h:1764
NCursesWindow::attroff
int attroff(chtype at)
Switch off the window attributes;.
Definition: ncursesw.h:1407
NCursesWindow::parent
NCursesWindow * parent()
Get my parent.
Definition: ncursesw.h:1771
NCursesWindow
C++ class for windows.
Definition: ncursesw.h:907
NCursesWindow::useColors
static void useColors(void)
Call this routine very early if you want to have colors.
Definition: ncursesw.cc:505
NCursesWindow::addwstr
int addwstr(const wchar_t *str, int n=-1)
Write the wchar_t str to the window, stop writing if the terminating NUL or the limit n is reached.
Definition: ncursesw.cc:124
NCursesWindow::err_handler
void err_handler(const char *) const THROWS(NCursesException)
Signal an error with the given message text.
Definition: ncursesw.cc:231
NCursesWindow::add_attr_char
int add_attr_char(int y, int x)
Put attributed character from given position to the window.
Definition: ncursesw.cc:167
NCursesWindow::begy
int begy() const
Line of top left corner relative to stdscr.
Definition: ncursesw.h:1087
NCursesWindow::has_mouse
bool has_mouse() const
Return TRUE if terminal supports a mouse, FALSE otherwise.
Definition: ncursesw.cc:595
NCursesWindow::child
NCursesWindow * child()
Get the first child window.
Definition: ncursesw.h:1757
NCursesWindow::cols
static int cols()
Number of cols on terminal, not window.
Definition: ncursesw.h:1049
NCursesWindow::w
WINDOW * w
the curses WINDOW
Definition: ncursesw.h:949
NCursesWindow::box
int box()
Draw a box around the window with the given vertical and horizontal drawing characters.
Definition: ncursesw.h:1464
NCursesWindow::setcolor
int setcolor(short pair)
Set actually used palette entry.
Definition: ncursesw.cc:580
NCursesWindow::meta
int meta(bool bf)
If called with bf=TRUE, keys may generate 8-Bit characters.
Definition: ncursesw.h:1682
NCursesWindow::getcolor
short getcolor() const
Actual color pair.
Definition: ncursesw.cc:553
NCursesWindow::par
NCursesWindow * par
parent, if subwindow
Definition: ncursesw.h:959
NCursesWindow::width
int width() const
Number of columns in this window.
Definition: ncursesw.h:1077
NCursesWindow::isDescendant
bool isDescendant(NCursesWindow &win)
Return TRUE if win is a descendant of this.
Definition: ncursesw.cc:416
NCursesWindow::keypad
int keypad(bool bf)
If called with bf=TRUE, the application will interpret function keys.
Definition: ncursesw.h:1676
NCursesWindow::NumberOfColors
static int NumberOfColors()
Number of available colors.
Definition: ncursesw.cc:544
NCursesWindow::kill_subwindows
void kill_subwindows()
Destroy all subwindows.
Definition: ncursesw.cc:433
wpos
Screen position pair in the order line, column: (L, C)
Definition: position.h:110
NCursesWindow::in_wchar
int in_wchar(cchar_t *cchar)
Retrieve combined character under the current cursor position.
Definition: ncursesw.cc:154
NCursesWindow::vline
int vline(int len, chtype ch=0)
Draw a vertical line of len characters with the given character.
Definition: ncursesw.h:1501
NCursesWindow::height
int height() const
Number of lines in this window.
Definition: ncursesw.h:1072
NCursesWindow::add_wch
int add_wch(const cchar_t *cch)
Put a combined character to the window.
Definition: ncursesw.h:1246
NCursesWindow::subwins
NCursesWindow * subwins
head of subwindows std::list
Definition: ncursesw.h:963
NCursesWindow::~NCursesWindow
virtual ~NCursesWindow()
Destructor.
Definition: ncursesw.cc:452
NCursesWindow::leaveok
int leaveok(bool bf)
If bf is TRUE, curses will leave the cursor after an update whereever it is after the update.
Definition: ncursesw.h:1625
NCursesWindow::printw
int printw(const char *fmt,...)
Do a formatted print to the window.
Definition: ncursesw.cc:76
NCursesWindow::begx
int begx() const
Column of top left corner relative to stdscr.
Definition: ncursesw.h:1082
NCursesWindow::count
static long count
count of all active windows
Definition: ncursesw.h:941
NCursesWindow::sib
NCursesWindow * sib
next subwindow of parent
Definition: ncursesw.h:967
NCursesWindow::NCursesWindow
NCursesWindow()
Only for use by derived classes.
Definition: ncursesw.cc:256
NCursesWindow::alloced
bool alloced
TRUE if we own the WINDOW.
Definition: ncursesw.h:954
NCursesWindow::Clone
NCursesWindow Clone()
Make an exact copy of the window.
Definition: ncursesw.cc:362
wrect
A rectangle is defined by its position and size: wpos Pos, wsze Sze.
Definition: position.h:194