Linux/ Unix 鍵盤檢測程序

鍵盤檢測程序

最近在看Neil Matthew和Rick Stones的Beginning Linux Programming, 在 terminals 學到了如何檢測按鍵的方法.話不多說先上代碼:

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>

#define LOCAL_ESC_KEY   27

int main()
{
    initscr();

    cbreak();
    noecho();
    keypad(stdscr, TRUE);
    clear();
    mvprintw(5, 5, "Keypad  Detection demo. Press 'q' to quit");
    move(7, 5);
    refresh();
    int key = getch();

    while(key != ERR && key != 'q') {
        move(7, 5);
        clrtoeol();

        if( (key >= 'A' && key <= 'z') ||
            (key >= 'a' && key < 'z')) {
            printw("Key was %c", key);
        } else if( (key >= '0' && key <= '9') ) {
            printw("Key was %c", key);
        } else if( (key >= KEY_F0 && key <= KEY_F0+12) ) {
            printw("Key was F%d", key-KEY_F0);
        } else {
            switch(key) {
            case LOCAL_ESC_KEY: printw("Esc key");break;
            case KEY_END: printw("END key");break;
            case KEY_BEG: printw("BEGINNING key");break;
            case KEY_RIGHT: printw("RIGHT key");break;
            case KEY_LEFT: printw("LEFT key");break;
            case KEY_UP: printw("UP key");break;
            case KEY_DOWN: printw("DOWN key");break;
            // you may add more here...
            default: printw("Unmatched %d", key);break;
            }
        }           
        refresh();
        key = getch();
    }

    endwin();
    exit(0);
}

編譯: gcc -o proc main.c -lcurses
這裏使用了 curses,所以在編譯的時候要加上-lcurses選項.
而所有的 curses 程序都少不了這兩個函數
WINDOW *initscr(void);
成功則返回一個指向stdscr 的指針,否則返回 NULL 並打印報錯信息到 stderr. initscr通常是 curses 程序的第一個函數,起到初始化 curses 的作用
int endwin(void);
成功返回 OK, 失敗返回 ERR.
基本結構清楚後,這裏介紹終端的兩種輸入模式:cooked modecbreak mode.
cook mode 下終端會將輸入緩存, 程序只有在 ENTER 鍵按下後才能獲得輸入;而 cbreak mode 在按鍵按下的同時,程序即獲得輸入,也就是說前者有 buffer 緩衝而後者沒有.程序正是使用cbreak mode的輸入即得來檢測按鍵.
當initscr成功返回時,程序即進入cooked mode, 這時調用cbreak後終端即進入cbreak mode,另外爲了不讓按鍵輸入出現在屏幕上,程序調用noecho禁止回顯.
爲了獲得鍵盤輸入與功能按鍵(如方向鍵, F1等)的關係, 需要調用 keypad 函數
int keypad(WINDOW *win, bool bf);
這裏第一個參數傳入stdscr 指針即可.這樣環境初始化就完成了,接下來就可以檢測按鍵了, 有關按鍵的宏定義, 可以參見curses.h中的 KEY_ 開頭的宏, 具體命令:
cat /usr/include/curses.h | grep “KEY_”
這裏方便起見, 先貼出來:

#define KEY_CODE_YES    0400        /* A wchar_t contains a key code */
#define KEY_MIN     0401        /* Minimum curses key */
#define KEY_BREAK   0401        /* Break key (unreliable) */
#define KEY_SRESET  0530        /* Soft (partial) reset (unreliable) */
#define KEY_RESET   0531        /* Reset or hard reset (unreliable) */
#define KEY_DOWN    0402        /* down-arrow key */
#define KEY_UP      0403        /* up-arrow key */
#define KEY_LEFT    0404        /* left-arrow key */
#define KEY_RIGHT   0405        /* right-arrow key */
#define KEY_HOME    0406        /* home key */
#define KEY_BACKSPACE   0407        /* backspace key */
#define KEY_F0      0410        /* Function keys.  Space for 64 */
#define KEY_F(n)    (KEY_F0+(n))    /* Value of function key n */
#define KEY_DL      0510        /* delete-line key */
#define KEY_IL      0511        /* insert-line key */
#define KEY_DC      0512        /* delete-character key */
#define KEY_IC      0513        /* insert-character key */
#define KEY_EIC     0514        /* sent by rmir or smir in insert mode */
#define KEY_CLEAR   0515        /* clear-screen or erase key */
#define KEY_EOS     0516        /* clear-to-end-of-screen key */
#define KEY_EOL     0517        /* clear-to-end-of-line key */
#define KEY_SF      0520        /* scroll-forward key */
#define KEY_SR      0521        /* scroll-backward key */
#define KEY_NPAGE   0522        /* next-page key */
#define KEY_PPAGE   0523        /* previous-page key */
#define KEY_STAB    0524        /* set-tab key */
#define KEY_CTAB    0525        /* clear-tab key */
#define KEY_CATAB   0526        /* clear-all-tabs key */
#define KEY_ENTER   0527        /* enter/send key */
#define KEY_PRINT   0532        /* print key */
#define KEY_LL      0533        /* lower-left key (home down) */
#define KEY_A1      0534        /* upper left of keypad */
#define KEY_A3      0535        /* upper right of keypad */
#define KEY_B2      0536        /* center of keypad */
#define KEY_C1      0537        /* lower left of keypad */
#define KEY_C3      0540        /* lower right of keypad */
#define KEY_BTAB    0541        /* back-tab key */
#define KEY_BEG     0542        /* begin key */
#define KEY_CANCEL  0543        /* cancel key */
#define KEY_CLOSE   0544        /* close key */
#define KEY_COMMAND 0545        /* command key */
#define KEY_COPY    0546        /* copy key */
#define KEY_CREATE  0547        /* create key */
#define KEY_END     0550        /* end key */
#define KEY_EXIT    0551        /* exit key */
#define KEY_FIND    0552        /* find key */
#define KEY_HELP    0553        /* help key */
#define KEY_MARK    0554        /* mark key */
#define KEY_MESSAGE 0555        /* message key */
#define KEY_MOVE    0556        /* move key */
#define KEY_NEXT    0557        /* next key */
#define KEY_OPEN    0560        /* open key */
#define KEY_OPTIONS 0561        /* options key */
#define KEY_PREVIOUS    0562        /* previous key */
#define KEY_REDO    0563        /* redo key */
#define KEY_REFERENCE   0564        /* reference key */
#define KEY_REFRESH 0565        /* refresh key */
#define KEY_REPLACE 0566        /* replace key */
#define KEY_RESTART 0567        /* restart key */
#define KEY_RESUME  0570        /* resume key */
#define KEY_SAVE    0571        /* save key */
#define KEY_SBEG    0572        /* shifted begin key */
#define KEY_SCANCEL 0573        /* shifted cancel key */
#define KEY_SCOMMAND    0574        /* shifted command key */
#define KEY_SCOPY   0575        /* shifted copy key */
#define KEY_SCREATE 0576        /* shifted create key */
#define KEY_SDC     0577        /* shifted delete-character key */
#define KEY_SDL     0600        /* shifted delete-line key */
#define KEY_SELECT  0601        /* select key */
#define KEY_SEND    0602        /* shifted end key */
#define KEY_SEOL    0603        /* shifted clear-to-end-of-line key */
#define KEY_SEXIT   0604        /* shifted exit key */
#define KEY_SFIND   0605        /* shifted find key */
#define KEY_SHELP   0606        /* shifted help key */
#define KEY_SHOME   0607        /* shifted home key */
#define KEY_SIC     0610        /* shifted insert-character key */
#define KEY_SLEFT   0611        /* shifted left-arrow key */
#define KEY_SMESSAGE    0612        /* shifted message key */
#define KEY_SMOVE   0613        /* shifted move key */
#define KEY_SNEXT   0614        /* shifted next key */
#define KEY_SOPTIONS    0615        /* shifted options key */
#define KEY_SPREVIOUS   0616        /* shifted previous key */
#define KEY_SPRINT  0617        /* shifted print key */
#define KEY_SREDO   0620        /* shifted redo key */
#define KEY_SREPLACE    0621        /* shifted replace key */
#define KEY_SRIGHT  0622        /* shifted right-arrow key */
#define KEY_SRSUME  0623        /* shifted resume key */
#define KEY_SSAVE   0624        /* shifted save key */
#define KEY_SSUSPEND    0625        /* shifted suspend key */
#define KEY_SUNDO   0626        /* shifted undo key */
#define KEY_SUSPEND 0627        /* suspend key */
#define KEY_UNDO    0630        /* undo key */
#define KEY_MOUSE   0631        /* Mouse event has occurred */
#define KEY_RESIZE  0632        /* Terminal resize event */
#define KEY_EVENT   0633        /* We were interrupted by an event */
#define KEY_MAX     0777        /* Maximum key value is 0633 */

上面的程序只做了對於數字,字母,方向鍵, F n鍵以及 ESC 鍵檢測.而根據這些宏, 你就可以完善上述程序.

參考


Beginning Linux® Programming 4th Edition, Neil Matthew && Richard Stones

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章