edline.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * edline.c:
  3. * Text input on a line of the screen.
  4. *
  5. */
  6. static const char rcsid[] = "$Id: edline.c,v 1.2 2002/11/04 12:27:35 chris Exp $";
  7. #include <ctype.h>
  8. #include <curses.h>
  9. #include <string.h>
  10. #include "iftop.h"
  11. static int min(const int a, const int b) {
  12. return a < b ? a : b;
  13. }
  14. /* edline:
  15. * Display on line linenum of the screen the prompt and allow the user to input
  16. * a line of text, whose initial value is as supplied. */
  17. char *edline(int linenum, const char *prompt, const char *initial) {
  18. int xstart, slen, off = 0, pos, i, c;
  19. char *str;
  20. xstart = strlen(prompt) + 2;
  21. if (initial) {
  22. str = xmalloc(slen = strlen(initial) * 2 + 1);
  23. strcpy(str, initial);
  24. } else {
  25. str = xmalloc(slen = 256);
  26. *str = 0;
  27. }
  28. pos = strlen(str);
  29. do {
  30. c = getch();
  31. switch (c) {
  32. case KEY_DL:
  33. case 21: /* ^U */
  34. *str = 0;
  35. pos = 0;
  36. break;
  37. case KEY_LEFT:
  38. --pos;
  39. if (pos < 0) {
  40. beep();
  41. pos = 0;
  42. }
  43. break;
  44. case KEY_RIGHT:
  45. ++pos;
  46. if (pos > strlen(str)) {
  47. beep();
  48. pos = strlen(str);
  49. }
  50. break;
  51. case KEY_HOME:
  52. case 1: /* ^A */
  53. pos = 0;
  54. break;
  55. case KEY_END:
  56. case 5: /* ^E */
  57. pos = strlen(str);
  58. break;
  59. case KEY_DC:
  60. if (pos == strlen(str))
  61. beep();
  62. else
  63. memmove(str + pos, str + pos + 1, strlen(str + pos + 1) + 1);
  64. break;
  65. case KEY_BACKSPACE:
  66. if (pos == 0)
  67. beep();
  68. else {
  69. memmove(str + pos - 1, str + pos, strlen(str + pos) + 1);
  70. --pos;
  71. }
  72. break;
  73. case 23: /* ^W */
  74. for (i = pos; i > 0; --i)
  75. if (!isspace((int)str[i])) break;
  76. for (; i > 0; --i)
  77. if (isspace((int)str[i])) break;
  78. if (i != pos) {
  79. memmove(str + i, str + pos, strlen(str + pos) + 1);
  80. pos = i;
  81. }
  82. break;
  83. case ERR:
  84. break;
  85. default:
  86. if (isprint(c) && c != '\t') {
  87. if (strlen(str) == slen - 1)
  88. str = xrealloc(str, slen *= 2);
  89. memmove(str + pos + 1, str + pos, strlen(str + pos) + 1);
  90. str[pos++] = (char)c;
  91. } else
  92. beep();
  93. break;
  94. }
  95. /* figure out the offset to use for the string */
  96. off = 0;
  97. if (pos > COLS - xstart - 1)
  98. off = pos - (COLS - xstart - 1);
  99. /* display the string */
  100. mvaddstr(linenum, 0, prompt);
  101. addstr("> ");
  102. addnstr(str + off, min(strlen(str + off), COLS - xstart - 1));
  103. clrtoeol();
  104. move(linenum, xstart + pos - off);
  105. refresh();
  106. } while (c != KEY_ENTER && c != '\r' && c != '\x1b' && c != 7 /* ^G */);
  107. if (c == KEY_ENTER || c == '\r')
  108. /* Success */
  109. return str;
  110. else {
  111. xfree(str);
  112. return NULL;
  113. }
  114. }