关于linux捕捉鼠标事件的方法

发布于:2024-07-04 ⋅ 阅读:(19) ⋅ 点赞:(0)

网上找了很多方法,都比较杂乱。这篇文章专注于读取鼠标的动作:左键、右键、中键、滚轮。

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