ctkeyb.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 652 行 · 第 1/2 页
C
652 行
void nextc_unget( char *str, int n )
{
UnreadPos-=n;
//assert(UnreadPos>=0);
memcpy( &(UnreadBuffer[UnreadPos]), str, n );
}
int find_entry( const void *pkey, const void *pbase )
{
const EVENT *evp = pkey;
const event_shift_map *entry = pbase;
return( *evp - entry->normal );
}
EVENT ck_keyboardevent()
/**********************/
{
EVENT ev;
EVENT search_ev;
event_shift_map *entry;
ev = TrieRead();
if( sticky & S_INTRO ) {
switch( ev ) {
case 'f':
case 'F':
ev = EV_STICKY_FUNC;
sticky &= ~S_INTRO;
break;
case 's':
case 'S':
ev = EV_STICKY_SHIFT;
sticky &= ~S_INTRO;
break;
case 'c':
case 'C':
ev = EV_STICKY_CTRL;
sticky &= ~S_INTRO;
break;
case 'a':
case 'A':
ev = EV_STICKY_ALT;
sticky &= ~S_INTRO;
break;
}
}
switch( ev ) {
case EV_STICKY_FUNC:
sticky ^= S_FUNC;
break;
case EV_STICKY_SHIFT:
sticky ^= S_SHIFT;
break;
case EV_STICKY_CTRL:
sticky ^= S_CTRL;
break;
case EV_STICKY_ALT:
sticky ^= S_ALT;
break;
case EV_STICKY_INTRO:
sticky ^= S_INTRO;
break;
case EV_SHIFT_PRESS:
real_shift |= S_SHIFT;
break;
case EV_CTRL_PRESS:
real_shift |= S_CTRL;
break;
case EV_ALT_PRESS:
real_shift |= S_ALT;
break;
case EV_SHIFT_RELEASE:
if( !(real_shift & S_SHIFT) ) ev = EV_NO_EVENT;
real_shift &= ~S_SHIFT;
break;
case EV_CTRL_RELEASE:
if( !(real_shift & S_CTRL) ) ev = EV_NO_EVENT;
real_shift &= ~S_CTRL;
break;
case EV_ALT_RELEASE:
if( !(real_shift & S_ALT) ) ev = EV_NO_EVENT;
real_shift &= ~S_ALT;
break;
case EV_NO_EVENT:
break;
default:
if( sticky & S_FUNC ) {
if( ev == '0' ) {
ev = EV_FUNC( 10 );
} else if( ev == 'a' || ev == 'A' ) {
ev = EV_FUNC_11;
} else if( ev == 'b' || ev == 'B' ) {
ev = EV_FUNC_12;
} else if( isdigit( ev ) ) {
ev = EV_FUNC( ev - '0' );
}
sticky &= ~S_FUNC;
}
if( !(real_shift & S_CTRL) ) {
/*
If the ctrl key isn't down (won't ever be on a terminal)
then we want to see certain CTRL-? combinations come back
as some standard UI events.
*/
switch( ev ) {
case '\x08':
ev = EV_RUB_OUT;
break;
case '\x09':
ev = EV_TAB_FORWARD;
break;
case '\x0c':
ev = EV_REDRAW_SCREEN;
break;
}
}
ShftState = sticky | real_shift;
sticky = 0;
#define S_MASK (S_SHIFT|S_CTRL|S_ALT)
if( ShftState & S_MASK ) {
search_ev = tolower( ev );
entry = bsearch( &search_ev, ShiftMap, NUM_ELTS( ShiftMap ),
sizeof( ShiftMap[0] ), find_entry );
if( entry != NULL ) {
if( ShftState & S_SHIFT ) {
ev = entry->shift;
} else if( ShftState & S_CTRL ) {
ev = entry->ctrl;
} else { /* must be ALT */
ev = entry->alt;
}
}
}
QNXDebugPrintf1( "UI: Something read: %4.4X", ev );
return( ev );
}
ShftState = real_shift;
QNXDebugPrintf1( "UI: Something read: %4.4X", ev );
return( ev );
}
EVENT tk_keyboardevent()
{
extern void tm_saveevent();
EVENT ev;
ev = ck_keyboardevent();
if( ev != EV_MOUSE_PRESS ) return( ev );
QNXDebugPrintf0( "UI: Mouse event handling" );
tm_saveevent();
return( EV_NO_EVENT ); /* make UI check for mouse events */
}
static int ck_stop()
{
dev_read( UIConHandle, NULL, 0, 0, 0, 0, 0, 0 );
while( Creceive( UILocalProxy, 0, 0 ) > 0 )
{}
return 0;
}
static int ck_flush()
/********************/
{
tcflush( UIConHandle, TCIFLUSH );
return 0;
}
static int ck_shift_state()
/*************************/
{
return( ShftState );
}
static int ck_restore()
/*********************/
{
struct termios new;
new = SaveTermSet;
new.c_iflag &= ~(IXOFF | IXON);
new.c_oflag &= ~OPOST;
new.c_lflag &= ~(ECHO | ICANON | NOFLSH);
new.c_lflag |= ISIG;
if( UIConCtrl != NULL ) {
/* We have an honest-to-god console. Disable Ctrl/C - use Ctrl/Break */
new.c_cc[VINTR] = '\0';
}
new.c_cc[VMIN] = 1;
new.c_cc[VTIME] = 0;
tcsetattr( UIConHandle, TCSADRAIN, &new );
if( UIConCtrl != NULL ) {
console_protocol( UIConCtrl, 0, _CON_PROT_QNX4 );
console_ctrl( UIConCtrl, 0, CONSOLE_SCANMODE, CONSOLE_SCANMODE );
}
return 0;
}
static void term_handler( int signo )
{
signo = signo;
ck_fini();
_exit( 0 );
}
extern void restorekeyb();
/* We want to ignore the following escapes when running on a console */
#include "conesc.gh"
#if 0
static const char * const ConIgnore[] = {
"\xff\x20", /* extended key follows */
"\xff\x21", /* key up */
"\xff\x28", /* E0 code */
"\xff\x29", /* right shift follows */
"\xff\x28\xff\x23", /* fake shift down */
"\xff\x28\xff\x22", /* fake shift up */
"\xff\x28\xff\x29\xff\x23", /* fake right shift down */
"\xff\x28\xff\x29\xff\x22", /* fake right shift up */
};
#endif
static int ck_init()
/******************/
{
unsigned i;
EVENT ev;
tcgetattr( UIConHandle, &SaveTermSet );
if( !init_trie() ) return( FALSE );
switch( ti_read_tix( UIConCtrl == NULL ) ) {
case TIX_FAIL:
return( FALSE );
case TIX_NOFILE:
if( UIConCtrl != NULL ) {
for( i = 0; i < NUM_ELTS( ConEscapes ); i += strlen( &ConEscapes[i] ) + 1 ) {
ev = ConEscapes[i+0] + (ConEscapes[i+1] << 8);
i += 2;
if( !TrieAdd( ev, &ConEscapes[i] ) ) {
return( FALSE );
}
}
}
}
if( UIConCtrl != NULL ) {
SaveProtocol = console_protocol( UIConCtrl, 0, _CON_PROT_QNX4 );
SaveCtrl = console_ctrl( UIConCtrl, 0, CONSOLE_SCANMODE, CONSOLE_SCANMODE );
}
SavePGroup = tcgetpgrp( UIConHandle );
tcsetpgrp( UIConHandle, UIPGroup );
restorekeyb();
signal( SIGTERM, &term_handler );
return( TRUE );
}
static int ck_fini()
/************************/
{
extern void savekeyb();
savekeyb();
tcsetpgrp( UIConHandle, SavePGroup );
signal( SIGTERM, SIG_DFL );
return 0;
}
static int ck_save()
{
tcsetattr( UIConHandle, TCSADRAIN, &SaveTermSet );
if( UIConCtrl != NULL ) {
console_protocol( UIConCtrl, 0, SaveProtocol );
console_ctrl( UIConCtrl, 0, SaveCtrl, CONSOLE_SCANMODE );
/* There might be a KEY-UP event stuck in the buffer */
tcflush( UIConHandle, TCIFLUSH );
}
return 0;
}
static int init_trie()
{
charoffset *coffs; // start of char-offset table
char *str;
char buff[2];
int i;
if( !TrieInit() ) return( FALSE );
buff[1] = '\0';
for( i = 0; i < NUM_ELTS( InStandard ); ++i ) {
buff[0] = InStandard[i].ch;
if( !TrieAdd( InStandard[i].ev, buff ) ) {
TrieFini();
return( FALSE );
}
}
for( i = 0; i < NUM_ELTS( InTerminfo ); ++i ) {
coffs = (charoffset *)&__cur_term->_strs;
coffs = (void *)((char *)coffs + InTerminfo[i].offset );
str = &__cur_term->_strtab[*coffs];
if( !TrieAdd( InTerminfo[i].ev, str ) ) {
TrieFini();
return( FALSE );
}
}
return( TRUE );
}
Keyboard ConsKeyboard = {
ck_init,
ck_fini,
ck_arm,
ck_save,
ck_restore,
ck_flush,
ck_stop,
ck_shift_state,
ck_unevent
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?