cwidget  0.5.18
curses++.h
1 // curses++.h (this is -*-c++-*-)
2 //
3 // Copyright 1999-2005, 2007 Daniel Burrows
4 // Copyright 2019 Manuel A. Fernandez Montecelo
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; see the file COPYING. If not, write to
18 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 // Boston, MA 02111-1307, USA.
20 //
21 // Simple class wrappers around various CURSES functions.
22 
23 #ifndef CURSES_PLUSPLUS_H
24 #define CURSES_PLUSPLUS_H
25 
26 #include <string>
27 #include <ncursesw/curses.h>
28 
29 #include <cwidget/generic/util/eassert.h>
30 
31 // For isspace
32 #include <ctype.h>
33 
34 #include <string.h>
35 
36 #include <cwidget-config.h>
37 
38 namespace cwidget
39 {
48  struct wchtype
49  {
55  wchar_t ch;
56 
60  attr_t attrs;
61 
62  wchtype() = default;
63 
64  wchtype(const wchar_t &_ch, const attr_t &_attrs)
65  :ch(_ch), attrs(_attrs)
66  {
67  }
68 
69  bool operator==(const wchtype &other) const
70  {
71  return ch==other.ch && attrs==other.attrs;
72  }
73 
74  bool operator!=(const wchtype &other) const
75  {
76  return ch!=other.ch || attrs!=other.attrs;
77  }
78 
79  bool operator<(const wchtype &other) const
80  {
81  return ch<other.ch || (ch==other.ch && attrs<other.attrs);
82  }
83 
84  bool operator<=(const wchtype &other) const
85  {
86  return (*this) == other || (*this) < other;
87  }
88 
89  bool operator>(const wchtype &other) const
90  {
91  return !((*this)<=other);
92  }
93 
94  bool operator>=(const wchtype &other) const
95  {
96  return !((*this)<other);
97  }
98  };
99 }
100 
101 namespace std {
102  template <>
112  struct TRAITS_CLASS<chtype> {
113  typedef chtype char_type;
114 
115  static void assign (char_type& c1, const char_type& c2)
116  { c1 = c2; }
117  static bool eq (const char_type & c1, const char_type& c2)
118  { return (c1 == c2); }
119  static bool ne (const char_type& c1, const char_type& c2)
120  { return (c1 != c2); }
121  static bool lt (const char_type& c1, const char_type& c2)
122  { return (c1 < c2); }
123  static char_type eos () { return 0; }
124  static bool is_del(char_type a) { return isspace(a|A_CHARTEXT); }
125 
126  static int compare (const char_type* s1, const char_type* s2, size_t n);
127  static size_t length (const char_type* s);
128  static char_type* copy (char_type* s1, const char_type* s2, size_t n)
129  { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); }
130  static char_type* move (char_type* s1, const char_type* s2, size_t n)
131  { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); }
132  static char_type* assign (char_type* s1, size_t n, const char_type& c);
133  };
134 
135  template <>
136  struct TRAITS_CLASS<cwidget::wchtype> {
137  typedef cwidget::wchtype char_type;
138 
139  static void assign (char_type& c1, const char_type& c2)
140  { c1 = c2; }
141  static bool eq (const char_type & c1, const char_type& c2)
142  { return (c1 == c2); }
143  static bool ne (const char_type& c1, const char_type& c2)
144  { return (c1 != c2); }
145  static bool lt (const char_type& c1, const char_type& c2)
146  { return (c1 < c2); }
147  static char_type eos () { return cwidget::wchtype(0,0); }
148  static bool is_del(char_type a) { return isspace(a.ch); }
149 
150  static int compare (const char_type* s1, const char_type* s2, size_t n);
151  static size_t length (const char_type* s);
152  static char_type* copy (char_type* s1, const char_type* s2, size_t n)
153  { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); }
154  static char_type* move (char_type* s1, const char_type* s2, size_t n)
155  { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); }
156  static char_type* assign (char_type* s1, size_t n, const char_type& c);
157  };
158 }
159 
160 namespace cwidget
161 {
162  class style;
163 
169  class chstring:public std::basic_string<chtype>
170  {
171  typedef std::basic_string<chtype> super;
172  public:
173  chstring(const std::basic_string<chtype> &s)
174  :std::basic_string<chtype>(s) {}
175 
176  chstring(const std::string &s);
177  chstring(const std::string &s, const style &st);
178 
179  chstring(const chstring &s):super(s) {}
183  chstring(const chstring &s, const style &st);
184 
185  chstring(const chstring &s, size_t loc, size_t n=npos)
186  :super(s, loc, n) {}
187 
188  chstring(size_t n, chtype c)
189  :super(n, c) {}
190 
192  chstring &operator=(const std::string &s);
193 
195  void apply_style(const style &st);
196  };
197 
198  class wchstring:public std::basic_string<wchtype>
199  {
200  typedef std::basic_string<wchtype> super;
201  public:
202  wchstring(const std::basic_string<wchtype> &s)
203  :std::basic_string<wchtype>(s) {}
204 
206  wchstring(const std::wstring &s);
207 
211  wchstring(const std::wstring &s, const style &st);
212 
213  wchstring(const wchstring &s):super(s) {}
217  wchstring(const wchstring &s, const style &st);
218 
219  wchstring(const wchstring &s, size_t loc, size_t n=npos)
220  :super(s, loc, n) {}
221 
222  wchstring(size_t n, wchtype c)
223  :super(n, c) {}
224 
225  wchstring(size_t n, wchar_t c, attr_t a)
226  :super(n, wchtype(c, a)) {}
227 
229  void apply_style(const style &st);
230 
232  int width() const;
233  };
234 
235  inline chtype _getbkgd(WINDOW *win)
236  {
237  return getbkgd(win);
238  }
239 
240  inline int _box(WINDOW *win, chtype verch, chtype horch)
241  {
242  return box(win, verch, horch);
243  }
244 
245  inline void _getyx(WINDOW *win, int &y, int &x)
246  {
247  getyx(win, y, x);
248  }
249 
250  inline void _getparyx(WINDOW *win, int &y, int &x)
251  {
252  getparyx(win, y, x);
253  }
254 
255  inline void _getbegyx(WINDOW *win, int &y, int &x)
256  {
257  getbegyx(win, y, x);
258  }
259 
260  inline void _getmaxyx(WINDOW *win, int &y, int &x)
261  {
262  getmaxyx(win, y, x);
263  }
264 
265  inline int _getmaxy(WINDOW *win)
266  {
267  return getmaxy(win);
268  }
269 
270  inline int _getmaxx(WINDOW *win)
271  {
272  return getmaxx(win);
273  }
274 
275  inline int _touchwin(WINDOW *win)
276  {
277  return touchwin(win);
278  }
279 
280  inline int _untouchwin(WINDOW *win)
281  {
282  return untouchwin(win);
283  }
284 
285 #undef getbkgd
286 #undef box
287 
288 #undef getyx
289 #undef getparyx
290 #undef getbegyx
291 #undef getmaxyx
292 #undef getmaxy
293 #undef getmaxx
294 
295 #undef addch
296 #undef addchnstr
297 #undef addchstr
298 #undef add_wch
299 #undef addnstr
300 #undef addstr
301 #undef attroff
302 #undef attron
303 #undef attrset
304 #undef attr_set
305 #undef bkgd
306 #undef bkgdset
307 #undef clear
308 #undef clrtobot
309 #undef clrtoeol
310 #undef delch
311 #undef deleteln
312 #undef echochar
313 #undef erase
314 #undef getch
315 #undef get_wch
316 #undef getstr
317 #undef inch
318 #undef inchnstr
319 #undef innstr
320 #undef insch
321 #undef insdelln
322 #undef insertln
323 #undef insnstr
324 #undef insstr
325 #undef instr
326 #undef move
327 #undef refresh
328 #undef scrl
329 #undef scroll
330 #undef setscrreg
331 #undef standend
332 #undef standout
333 #undef timeout
334 
335 #undef mvaddch
336 #undef mvadd_wch
337 #undef mvaddchnstr
338 #undef mvaddchstr
339 #undef mvaddnstr
340 #undef mvaddstr
341 #undef mvdelch
342 #undef mvgetch
343 #undef mvget_wch
344 #undef mvgetnstr
345 #undef mvgetstr
346 #undef mvhline
347 #undef mvinch
348 #undef mvinchnstr
349 #undef mvinchstr
350 #undef mvinnstr
351 #undef mvinsch
352 #undef mvinsnstr
353 #undef mvinsstr
354 #undef mvinstr
355 #undef mvvline
356 
357 #undef border
358 #undef hline
359 #undef vline
360 
361 #undef touchline
362 
363  // The following class encapsulates a CURSES window, mostly with inlined
364  // versions of w* and mvw*. subwin and newwin are encapsulated with
365  // constructors; casting to WINDOW * is also supported.
366  //
367  // er, these will be inlined. Right?
368  class cwindow
369  {
370  // Blech. Used to memory-manage WINDOW *s
371  class cwindow_master
372  {
373  WINDOW *win;
374  int refs;
375  cwindow_master *parent;
376 
377  friend class cwindow;
378 
379  ~cwindow_master()
380  {
381  eassert(refs==0);
382 
383  if(win)
384  delwin(win);
385  if(parent)
386  parent->deref();
387  }
388  public:
389  cwindow_master(WINDOW *_win, cwindow_master *_parent)
390  :win(_win), refs(0), parent(_parent)
391  {
392  if(parent)
393  parent->ref();
394  }
395 
396  inline void ref()
397  {
398  refs++;
399  }
400 
401  // ??????
402  inline void deref()
403  {
404  refs--;
405 
406  if(refs==0)
407  delete this;
408  }
409  };
410 
411  WINDOW *win;
412  // The actual curses window
413 
414  cwindow_master *master;
415  // Keeps track of where we got this from (so we can deref() it later)
416 
417  cwindow(WINDOW *_win, cwindow_master *_master)
418  :win(_win), master(_master)
419  {
420  master->ref();
421  }
422  public:
423  cwindow(WINDOW *_win):win(_win), master(new cwindow_master(_win, NULL))
424  {
425  master->ref();
426  }
427  cwindow(const cwindow &a):win(a.win), master(a.master)
428  {
429  master->ref();
430  }
431 
432  ~cwindow()
433  {
434  master->deref();
435  }
436 
437  cwindow derwin(int h, int w, int y, int x)
438  {
439  WINDOW *new_win=::derwin(win, h, w, y, x);
440  return cwindow(new_win, new cwindow_master(new_win, master));
441  }
442 
443  int mvwin(int y, int x) {return ::mvwin(win, y, x);}
444 
445  void syncup() {wsyncup(win);}
446  int syncok(bool bf) {return ::syncok(win, bf);}
447  void cursyncup() {wcursyncup(win);}
448  void syncdown() {wsyncdown(win);}
449 
450  int scroll(int n=1) {return wscrl(win, n);}
451  // Does both scroll() and wscsrl()
452 
453  int addch(chtype ch) {return waddch(win, ch);}
454  int mvaddch(int y, int x, chtype ch) {return mvwaddch(win, y, x, ch);}
455 
456  int add_wch(wchar_t wch)
457  {
458  wchar_t tmp[2];
459  tmp[0]=wch;
460  tmp[1]=0;
461 
462  cchar_t cch;
463  if(setcchar(&cch, tmp, 0, 0, 0)==ERR)
464  return ERR;
465  else
466  return wadd_wch(win, &cch);
467  }
468 
469  int mvadd_wch(int y, int x, wchar_t wch)
470  {
471  move(y, x);
472  return add_wch(wch);
473  }
474 
475  int add_wch(const cchar_t *cch)
476  {
477  return wadd_wch(win, cch);
478  }
479 
480  int mvadd_wch(int y, int x, const cchar_t *cch)
481  {
482  return mvwadd_wch(win, y, x, cch);
483  }
484 
485  int addstr(const std::wstring &str) {return addstr(str.c_str());}
486  int addnstr(const std::wstring &str, int n) {return addnstr(str.c_str(), n);}
487  int mvaddstr(int y, int x, const std::wstring &str) {return mvaddstr(y, x, str.c_str());}
488  int mvaddnstr(int y, int x, const std::wstring &str, int n) {return mvaddnstr(y, x, str.c_str(), n);}
489 
490  int addstr(const wchar_t *str) {return waddwstr(win, str);}
491  int addnstr(const wchar_t *str, int n) {return waddnwstr(win, str, n);}
492  int mvaddstr(int y, int x, const wchar_t *str) {return mvwaddwstr(win, y, x, str);}
493  int mvaddnstr(int y, int x, const wchar_t *str, int n) {return mvwaddnwstr(win, y, x, str, n);}
494 
495  int addstr(const char *str) {return waddstr(win, str);}
496  int addnstr(const char *str, int n) {return waddnstr(win, str, n);}
497  int mvaddstr(int y, int x, const char *str) {return mvwaddstr(win, y, x, str);}
498  int mvaddnstr(int y, int x, const char *str, int n) {return mvwaddnstr(win, y, x, str, n);}
499 
500  // The following are implemented hackily due to the weirdness of
501  // curses. NB: they don't work with characters of negative width.
502  int addstr(const wchstring &str);
503  int addnstr(const wchstring &str, size_t n);
504  int mvaddstr(int y, int x, const wchstring &str);
505  int mvaddnstr(int y, int x, const wchstring &str, size_t n);
506 
507  int addstr(const chstring &str) {return waddchstr(win, str.c_str());}
508  int addnstr(const chstring &str, int n) {return waddchnstr(win, str.c_str(), n);}
509  int mvaddstr(int y, int x, const chstring &str) {return mvwaddchstr(win, y, x, str.c_str());}
510  int mvaddnstr(int y, int x, const chstring &str, int n) {return mvwaddchnstr(win, y, x, str.c_str(), n);}
511 
512  int attroff(int attrs) {return wattroff(win, attrs);}
513  int attron(int attrs) {return wattron(win, attrs);}
514  int attrset(int attrs) {return wattrset(win, attrs);}
515  // int attr_set(int attrs, void *opts) {return wattr_set(win, attrs, opts);}
516 
517  void bkgdset(const chtype ch) {wbkgdset(win, ch);}
518  int bkgd(const chtype ch) {return wbkgd(win, ch);}
519  chtype getbkgd() {return _getbkgd(win);}
520 
521  int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br)
522  {return wborder(win, ls, rs, ts, bs, tl, tr, bl, br);}
523 
524  int box(chtype verch, chtype horch) {return _box(win, verch, horch);}
525  int hline(chtype ch, int n) {return whline(win, ch, n);}
526  int vline(chtype ch, int n) {return wvline(win, ch, n);}
527  int mvhline(int y, int x, chtype ch, int n) {return mvwhline(win, y, x, ch, n);}
528  int mvvline(int y, int x, chtype ch, int n) {return mvwvline(win, y, x, ch, n);}
529 
530  int delch() {return wdelch(win);}
531  int mvdelch(int y, int x) {return mvwdelch(win, y, x);}
532 
533  int deleteln() {return wdeleteln(win);}
534  int insdelln(int n) {return winsdelln(win,n);}
535  int insertln() {return winsertln(win);}
536 
537  int echochar(chtype ch) {return wechochar(win, ch);}
538 
539  int getch() {return wgetch(win);}
540  int mvgetch(int y, int x) {return mvwgetch(win, y, x);}
541 
542  int get_wch(wint_t *wch) {return wget_wch(win, wch);}
543  int mvget_wch(int y, int x, wint_t *wch) {return mvwget_wch(win, y, x, wch);}
544 
545  int move(int y, int x) {return wmove(win, y, x);}
546  void getyx(int &y, int &x) {_getyx(win, y, x);}
547  void getparyx(int &y, int &x) {_getparyx(win, y, x);}
548  void getbegyx(int &y, int &x) {_getbegyx(win, y, x);}
549  void getmaxyx(int &y, int &x) {_getmaxyx(win, y, x);}
550  int getmaxy() {return _getmaxy(win);}
551  int getmaxx() {return _getmaxx(win);}
552 
553  void show_string_as_progbar(int x, int y, const std::wstring &s,
554  int attr1, int attr2, int size1,
555  int totalsize);
556  // Glitz bit :) Displays the given string with a progress bar behind it.
557 
558  void display_header(std::wstring s, const attr_t attr);
559  void display_status(std::wstring s, const attr_t attr);
560  // Make it easier to write interfaces that have a header and status line..
561  // they do what they say :)
562 
563  int overlay(cwindow &dstwin) {return ::overlay(win, dstwin.win);}
564  int overwrite(cwindow &dstwin) {return ::overwrite(win, dstwin.win);}
565  int copywin(cwindow &dstwin, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int overlay)
566  {return ::copywin(win, dstwin.win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, overlay);}
567 
568  int refresh() {return wrefresh(win);}
569  int noutrefresh() {return wnoutrefresh(win);}
570 
571  int touch() {return _touchwin(win);}
572  int untouch() {return _untouchwin(win);}
573  int touchln(int y, int n, int changed) {return ::wtouchln(win, y, n, changed);}
574  int touchline(int start, int count) {return touchln(start, count, 1);}
575  int untouchline(int start, int count) {return touchln(start, count, 0);}
576 
577  int erase() {return werase(win);}
578  int clear() {return wclear(win);}
579  int clrtobot() {return wclrtobot(win);}
580  int clrtoeol() {return wclrtoeol(win);}
581 
582  int keypad(bool bf) {return ::keypad(win,bf);}
583  int meta(bool bf) {return ::meta(win,bf);}
584  int nodelay(bool bf) {return ::nodelay(win, bf);}
585  int notimeout(bool bf) {return ::notimeout(win, bf);}
586  void timeout(int delay) {wtimeout(win, delay);}
587 
588  int clearok(bool bf) {return ::clearok(win, bf);}
589  int idlok(bool bf) {return ::idlok(win, bf);}
590  void idcok(bool bf) {::idcok(win, bf);}
591  void immedok(bool bf) {::immedok(win, bf);}
592 #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR>=5
593  int leaveok(bool bf) {int rval=::leaveok(win, bf); curs_set(bf?0:1); return rval;}
594 #else
595  int leaveok(bool bf) {return ::leaveok(win, bf);}
596 #endif
597  int setscrreg(int top, int bot) {return wsetscrreg(win, top, bot);}
598  int scrollok(bool bf) {return ::scrollok(win,bf);}
599 
600  int printw(char *str, ...);
601  /* You guessed it.. :) */
602 
603  bool enclose(int y, int x) {return wenclose(win, y, x);}
604 
605  WINDOW *getwin() {return win;}
606  operator bool () {return win!=NULL;}
607  cwindow &operator =(const cwindow &a)
608  {
609  cwindow_master *newmaster=a.master;
610  newmaster->ref();
611 
612  master->deref();
613  master=newmaster;
614  win=a.win;
615  return *this;
616  }
617  bool operator ==(cwindow &other) {return win==other.win;}
618  bool operator !=(cwindow &other) {return win!=other.win;}
619 
620  static void remove_cruft();
621  };
622 
623  extern cwindow rootwin;
624  // This is stdscr, but calling it 'stdscr' would confuse the compiler, so I'm
625  // confusing the programmer instead :)
626 
627  void init_curses();
628  // Initializes curses and sets rootwin to the correct value
629 
630  void resize();
631  // Called when a terminal resize is detected.
632 }
633 
634 #endif
A string class which stores attributes along with characters.
Definition: curses++.h:170
void apply_style(const style &st)
Change the attributes of this string by using the given style.
Definition: curses++.cc:62
chstring & operator=(const std::string &s)
Assign the characters of s to this, setting all attributes to A_NORMAL.
Definition: curses++.cc:209
Definition: curses++.h:369
A "style" is a setting to be applied to a display element (widget, text, etc).
Definition: style.h:52
Definition: curses++.h:199
wchstring(const std::wstring &s)
Create a new wchstring with empty attribute information.
wchstring(const std::wstring &s, const style &st)
Create a new wchstring from the given wide string with the given attributes.
void apply_style(const style &st)
Change the attributes of this string by using the given style.
Definition: curses++.cc:89
int width() const
Return the number of columns occupied by this string.
Definition: curses++.cc:95
The namespace containing everything defined by cwidget.
Definition: columnify.cc:28
A structure that amalgamates a wchar_t together with attributes.
Definition: curses++.h:49
attr_t attrs
The text attributes (including color) associated with this character.
Definition: curses++.h:60
wchar_t ch
The character value associated with this string.
Definition: curses++.h:55