blob: a4b6ea871c0e81e792a67a9eeaa13586ed8185db [file] [log] [blame]
#include <curses.h>
#include <stddef.h>
#include <unistd.h>
#include "mucurses.h"
/** @file
*
* MuCurses keyboard input handling functions
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define INPUT_DELAY 200 // half-blocking delay timer resolution (ms)
#define INPUT_DELAY_TIMEOUT 1000 // half-blocking delay timeout
int m_delay; /*
< 0 : blocking read
0 : non-blocking read
> 0 : timed blocking read
*/
bool m_echo;
bool m_cbreak;
static int _wgetc ( WINDOW *win ) {
int timer, c;
if ( win == NULL )
return ERR;
timer = INPUT_DELAY_TIMEOUT;
while ( ! win->scr->peek( win->scr ) ) {
if ( m_delay == 0 ) // non-blocking read
return ERR;
if ( timer > 0 ) { // time-limited blocking read
if ( m_delay > 0 )
timer -= INPUT_DELAY;
mdelay( INPUT_DELAY );
} else { return ERR; } // non-blocking read
}
c = win->scr->getc( win->scr );
if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters
_wputch( win, (chtype) ( c | win->attrs ), WRAP );
return c;
}
/**
* Pop a character from the FIFO into a window
*
* @v *win window in which to echo input
* @ret c char from input stream
*/
int wgetch ( WINDOW *win ) {
int c;
c = _wgetc( win );
if ( m_echo ) {
if ( c >= KEY_MIN ) {
switch(c) {
case KEY_LEFT :
case KEY_BACKSPACE :
_wcursback( win );
wdelch( win );
break;
default :
beep();
break;
}
} else {
_wputch( win, (chtype)( c | win->attrs ), WRAP );
}
}
return c;
}
/**
* Read at most n characters from the FIFO into a window
*
* @v *win window in which to echo input
* @v *str pointer to string in which to store result
* @v n maximum number of characters to read into string (inc. NUL)
* @ret rc return status code
*/
int wgetnstr ( WINDOW *win, char *str, int n ) {
char *_str;
int c;
if ( n == 0 ) {
*str = '\0';
return OK;
}
_str = str;
while ( ( c = _wgetc( win ) ) != ERR ) {
/* termination enforcement - don't let us go past the
end of the allocated buffer... */
if ( n == 0 && ( c >= 32 && c <= 126 ) ) {
_wcursback( win );
wdelch( win );
} else {
if ( c >= 32 && c <= 126 ) {
*(_str++) = c; n--;
} else {
switch(c) {
case KEY_LEFT :
case KEY_BACKSPACE :
_wcursback( win );
wdelch( win );
break;
case KEY_ENTER :
*_str = '\0';
return OK;
default :
beep();
break;
}
}
}
}
return ERR;
}
/**
*
*/
int echo ( void ) {
m_echo = TRUE;
return OK;
}
/**
*
*/
int noecho ( void ) {
m_echo = FALSE;
return OK;
}