2 控制光标闪烁(2)(harib15b)

接下来我们来实现稍微有点麻烦的命令行窗口中光标闪烁的控制。之所以说稍微有点麻烦,是因为命令行窗口是另外一个任务,无法从HariMain中改变它里面的变量。

那么应该怎样由HariMain(任务A)向console_task(命令行窗口)传递信息,告诉它“不需让光标闪烁”或者“需要让光标闪烁”呢?像传递按键编码一样,我们可以使用FIFO来实现。

我们先将光标开始闪烁定义为2,停止闪烁定义为3。

本次的bootpack.c节选

  1. void HariMain(void)
  2. {
  3. (中略)
  4. for (;;) {
  5. (中略)
  6. if (fifo32_status(&fifo) == 0) {
  7. (中略)
  8. } else {
  9. (中略)
  10. if (256 <= i && i <= 511) { /*键盘数据*/
  11. (中略)
  12. if (i == 256 + 0x0f) { /* Tab键*/
  13. if (key_to == 0) {
  14. key_to = 1;
  15. make_wtitle8(buf_win, sht_win->bxsize, "task_a", 0);
  16. make_wtitle8(buf_cons, sht_cons->bxsize, "console", 1);
  17. cursor_c = -1; /*不显示光标*/
  18. boxfill8(sht_win->buf, sht_win->bxsize, COL8_FFFFFF, cursor_x, 28,
  19. cursor_x + 7, 43);
  20. /*这里! */ fifo32_put(&task_cons->fifo, 2); /*命令行窗口光标ON */
  21. } else {
  22. key_to = 0;
  23. make_wtitle8(buf_win, sht_win->bxsize, "task_a", 1);
  24. make_wtitle8(buf_cons, sht_cons->bxsize, "console", 0);
  25. cursor_c = COL8_000000; /*显示光标*/
  26. /*这里! */ fifo32_put(&task_cons->fifo, 3); /*命令行窗口光标OFF */
  27. }
  28. sheet_refresh(sht_win, 0, 0, sht_win->bxsize, 21);
  29. sheet_refresh(sht_cons, 0, 0, sht_cons->bxsize, 21);
  30. }
  31. (中略)
  32. } else if (512 <= i && i <= 767) { /*鼠标数据*/
  33. (中略)
  34. } else if (i <= 1) { /*光标用定时器*/
  35. (中略)
  36. }
  37. }
  38. }
  39. }

HariMain这样改就差不多了。

■■■■■

下面该轮到console_task了。在启动的时候是任务A处于输入状态,因此我们在一开始就将cursor_c置为-1,剩下的部分和任务A大同小异。

本次的bootpack.c节选

  1. void console_task(struct SHEET *sheet)
  2. {
  3. struct TIMER *timer;
  4. struct TASK *task = task_now();
  5. int i, fifobuf[128], cursor_x = 16, cursor_c = -1; /*这里!*/
  6. char s[2];
  7. (中略)
  8. for (;;) {
  9. io_cli();
  10. if (fifo32_status(&task->fifo) == 0) {
  11. task_sleep(task);
  12. io_sti();
  13. } else {
  14. i = fifo32_get(&task->fifo);
  15. io_sti();
  16. if (i <= 1) { /*光标用定时器*/
  17. /*从此开始*/ if (i != 0) {
  18. timer_init(timer, &task->fifo, 0); /*下次置为0 */
  19. if (cursor_c >= 0) {
  20. cursor_c = COL8_FFFFFF;
  21. }
  22. } else {
  23. timer_init(timer, &task->fifo, 1); /*下次置为1 */
  24. if (cursor_c >= 0) {
  25. cursor_c = COL8_000000;
  26. }
  27. /*到此结束*/ }
  28. timer_settime(timer, 50);
  29. }
  30. if (i == 2) { /*光标ON */ /*从此开始*/
  31. cursor_c = COL8_FFFFFF;
  32. }
  33. if (i == 3) { /*光标OFF */
  34. boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, 28, cursor_x + 7, 43);
  35. cursor_c = -1;
  36. } /*到此结束*/
  37. if (256 <= i && i <= 511) { /*键盘数据(通过任务A) */
  38. if (i == 8 + 256) {
  39. /*退格键*/
  40. if (cursor_x > 16) {
  41. /*用空白擦除光标后将光标前移一位 */
  42. putfonts8_asc_sht(sheet, cursor_x, 28, COL8_FFFFFF, COL8_000000, " ", 1);
  43. cursor_x -= 8;
  44. }
  45. } else {
  46. /*一般字符*/
  47. if (cursor_x < 240) {
  48. /*显示一个字符之后将光标后移一位 */
  49. s[0] = i - 256;
  50. s[1] = 0;
  51. putfonts8_asc_sht(sheet, cursor_x, 28, COL8_FFFFFF, COL8_000000, s, 1);
  52. cursor_x += 8;
  53. }
  54. }
  55. }
  56. /*重新显示光标*/
  57. if (cursor_c >= 0) { /*从此开始*/
  58. boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
  59. } /*到此结束*/
  60. sheet_refresh(sheet, cursor_x, 28, cursor_x + 8, 44);
  61. }
  62. }
  63. }

■■■■■

还是一如既往来“make run”,不知道能不能成功呢。

2 控制光标闪烁(2)(harib15b) - 图1

命令行窗口的光标也不见了哦!

成功了!怎么样,是不是变得很酷呢?