Linux 的 Input Device 是重要的一個 subsystem,在進行實例介紹前,先大略了解一下相關的 API。

Linux Input Device

input.c是Linux的”input”驅動程式,主要支援鍵盤與滑鼠的輸入;input.c介面有趣的地方是採用了事件(event)的方式來處理輸入,以下是input.c介面重要的資料結構與函數:

* struct input_dev
* void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
* void input_register_device(struct input_dev *);
* void input_unregister_device(struct input_dev *);
* void input_register_handler(struct input_handler *);
* void input_unregister_handler(struct input_handler *);

Linux 的input機制可用來實作「虛擬鍵盤」或「虛擬滑鼠」,只要呼叫input_event()將輸入資料發佈給input handler即可。

struct input_dev是用來描述輸入事件的重要資料結構,其原型宣告如下:

struct input_dev {

void *private;

int number;
char *name;
unsigned short idbus;
unsigned short idvendor;
unsigned short idproduct;
unsigned short idversion;

unsigned long evbit[NBITS(EV_MAX)];
unsigned long keybit[NBITS(KEY_MAX)];
unsigned long relbit[NBITS(REL_MAX)];
unsigned long absbit[NBITS(ABS_MAX)];
unsigned long mscbit[NBITS(MSC_MAX)];
unsigned long ledbit[NBITS(LED_MAX)];
unsigned long sndbit[NBITS(SND_MAX)];
unsigned long ffbit[NBITS(FF_MAX)];
int ff_effects_max;

unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;

unsigned int repeat_key;
struct timer_list timer;

int abs[ABS_MAX + 1];
int rep[REP_MAX + 1];

unsigned long key[NBITS(KEY_MAX)];
unsigned long led[NBITS(LED_MAX)];
unsigned long snd[NBITS(SND_MAX)];

int absmax[ABS_MAX + 1];
int absmin[ABS_MAX + 1];
int absfuzz[ABS_MAX + 1];
int absflat[ABS_MAX + 1];

int (*open)(struct input_dev *dev);
void (*close)(struct input_dev *dev);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
int (*erase_effect)(struct input_dev *dev, int effect_id);

struct input_handle *handle;
struct input_dev *next;
};

定義按鍵

我們可以設定struct input_dev裡的evbit欄位,來定義所要接受的輸入類型,目前共有8種輸入類型如下:

* EV_KEY:Keys and buttons(按鍵與按鈕)。
* EV_REL:Relative axes(相對座標)。
* EV_ABS:Absolute axes(絕對座標)。
* EV_MSC:Misc events(其它事件)。
* EV_LED:LEDs。
* EV_SND:Sounds(聲音輸入)。
* EV_REP:Autorepeat values(自動重覆數值)。
* EV_FF:Force feedback事件。

以下是一個範例,我們指定dev可接受EV_KEY事件:

dev.evbit[0] = BIT(EV_KEY);

evbit是一個陣列,每個元素可以索引一種輸入類型。每種輸入類型均可指定特定的輸入資料,例如:TAB鍵。指定方式是使用set_bit()或BIT巨集來設定每種輸入類型的陣列。以下是各輸入類型的欄位名稱:

* keybit[NBITS(KEY_MAX)]:Keys and buttons(按鍵與按鈕)。
* relbit[NBITS(REL_MAX)]:Relative axes(相對座標)。
* absbit[NBITS(ABS_MAX)]:Absolute axes(絕對座標)。
* mscbit[NBITS(MSC_MAX)]:Misc events(其它事件)。
* ledbit[NBITS(LED_MAX)]:LEDs。
* sndbit[NBITS(SND_MAX)]:Sounds(聲音輸入)。
* ffbit[NBITS(FF_MAX)]:Force feedback事件。

以下是使用set_bit()的範例:

* set_bit(KEY_UP, dev.keybit);
* set_bit(KEY_LEFT, dev.keybit);

或是使用BIT巨集也可以:

* keybit[0] = BIT(KEYUP) | BIT(KEY_LEFT);

input.h裡做位元運算的3個巨集如下:

* NBITS(x):計算要幾個陣列元素,才夠紀錄第x個位元。
* BIT(x):傳回單獨第x個位元為1時所代表的數值,例如:x=0時為0x1,x=1時為0x2,x=2時為0x4。
* LONG(x):第x個位元是屬於第幾個陣列元素(即索引值)。

我們先設定驅動程式能接受EV_KEY事件,然後指定EV_KEY事件的特定輸入值為KEY_UP與KEY_LEFT按鍵。不同事件的輸入資料定義,請參考input.h檔,例如以下是EV_KEY事件的按鍵1~按鍵9定義:

/*
* Keys and buttons
*/

#define KEY_1 2
#define KEY_2 3
#define KEY_3 4
#define KEY_4 5
#define KEY_5 6
#define KEY_6 7
#define KEY_7 8
#define KEY_8 9
#define KEY_9 10

設定好struct input_dev後再呼叫input_register_device()註冊至上層。當”input device”註冊至kernel後,當該input device被開啟時,便呼叫input device的open method;當input device關閉時,便呼叫input device的close method。
實作input device的open method時,若成功應傳回0,失敗的話則傳回任意的非零值;close method則不須傳回值。

Report 按鍵

使用者的按鍵往上層回報所使用的API如下:

* input_report_key(struct input_dev *dev, unsigned int code, int value);
* input_report_rel(struct input_dev *dev, unsigned int code, int value);
* input_report_abs(struct input_dev *dev, unsigned int code, int value);
* input_report_key與input_report_rel其實都是使用input_event()的巨集,input_event()的函數原型與參數說明如下:
* void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);

* @dev:指向input device的指標。
* @type:輸入類型(EV_KEY、EV_ABS等)。
* @code:輸入按鍵(例如EV_KEY的KEY_1)。
* @value:按鍵值。

Input Handler

任何的按鍵輸入,都應呼叫input_event()來將input event送到input.c,再由input.c分派事件(遶送)到每一個”input handler”。有註冊input handler的驅動程式,都能讀取輸入資料。

--jollen

Linux Input Device相关推荐

  1. Linux执行docker命令后报the input device is not a TTY错误

    1.错误场景 root@localhost:~$ gunzip < test.sql.gz | docker exec -it mysql mysql -uroot -p test the in ...

  2. Linux input子系统 io控制字段【转】

    转自:http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html http://blog.csdn.net/guoshaobei/arc ...

  3. Docker exec 命令执行出错, 显示 the input device is not aTTY 的解决办法

    问题描述 在使用 docker exec 命令进入容器时,发现报错信息如下: the input device is not a TTY. If you are using mintty, try p ...

  4. linux input输入子系统分析《三》:S3C2440的触摸屏驱动实例

    1.1    本节阅读前提 本节的说明建立在前两节的基础之上,需要先阅读如下两篇章: linux input输入子系统分析<一>:初识input输入子系统 linux input输入子系统 ...

  5. linux input子系统分析--子系统核心.事件处理层.事件传递过程

    linux input子系统分析--子系统核心.事件处理层.事件传递过程 一.  输入子系统核心分析. 1.输入子系统核心对应与/drivers/input/input.c文件,这个也是作为一个模块注 ...

  6. linux input子系统分析--主要函数

    linux input子系统分析--主要函数 一. 各种注册函数 因为分析一所讲的每种数据结构都代表一类对象,所以每种数据结构都会对应一个注册函数,他们都定义在子系统核心的input.c文件中.主要有 ...

  7. linux input输入子系统分析《一》:初识input输入子系统

    主要讲述本人在学习Linux内核input子系统的全部过程,如有分析不当,多谢指正.以下交流方式,文章欢迎转载,保留联系信息,以便交流. 邮箱:eabi010@gmail.com 主页:www.iel ...

  8. Android 驱动(12)---Linux DTS(Device Tree Source)设备树详解

    Linux DTS(Device Tree Source)设备树详解 Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) Linux DTS(Device Tr ...

  9. 【Linux】Linux input子系统之Input event codes

    文章目录 前言 正文 附件 参考文章 前言 在阅读和修改Linux kernel中Touch相关驱动代码时经常可以见到形如INPUT_PROP_DIRECT EV_SYN BTN_TOUCH之类的In ...

最新文章

  1. [译] 最佳安全实践:在 Java 和 Android 中使用 AES 进行对称加密
  2. SpringBoot笔记:SpringBoot集成SpringbootAdmin监控
  3. PHP结合Ueditor并修改图片上传路径
  4. 后端接收到信息并返回了但是前端无响应_Bug的噩梦:前端调试必备的7个“大杀器”...
  5. Qt Creator操作方法
  6. 我的MYSQL学习心得(二)
  7. jupyter notebook python插件_Jupyter notebook一款非常好用的python IDE
  8. javascript简单介绍
  9. js浏览器对象模型(BOM)
  10. java装饰模式_Java装饰者模式实例详解
  11. SQL Server时间粒度系列----第9节时间粒度示例演示
  12. 登陆获取cookie
  13. ubuntu服务器设置_Ubuntu服务器设置–安全最佳实践
  14. MySQL 第六次练习(索引)
  15. Session Cookie 之我见
  16. openstack trove实例状态转换条件--Mitaka版本
  17. linux 中select()函数的使用
  18. 泰坦尼克号数据集下载
  19. matlab入门基础函数
  20. AmazeUI 离线文档

热门文章

  1. 隧道不能访问web vxaln_SpringBoot实现本地存储文件上传及提供HTTP访问服务
  2. 华兴数控g71外圆循环编程_数控车床加工编程典型实例分析(西门子802S数控系统)...
  3. php打印矩阵,PHP实现顺时针打印矩阵(螺旋矩阵)的方法示例
  4. jQuery中的ajax、jquery中ajax全局事件、load实现页面无刷新局部加载、ajax跨域请求jsonp、利用formData对象向服务端异步发送二进制数据,表单序列化(异步获取表单内容)
  5. 指标体系|四个模型教会你指标体系构建的方法
  6. 互联网日报 | 阿里国内消费者已接近10亿;联想布局半导体赛道;我国5G用户超过6千万户...
  7. 设计链表(Leetcode第707题)
  8. drools动态配置规则_基于 Flink 和 Drools 的实时日志处理
  9. mysql 事务回滚_SQL基础丨事务处理
  10. 《大数据》2022年第1期目次摘要