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.

kb.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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 );
  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 >= KEY_MIN ) {
  89. switch(c) {
  90. case KEY_LEFT :
  91. case KEY_BACKSPACE :
  92. _wcursback( win );
  93. wdelch( win );
  94. break;
  95. case KEY_ENTER :
  96. *_str = '\0';
  97. return OK;
  98. default :
  99. beep();
  100. break;
  101. }
  102. }
  103. if ( c >= 32 && c <= 126 ) {
  104. *(_str++) = c; n--;
  105. }
  106. }
  107. }
  108. return ERR;
  109. }
  110. /**
  111. *
  112. */
  113. int echo ( void ) {
  114. m_echo = TRUE;
  115. return OK;
  116. }
  117. /**
  118. *
  119. */
  120. int noecho ( void ) {
  121. m_echo = FALSE;
  122. return OK;
  123. }