更詳細的講解和代碼調試演示過程,請參看視頻
Linux kernel Hacker, 從零構建本身的內核vue
咱們實現了鍵盤的輸入焦點切換,但儘管控制命令臺激活後,若是咱們敲擊鍵盤,會發現字符輸入的仍是前頭的Message box.這一節,咱們要實現把鍵盤敲擊的內容輸入到被切換的窗口。微信
實現的思路是這樣的,咱們爲每一個任務配置一個輸入隊列,當窗口被激活時,一旦有鍵盤輸入,主進程首先會把鍵盤數據獲取到,而後判斷當前被激活的是哪一個窗口,而後找到運行窗口所對應的進程對象,經過進程對象得到其對應的輸入隊列,因而把鍵盤傳過來的信息放入到輸入隊列中,而後激活對應的進程對象。markdown
爲此,咱們對代碼作以下修改,首先是multi_task.h:app
struct TASK { int sel, flags; int priority; int level; struct FIFO8 fifo; struct TSS32 tss; };
上面的改動就是添加了一個隊列,用來獲取信息輸入。接下來修改的是主進程的CMain 函數,一旦鍵盤事件產生後,CMain會被激活,這時它能夠把接收到的字符投入到對應窗口進程的隊列中:函數
void CMain(void) { .... for(;;) { .... else if (key_to == 0) { 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; 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); } } else { task_sleep(task_a); fifo8_put(&task_cons->fifo, data); } } .... } .... }
若是當前激活的窗口是Message Box 那麼字符就直接顯示在文本框中,要否則咱們把當前主進程掛起,而後把鍵盤數據經過fifo8_put把數據投入到控制檯進程對應的隊列中。咱們必定要記得把主進程掛起,要否則主進程會一直佔據CPU資源,從而控制檯進程不能運行,進而沒法及時處理鍵盤數據。ui
咱們再看看控制檯進程的改變:url
void console_task(struct SHEET *sheet) { .... else { if (i == 0x0e && cursor_x > 8) { 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); cursor_x -= 8; 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); } else { if (cursor_x < 240 &&i< 0x54 && keytable[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] = keytable[i]; s[1] = 0; showString(shtctl, sheet, cursor_x, 28, COL8_FFFFFF, s); cursor_x += 8; } } } .... }
變量i的值就是CMain傳進來鍵盤數據,若是i的值是0x0e,表示鍵盤按鈕是退格鍵,接收到這個按鍵時,咱們要作的是把光標前面的字符給刪除掉。在刪除字符時,咱們須要注意一點,就是對光標的處理,因爲光標效果是經過繪製一個白色方塊,而後再繪製一個黑色方塊來實現的,若是退格時,光標正好是白色方塊,那麼咱們把光標向前移動一個字符的位置後,就會在光標的原來位置留下一個白色方塊,所以在把光標向前移動前,咱們先要在光標原來的位置用背景色繪製同等大小的方塊,把白色方塊給覆蓋的,這就是爲什麼在cursor_x -= 8; 這條語句前會有三條用於繪製窗口的語句。spa
把光標向前移動一個字符的位置後,光標前面的字符就會被光標的方塊給覆蓋掉,從而實現字符刪除的特效。.net
若是輸入的是其餘字符,那麼同理,先把光標當前的位置用背景色覆蓋掉,而後在把字符顯示出來,接着把光標向後移動一個字符的位置,在新位置上交替繪製光標方塊。命令行
上面的代碼完成後,效果以下:
你們能夠看到,系統運行後,經過tab把輸入焦點切換到後面的控制檯,而後點擊鍵盤,鍵盤對應的字符會出如今命令行窗口上,一旦命令行窗口能接收字符,咱們後面就能夠在系統上開發其餘程序,而後經過命令行窗口來運行。
更詳實的代碼講解和演示調試過程請參看視頻。
本文分享自微信公衆號 - Coding迪斯尼(gh_c9f933e7765d)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。