操作系統(tǒng)內(nèi)核開發(fā):輸入文本框和鼠標(biāo)移動窗體

Linux kernel Hacker, 從零構(gòu)建自己的內(nèi)核

上一節(jié),我們實現(xiàn)了按鍵轉(zhuǎn)換成字符的功能,這一節(jié)坤塞,我們更近一步预皇,在message box中實現(xiàn)一個輸入文本框,按鍵時诉植,字符顯示在文本框內(nèi),并且輸入光標(biāo)在文本框中不斷閃動。

在內(nèi)核的C語言部分张弛,也就是write_vga_desktop.c中做如下改動:

void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c) {
    int x1 = x0 + sx, y1 = y0 + sy;
    boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3);
    boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1);
    boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2);
    boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2);
    boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2);
    boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0);
    boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1);
    boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1);
    boxfill8(sht->buf, sht->bxsize, c, x0 - 1, y0 - 1, x1 + 0, y1 + 0); 
}

我們增加了一個函數(shù)叫make_textbox8, 它的作用是繪制一個有邊框的白色方塊,這個方塊其實就模擬了輸入文本框酪劫。然后我們對繪制message box的實現(xiàn)方法做一些修改吞鸭,以便文本框能輸入到message box的主窗體里:

struct SHEET*  message_box(struct SHTCTL *shtctl,  char *title) {
    struct SHEET *sht_win;
    unsigned char *buf_win;
    
    sht_win = sheet_alloc(shtctl);
    buf_win = (unsigned char *)memman_alloc_4k(memman, 160 * 68);
    sheet_setbuf(sht_win, buf_win, 160, 68, -1);

    make_window8(shtctl, sht_win, title);
    make_textbox8(sht_win, 8, 28, 144, 16, COL8_FFFFFF);    
    
    sheet_slide(shtctl, sht_win, 80, 72);
    sheet_updown(shtctl, sht_win, 2);

    return sht_win;
}

上面的窗體繪制函數(shù)中,在繪制好message box的主窗體后覆糟,里面把白色文本框畫到主窗體的中央刻剥。有了文本框后,我們可以接著實現(xiàn)字符輸入功能滩字。

void CMain(void) {
    ....
    int cursor_x = 8, cursor_c=COL8_FFFFFF
    ....
    for(;;) {
    ....
    else if (keytable[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 buf[2] = {keytable[data], 0};
                   showString(shtctl,  shtMsgBox, cursor_x, 28, COL8_000000, buf);
                   cursor_x += 8;
                
              
              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);
           }
                     
       }
    ....
    else if (fifo8_status(&timerinfo) != 0) {
           io_sti();
           int i = fifo8_get(&timerinfo);
           if (i == 10) {
               showString(shtctl, sht_back, 0, 0, COL8_FFFFFF, " new 5[sec]");
           } else if (i == 2) {
               showString(shtctl, sht_back, 0, 16, COL8_FFFFFF, "3[sec]");
           } else {
               if (i != 0) {
                  timer_init(timer3, &timerinfo, 0);
                  cursor_c = COL8_000000;
               } else {
                  timer_init(timer3, &timerinfo, 1);
                  cursor_c = COL8_FFFFFF;
               }

               timer_settime(timer3, 50);
               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);

           }
       }
       
     ......
    }
    ....
}

一旦有鍵盤事件時造虏,內(nèi)核先把掃描碼轉(zhuǎn)換成對應(yīng)的字符,然后繪制到message box窗體的文本框中麦箍,cursor_x是字符輸入的位置漓藕,沒輸入一個字符,它的值增加8挟裂,因為一個字符的像素寬度是8.為何在輸入字符前享钞,需要調(diào)用boxfill8,和sheet_refresh這兩個函數(shù)呢诀蓉,這是因為光標(biāo)閃爍時栗竖,會由黑色變成白色,如果光標(biāo)變成黑色時渠啤,我們正好按下鍵盤的話狐肢,那么字符顯示時的背景將是黑色的,但是我們的字體本身就是黑色的埃篓,所以一旦這種情況發(fā)生的時处坪,如果不調(diào)用這兩個函數(shù)先把字體要顯示的位置刷成白色的話,字體就顯示不出來,而顯示的是一個黑色小方塊同窘,具體情形玄帕,大家參考視頻講解會更明白。

在主循環(huán)中想邦,當(dāng)timer3 超時時裤纹,我們可以變換光標(biāo)的顏色,如果原來是白色丧没,那么把它轉(zhuǎn)換成黑色鹰椒,如果原來是黑色,則轉(zhuǎn)換成白色呕童,需要注意的是漆际,此時光標(biāo)顯示的位置是在message box的文本框內(nèi)。

上面代碼編譯運行后夺饲,效果如下:


這里寫圖片描述

鼠標(biāo)移動窗體

接下來奸汇,我們看看如何實現(xiàn)鼠標(biāo)移動message box的效果,這個實現(xiàn)很簡單往声,在內(nèi)核的C語言部分做如下改動:

void  show_mouse_info(struct SHTCTL *shtctl, struct SHEET *sht_back,struct SHEET *sht_mouse) {
    char*vram = buf_back;
    unsigned char data = 0;
     
    io_sti();
    data = fifo8_get(&mouseinfo);
    if (mouse_decode(&mdec, data) != 0) {
         computeMousePosition(shtctl, sht_back, &mdec);
        
         sheet_slide(shtctl, sht_mouse, mx, my);
         if ((mdec.btn & 0x01) != 0) {
            sheet_slide(shtctl, shtMsgBox, mx - 80, my - 8); 
         }
    }
}

在鼠標(biāo)事件發(fā)生后擂找,硬件會給端口發(fā)送鼠標(biāo)相關(guān)數(shù)據(jù),內(nèi)核拿到數(shù)據(jù)后會進行解析浩销,如果結(jié)構(gòu)體mdec.btn的第0位設(shè)置成1的話贯涎,就表明,此時鼠標(biāo)的左鍵按下了慢洋,這樣塘雳,當(dāng)我們繪制鼠標(biāo)時,把message box 窗體同步移動到鼠標(biāo)的相應(yīng)位置且警,這樣就能實現(xiàn)窗體隨鼠標(biāo)移動了粉捻,當(dāng)然礁遣,當(dāng)前做法存在一個問題是斑芜,我們沒有判斷鼠標(biāo)左鍵按下時,鼠標(biāo)是否在message box的窗體范圍內(nèi)祟霍,這個功能往后我們再添加上杏头,上面的代碼編譯后運行效果如下:


這里寫圖片描述

窗體被從左上角移動到了右下角,具體效果沸呐,參看視頻會更加明顯醇王。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市崭添,隨后出現(xiàn)的幾起案子寓娩,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棘伴,死亡現(xiàn)場離奇詭異寞埠,居然都是意外死亡,警方通過查閱死者的電腦和手機焊夸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門仁连,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人阱穗,你說我怎么就攤上這事饭冬。” “怎么了揪阶?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵昌抠,是天一觀的道長。 經(jīng)常有香客問我鲁僚,道長扰魂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任蕴茴,我火速辦了婚禮劝评,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倦淀。我一直安慰自己蒋畜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布撞叽。 她就那樣靜靜地躺著姻成,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愿棋。 梳的紋絲不亂的頭發(fā)上科展,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音糠雨,去河邊找鬼才睹。 笑死,一個胖子當(dāng)著我的面吹牛甘邀,可吹牛的內(nèi)容都是我干的琅攘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼松邪,長吁一口氣:“原來是場噩夢啊……” “哼坞琴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逗抑,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤剧辐,失蹤者是張志新(化名)和其女友劉穎寒亥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荧关,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡护盈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了羞酗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腐宋。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖檀轨,靈堂內(nèi)的尸體忽然破棺而出胸竞,到底是詐尸還是另有隱情,我是刑警寧澤参萄,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布卫枝,位于F島的核電站,受9級特大地震影響讹挎,放射性物質(zhì)發(fā)生泄漏校赤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一筒溃、第九天 我趴在偏房一處隱蔽的房頂上張望马篮。 院中可真熱鬧,春花似錦怜奖、人聲如沸浑测。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迁央。三九已至,卻和暖如春滥崩,著一層夾襖步出監(jiān)牢的瞬間岖圈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工钙皮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蜂科,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓株灸,卻偏偏與公主長得像崇摄,于是被迫代替她去往敵國和親擎值。 傳聞我的和親對象是個殘疾皇子慌烧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

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