介绍
云电脑有两种鼠标模式:
客户端模式:
客户端画鼠标,服务端隐藏鼠标,发送位置,按键等信息到服务端,服务端更新,服务端发送鼠标形状等光标信息,客户端更新;
这种模式下,鼠标事件会被注入到虚拟鼠标设备,再通知到guest os。
服务端模式:
服务端画鼠标,客户端隐藏鼠标。
鼠标事件会被发送到agent(跑在guest os上),agent再写入guest os。
鼠标事件走哪个设备?
一共有3种设备,agent/qemu tablet/qemu mouse. 不同的事件,判断走哪个设备的逻辑不一样。
以mouse press 为例。这是一个鼠标按键消息。
走agent :
client 鼠标模式 + agent mouse变量为TRUE + vdagent存在 + 客户端没有CAP_MOUSE_QEMU(指定走qemu鼠标)
走tablet设备:
client鼠标模式+ 不满足走agent的条件+tablet设备存在。
走mouse设备:
上述条件不符合,且mouse设备存在。
qemu tablet和qemu mouse设备调查
mouse:
Virtual Mouse. This will override the PS/2 mouse emulation when activated.
tablet:
Pointer device that uses absolute coordinates (like a touchscreen). This means QEMU is able to report the mouse position without having to grab the mouse. Also overrides the PS/2 mouse emulation when activated.
从代码看,mouse设备和tablet设备的主要不同是:
- tablet设备使用绝对坐标系(INPUT_EVENT_MASK_ABS);
- tablet 设备多了一个wheel(滚轮)接口。
它们都继承自usb-hid设备。
事件通知guest流程:
hid初始化的时候,会指定回调函数usb_hid_changed
hid_init(&us->hid, kind, usb_hid_changed);
clink server 收到鼠标事件的时候,会回调usb_hid_changed,usb_hid_changed起中断,通知guest。
举例:wheel消息写入tablet设备流程:
收到mouse press
|-> sif->wheel
|-> tablet_wheel
|-> qemu_input_event_sync_impl
|-> hid_pointer_sync
|-> usb_hid_changed