更详细的讲解和代码调试演示过程,请参看视频
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源创计划”,欢迎正在阅读的你也加入,一块儿分享。