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