SylixOS xinput 系统

来源:互联网 发布:安卓数据查询源码 编辑:程序博客网 时间:2024/05/17 03:51

xinput系统简介

SylixOS提供了一个xinput子系统,对键盘、鼠标、触摸屏等设备进行了一个统一管理,SylixOS的xinput系统支持热插拔,可随意添加删除输入设备,使用上很方便、很灵活,下面我们从一个框架图开始来开始学习SylixOS xinput子系统。

xinput分析

xinput系统框架图

SylixOS xinput

从图中看xinput系统分为3层:xinput设备层驱动层,xinput核心处理层,物理设备层,下面我们结合源码来分析个层的含义

xinput设备驱动层

xinput设备将所有输入设备抽象成了键盘和鼠标设备(xmse、xkbd),并且实现了标准的NEW_1型驱动,如下代码片段所示,这样对于上层如Qt应用就可以像操作普通文件那样对键盘、鼠标、触摸屏等设备进行正常的读操作了。

...    fileop.owner     = THIS_MODULE;    fileop.fo_create = xinput_open;    fileop.fo_open   = xinput_open;    fileop.fo_close  = xinput_close;    fileop.fo_read   = xinput_read;    fileop.fo_lstat  = xinput_lstat;    fileop.fo_ioctl  = xinput_ioctl;xinput_drv_num = iosDrvInstallEx2(&fileop, LW_DRV_TYPE_NEW_1);...

xinput核心处理层

xinput的核心处理层负责监控物理设备的热插拔事件,以及从物理设备层取得输入事件,然后通知给xinput设备驱动层,以唤醒上层的应用。这些处理过程都在一个线程中完成,下面代码片段是这个线程的部分工作。

xinput_hotplug_fd = open("/dev/hotplug", O_RDONLY);    for (;;) {        if (need_check) { /* need check if a device has been plug on */            xdev_try_open();        }    ...        ret = select(width, &fdset, LW_NULL, LW_NULL, &timeval);        ...                temp = read(xinput_hotplug_fd, hpmsg, LW_HOTPLUG_DEV_MAX_MSGSIZE);        ...                        temp = read(input->fd, (PVOID)&knotify, sizeof(knotify));                            API_MsgQueueSend(kdb_xinput.queue, (void *)&knotify, (u_long)temp);                            SEL_WAKE_UP_ALL(&kdb_xinput.sel_list, SELREAD);        ...                        temp = read(input->fd, (PVOID)mnotify,                                sizeof(mouse_event_notify) * MAX_INPUT_POINTS);                            API_MsgQueueSend(mse_xinput.queue, (void *)mnotify, (u_long)temp);                            SEL_WAKE_UP_ALL(&mse_xinput.sel_list, SELREAD);        ...    }    ...

上面的代码片段只是保留了能够说明工作内容的部分,可能看起来很怪,但从这些片段中足以让我们了解了xinput层3个工作内容:

  • 读取“/dev/hotplug”监视设备的插拔;
  • 读取knotify(键盘类事件),唤醒xinput读;
  • 读取mnotify(鼠标类事件),唤醒xinput读.

代码的详细实现可参看SylixOS源码。

物理设备层

这一层包括了各种输入设备,如USB鼠标、USB键盘、触摸屏、PCI输入设备等,这些设备驱动需要驱动程序员自己编写,需要注意的是,这些设备驱动应该传递下面的键盘或者鼠标事件给xinput子系统。

下面是键盘事件结构:

typedef struct keyboard_event_notify {    int32_t             nmsg;                               /*  message num, usually one msg*/    int32_t             type;                               /*  press or release            */    int32_t             ledstate;                           /*  LED stat                    */    int32_t             fkstat;                             /*  func-key stat               */    int32_t             keymsg[KE_MAX_KEY_ST];              /*  key code                    */} keyboard_event_notify;

下面是鼠标事件结构:

typedef struct mouse_event_notify {    int32_t             ctype;                               /*  coordinate type             */    int32_t             kstat;                               /*  mouse button stat           */    int32_t             wscroll[MOUSE_MAX_WHEEL];            /*  wheel scroll                */    int32_t             xmovement;                           /*  the relative displacement   */    int32_t             ymovement;    /*     *  if use absolutely coordinate (such as touch screen)     *  if you use touch screen:     *  (kstat & MOUSE_LEFT) != 0 (press)     *  (kstat & MOUSE_LEFT) == 0 (release)     */#define xanalog         xmovement                          /*  analog samples values       */#define yanalog         ymovement} mouse_event_notify;
0 0