home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / GCC / GERLIB_DEV08B.LHA / gerlib / libg++ / src / CursesW.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-12  |  5.4 KB  |  256 lines

  1. /* 
  2. Copyright (C) 1989, 1992 Free Software Foundation
  3.     written by Eric Newton (newton@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef __GNUG__
  18. #pragma implementation
  19. #endif
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <builtin.h>
  23. #include <values.h>
  24. #ifndef _OLD_STREAMS
  25. #include <strstream.h>
  26. //#include <ioprivate.h>
  27. #endif
  28. // Include CurseW.h and/or curses.h *after* iostream includes,
  29. // because curses.h defines a clear macro that conflicts with iostream. Sigh.
  30. #include <CursesW.h>
  31.  
  32. #if _G_HAVE_CURSES
  33.  
  34. int CursesWindow::count = 0;
  35.  
  36. /*
  37.  * C++ interface to curses library.
  38.  *
  39.  */
  40.  
  41. #if !defined(_IO_MAGIC) && !defined(HAVE_VSCANF) &&!defined vsscanf
  42. extern "C" int _doscan(FILE *, const char*, va_list args);
  43.  
  44. static int vsscanf(char *buf, const char * fmt, va_list args)
  45. {
  46.   FILE b;
  47. #ifdef _IOSTRG
  48.   b._flag = _IOREAD|_IOSTRG;
  49. #else
  50.   b._flag = _IOREAD;
  51. #endif
  52.   b._base = (unsigned char*)buf;
  53.   b._ptr = (unsigned char*)buf;
  54.   b._cnt = BUFSIZ;
  55.   return _doscan(&b, fmt, args);
  56. }
  57. #endif
  58.  
  59. /*
  60.  * varargs functions are handled conservatively:
  61.  * They interface directly into the underlying 
  62.  * _doscan, _doprnt and/or vfprintf routines rather than
  63.  * assume that such things are handled compatibly in the curses library
  64.  */
  65.  
  66. int CursesWindow::scanw(const char * fmt, ...)
  67. {
  68.   va_list args;
  69.   va_start(args, fmt);
  70. #ifdef VMS
  71.   int result = wscanw(w , fmt , args);
  72. #else /* NOT VMS */
  73.   char buf[BUFSIZ];
  74.   int result = wgetstr(w, buf);
  75.   if (result == OK) {
  76.  
  77. #ifdef _IO_MAGIC /* GNU iostreams */
  78.     strstreambuf ss(buf, BUFSIZ);
  79.     result = ss.vscan(fmt, args);
  80. #else
  81.     result = vsscanf(buf, fmt, args);
  82. #endif
  83.   }
  84. #endif /* !VMS */
  85.   va_end(args);
  86.   return result;
  87. }
  88.  
  89. int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
  90. {
  91.   va_list args;
  92.   va_start(args, fmt);
  93.   char buf[BUFSIZ];
  94.   int result = wmove(w, y, x);
  95.   if (result == OK)
  96. #ifdef VMS
  97.   result=wscanw(w , fmt , args);
  98. #else /* !VMS */
  99.  {
  100.     result = wgetstr(w, buf);
  101.     if (result == OK) {
  102. #ifdef _IO_MAGIC /* GNU iostreams */
  103.     strstreambuf ss(buf, BUFSIZ);
  104.     result = ss.vscan(fmt, args);
  105. #else
  106.     result = vsscanf(buf, fmt, args);
  107. #endif
  108.   }
  109.   }
  110. #endif /* !VMS */
  111.   va_end(args);
  112.   return result;
  113. }
  114.  
  115. int CursesWindow::printw(const char * fmt, ...)
  116. {
  117.   va_list args;
  118.   va_start(args, fmt);
  119.   char buf[BUFSIZ];
  120.   vsprintf(buf, fmt, args);
  121.   va_end(args);
  122.   return waddstr(w, buf);
  123. }
  124.  
  125.  
  126. int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
  127. {
  128.   va_list args;
  129.   va_start(args, fmt);
  130.   int result = wmove(w, y, x);
  131.   if (result == OK)
  132.   {
  133.     char buf[BUFSIZ];
  134.     vsprintf(buf, fmt, args);
  135.     result = waddstr(w, buf);
  136.   }
  137.   va_end(args);
  138.   return result;
  139. }
  140.  
  141. CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
  142. {
  143.   if (count==0)
  144.     initscr();
  145.  
  146.   w = newwin(lines, cols, begin_y, begin_x);
  147.   if (w == 0)
  148.   {
  149.     (*lib_error_handler)("CursesWindow", "Cannot construct window");
  150.   }
  151.  
  152.   alloced = 1;
  153.   subwins = par = sib = 0;
  154.   count++;
  155. }
  156.  
  157. CursesWindow::CursesWindow(WINDOW* &window)
  158. {
  159.   if (count==0)
  160.     initscr();
  161.  
  162.   w = window;
  163.   alloced = 0;
  164.   subwins = par = sib = 0;
  165.   count++;
  166. }
  167.  
  168. CursesWindow::CursesWindow(CursesWindow& win, int l, int c, 
  169.                            int by, int bx, char absrel)
  170. {
  171.  
  172.   if (absrel == 'r') // relative origin
  173.   {
  174.     by += win.begy();
  175.     bx += win.begx();
  176.   }
  177.  
  178.   // Even though we treat subwindows as a tree, the standard curses
  179.   // library needs the `subwin' call to link to the root in
  180.   // order to correctly perform refreshes, etc.
  181.  
  182.   CursesWindow* root = &win;
  183.   while (root->par != 0) root = root->par;
  184.  
  185.   w = subwin(root->w, l, c, by, bx);
  186.   if (w == 0)
  187.   {
  188.     (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
  189.   }
  190.  
  191.   par = &win;
  192.   sib = win.subwins;
  193.   win.subwins = this;
  194.   subwins = 0;
  195.   alloced = 1;
  196.   count++;
  197. }
  198.  
  199.  
  200. void CursesWindow::kill_subwindows()
  201. {
  202.   for (CursesWindow* p = subwins; p != 0; p = p->sib)
  203.   {
  204.     p->kill_subwindows();
  205.     if (p->alloced)
  206.     {
  207.       if (p->w != 0)
  208.         ::delwin(p->w);
  209.       p->alloced = 0;
  210.     }
  211.     p->w = 0; // cause a run-time error if anyone attempts to use...
  212.   }
  213. }
  214.     
  215. CursesWindow::~CursesWindow() 
  216. {
  217.   kill_subwindows();
  218.  
  219.   if (par != 0)   // Snip us from the parent's list of subwindows.
  220.   {
  221.     CursesWindow * win = par->subwins;
  222.     CursesWindow * trail = 0;
  223.     for (;;)
  224.     {
  225.       if (win == 0)
  226.         break;
  227.       else if (win == this)
  228.       {
  229.         if (trail != 0)
  230.           trail->sib = win->sib;
  231.         else
  232.           par->subwins = win->sib;
  233.         break;
  234.       }
  235.       else
  236.       {
  237.         trail = win;
  238.         win = win->sib;
  239.       }
  240.     }
  241.   }
  242.  
  243.   if (alloced && w != 0) 
  244.     delwin(w);
  245.  
  246.   --count;
  247.   if (count == 0) 
  248.     endwin();
  249.   else if (count < 0) // cannot happen!
  250.   {
  251.     (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
  252.   }
  253. }
  254.  
  255. #endif /* _G_HAVE_CURSES */
  256.