UEFI开发探索31–鼠标GUI构建

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

进行了上一篇博客所描述的各种实验,相关的代码基本都已经搭建好了,我们可以着手进行对GUI界面的鼠标支持了。

UEFI对开发者提供中断支持,所有异步操作都可以通过Event来完成。Simple Pointer Procotol也提供了对此机制的支持,根据文档中函数的说明,构建如下的函数:

图1 鼠标GUI函数

Line8-Line10的四个函数是主力工作的函数:初始化鼠标图像initMouseArrow;检查是否有鼠标事件触发CheckMouseEvent;获取鼠标消息GetMouseState;更新鼠标状态putMouseArrow。

相比之前Legacy BIOS下构建的鼠标驱动,这个简化得太多了,不由得想安慰一下苦苦调试的当年的我。

1 程序构建

一些相对较老的BIOS,对鼠标支持得还不是很好,不过去定位Simple Pointer Protocol的时候,还是能定位到。这种情况对代码逻辑没有什么影响,只是无法在GUI界面上支持鼠标了。

另外一个问题是,前一篇中挖下的问题坑:RelativeMovementX、RelativeMovementY和USB HID协议中的逻辑位移量有什么区别和联系。我个人的猜测是,没有什么直接联系。这是两个不同架构体系下,对鼠标位移量的不同表达。

在UEFI下,鼠标位置的移动,应该结合Mode->ResolutionX、Mode->ResolutionY来综合考虑。如果以像素单位,鼠标的位移公式应该为RelativeMovmentX * MouseRegulator/ResolutionX(Y轴的计算公式类似)。其中,MouseRegulator为用户定义的调节因子,用来调节鼠标移动的灵敏度。

比如,在我的程序中,我将调节因子设为了8。

图2 图形模式下鼠标显示

程序逻辑很简单:当用户鼠标左键和右键同时按下,退出while循环。在循环体中,如果发生了鼠标事件,则获取鼠标的信息。计算出位移值,更新鼠标位置,同时更新鼠标图像。

也许是因为汇编程序写得比较多,对程序的运行效率我比较执着。计算位移量时,也简化了计算过程,主要通过移位计算来实现。其中,右移xScale和yScale分别代表ResolutionX和ResolutionY的除法计算。

测试中发现,ResolutionX一般都是2^n,所以将其幂n计算出来了。采用这种方法,不用去关心恼人的类型转换,代码也简化了很多。

2 程序运行

和上一篇一样,鼠标的程序无法在模拟环境下运行。编译成X64的UEFI app,在实际机器上运行效果如下(intel NUC6CAY):(视频太大了,无法转换为2M以下的GIF图像,我将视频放在了百度云上了- 20190703鼠标程序演示.mp4)

图3 在NUC6CAY上运行鼠标程序

我在能找到的几个平台上都试了下,特别是2016年之后的机器,支持得都很好。至此,鼠标的支持工作就完成了。

为了便于在模拟环境上演示,添加了一段代码,用键盘方向键来控制鼠标图标的移动。与鼠标控制代码共存,也工作得很好,下面是在模拟环境下运行的情况(此时不支持鼠标,只能通过键盘方向键控制)

图4 键盘控制鼠标图标

3 One More Thing

在实际的商业产品中,“颜值”非常重要,如何激起用户的购买欲望,除去功能性满足要求外,产品的外观占据的比重比我们想象的要大得多。

我有段时间特别沉迷于图像特效的处理,也试着把隔离卡的底层界面做得有透明感,仿照苹果的UI做了一些设计。当时的Leader笑我不务正业,做完后的程序最终也没有用到产品上。

在我自己的开源项目Foxdisk的开发中,终于一偿夙愿。把我喜欢的一些特效,比如图像的渐隐、渐出;图标透明、字体自动阴影、亮化和暗化等等,都实现了出来。

人的本性终究是按捺不住的啊~~

实际上,本篇博客中的代码实现,鼠标图标就是透明的,在Gif图中可以看出。其实原理也比较简单,组合之后,能实现很多有意思的效果。

我在UEFI代码中实现了一部分特效功能,下一篇就来聊聊这个。

百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
文件在 21 Mouse-GUI 下

2,068 total views, 1 views today

发表评论

电子邮件地址不会被公开。