网上找了很多方法,都比较杂乱。这篇文章专注于读取鼠标的动作:左键、右键、中键、滚轮。
linux的设备都以文件形式存放,要读取鼠标,有两种方法,一种是通过/dev/input/mice,一种是通过/dev/input/eventx (x是标号,0,1,2..... 具体的进这个文件夹查看)。两种方式各有优劣,后面讲。
我们先从简单的开始 读取/dev/input/mice获取鼠标事件。
一般的Linux系统无论鼠标是否连接,mice文件都会存在。读取操作非常简单
读取流程:
1.使用open()函数打开该文件
2.read函数读取该文件
3.在while循环中轮询并打印事件
下面看看代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(int argc, char** argv)
{int fd, bytes;char data[3];const char *pDevice = "/dev/input/mice";// Open Mousefd = open(pDevice, O_RDWR);if(fd == -1){printf("ERROR Opening %s\n", pDevice);return -1;}int left, middle, right;signed char x, y;while(1){// Read Mouse bytes = read(fd, data, sizeof(data));if(bytes > 0){left = data[0] & 0x1; right = data[0] & 0x2;middle = data[0] & 0x4;x = data[1];y = data[2];printf("x=%d, y=%d, left=%d, middle=%d, right=%d\n", x, y, left, middle, right);} }return 0;
}
从mice文件中读取三个字节数据,data[0]内含按键信息,最低位为1时代表左键按下即xxxx xxx1时左键按下。以此类推,最后三位分别代表左键、右键、中键。 data[1]、data[2]代表x与y的相对坐标,即本次鼠标移动与上次鼠标移动了多少坐标,向左则x为负,向下则y为负。
到这里通过mice文件获取鼠标事件就已经结束了,肯定有人会问,滚轮呢?
读取mice文件很简单,但它的缺点就是不包含滚轮信息。
使用event文件获取鼠标事件。
首先使用
sudo cat /dev/input/eventx
然后移动鼠标,如果出现输出则可以确定鼠标对应的event文件
我的设备对应event6
在linux/input.h文件内定义了输入事件结构体,根据该结构体来获取信息
输入事件的结构体:
struct input_event {struct timeval time; //按键时间__u16 type; //事件的类型__u16 code; //要模拟成什么按键__s32 value; //是按下1还是释放0};
type:事件的类型
EV_KEY, 按键事件)鼠标的左键右键等;
EV_REL, 相对坐标
EV_ABS, 绝对坐标
code 事件代码
主要是一些宏定义,具体可查看input.h内文件,如何使用请参考下面的代码
value:事件的值
如果事件的类型代码是EV_KEY,当按键按下时值为1,松开时值为0;如果事件的类型代码是EV_ REL,value的正数值和负数值分别代表两个不同方向的值。例如:如果code是REL_X,value是10的话,就表示鼠标相对于上一次的坐标,往x轴向右移动10个像素点。
代码如下:
#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <linux/input.h>int main(int argc, char** argv){int fd, bytes;struct input_event event;char data[3];const char *pDevice = "/dev/input/event6";// Open Mousefd = open(pDevice, O_RDWR);if(fd == -1){printf("ERROR Opening %s\n", pDevice);return -1;}while(1){// Read Mouse bytes = read(fd, &event, sizeof(struct input_event));if(event.type == EV_KEY){switch(event.code){case BTN_LEFT: printf("left:%d\n", event.value);break;case BTN_RIGHT: printf("right:%d\n",event.value);break;case BTN_MIDDLE: printf("middle:%d\n",event.value);break;}}if(event.type == EV_ABS){switch(event.code){case ABS_X: printf("x:%d\n",event.value);break; case ABS_Y: printf("y:%d\n",event.value);break; }}if(event.type == EV_REL){switch(event.code){ case REL_WHEEL: printf("wheel:%d\n", event.value);break; //滚轮}}}return 0; }
这里我的鼠标不支持读取相对坐标,因此鼠标只读取绝对坐标,注意滚轮事件属于相对事件。
参考:linux - How do you read the mouse button state from /dev/input/mice? - Stack Overflow