网上找了很多方法,都比较杂乱。这篇文章专注于读取鼠标的动作:左键、右键、中键、滚轮。
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 Mouse
fd = 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 Mouse
fd = 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