Linux系统编程应用 Linux Input子系统

著论准过秦,作赋拟子虚。这篇文章主要讲述Linux系统编程应用 Linux Input子系统相关的知识,希望能为你提供帮助。


?1. 什么是输入子系统 ??
输入子系统是 Linux内核用于管理各种输入设备 (键盘,鼠标,遥控杆,书写板等等 )的部分,用户通过输入子系统进行内核,命令行,图形接口之间的交换。输入子系统在内核里实现,因为设备经常要通过特定的硬件接口被访问 (例如串口, ps/2, usb等等 ),这些硬件接口由内核保护和管理。内核给用户导出一套固定的硬件无关的 input API,供用户空间程序使用。


?2. 理解内核内部实现?
输入子系统分为三块: input core, drivers和 event handlers。他们之间的关系如图 1所示。正常的路径是从底层硬件到驱动,从驱动到 input core,从 input core到 event handler,从 event handler到 user space。此外,还存在一个返回路径 (return path)。返回路径允许给一个键盘设置 LED,给一个 force feedback joystick提供 motion commands。路径的两个方向(指从内核到用户的方向和从用户到内核的方向)使用相同的event定义和不同的 type identifier。


?3. 相关结构体?
[root@uplooking ~]# vim /usr/include/linux/input.h

/*
* The event structure itself
*/
struct input_event
struct timeval time; 输入事件时间;
__u16 type; 类型;
__u16 code; 按键值:
__s32 value; 按键状态:
;







type类型可以设置为如下:
/*
* Event types
*/

#define EV_SYN0x00//表示设备所支持所有的事件
#define EV_KEY0x01//按键
#define EV_REL0x02//鼠标事件 相对坐标
#define EV_ABS0x03//手写板事件 绝对坐标
#define EV_MSC0x04//其他类型
#define EV_SW0x05
#define EV_LED0x11//LED灯设备
#define EV_SND0x12//蜂鸣器 输入声音
#define EV_REP0x14//允许重复按键类型
#define EV_FF0x15
#define EV_PWR0x16//电源管理事件
#define EV_FF_STATUS0x17
#define EV_MAX0x1f







code:事件代码




事件的代码。如果事件的类型代码是EV_KEY,该代码code为设备键盘代码,代码值0~127为键盘上的按键代码, 0x110~0x116 为鼠标上按键代码,其中0x110(BTN_ LEFT)为鼠标左键,0x111(BTN_RIGHT)为鼠标右键,0x112(BTN_ MIDDLE)为鼠标中键。其它代码含义请参看include/linux /input.h文件。如果事件的类型代码是EV_REL,code值表示轨迹的类型。如指示鼠标的X轴方向 REL_X (代码为0x00),指示鼠标的Y轴方向REL_Y(代码为0x01),指示鼠标中轮子方向REL_WHEEL(代码为0x08)。
*
* Keys and buttons
*/

#define KEY_RESERVED0
#define KEY_ESC1
#define KEY_12
#define KEY_23
#define KEY_34
#define KEY_45
#define KEY_56
#define KEY_67
#define KEY_78
#define KEY_89
#define KEY_910
#define KEY_011
#define KEY_MINUS12
#define KEY_EQUAL13
#define KEY_BACKSPACE14
#define KEY_TAB15
#define KEY_Q16
#define KEY_W17
#define KEY_E18
#define KEY_R19
#define KEY_T20
#define KEY_Y21
#define KEY_U22
#define KEY_I23
#define KEY_O24
#define KEY_P25
#define KEY_LEFTBRACE26
#define KEY_RIGHTBRACE27
#define KEY_ENTER28
#define KEY_LEFTCTRL29
#define KEY_A30
#define KEY_S31
#define KEY_D32
#define KEY_F33
#define KEY_G34
#define KEY_H35
#define KEY_J36
#define KEY_K37
#define KEY_L38
#define KEY_SEMICOLON39
#define KEY_APOSTROPHE40
#define KEY_GRAVE41
#define KEY_LEFTSHIFT42
#define KEY_BACKSLASH43
#define KEY_Z44
#define KEY_X45
#define KEY_C46
#define KEY_V47
#define KEY_B48
#define KEY_N49
#define KEY_M50
#define KEY_COMMA51
#define KEY_DOT52
#define KEY_SLASH53
#define KEY_RIGHTSHIFT54
#define KEY_KPASTERISK55
#define KEY_LEFTALT56
#define KEY_SPACE57
#define KEY_CAPSLOCK58
#define KEY_F159
#define KEY_F260
#define KEY_F361
#define KEY_F462
#define KEY_F563
#define KEY_F664
#define KEY_F765
#define KEY_F866
#define KEY_F967
#define KEY_F1068
#define KEY_NUMLOCK69
#define KEY_SCROLLLOCK70
#define KEY_KP771
#define KEY_KP872
#define KEY_KP973
#define KEY_KPMINUS74
#define KEY_KP475
#define KEY_KP576
#define KEY_KP677
#define KEY_KPPLUS78
#define KEY_KP179
#define KEY_KP280
#define KEY_KP381
#define KEY_KP082
#define KEY_KPDOT83

#define KEY_ZENKAKUHANKAKU85
#define KEY_102ND86
#define KEY_F1187
#define KEY_F1288
#define KEY_RO89
#define KEY_KATAKANA90
#define KEY_HIRAGANA91
#define KEY_HENKAN92
#define KEY_KATAKANAHIRAGANA93
#define KEY_MUHENKAN94
#define KEY_KPJPCOMMA95
#define KEY_KPENTER96
#define KEY_RIGHTCTRL97
#define KEY_KPSLASH98
#define KEY_SYSRQ99
#define KEY_RIGHTALT100
#define KEY_LINEFEED101
#define KEY_HOME102
#define KEY_UP103
#define KEY_PAGEUP104
#define KEY_LEFT105
#define KEY_RIGHT106
#define KEY_END107
#define KEY_DOWN108
#define KEY_PAGEDOWN109
#define KEY_INSERT110
#define KEY_DELETE111
#define KEY_MACRO112
#define KEY_MUTE113
#define KEY_VOLUMEDOWN114
#define KEY_VOLUMEUP115
#define KEY_POWER116
#define KEY_KPEQUAL117
#define KEY_KPPLUSMINUS118
#define KEY_PAUSE119

#define KEY_KPCOMMA121
#define KEY_HANGEUL122
#define KEY_HANGUELKEY_HANGEUL
#define KEY_HANJA123
#define KEY_YEN124
#define KEY_LEFTMETA125
#define KEY_RIGHTMETA126
#define KEY_COMPOSE127



鼠标相关的值


#define BTN_MOUSE0x110
#define BTN_LEFT0x110
#define BTN_RIGHT0x111
#define BTN_MIDDLE0x112
#define BTN_SIDE0x113
#define BTN_EXTRA0x114
#define BTN_FORWARD0x115
#define BTN_BACK0x116
#define BTN_TASK0x117



相对坐标
Type为EV_REL时,code表示操作的是哪个坐标轴,如:REL_X,REL_Y。(因为鼠标有x,y两个轴向,所以一次鼠标移动,会产生两个input_event)


*
* Relative axes
*/

#define REL_X0x00
#define REL_Y0x01
#define REL_Z0x02
#define REL_RX0x03
#define REL_RY0x04
#define REL_RZ0x05
#define REL_HWHEEL0x06
#define REL_DIAL0x07
#define REL_WHEEL0x08
#define REL_MISC0x09
#define REL_MAX0x0f

?value:根据Type的不同而含义不同。?
例如: Type为EV_KEY时,value: 0表示按键抬起。1表示按键按下。(4表示持续按下等?)。 Type为EV_REL时,value: 表明移动的值和方向(正负值)。 Type为EV_ABS时,code表示绝对位置。


?4. 键盘设备示例代码?
Linux系统编程应用 Linux Input子系统

文章图片



执行结果如下:
Linux系统编程应用 Linux Input子系统

文章图片



?5. 鼠标设备示例代码?
Linux系统编程应用 Linux Input子系统

文章图片



执行结果如下:
Linux系统编程应用 Linux Input子系统

文章图片



?6. 模拟鼠标和按键的示例代码?
#include < stdio.h>
#include < linux/input.h>
#include < fcntl.h>
#include < sys/time.h>
#include < unistd.h>

//按键模拟,按键包含按下和松开两个环节

void simulate_key(int fd, int kval)


struct input_event event;
gettimeofday(& event.time, 0);

//按下kval键
event.type = EV_KEY;
event.value = https://www.songbingjia.com/android/1;
event.code = kval;
write(fd, & event, sizeof(event));
//同步,也就是把它报告给系统
event.type = EV_SYN;
event.value = https://www.songbingjia.com/android/0;
event.code = SYN_REPORT;
write(fd, & event, sizeof(event));

memset(& event, 0, sizeof(event));
gettimeofday(& event.time, 0);
//松开kval键
event.type = EV_KEY;
event.value = https://www.songbingjia.com/android/0;
event.code = kval;
write(fd, & event, sizeof(event));

//同步,也就是把它报告给系统
event.type = EV_SYN;
event.value = https://www.songbingjia.com/android/0;
event.code = SYN_REPORT;
write(fd, & event, sizeof(event));


//鼠标移动模拟
void simulate_mouse(int fd, int rel_x, int rel_y)

struct input_event event;
gettimeofday(& event.time, 0);
//x轴坐标的相对位移
event.type = EV_REL;
event.value = https://www.songbingjia.com/android/rel_x;
event.code = REL_X;
write(fd, & event, sizeof(event));

//y轴坐标的相对位移

event.type = EV_REL;
event.value = https://www.songbingjia.com/android/rel_y;
event.code = REL_Y;
write(fd, & event, sizeof(event));
//同步
event.type = EV_SYN;
event.value = https://www.songbingjia.com/android/0;
event.code = SYN_REPORT;
write(fd, & event, sizeof(event));



int main(int argc, char **argv)

int fd_mouse = -1;
int fd_kbd = -1;
int i = 0;

fd_kbd = open("/dev/input/event3", O_RDWR);
if(fd_kbd < = 0)

printf("Can not open keyboard input file\\n");
return -1;


fd_mouse = open("/dev/input/event2", O_RDWR);
if(fd_mouse < = 0)

printf("Can not open mouse input file\\n");
return -1;


for (i = 0; i < 50; i++)

simulate_key(fd_mouse, BTN_LEFT); //模拟按下鼠标左键
//if (i % 3 == 0)
//simulate_key(fd_kbd, KEY_A); //模拟按下键盘A键
//模拟鼠标相对上次x和y轴相应移动10个像素
//simulate_mouse(fd_mouse, 10, 10);
sleep(3);

close(fd_kbd);
close(fd_mouse);





【Linux系统编程应用 Linux Input子系统】


    推荐阅读