iPXE
kb.c
Go to the documentation of this file.
00001 #include <curses.h>
00002 #include <stddef.h>
00003 #include <unistd.h>
00004 #include "mucurses.h"
00005 
00006 /** @file
00007  *
00008  * MuCurses keyboard input handling functions
00009  */
00010 
00011 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00012 
00013 #define INPUT_DELAY             200 // half-blocking delay timer resolution (ms)
00014 #define INPUT_DELAY_TIMEOUT     1000 // half-blocking delay timeout
00015 
00016 int m_delay; /* 
00017                 < 0 : blocking read
00018                 0   : non-blocking read
00019                 > 0 : timed blocking read
00020              */
00021 bool m_echo;
00022 bool m_cbreak;
00023 
00024 static int _wgetc ( WINDOW *win ) {
00025         int timer, c;
00026 
00027         if ( win == NULL )
00028                 return ERR;
00029 
00030         timer = INPUT_DELAY_TIMEOUT;
00031         while ( ! win->scr->peek( win->scr ) ) {
00032                 if ( m_delay == 0 ) // non-blocking read
00033                         return ERR;
00034                 if ( timer > 0 ) {  // time-limited blocking read
00035                         if ( m_delay > 0 )
00036                                 timer -= INPUT_DELAY;
00037                         mdelay( INPUT_DELAY );
00038                 } else { return ERR; } // non-blocking read
00039         }
00040 
00041         c = win->scr->getc( win->scr );
00042 
00043         if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters
00044                 _wputch( win, (chtype) ( c | win->attrs ), WRAP );
00045 
00046         return c;
00047 }
00048 
00049 /**
00050  * Pop a character from the FIFO into a window
00051  *
00052  * @v *win      window in which to echo input
00053  * @ret c       char from input stream
00054  */
00055 int wgetch ( WINDOW *win ) {
00056         int c;
00057 
00058         c = _wgetc( win );
00059 
00060         if ( m_echo ) {
00061                 if ( c >= KEY_MIN ) {
00062                         switch(c) {
00063                         case KEY_LEFT :
00064                         case KEY_BACKSPACE :
00065                                 _wcursback( win );
00066                                 wdelch( win );
00067                                 break;
00068                         default :
00069                                 beep();
00070                                 break;
00071                         }
00072                 } else {
00073                         _wputch( win, (chtype)( c | win->attrs ), WRAP );
00074                 }
00075         }
00076 
00077         return c;
00078 }
00079 
00080 /**
00081  * Read at most n characters from the FIFO into a window
00082  *
00083  * @v *win      window in which to echo input
00084  * @v *str      pointer to string in which to store result
00085  * @v n         maximum number of characters to read into string (inc. NUL)
00086  * @ret rc      return status code
00087  */
00088 int wgetnstr ( WINDOW *win, char *str, int n ) {
00089         char *_str;
00090         int c;
00091 
00092         if ( n == 0 ) {
00093                 *str = '\0';
00094                 return OK;
00095         }
00096 
00097         _str = str;
00098 
00099         while ( ( c = _wgetc( win ) ) != ERR ) {
00100                 /* termination enforcement - don't let us go past the
00101                    end of the allocated buffer... */
00102                 if ( n == 0 && ( c >= 32 && c <= 126 ) ) {
00103                         _wcursback( win );
00104                         wdelch( win );
00105                 } else {
00106                         if ( c >= 32 && c <= 126 ) {
00107                                 *(_str++) = c; n--;
00108                         } else {
00109                                 switch(c) {
00110                                 case KEY_LEFT :
00111                                 case KEY_BACKSPACE :
00112                                         _wcursback( win );
00113                                         wdelch( win );
00114                                         break;
00115                                 case KEY_ENTER :
00116                                         *_str = '\0';
00117                                         return OK;
00118                                 default :
00119                                         beep();
00120                                         break;
00121                                 }
00122                         }
00123                 }
00124         }
00125 
00126         return ERR;
00127 }
00128 
00129 
00130 /**
00131  *
00132  */
00133 int echo ( void ) {
00134         m_echo = TRUE;
00135         return OK;
00136 }
00137 
00138 /**
00139  *
00140  */
00141 int noecho ( void ) {
00142         m_echo = FALSE;
00143         return OK;
00144 }