minigui 4.0 源代码分析(三)
2020-11-23 本文已影响0人
RonZheng2010
1. MSGQUEUE与MSG
MSGQUEUE是消息队列,MSG是队列中的消息。后面还有一节说明进一步的细节。
![](https://img.haomeiwen.com/i15107051/d79304c82ff87b4a.png)
关于MSGQUEUE,
- 成员msg[]是用作环形缓存的数组,成员writepos是推送消息的位置,readpos是获取消息的位置。
- 成员wait是“有消息待处理”的信号量,
- 成员sync_msg是“有同步消息待处理”的信号量。
1.1 创建消息队列
mg_InitMsgQueue()创建消息队列。用户可以指定队列大小,缺省值为32。
![](https://img.haomeiwen.com/i15107051/5b7fbb87a6c793a1.png)
1.2 向队列推送消息
Kernel_QueueMessage()用于向队列中推送消息。
![](https://img.haomeiwen.com/i15107051/caee9a4e46eef1f0.png)
2. 用户输入输出
2.1 INPUT
INPUT定义用户输入子系统。
- 成员id是名称。
- 成员函数init_input()初始化子系统
- 成员函数get_mouse_xy()/set_mouse_xy()读取/设置鼠标位置,
- 成员函数get_keyboard_state()得到键盘状态。
- 成员函数wait_event()/wait_event_ex()获取输入消息。
![](https://img.haomeiwen.com/i15107051/7824314da6bac3a1.png)
全局数组inputs[]定义一系列的输入子系统,其中每个子系统与特定设备相关。这里指定系统名称、系统初始化函数。
INPUT inputs [] = {
{"dummy", InitDummyInput, TermDummyInput},
{"pc_xvfb", InitPCXVFBInput, TermPCXVFBInput},
{"nexus", InitNexusInput, TermNexusInput},
...
};
这里说明的例子还是gvfb提供的虚拟设备“pc_xvfb”。
2.2 设备pc_xvfb
如前所说,minigui进程通过unix socket与gvfb进程连接。
![](https://img.haomeiwen.com/i15107051/e618ce74a59cded6.png)
gvfb进程捕捉输入消息,通过unix socket通道发给minigui进程。Minigui进程根据消息类型,相应地构造自己的消息XVFBEVENT,发送给minigui进程的顶层窗口HWND_DESKTOP。
2.3 XVFBEVENT
XVFBEVENT定义输入事件。
- 成员event_type是事件类型
- 成员key是键盘消息的数据,这是个XVFBKEYDATA结构
- 成员mouse是鼠标消息的数据,这是个XVFBMOUSEDATA结构
![](https://img.haomeiwen.com/i15107051/bf810d82c046c944.png)
2.4 mg_InitIAL()
mg_InitIAL()初始化输入输出子系统。
- 根据指定的名字,在数组inputs[]中查找INPUT实例。这里是”pcxvfb”。
- 调用INPUT::Init_Input(),初始化INPUT结构。其中设置INPUT的其他成员函数。。这里调用InputPCXVFBInput(),将pcxvfb提供的wait_event()设置为成员函数wait_event()。
![](https://img.haomeiwen.com/i15107051/9bb0a903988656c0.png)
2.5 IAL_WaitEvent()
IAL_WaitEvent()等待用户输入,得到相应的输入事件。这里它调用pxxvfb提供的wait_event()。其中,
- 调用mg_select(),在__mg_pcxvfb_client_sockfd上等待,这是在PCXVFB_VideoInit()中创建的socket。
- 等待返回后,调用read_socket()在socket上读取event类型。然后根据event类型,读取event数据。
- 构造输入事件,也就是XVFBEVENT实例,并返回给调用者。
![](https://img.haomeiwen.com/i15107051/94dbba4fa18f6d4d.png)