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
38namespace 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
101namespace 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> {
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
160namespace 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?
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