getstr.c 11 KB

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