Home | History | Annotate | Line # | Download | only in libcurses
getstr.c revision 1.23
      1  1.23     blymn /*	$NetBSD: getstr.c,v 1.23 2013/10/01 11:41:14 blymn Exp $	*/
      2   1.8     mikel 
      3   1.1       cgd /*
      4   1.7       cgd  * Copyright (c) 1981, 1993, 1994
      5   1.5       cgd  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8   1.1       cgd  * modification, are permitted provided that the following conditions
      9   1.1       cgd  * are met:
     10   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15  1.18       agc  * 3. Neither the name of the University nor the names of its contributors
     16   1.1       cgd  *    may be used to endorse or promote products derived from this software
     17   1.1       cgd  *    without specific prior written permission.
     18   1.1       cgd  *
     19   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29   1.1       cgd  * SUCH DAMAGE.
     30   1.1       cgd  */
     31   1.1       cgd 
     32  1.13       jdc #include <assert.h>
     33   1.8     mikel #include <sys/cdefs.h>
     34   1.1       cgd #ifndef lint
     35   1.8     mikel #if 0
     36   1.7       cgd static char sccsid[] = "@(#)getstr.c	8.2 (Berkeley) 5/4/94";
     37   1.8     mikel #else
     38  1.23     blymn __RCSID("$NetBSD: getstr.c,v 1.23 2013/10/01 11:41:14 blymn Exp $");
     39   1.8     mikel #endif
     40  1.10       mrg #endif				/* not lint */
     41   1.1       cgd 
     42  1.21  christos #include <ctype.h>
     43   1.7       cgd #include "curses.h"
     44  1.11     blymn #include "curses_private.h"
     45  1.11     blymn 
     46  1.11     blymn #ifndef _CURSES_USE_MACROS
     47  1.11     blymn 
     48  1.11     blymn /*
     49  1.13       jdc  * getnstr --
     50  1.13       jdc  *	Get a string (of maximum n) characters from stdscr starting at
     51  1.13       jdc  *	(cury, curx).
     52  1.13       jdc  */
     53  1.13       jdc int
     54  1.13       jdc getnstr(char *str, int n)
     55  1.13       jdc {
     56  1.13       jdc 	return wgetnstr(stdscr, str, n);
     57  1.13       jdc }
     58  1.13       jdc 
     59  1.13       jdc /*
     60  1.11     blymn  * getstr --
     61  1.11     blymn  *	Get a string from stdscr starting at (cury, curx).
     62  1.11     blymn  */
     63  1.13       jdc __warn_references(getstr,
     64  1.13       jdc     "warning: this program uses getstr(), which is unsafe.")
     65  1.11     blymn int
     66  1.11     blymn getstr(char *str)
     67  1.11     blymn {
     68  1.11     blymn 	return wgetstr(stdscr, str);
     69  1.11     blymn }
     70  1.11     blymn 
     71  1.11     blymn /*
     72  1.13       jdc  * mvgetnstr --
     73  1.13       jdc  *      Get a string (of maximum n) characters from stdscr starting at (y, x).
     74  1.13       jdc  */
     75  1.13       jdc int
     76  1.13       jdc mvgetnstr(int y, int x, char *str, int n)
     77  1.13       jdc {
     78  1.13       jdc 	return mvwgetnstr(stdscr, y, x, str, n);
     79  1.13       jdc }
     80  1.13       jdc 
     81  1.13       jdc /*
     82  1.11     blymn  * mvgetstr --
     83  1.11     blymn  *      Get a string from stdscr starting at (y, x).
     84  1.11     blymn  */
     85  1.13       jdc __warn_references(mvgetstr,
     86  1.13       jdc     "warning: this program uses mvgetstr(), which is unsafe.")
     87  1.11     blymn int
     88  1.11     blymn mvgetstr(int y, int x, char *str)
     89  1.11     blymn {
     90  1.11     blymn 	return mvwgetstr(stdscr, y, x, str);
     91  1.11     blymn }
     92  1.11     blymn 
     93  1.11     blymn /*
     94  1.13       jdc  * mvwgetnstr --
     95  1.13       jdc  *      Get a string (of maximum n) characters from the given window starting
     96  1.13       jdc  *	at (y, x).
     97  1.13       jdc  */
     98  1.13       jdc int
     99  1.13       jdc mvwgetnstr(WINDOW *win, int y, int x, char *str, int n)
    100  1.13       jdc {
    101  1.13       jdc 	if (wmove(win, y, x) == ERR)
    102  1.13       jdc 		return ERR;
    103  1.13       jdc 
    104  1.13       jdc 	return wgetnstr(win, str, n);
    105  1.13       jdc }
    106  1.13       jdc 
    107  1.13       jdc /*
    108  1.11     blymn  * mvwgetstr --
    109  1.11     blymn  *      Get a string from the given window starting at (y, x).
    110  1.11     blymn  */
    111  1.13       jdc __warn_references(mvgetstr,
    112  1.13       jdc     "warning: this program uses mvgetstr(), which is unsafe.")
    113  1.11     blymn int
    114  1.11     blymn mvwgetstr(WINDOW *win, int y, int x, char *str)
    115  1.11     blymn {
    116  1.11     blymn 	if (wmove(win, y, x) == ERR)
    117  1.11     blymn 		return ERR;
    118  1.11     blymn 
    119  1.11     blymn 	return wgetstr(win, str);
    120  1.11     blymn }
    121  1.11     blymn 
    122  1.11     blymn #endif
    123   1.1       cgd 
    124   1.1       cgd /*
    125   1.4   mycroft  * wgetstr --
    126   1.5       cgd  *	Get a string starting at (cury, curx).
    127   1.1       cgd  */
    128  1.13       jdc __warn_references(wgetstr,
    129  1.13       jdc     "warning: this program uses wgetstr(), which is unsafe.")
    130   1.4   mycroft int
    131  1.11     blymn wgetstr(WINDOW *win, char *str)
    132   1.4   mycroft {
    133  1.13       jdc 	return __wgetnstr(win, str, -1);
    134  1.13       jdc }
    135  1.13       jdc 
    136  1.13       jdc /*
    137  1.13       jdc  * wgetnstr --
    138  1.13       jdc  *	Get a string starting at (cury, curx).
    139  1.13       jdc  *	Note that n <  2 means that we return ERR (SUSv2 specification).
    140  1.13       jdc  */
    141  1.13       jdc int
    142  1.13       jdc wgetnstr(WINDOW *win, char *str, int n)
    143  1.13       jdc {
    144  1.13       jdc 	if (n < 1)
    145  1.13       jdc 		return (ERR);
    146  1.13       jdc 	if (n == 1) {
    147  1.13       jdc 		str[0] = '\0';
    148  1.13       jdc 		return (ERR);
    149  1.13       jdc 	}
    150  1.13       jdc 	return __wgetnstr(win, str, n);
    151  1.13       jdc }
    152  1.13       jdc 
    153  1.13       jdc /*
    154  1.13       jdc  * __wgetnstr --
    155  1.13       jdc  *	The actual implementation.
    156  1.13       jdc  *	Note that we include a trailing '\0' for safety, so str will contain
    157  1.13       jdc  *	at most n - 1 other characters.
    158  1.13       jdc  *	XXX: character deletion from screen is based on how the characters
    159  1.13       jdc  *	are displayed by wgetch().
    160  1.13       jdc  */
    161  1.13       jdc int
    162  1.13       jdc __wgetnstr(WINDOW *win, char *str, int n)
    163  1.13       jdc {
    164  1.13       jdc 	char *ostr, ec, kc;
    165  1.21  christos 	int c, xpos, oldx, remain;
    166  1.12     blymn 
    167  1.12     blymn 	ostr = str;
    168  1.12     blymn 	ec = erasechar();
    169  1.13       jdc 	kc = killchar();
    170  1.21  christos 	xpos = oldx = win->curx;
    171  1.13       jdc 	_DIAGASSERT(n == -1 || n > 1);
    172  1.13       jdc 	remain = n - 1;
    173  1.16     blymn 
    174  1.13       jdc 	while ((c = wgetch(win)) != ERR && c != '\n' && c != '\r') {
    175  1.13       jdc #ifdef DEBUG
    176  1.19       jdc 		__CTRACE(__CTRACE_INPUT,
    177  1.19       jdc 		    "__wgetnstr: win %p, char 0x%x, remain %d\n",
    178  1.19       jdc 		    win, c, remain);
    179  1.13       jdc #endif
    180  1.13       jdc 		*str = c;
    181  1.23     blymn 		__touchline(win, win->cury, 0, (int) win->maxx - 1);
    182  1.13       jdc 		if (c == ec || c == KEY_BACKSPACE || c == KEY_LEFT) {
    183  1.12     blymn 			*str = '\0';
    184  1.12     blymn 			if (str != ostr) {
    185  1.13       jdc 				if ((char) c == ec) {
    186  1.21  christos 					mvwaddch(win, win->cury, xpos, ' ');
    187  1.21  christos 					if (xpos > oldx)
    188  1.21  christos 						mvwaddch(win, win->cury,
    189  1.21  christos 						    xpos - 1, ' ');
    190  1.21  christos 					if (win->curx > xpos - 1)
    191  1.21  christos 						wmove(win, win->cury, xpos - 1);
    192  1.21  christos 					xpos--;
    193  1.13       jdc 				}
    194  1.13       jdc 				if (c == KEY_BACKSPACE || c == KEY_LEFT) {
    195  1.13       jdc 					/* getch() displays the key sequence */
    196  1.21  christos 					mvwaddch(win, win->cury, win->curx,
    197  1.21  christos 					    ' ');
    198  1.20     blymn 					mvwaddch(win, win->cury, win->curx - 1,
    199  1.13       jdc 					    ' ');
    200  1.21  christos 					if (win->curx > xpos)
    201  1.21  christos 						wmove(win, win->cury, xpos - 1);
    202  1.21  christos 					xpos--;
    203  1.13       jdc 				}
    204  1.12     blymn 				str--;
    205  1.13       jdc 				if (n != -1) {
    206  1.13       jdc 					/* We're counting chars */
    207  1.13       jdc 					remain++;
    208  1.13       jdc 				}
    209  1.13       jdc 			} else {        /* str == ostr */
    210  1.21  christos 				/* getch() displays the other keys */
    211  1.21  christos 				if (win->curx > oldx)
    212  1.13       jdc 					mvwaddch(win, win->cury, win->curx - 1,
    213  1.13       jdc 					    ' ');
    214  1.13       jdc 				wmove(win, win->cury, oldx);
    215  1.21  christos 				xpos = oldx;
    216  1.13       jdc 			}
    217  1.13       jdc 		} else if (c == kc) {
    218  1.13       jdc 			*str = '\0';
    219  1.13       jdc 			if (str != ostr) {
    220  1.13       jdc 				/* getch() displays the kill character */
    221  1.13       jdc 				mvwaddch(win, win->cury, win->curx - 1, ' ');
    222  1.13       jdc 				/* Clear the characters from screen and str */
    223  1.13       jdc 				while (str != ostr) {
    224  1.13       jdc 					mvwaddch(win, win->cury, win->curx - 1,
    225  1.13       jdc 					    ' ');
    226  1.13       jdc 					wmove(win, win->cury, win->curx - 1);
    227  1.13       jdc 					str--;
    228  1.13       jdc 					if (n != -1)
    229  1.13       jdc 						/* We're counting chars */
    230  1.13       jdc 						remain++;
    231  1.13       jdc 				}
    232  1.13       jdc 				mvwaddch(win, win->cury, win->curx - 1, ' ');
    233  1.13       jdc 				wmove(win, win->cury, win->curx - 1);
    234  1.12     blymn 			} else
    235  1.13       jdc 				/* getch() displays the kill character */
    236  1.13       jdc 				mvwaddch(win, win->cury, oldx, ' ');
    237  1.13       jdc 			wmove(win, win->cury, oldx);
    238  1.13       jdc 		} else if (c >= KEY_MIN && c <= KEY_MAX) {
    239  1.13       jdc 			/* getch() displays these characters */
    240  1.21  christos 			mvwaddch(win, win->cury, xpos, ' ');
    241  1.21  christos 			wmove(win, win->cury, xpos);
    242  1.13       jdc 		} else {
    243  1.13       jdc 			if (remain) {
    244  1.22  christos 				if (iscntrl((unsigned char)c))
    245  1.21  christos 					mvwaddch(win, win->cury, xpos, ' ');
    246  1.13       jdc 				str++;
    247  1.21  christos 				xpos++;
    248  1.13       jdc 				remain--;
    249  1.22  christos 			} else
    250  1.21  christos 				mvwaddch(win, win->cury, xpos, ' ');
    251  1.22  christos 			wmove(win, win->cury, xpos);
    252  1.13       jdc 		}
    253  1.12     blymn 	}
    254  1.16     blymn 
    255  1.13       jdc 	if (c == ERR) {
    256   1.1       cgd 		*str = '\0';
    257   1.4   mycroft 		return (ERR);
    258   1.4   mycroft 	}
    259   1.4   mycroft 	*str = '\0';
    260   1.4   mycroft 	return (OK);
    261   1.1       cgd }
    262