pdcurses/getstr.c

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

mercurial