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 + -
显示快捷键?