java開發(fā)系統(tǒng)內(nèi)核:實現(xiàn)shift按鍵效果

更詳細(xì)的講解和代碼調(diào)試演示過程蒲凶,請參看視頻
Linux kernel Hacker, 從零構(gòu)建自己的內(nèi)核

前幾節(jié),我們花費不少精力在鍵盤響應(yīng)的處理之上帝雇,到目前為止绪爸,我們的內(nèi)核能夠準(zhǔn)確的將按鍵字符合理的顯示在指定窗口上。但目前還有一些遺憾厕宗,就是當(dāng)前內(nèi)核對shift 鍵的按下不做反應(yīng)画舌。按理堕担,當(dāng)shift鍵按下后,再按數(shù)字鍵1曲聂,那么顯示的字符應(yīng)該是"!"而不是“1”霹购,本節(jié)我們要處理的就是響應(yīng)shift鍵的點擊處理,完成本節(jié)后朋腋,內(nèi)核效果如下:

這里寫圖片描述

我們可以看到厕鹃,當(dāng)按下shift鍵后,再點擊數(shù)字鍵1乍丈,2,3,顯示的不再是數(shù)字字符把将,而是對應(yīng)的特殊字符.我們看看對應(yīng)代碼的實現(xiàn)轻专,首先需要修改的是write_vga_desktop.c:

static char keytable1[0x80] = {
        0,   0,   '!', '@', '#', '$', '%','^', '&', '*', '(', ')', '-', '=', '~', 0,   0,
        'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0,   0,   'A', 'S',
        'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0,   0,   '}', 'Z', 'X', 'C', 'V',
        'B', 'N', 'M', '<', '>', '?', 0,   '*', 0,   ' ', 0,   0,   0,   0,   0,   0,
        0,   0,   0,   0,   0,   0,   0,   '7', '8', '9', '-', '4', '5', '6', '+', '1',
        '2', '3', '0', '.', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
        0,   0,   0,   '_', 0,   0,   0,   0,   0,   0,   0,   0,   0,   '|', 0,   0
    };

int  key_shift = 0;

首先我們增加了一個輸入表keytable1,已經(jīng)一個變量key_shift, 當(dāng)shift鍵被按下時這個變量的值變?yōu)榉?,當(dāng)shift鍵松開后察蹲,該變量的值恢復(fù)為0.對應(yīng)的當(dāng)shift鍵按下時请垛,顯示鍵盤字符時使用keytable1表,如果shift鍵沒有被按下洽议,那么使用keytable表宗收。

char  transferScanCode(int data) {
    if (data == 0x2a)  {//left shift key down
        key_shift |= 1;
    }

    if (data == 0x36) {
        //right shift key down 
        key_shift |= 2; 
    }

    if (data == 0xaa) {
        //left shift key up
        key_shift &= ~1;
    }
    
    if (data == 0xb6) {
       //right shift key up
        key_shift &= ~2;
    }

    if (data == 0x2a || data == 0x36 || data == 0xaa || data == 0xb6 || 
        data >= 0x54) {
        return 0;
    }

    char c = 0;
    
    if (key_shift == 0 && data<0x54 && keytable[data] != 0) {
        c = keytable[data];
    } 
    else if (key_shift != 0 && data < 0x80 && keytable1[data] != 0){
        c = keytable1[data];
    }
    else {
        c = 0;
    }

    return c;
}

上面的函數(shù)用于處理按鍵產(chǎn)生的掃描碼和斷碼,當(dāng)左邊的shift鍵按下時亚兄,鍵盤發(fā)出的掃描碼是0x2a, 右邊的shift鍵按下時混稽,鍵盤的掃描碼是0x36,當(dāng)左邊的shift按鍵松開時,鍵盤發(fā)送的斷碼是0xaa,右邊的shift鍵放開后审胚,鍵盤發(fā)送的斷碼是0xb6. 一旦左邊的shift鍵按下時匈勋,key_shift的值設(shè)置為1,右邊shift鍵按下時膳叨,key_shift的值為2洽洁。當(dāng)shift按鍵松開后,key_shift的值變?yōu)?.

從代碼中也可以看到菲嘴,如果key_shift的值不等于0饿自,也就是shift鍵被按下,那么我們到keytable1里面去查找按鍵對應(yīng)的字符龄坪,如果key_shift值是0昭雌,也就是shift鍵沒有被按下,那么我們到 keytable表中去查找按鍵對應(yīng)的字符悉默。我們再看看字符是如何顯示出來的:

void CMain(void) {
....
    for(;;) {
    ....
    else if (key_to == 0) {
               if (transferScanCode(data) != 0 && cursor_x < 144) {
                   boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, COL8_FFFFFF,cursor_x,
                   28, cursor_x + 7, 43);
                   sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
                   char c = transferScanCode(data);
                   char buf[2] = {c, 0};
                   showString(shtctl,  shtMsgBox, cursor_x, 28, COL8_000000, buf);
                   cursor_x += 8;
                
                   stop_task_A = 1;

                   boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, cursor_c, cursor_x,
                  28, cursor_x + 7, 43);
                  sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
              } 
    }
....
}

void console_task(struct SHEET *sheet) {
....
    for(;;) {
    ....
    else {
                           if (cursor_x < 240  && transferScanCode(i) != 0) {
                           boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x,
                28, cursor_x + 7, 43);
                           sheet_refresh(shtctl, sheet, cursor_x, 28, cursor_x+8, 44);

                           s[0] = transferScanCode(i);
                           s[1] = 0;
                           showString(shtctl, sheet, cursor_x, 28, COL8_FFFFFF, s);
                           cursor_x += 8;
                       }
       ....
    }
}

從上面的代碼我們可以看到城豁,無論是控制臺窗口還是文本框窗口,在顯示字符前抄课,都先調(diào)用transferScanCode函數(shù)去將鍵盤發(fā)過來的數(shù)值進行轉(zhuǎn)換唱星,如果轉(zhuǎn)換的結(jié)果不是0雳旅,那么將得到的字符顯示到窗口中。完成上面代碼后间聊,即可得本文開頭所描述的運行結(jié)果攒盈。

更詳細(xì)的代碼講解和調(diào)試,請參看視頻哎榴。

更多技術(shù)信息型豁,包括操作系統(tǒng),編譯器尚蝌,面試算法迎变,機器學(xué)習(xí),人工智能飘言,請關(guān)照我的公眾號:


這里寫圖片描述
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末衣形,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子姿鸿,更是在濱河造成了極大的恐慌谆吴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苛预,死亡現(xiàn)場離奇詭異句狼,居然都是意外死亡,警方通過查閱死者的電腦和手機热某,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門腻菇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人苫拍,你說我怎么就攤上這事芜繁。” “怎么了绒极?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵骏令,是天一觀的道長。 經(jīng)常有香客問我垄提,道長榔袋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任铡俐,我火速辦了婚禮凰兑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘审丘。我一直安慰自己吏够,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锅知,像睡著了一般播急。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上售睹,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天桩警,我揣著相機與錄音,去河邊找鬼昌妹。 笑死捶枢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的飞崖。 我是一名探鬼主播烂叔,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼固歪!你這毒婦竟也來了长已?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤昼牛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后康聂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贰健,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年恬汁,在試婚紗的時候發(fā)現(xiàn)自己被綠了伶椿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡氓侧,死狀恐怖脊另,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情约巷,我是刑警寧澤偎痛,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站独郎,受9級特大地震影響踩麦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜氓癌,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一谓谦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贪婉,春花似錦反粥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莫湘。三九已至,卻和暖如春娜膘,著一層夾襖步出監(jiān)牢的瞬間逊脯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工竣贪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留军洼,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓演怎,卻偏偏與公主長得像匕争,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子爷耀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容