You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <curses.h>
  2. #include <stddef.h>
  3. #include <unistd.h>
  4. #include "mucurses.h"
  5. /** @file
  6. *
  7. * MuCurses keyboard input handling functions
  8. */
  9. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  10. #define INPUT_DELAY 200 // half-blocking delay timer resolution (ms)
  11. #define INPUT_DELAY_TIMEOUT 1000 // half-blocking delay timeout
  12. int m_delay; /*
  13. < 0 : blocking read
  14. 0 : non-blocking read
  15. > 0 : timed blocking read
  16. */
  17. bool m_echo;
  18. bool m_cbreak;
  19. static int _wgetc ( WINDOW *win ) {
  20. int timer, c;
  21. if ( win == NULL )
  22. return ERR;
  23. timer = INPUT_DELAY_TIMEOUT;
  24. while ( ! win->scr->peek( win->scr ) ) {
  25. if ( m_delay == 0 ) // non-blocking read
  26. return ERR;
  27. if ( timer > 0 ) { // time-limited blocking read
  28. if ( m_delay > 0 )
  29. timer -= INPUT_DELAY;
  30. mdelay( INPUT_DELAY );
  31. } else { return ERR; } // non-blocking read
  32. }
  33. c = win->scr->getc( win->scr );
  34. if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters
  35. _wputch( win, (chtype) ( c | win->attrs ), WRAP );
  36. return c;
  37. }
  38. /**
  39. * Pop a character from the FIFO into a window
  40. *
  41. * @v *win window in which to echo input
  42. * @ret c char from input stream
  43. */
  44. int wgetch ( WINDOW *win ) {
  45. int c;
  46. c = _wgetc( win );
  47. if ( m_echo ) {
  48. if ( c >= KEY_MIN ) {
  49. switch(c) {
  50. case KEY_LEFT :
  51. case KEY_BACKSPACE :
  52. _wcursback( win );
  53. wdelch( win );
  54. break;
  55. default :
  56. beep();
  57. break;
  58. }
  59. } else {
  60. _wputch( win, (chtype)( c | win->attrs ), WRAP );
  61. }
  62. }
  63. return c;
  64. }
  65. /**
  66. * Read at most n characters from the FIFO into a window
  67. *
  68. * @v *win window in which to echo input
  69. * @v *str pointer to string in which to store result
  70. * @v n maximum number of characters to read into string (inc. NUL)
  71. * @ret rc return status code
  72. */
  73. int wgetnstr ( WINDOW *win, char *str, int n ) {
  74. char *_str;
  75. int c;
  76. if ( n == 0 ) {
  77. *str = '\0';
  78. return OK;
  79. }
  80. _str = str;
  81. while ( ( c = _wgetc( win ) ) != ERR ) {
  82. /* termination enforcement - don't let us go past the
  83. end of the allocated buffer... */
  84. if ( n == 0 && ( c >= 32 && c <= 126 ) ) {
  85. _wcursback( win );
  86. wdelch( win );
  87. } else {
  88. if ( c >= 32 && c <= 126 ) {
  89. *(_str++) = c; n--;
  90. } else {
  91. switch(c) {
  92. case KEY_LEFT :
  93. case KEY_BACKSPACE :
  94. _wcursback( win );
  95. wdelch( win );
  96. break;
  97. case KEY_ENTER :
  98. *_str = '\0';
  99. return OK;
  100. default :
  101. beep();
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. return ERR;
  108. }
  109. /**
  110. *
  111. */
  112. int echo ( void ) {
  113. m_echo = TRUE;
  114. return OK;
  115. }
  116. /**
  117. *
  118. */
  119. int noecho ( void ) {
  120. m_echo = FALSE;
  121. return OK;
  122. }