Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* PDCurses */
  2.  
  3. #include <curspriv.h>
  4.  
  5. /*man-start**************************************************************
  6.  
  7. getstr
  8. ------
  9.  
  10. ### Synopsis
  11.  
  12.     int getstr(char *str);
  13.     int wgetstr(WINDOW *win, char *str);
  14.     int mvgetstr(int y, int x, char *str);
  15.     int mvwgetstr(WINDOW *win, int y, int x, char *str);
  16.     int getnstr(char *str, int n);
  17.     int wgetnstr(WINDOW *win, char *str, int n);
  18.     int mvgetnstr(int y, int x, char *str, int n);
  19.     int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n);
  20.  
  21.     int get_wstr(wint_t *wstr);
  22.     int wget_wstr(WINDOW *win, wint_t *wstr);
  23.     int mvget_wstr(int y, int x, wint_t *wstr);
  24.     int mvwget_wstr(WINDOW *win, int, int, wint_t *wstr);
  25.     int getn_wstr(wint_t *wstr, int n);
  26.     int wgetn_wstr(WINDOW *win, wint_t *wstr, int n);
  27.     int mvgetn_wstr(int y, int x, wint_t *wstr, int n);
  28.     int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n);
  29.  
  30. ### Description
  31.  
  32.    These routines call wgetch() repeatedly to build a string,
  33.    interpreting erase and kill characters along the way, until a newline
  34.    or carriage return is received. When PDCurses is built with wide-
  35.    character support enabled, the narrow-character functions convert the
  36.    wgetch()'d values into a multibyte string in the current locale
  37.    before returning it. The resulting string is placed in the area
  38.    pointed to by *str. The routines with n as the last argument read at
  39.    most n characters.
  40.  
  41.    Note that there's no way to know how long the buffer passed to
  42.    wgetstr() is, so use wgetnstr() to avoid buffer overflows.
  43.  
  44. ### Return Value
  45.  
  46.    These functions return ERR on failure or any other value on success.
  47.  
  48. ### Portability
  49.                              X/Open  ncurses  NetBSD
  50.     getstr                      Y       Y       Y
  51.     wgetstr                     Y       Y       Y
  52.     mvgetstr                    Y       Y       Y
  53.     mvwgetstr                   Y       Y       Y
  54.     getnstr                     Y       Y       Y
  55.     wgetnstr                    Y       Y       Y
  56.     mvgetnstr                   Y       Y       Y
  57.     mvwgetnstr                  Y       Y       Y
  58.     get_wstr                    Y       Y       Y
  59.     wget_wstr                   Y       Y       Y
  60.     mvget_wstr                  Y       Y       Y
  61.     mvwget_wstr                 Y       Y       Y
  62.     getn_wstr                   Y       Y       Y
  63.     wgetn_wstr                  Y       Y       Y
  64.     mvgetn_wstr                 Y       Y       Y
  65.     mvwgetn_wstr                Y       Y       Y
  66.  
  67. **man-end****************************************************************/
  68.  
  69. #define MAXLINE 255
  70.  
  71. int wgetnstr(WINDOW *win, char *str, int n)
  72. {
  73. #ifdef PDC_WIDE
  74.     wchar_t wstr[MAXLINE + 1];
  75.  
  76.     if (n < 0 || n > MAXLINE)
  77.         n = MAXLINE;
  78.  
  79.     if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR)
  80.         return ERR;
  81.  
  82.     return PDC_wcstombs(str, wstr, n);
  83. #else
  84.     int ch, i, num, x, chars;
  85.     char *p;
  86.     bool stop, oldecho, oldcbreak, oldnodelay;
  87.  
  88.     PDC_LOG(("wgetnstr() - called\n"));
  89.  
  90.     if (!win || !str)
  91.         return ERR;
  92.  
  93.     chars = 0;
  94.     p = str;
  95.     stop = FALSE;
  96.  
  97.     x = win->_curx;
  98.  
  99.     oldcbreak = SP->cbreak; /* remember states */
  100.     oldecho = SP->echo;
  101.     oldnodelay = win->_nodelay;
  102.  
  103.     SP->echo = FALSE;       /* we do echo ourselves */
  104.     cbreak();               /* ensure each key is returned immediately */
  105.     win->_nodelay = FALSE;  /* don't return -1 */
  106.  
  107.     wrefresh(win);
  108.  
  109.     while (!stop)
  110.     {
  111.         ch = wgetch(win);
  112.  
  113.         switch (ch)
  114.         {
  115.  
  116.         case '\t':
  117.             ch = ' ';
  118.             num = TABSIZE - (win->_curx - x) % TABSIZE;
  119.             for (i = 0; i < num; i++)
  120.             {
  121.                 if (chars < n)
  122.                 {
  123.                     if (oldecho)
  124.                         waddch(win, ch);
  125.                     *p++ = ch;
  126.                     ++chars;
  127.                 }
  128.                 else
  129.                     beep();
  130.             }
  131.             break;
  132.  
  133.         case _ECHAR:        /* CTRL-H -- Delete character */
  134.             if (p > str)
  135.             {
  136.                 if (oldecho)
  137.                     waddstr(win, "\b \b");
  138.                 ch = (unsigned char)(*--p);
  139.                 if ((ch < ' ') && (oldecho))
  140.                     waddstr(win, "\b \b");
  141.                 chars--;
  142.             }
  143.             break;
  144.  
  145.         case _DLCHAR:       /* CTRL-U -- Delete line */
  146.             while (p > str)
  147.             {
  148.                 if (oldecho)
  149.                     waddstr(win, "\b \b");
  150.                 ch = (unsigned char)(*--p);
  151.                 if ((ch < ' ') && (oldecho))
  152.                     waddstr(win, "\b \b");
  153.             }
  154.             chars = 0;
  155.             break;
  156.  
  157.         case _DWCHAR:       /* CTRL-W -- Delete word */
  158.  
  159.             while ((p > str) && (*(p - 1) == ' '))
  160.             {
  161.                 if (oldecho)
  162.                     waddstr(win, "\b \b");
  163.  
  164.                 --p;        /* remove space */
  165.                 chars--;
  166.             }
  167.             while ((p > str) && (*(p - 1) != ' '))
  168.             {
  169.                 if (oldecho)
  170.                     waddstr(win, "\b \b");
  171.  
  172.                 ch = (unsigned char)(*--p);
  173.                 if ((ch < ' ') && (oldecho))
  174.                     waddstr(win, "\b \b");
  175.                 chars--;
  176.             }
  177.             break;
  178.  
  179.         case '\n':
  180.         case '\r':
  181.             stop = TRUE;
  182.             if (oldecho)
  183.                 waddch(win, '\n');
  184.             break;
  185.  
  186.         default:
  187.             if (chars < n)
  188.             {
  189.                 if (!SP->key_code && ch < 0x100)
  190.                 {
  191.                     *p++ = ch;
  192.                     if (oldecho)
  193.                         waddch(win, ch);
  194.                     chars++;
  195.                 }
  196.             }
  197.             else
  198.                 beep();
  199.  
  200.             break;
  201.  
  202.         }
  203.  
  204.         wrefresh(win);
  205.     }
  206.  
  207.     *p = '\0';
  208.  
  209.     SP->echo = oldecho;     /* restore old settings */
  210.     SP->cbreak = oldcbreak;
  211.     win->_nodelay = oldnodelay;
  212.  
  213.     return OK;
  214. #endif
  215. }
  216.  
  217. int getstr(char *str)
  218. {
  219.     PDC_LOG(("getstr() - called\n"));
  220.  
  221.     return wgetnstr(stdscr, str, MAXLINE);
  222. }
  223.  
  224. int wgetstr(WINDOW *win, char *str)
  225. {
  226.     PDC_LOG(("wgetstr() - called\n"));
  227.  
  228.     return wgetnstr(win, str, MAXLINE);
  229. }
  230.  
  231. int mvgetstr(int y, int x, char *str)
  232. {
  233.     PDC_LOG(("mvgetstr() - called\n"));
  234.  
  235.     if (move(y, x) == ERR)
  236.         return ERR;
  237.  
  238.     return wgetnstr(stdscr, str, MAXLINE);
  239. }
  240.  
  241. int mvwgetstr(WINDOW *win, int y, int x, char *str)
  242. {
  243.     PDC_LOG(("mvwgetstr() - called\n"));
  244.  
  245.     if (wmove(win, y, x) == ERR)
  246.         return ERR;
  247.  
  248.     return wgetnstr(win, str, MAXLINE);
  249. }
  250.  
  251. int getnstr(char *str, int n)
  252. {
  253.     PDC_LOG(("getnstr() - called\n"));
  254.  
  255.     return wgetnstr(stdscr, str, n);
  256. }
  257.  
  258. int mvgetnstr(int y, int x, char *str, int n)
  259. {
  260.     PDC_LOG(("mvgetnstr() - called\n"));
  261.  
  262.     if (move(y, x) == ERR)
  263.         return ERR;
  264.  
  265.     return wgetnstr(stdscr, str, n);
  266. }
  267.  
  268. int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n)
  269. {
  270.     PDC_LOG(("mvwgetnstr() - called\n"));
  271.  
  272.     if (wmove(win, y, x) == ERR)
  273.         return ERR;
  274.  
  275.     return wgetnstr(win, str, n);
  276. }
  277.  
  278. #ifdef PDC_WIDE
  279. int wgetn_wstr(WINDOW *win, wint_t *wstr, int n)
  280. {
  281.     int ch, i, num, x, chars;
  282.     wint_t *p;
  283.     bool stop, oldecho, oldcbreak, oldnodelay;
  284.  
  285.     PDC_LOG(("wgetn_wstr() - called\n"));
  286.  
  287.     if (!win || !wstr)
  288.         return ERR;
  289.  
  290.     chars = 0;
  291.     p = wstr;
  292.     stop = FALSE;
  293.  
  294.     x = win->_curx;
  295.  
  296.     oldcbreak = SP->cbreak; /* remember states */
  297.     oldecho = SP->echo;
  298.     oldnodelay = win->_nodelay;
  299.  
  300.     SP->echo = FALSE;       /* we do echo ourselves */
  301.     cbreak();               /* ensure each key is returned immediately */
  302.     win->_nodelay = FALSE;  /* don't return -1 */
  303.  
  304.     wrefresh(win);
  305.  
  306.     while (!stop)
  307.     {
  308.         ch = wgetch(win);
  309.  
  310.         switch (ch)
  311.         {
  312.  
  313.         case '\t':
  314.             ch = ' ';
  315.             num = TABSIZE - (win->_curx - x) % TABSIZE;
  316.             for (i = 0; i < num; i++)
  317.             {
  318.                 if (chars < n)
  319.                 {
  320.                     if (oldecho)
  321.                         waddch(win, ch);
  322.                     *p++ = ch;
  323.                     ++chars;
  324.                 }
  325.                 else
  326.                     beep();
  327.             }
  328.             break;
  329.  
  330.         case _ECHAR:        /* CTRL-H -- Delete character */
  331.             if (p > wstr)
  332.             {
  333.                 if (oldecho)
  334.                     waddstr(win, "\b \b");
  335.                 ch = *--p;
  336.                 if ((ch < ' ') && (oldecho))
  337.                     waddstr(win, "\b \b");
  338.                 chars--;
  339.             }
  340.             break;
  341.  
  342.         case _DLCHAR:       /* CTRL-U -- Delete line */
  343.             while (p > wstr)
  344.             {
  345.                 if (oldecho)
  346.                     waddstr(win, "\b \b");
  347.                 ch = *--p;
  348.                 if ((ch < ' ') && (oldecho))
  349.                     waddstr(win, "\b \b");
  350.             }
  351.             chars = 0;
  352.             break;
  353.  
  354.         case _DWCHAR:       /* CTRL-W -- Delete word */
  355.  
  356.             while ((p > wstr) && (*(p - 1) == ' '))
  357.             {
  358.                 if (oldecho)
  359.                     waddstr(win, "\b \b");
  360.  
  361.                 --p;        /* remove space */
  362.                 chars--;
  363.             }
  364.             while ((p > wstr) && (*(p - 1) != ' '))
  365.             {
  366.                 if (oldecho)
  367.                     waddstr(win, "\b \b");
  368.  
  369.                 ch = *--p;
  370.                 if ((ch < ' ') && (oldecho))
  371.                     waddstr(win, "\b \b");
  372.                 chars--;
  373.             }
  374.             break;
  375.  
  376.         case '\n':
  377.         case '\r':
  378.             stop = TRUE;
  379.             if (oldecho)
  380.                 waddch(win, '\n');
  381.             break;
  382.  
  383.         default:
  384.             if (chars < n)
  385.             {
  386.                 if (!SP->key_code)
  387.                 {
  388.                     *p++ = ch;
  389.                     if (oldecho)
  390.                         waddch(win, ch);
  391.                     chars++;
  392.                 }
  393.             }
  394.             else
  395.                 beep();
  396.  
  397.             break;
  398.  
  399.         }
  400.  
  401.         wrefresh(win);
  402.     }
  403.  
  404.     *p = '\0';
  405.  
  406.     SP->echo = oldecho;     /* restore old settings */
  407.     SP->cbreak = oldcbreak;
  408.     win->_nodelay = oldnodelay;
  409.  
  410.     return OK;
  411. }
  412.  
  413. int get_wstr(wint_t *wstr)
  414. {
  415.     PDC_LOG(("get_wstr() - called\n"));
  416.  
  417.     return wgetn_wstr(stdscr, wstr, MAXLINE);
  418. }
  419.  
  420. int wget_wstr(WINDOW *win, wint_t *wstr)
  421. {
  422.     PDC_LOG(("wget_wstr() - called\n"));
  423.  
  424.     return wgetn_wstr(win, wstr, MAXLINE);
  425. }
  426.  
  427. int mvget_wstr(int y, int x, wint_t *wstr)
  428. {
  429.     PDC_LOG(("mvget_wstr() - called\n"));
  430.  
  431.     if (move(y, x) == ERR)
  432.         return ERR;
  433.  
  434.     return wgetn_wstr(stdscr, wstr, MAXLINE);
  435. }
  436.  
  437. int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr)
  438. {
  439.     PDC_LOG(("mvwget_wstr() - called\n"));
  440.  
  441.     if (wmove(win, y, x) == ERR)
  442.         return ERR;
  443.  
  444.     return wgetn_wstr(win, wstr, MAXLINE);
  445. }
  446.  
  447. int getn_wstr(wint_t *wstr, int n)
  448. {
  449.     PDC_LOG(("getn_wstr() - called\n"));
  450.  
  451.     return wgetn_wstr(stdscr, wstr, n);
  452. }
  453.  
  454. int mvgetn_wstr(int y, int x, wint_t *wstr, int n)
  455. {
  456.     PDC_LOG(("mvgetn_wstr() - called\n"));
  457.  
  458.     if (move(y, x) == ERR)
  459.         return ERR;
  460.  
  461.     return wgetn_wstr(stdscr, wstr, n);
  462. }
  463.  
  464. int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n)
  465. {
  466.     PDC_LOG(("mvwgetn_wstr() - called\n"));
  467.  
  468.     if (wmove(win, y, x) == ERR)
  469.         return ERR;
  470.  
  471.     return wgetn_wstr(win, wstr, n);
  472. }
  473. #endif
  474.