curses++.h

00001 // curses++.h  (this is -*-c++-*-)
00002 //
00003 //  Copyright 1999-2005, 2007 Daniel Burrows
00004 //
00005 //  This program is free software; you can redistribute it and/or modify
00006 //  it under the terms of the GNU General Public License as published by
00007 //  the Free Software Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //
00010 //  This program is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //  GNU General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU General Public License
00016 //  along with this program; see the file COPYING.  If not, write to
00017 //  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018 //  Boston, MA 02111-1307, USA.
00019 //
00020 //  Simple class wrappers around various CURSES functions.
00021 
00022 #ifndef CURSES_PLUSPLUS_H
00023 #define CURSES_PLUSPLUS_H
00024 
00025 #include <string>
00026 #include <ncursesw/curses.h>
00027 
00028 #include <cwidget/generic/util/eassert.h>
00029 
00030 // For isspace
00031 #include <ctype.h>
00032 
00033 #include <string.h>
00034 
00035 #include <cwidget-config.h>
00036 
00037 namespace cwidget
00038 {
00047   struct wchtype
00048   {
00054     wchar_t ch;
00055 
00059     attr_t attrs;
00060 
00061     wchtype()
00062     {
00063     }
00064 
00065     wchtype(const wchar_t &_ch, const attr_t &_attrs)
00066       :ch(_ch), attrs(_attrs)
00067     {
00068     }
00069 
00070     bool operator==(const wchtype &other) const
00071     {
00072       return ch==other.ch && attrs==other.attrs;
00073     }
00074 
00075     bool operator!=(const wchtype &other) const
00076     {
00077       return ch!=other.ch || attrs!=other.attrs;
00078     }
00079 
00080     bool operator<(const wchtype &other) const
00081     {
00082       return ch<other.ch || (ch==other.ch && attrs<other.attrs);
00083     }
00084 
00085     bool operator<=(const wchtype &other) const
00086     {
00087       return (*this) == other || (*this) < other;
00088     }
00089 
00090     bool operator>(const wchtype &other) const
00091     {
00092       return !((*this)<=other);
00093     }
00094 
00095     bool operator>=(const wchtype &other) const
00096     {
00097       return !((*this)<other);
00098     }
00099   };
00100 }
00101 
00102 namespace std {
00103   template <>
00113   struct TRAITS_CLASS<chtype> {
00114     typedef chtype char_type;
00115 
00116     static void assign (char_type& c1, const char_type& c2)
00117     { c1 = c2; }
00118     static bool eq (const char_type & c1, const char_type& c2)
00119     { return (c1 == c2); }
00120     static bool ne (const char_type& c1, const char_type& c2)
00121     { return (c1 != c2); }
00122     static bool lt (const char_type& c1, const char_type& c2)
00123     { return (c1 < c2); }
00124     static char_type eos () { return 0; }
00125     static bool is_del(char_type a) { return isspace(a|A_CHARTEXT); }
00126 
00127     static int compare (const char_type* s1, const char_type* s2, size_t n);
00128     static size_t length (const char_type* s);
00129     static char_type* copy (char_type* s1, const char_type* s2, size_t n)
00130     { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); }
00131     static char_type* move (char_type* s1, const char_type* s2, size_t n)
00132     { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); }
00133     static char_type* assign (char_type* s1, size_t n, const char_type& c);
00134   };
00135 
00136   template <>
00137   struct TRAITS_CLASS<cwidget::wchtype> {
00138     typedef cwidget::wchtype char_type;
00139 
00140     static void assign (char_type& c1, const char_type& c2)
00141     { c1 = c2; }
00142     static bool eq (const char_type & c1, const char_type& c2)
00143     { return (c1 == c2); }
00144     static bool ne (const char_type& c1, const char_type& c2)
00145     { return (c1 != c2); }
00146     static bool lt (const char_type& c1, const char_type& c2)
00147     { return (c1 < c2); }
00148     static char_type eos () { return cwidget::wchtype(0,0); }
00149     static bool is_del(char_type a) { return isspace(a.ch); }
00150 
00151     static int compare (const char_type* s1, const char_type* s2, size_t n);
00152     static size_t length (const char_type* s);
00153     static char_type* copy (char_type* s1, const char_type* s2, size_t n)
00154     { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); }
00155     static char_type* move (char_type* s1, const char_type* s2, size_t n)
00156     { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); }
00157     static char_type* assign (char_type* s1, size_t n, const char_type& c);
00158   };
00159 }
00160 
00161 namespace cwidget
00162 {
00163   class style;
00164 
00170   class chstring:public std::basic_string<chtype>
00171   {
00172     typedef std::basic_string<chtype> super;
00173   public:
00174     chstring(const std::basic_string<chtype> &s)
00175       :std::basic_string<chtype>(s) {}
00176 
00177     chstring(const std::string &s);
00178     chstring(const std::string &s, const style &st);
00179 
00180     chstring(const chstring &s):super(s) {}
00184     chstring(const chstring &s, const style &st);
00185 
00186     chstring(const chstring &s, size_t loc, size_t n=npos)
00187       :super(s, loc, n) {}
00188 
00189     chstring(size_t n, chtype c)
00190       :super(n, c) {}
00191 
00193     chstring &operator=(const std::string &s);
00194 
00196     void apply_style(const style &st);
00197   };
00198 
00199   class wchstring:public std::basic_string<wchtype>
00200   {
00201     typedef std::basic_string<wchtype> super;
00202   public:
00203     wchstring(const std::basic_string<wchtype> &s)
00204       :std::basic_string<wchtype>(s) {}
00205 
00207     wchstring(const std::wstring &s);
00208 
00212     wchstring(const std::wstring &s, const style &st);
00213 
00214     wchstring(const wchstring &s):super(s) {}
00218     wchstring(const wchstring &s, const style &st);
00219 
00220     wchstring(const wchstring &s, size_t loc, size_t n=npos)
00221       :super(s, loc, n) {}
00222 
00223     wchstring(size_t n, wchtype c)
00224       :super(n, c) {}
00225 
00226     wchstring(size_t n, wchar_t c, attr_t a)
00227       :super(n, wchtype(c, a)) {}
00228 
00230     void apply_style(const style &st);
00231 
00233     int width() const;
00234   };
00235 
00236   inline chtype _getbkgd(WINDOW *win)
00237   {
00238     return getbkgd(win);
00239   }
00240 
00241   inline int _box(WINDOW *win, chtype verch, chtype horch)
00242   {
00243     return box(win, verch, horch);
00244   }
00245 
00246   inline void _getyx(WINDOW *win, int &y, int &x)
00247   {
00248     getyx(win, y, x);
00249   }
00250 
00251   inline void _getparyx(WINDOW *win, int &y, int &x)
00252   {
00253     getparyx(win, y, x);
00254   }
00255 
00256   inline void _getbegyx(WINDOW *win, int &y, int &x)
00257   {
00258     getbegyx(win, y, x);
00259   }
00260 
00261   inline void _getmaxyx(WINDOW *win, int &y, int &x)
00262   {
00263     getmaxyx(win, y, x);
00264   }
00265 
00266   inline int _getmaxy(WINDOW *win)
00267   {
00268     return getmaxy(win);
00269   }
00270 
00271   inline int _getmaxx(WINDOW *win)
00272   {
00273     return getmaxx(win);
00274   }
00275 
00276   inline int _touchwin(WINDOW *win)
00277   {
00278     return touchwin(win);
00279   }
00280 
00281   inline int _untouchwin(WINDOW *win)
00282   {
00283     return untouchwin(win);
00284   }
00285 
00286 #undef getbkgd
00287 #undef box
00288 
00289 #undef getyx
00290 #undef getparyx
00291 #undef getbegyx
00292 #undef getmaxyx
00293 #undef getmaxy
00294 #undef getmaxx
00295 
00296 #undef addch
00297 #undef addchnstr
00298 #undef addchstr
00299 #undef add_wch
00300 #undef addnstr
00301 #undef addstr
00302 #undef attroff
00303 #undef attron
00304 #undef attrset
00305 #undef attr_set
00306 #undef bkgd
00307 #undef bkgdset
00308 #undef clear
00309 #undef clrtobot
00310 #undef clrtoeol
00311 #undef delch
00312 #undef deleteln
00313 #undef echochar
00314 #undef erase
00315 #undef getch
00316 #undef get_wch
00317 #undef getstr
00318 #undef inch
00319 #undef inchnstr
00320 #undef innstr
00321 #undef insch
00322 #undef insdelln
00323 #undef insertln
00324 #undef insnstr
00325 #undef insstr
00326 #undef instr
00327 #undef move
00328 #undef refresh
00329 #undef scrl
00330 #undef scroll
00331 #undef setscrreg
00332 #undef standend
00333 #undef standout
00334 #undef timeout
00335 
00336 #undef mvaddch
00337 #undef mvadd_wch
00338 #undef mvaddchnstr
00339 #undef mvaddchstr
00340 #undef mvaddnstr
00341 #undef mvaddstr
00342 #undef mvdelch
00343 #undef mvgetch
00344 #undef mvget_wch
00345 #undef mvgetnstr
00346 #undef mvgetstr
00347 #undef mvhline
00348 #undef mvinch
00349 #undef mvinchnstr
00350 #undef mvinchstr
00351 #undef mvinnstr
00352 #undef mvinsch
00353 #undef mvinsnstr
00354 #undef mvinsstr
00355 #undef mvinstr
00356 #undef mvvline
00357 
00358 #undef border
00359 #undef hline
00360 #undef vline
00361 
00362 #undef touchline
00363 
00364   //  The following class encapsulates a CURSES window, mostly with inlined
00365   // versions of w* and mvw*.  subwin and newwin are encapsulated with
00366   // constructors; casting to WINDOW * is also supported.
00367   //
00368   //  er, these will be inlined.  Right?
00369   class cwindow
00370   {
00371     // Blech.  Used to memory-manage WINDOW *s
00372     class cwindow_master
00373     {
00374       WINDOW *win;
00375       int refs;
00376       cwindow_master *parent;
00377 
00378       friend class cwindow;
00379 
00380       ~cwindow_master()
00381       {
00382         eassert(refs==0);
00383 
00384         if(win)
00385           delwin(win);
00386         if(parent)
00387           parent->deref();
00388       }
00389     public:
00390       cwindow_master(WINDOW *_win, cwindow_master *_parent)
00391         :win(_win), refs(0), parent(_parent)
00392       {
00393         if(parent)
00394           parent->ref();
00395       }
00396 
00397       inline void ref()
00398       {
00399         refs++;
00400       }
00401 
00402       // ??????
00403       inline void deref()
00404       {
00405         refs--;
00406 
00407         if(refs==0)
00408           delete this;
00409       }
00410     };
00411 
00412     WINDOW *win;
00413     // The actual curses window
00414 
00415     cwindow_master *master;
00416     // Keeps track of where we got this from (so we can deref() it later)
00417 
00418     cwindow(WINDOW *_win, cwindow_master *_master)
00419       :win(_win), master(_master)
00420     {
00421       master->ref();
00422     }
00423   public:
00424     cwindow(WINDOW *_win):win(_win), master(new cwindow_master(_win, NULL))
00425     {
00426       master->ref();
00427     }
00428     cwindow(const cwindow &a):win(a.win), master(a.master)
00429     {
00430       master->ref();
00431     }
00432 
00433     ~cwindow()
00434     {
00435       master->deref();
00436     }
00437 
00438     cwindow derwin(int h, int w, int y, int x)
00439     {
00440       WINDOW *new_win=::derwin(win, h, w, y, x);
00441       return cwindow(new_win, new cwindow_master(new_win, master));
00442     }
00443 
00444     int mvwin(int y, int x) {return ::mvwin(win, y, x);}
00445 
00446     void syncup() {wsyncup(win);}
00447     int syncok(bool bf) {return ::syncok(win, bf);}
00448     void cursyncup() {wcursyncup(win);}
00449     void syncdown() {wsyncdown(win);}
00450 
00451     int scroll(int n=1) {return wscrl(win, n);}
00452     // Does both scroll() and wscsrl()
00453 
00454     int addch(chtype ch) {return waddch(win, ch);}
00455     int mvaddch(int y, int x, chtype ch) {return mvwaddch(win, y, x, ch);}
00456 
00457     int add_wch(wchar_t wch)
00458     {
00459       wchar_t tmp[2];
00460       tmp[0]=wch;
00461       tmp[1]=0;
00462 
00463       cchar_t cch;
00464       if(setcchar(&cch, tmp, 0, 0, 0)==ERR)
00465         return ERR;
00466       else
00467         return wadd_wch(win, &cch);
00468     }
00469 
00470     int mvadd_wch(int y, int x, wchar_t wch)
00471     {
00472       move(y, x);
00473       return add_wch(wch);
00474     }
00475 
00476     int add_wch(const cchar_t *cch)
00477     {
00478       return wadd_wch(win, cch);
00479     }
00480 
00481     int mvadd_wch(int y, int x, const cchar_t *cch)
00482     {
00483       return mvwadd_wch(win, y, x, cch);
00484     }
00485 
00486     int addstr(const std::wstring &str) {return addstr(str.c_str());}
00487     int addnstr(const std::wstring &str, int n) {return addnstr(str.c_str(), n);}
00488     int mvaddstr(int y, int x, const std::wstring &str) {return mvaddstr(y, x, str.c_str());}
00489     int mvaddnstr(int y, int x, const std::wstring &str, int n) {return mvaddnstr(y, x, str.c_str(), n);}
00490 
00491     int addstr(const wchar_t *str) {return waddwstr(win, str);}
00492     int addnstr(const wchar_t *str, int n) {return waddnwstr(win, str, n);}
00493     int mvaddstr(int y, int x, const wchar_t *str) {return mvwaddwstr(win, y, x, str);}
00494     int mvaddnstr(int y, int x, const wchar_t *str, int n) {return mvwaddnwstr(win, y, x, str, n);}
00495 
00496     int addstr(const char *str) {return waddstr(win, str);}
00497     int addnstr(const char *str, int n) {return waddnstr(win, str, n);}
00498     int mvaddstr(int y, int x, const char *str) {return mvwaddstr(win, y, x, str);}
00499     int mvaddnstr(int y, int x, const char *str, int n) {return mvwaddnstr(win, y, x, str, n);}
00500 
00501     // The following are implemented hackily due to the weirdness of
00502     // curses.  NB: they don't work with characters of negative width.
00503     int addstr(const wchstring &str);
00504     int addnstr(const wchstring &str, size_t n);
00505     int mvaddstr(int y, int x, const wchstring &str);
00506     int mvaddnstr(int y, int x, const wchstring &str, size_t n);
00507 
00508     int addstr(const chstring &str) {return waddchstr(win, str.c_str());}
00509     int addnstr(const chstring &str, int n) {return waddchnstr(win, str.c_str(), n);}
00510     int mvaddstr(int y, int x, const chstring &str) {return mvwaddchstr(win, y, x, str.c_str());}
00511     int mvaddnstr(int y, int x, const chstring &str, int n) {return mvwaddchnstr(win, y, x, str.c_str(), n);}
00512 
00513     int attroff(int attrs) {return wattroff(win, attrs);}
00514     int attron(int attrs) {return wattron(win, attrs);}
00515     int attrset(int attrs) {return wattrset(win, attrs);}
00516     //  int attr_set(int attrs, void *opts) {return wattr_set(win, attrs, opts);}
00517 
00518     void bkgdset(const chtype ch) {wbkgdset(win, ch);}
00519     int bkgd(const chtype ch) {return wbkgd(win, ch);}
00520     chtype getbkgd() {return _getbkgd(win);}
00521 
00522     int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br)
00523     {return wborder(win, ls, rs, ts, bs, tl, tr, bl, br);}
00524 
00525     int box(chtype verch, chtype horch) {return _box(win, verch, horch);}
00526     int hline(chtype ch, int n) {return whline(win, ch, n);}
00527     int vline(chtype ch, int n) {return wvline(win, ch, n);}
00528     int mvhline(int y, int x, chtype ch, int n) {return mvwhline(win, y, x, ch, n);}
00529     int mvvline(int y, int x, chtype ch, int n) {return mvwvline(win, y, x, ch, n);}
00530 
00531     int delch() {return wdelch(win);}
00532     int mvdelch(int y, int x) {return mvwdelch(win, y, x);}
00533 
00534     int deleteln() {return wdeleteln(win);}
00535     int insdelln(int n) {return winsdelln(win,n);}
00536     int insertln() {return winsertln(win);}
00537 
00538     int echochar(chtype ch) {return wechochar(win, ch);}
00539 
00540     int getch() {return wgetch(win);}
00541     int mvgetch(int y, int x) {return mvwgetch(win, y, x);}
00542 
00543     int get_wch(wint_t *wch) {return wget_wch(win, wch);}
00544     int mvget_wch(int y, int x, wint_t *wch) {return mvwget_wch(win, y, x, wch);}
00545 
00546     int move(int y, int x) {return wmove(win, y, x);}
00547     void getyx(int &y, int &x) {_getyx(win, y, x);}
00548     void getparyx(int &y, int &x) {_getparyx(win, y, x);}
00549     void getbegyx(int &y, int &x) {_getbegyx(win, y, x);}
00550     void getmaxyx(int &y, int &x) {_getmaxyx(win, y, x);}
00551     int getmaxy() {return _getmaxy(win);}
00552     int getmaxx() {return _getmaxx(win);}
00553 
00554     void show_string_as_progbar(int x, int y, const std::wstring &s,
00555                                 int attr1, int attr2, int size1,
00556                                 int totalsize);
00557     // Glitz bit :) Displays the given string with a progress bar behind it.
00558 
00559     void display_header(std::wstring s, const attr_t attr);
00560     void display_status(std::wstring s, const attr_t attr);
00561     // Make it easier to write interfaces that have a header and status line..
00562     // they do what they say :)
00563 
00564     int overlay(cwindow &dstwin) {return ::overlay(win, dstwin.win);}
00565     int overwrite(cwindow &dstwin) {return ::overwrite(win, dstwin.win);}
00566     int copywin(cwindow &dstwin, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int overlay)
00567     {return ::copywin(win, dstwin.win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, overlay);}
00568 
00569     int refresh() {return wrefresh(win);}
00570     int noutrefresh() {return wnoutrefresh(win);}
00571 
00572     int touch() {return _touchwin(win);}
00573     int untouch() {return _untouchwin(win);}
00574     int touchln(int y, int n, int changed) {return ::wtouchln(win, y, n, changed);}
00575     int touchline(int start, int count) {return touchln(start, count, 1);}
00576     int untouchline(int start, int count) {return touchln(start, count, 0);}
00577 
00578     int erase() {return werase(win);}
00579     int clear() {return wclear(win);}
00580     int clrtobot() {return wclrtobot(win);}
00581     int clrtoeol() {return wclrtoeol(win);}
00582 
00583     int keypad(bool bf) {return ::keypad(win,bf);}
00584     int meta(bool bf) {return ::meta(win,bf);}
00585     int nodelay(bool bf) {return ::nodelay(win, bf);}
00586     int notimeout(bool bf) {return ::notimeout(win, bf);}
00587     void timeout(int delay) {wtimeout(win, delay);}
00588 
00589     int clearok(bool bf) {return ::clearok(win, bf);}
00590     int idlok(bool bf) {return ::idlok(win, bf);}
00591     void idcok(bool bf) {::idcok(win, bf);}
00592     void immedok(bool bf) {::immedok(win, bf);}
00593 #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR>=5
00594     int leaveok(bool bf) {int rval=::leaveok(win, bf); curs_set(bf?0:1); return rval;}
00595 #else
00596     int leaveok(bool bf) {return ::leaveok(win, bf);}
00597 #endif
00598     int setscrreg(int top, int bot) {return wsetscrreg(win, top, bot);}
00599     int scrollok(bool bf) {return ::scrollok(win,bf);}
00600 
00601     int printw(char *str, ...);
00602     /* You guessed it.. :) */
00603 
00604     bool enclose(int y, int x) {return wenclose(win, y, x);}
00605 
00606     WINDOW *getwin() {return win;}
00607     operator bool () {return win!=NULL;}
00608     cwindow &operator =(const cwindow &a)
00609     {
00610       cwindow_master *newmaster=a.master;
00611       newmaster->ref();
00612 
00613       master->deref();
00614       master=newmaster;
00615       win=a.win;
00616       return *this;
00617     }
00618     bool operator ==(cwindow &other) {return win==other.win;}
00619     bool operator !=(cwindow &other) {return win!=other.win;}
00620 
00621     static void remove_cruft();
00622   };
00623 
00624   extern cwindow rootwin;
00625   // This is stdscr, but calling it 'stdscr' would confuse the compiler, so I'm
00626   // confusing the programmer instead :)
00627 
00628   void init_curses();
00629   // Initializes curses and sets rootwin to the correct value
00630 
00631   void resize();
00632   // Called when a terminal resize is detected.
00633 }
00634 
00635 #endif

Generated on Fri Feb 8 12:54:56 2008 for cwidget by  doxygen 1.5.4