kb.c 2.7KB

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