[Linux] C获取键盘,鼠标数据

文章介绍了如何在Linux系统中通过C语言获取键盘和鼠标输入事件,包括使用`cat/dev/input/eventX`命令查看16进制输出,以及通过设备文件读取`input_event`结构体来解析按键、坐标等信息。还提到了使用SDL2库在GUI项目中处理事件的方法。
摘要由CSDN通过智能技术生成

键盘检测指令:cat /dev/input/event1 | hexdump

鼠标检测指令:cat /dev/input/event2 | hexdump

当键盘/鼠标有输入时,会有对应的一堆16进制输出。它其实对应着input_event结构体【24字节】。

struct input_event 
{
      struct timeval time;
      __u16 type;
      __u16 code;
      __s32 value;
};
//==================获取键盘数据====================
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <string.h>
 
int main(void)
{
    #define KEY_PATH	"/dev/input/event1"
	int fd = -1, ret = -1;
	struct input_event ev;
	// 第1步:打开设备文件
	fd = open(KEY_PATH, O_RDONLY);
	if (fd < 0)
	{
		perror("open,error");
		return -1;
	}
    printf("welcome size=%d.\n",sizeof(struct input_event));
	
	while (1)
	{
		// 第2步:读取event事件包
		memset(&ev, 0, sizeof(struct input_event));
		ret = read(fd, &ev, sizeof(struct input_event));
		if (ret != sizeof(struct input_event))
		{
			perror("read,error");
			close(fd);
			return -1;
		}
		
		// 第3步:解析event包.
        printf("========================================================\n");
		printf("[%11u] type: %3d, code: %3d, value: %3d \n",ev.time.tv_sec,ev.type,ev.code,ev.value);
        //type: 1:按键同步
        //code: 键码['a'=30]
        //value:0:按键释放,1:按键按下,2:长按下
	}
 
	// 第4步:关闭设备
	close(fd);	
	return 0;
}

//=======获取鼠标数据=========
#include <X11/Xlib.h>
//LDFLAGS := -lX11
int GetDisplayInfo(int *screen_width,int *screen_height)
{
    Display *display = XOpenDisplay(NULL);
    if (display == NULL)
    {
        printf("Error: cannot open display\n");
        return 1;
    }
    int screen_num = DefaultScreen(display);
    Screen *screen = ScreenOfDisplay(display, screen_num);
    *screen_width = WidthOfScreen(screen);
    *screen_height = HeightOfScreen(screen);
    printf("Screen size: %dx%d pixels\n", WidthOfScreen(screen), HeightOfScreen(screen));
    printf("Screen resolution: %dx%d dpi\n", (int) (WidthOfScreen(screen) * 25.4 / DisplayWidthMM(display, screen_num)), 
                                             (int) (HeightOfScreen(screen) * 25.4 / DisplayHeightMM(display, screen_num)));
    XCloseDisplay(display);
    
    return 0;
}

int get_xy(int fd,struct input_event ts,int *x,int *y)
{
    static int nCnt = 0;
	read(fd,&ts,sizeof(ts));
	if(ts.type == EV_ABS && ts.code == ABS_X)
	{
		*x = ts.value;
        nCnt = (nCnt+1)%3;
		return nCnt;
	}
	if(ts.type == EV_ABS && ts.code == ABS_Y)
	{
		*y = ts.value;
        nCnt = (nCnt+1)%3;
		return nCnt;
	}
	
	return 0;
}


int main(void)
{
   #define MOUSE_PATH	"/dev/input/event2"
	int fd = -1, ret = -1;
	struct input_event ev;
    int data_size = sizeof(struct input_event);

	// 第1步:打开设备文件[需要权限运行]
	fd = open(MOUSE_PATH, O_RDONLY);
	if (fd < 0)
	{
		perror("open,error");
		return -1;
	}
    printf("mouse test [%s],data size=%d.\n",MOUSE_PATH,sizeof(struct input_event));
	
    int screen_width = 0;
    int screen_height = 0;
    if( GetDisplayInfo(&screen_width,&screen_height)>0)
    {
        perror("get display info,error");
        return -2;
    }

	while (1)
	{

       static int raw_x=0;
       static int raw_y=0;
        int tmp =0;

		tmp = get_xy(fd,ev,&raw_x,&raw_y);
        if(tmp==2)
        {
            int curr_x = 0;
            int curr_y = 0;
            curr_x = raw_x*screen_width/0xFFFF;
            curr_y = raw_y*screen_height/0xFFFF;
            printf("mousePos: x=%d,y=%d.\n",curr_x,curr_y);
        }
	}
	close(fd);	
	return 0;
}

方法2:采用SDL2 [simplle directmedia layer]  , 此方法用于GUI项目,事件只针对SDL创建的窗口内有效

#include <stdio.h>
#include <SDL2/SDL.h>

#define SDL_HOR_RES (800)
#define SDL_VER_RES (600)

typedef struct TagMonitor
{
    int screen_w;
    int screen_h;
    SDL_Renderer *render;
    SDL_Texture *texture;
} tagMonitor;

// 将屏幕设置成指定ARGB颜色
int update_win(tagMonitor *mt, uint32_t argb)
{
    uint32_t fb_data[SDL_HOR_RES * SDL_VER_RES]; // frame buffer data[w*h]
    for (size_t i = 0; i < SDL_HOR_RES * SDL_VER_RES; i++)
    {
        fb_data[i] = argb;
    }

    SDL_UpdateTexture(mt->texture, NULL, fb_data, mt->screen_w * 4);
    SDL_RenderClear(mt->render);
    // 设定渲染的目标区域
    SDL_Rect destRect;
    destRect.x = 0;
    destRect.y = 0;
    destRect.w = mt->screen_w;
    destRect.h = mt->screen_h;

    // 复制材质到渲染器对象
    if (SDL_RenderCopy(mt->render, mt->texture, NULL, &destRect))
    {
        printf("Error,%s \n", SDL_GetError());
        return -1;
    }
    // 执行渲染操作
    SDL_RenderPresent(mt->render);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值