键盘检测指令: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 <pthread.h>
#include <SDL2/SDL.h>
int main(void *arg)
{
// 窗口大小
int screen_w = 800;
int screen_h = 400;
// 初始化SDL
if (SDL_Init(SDL_INIT_EVERYTHING))
{
printf("could not initialize SDL: %s\n", SDL_GetError());
return -1;
}
SDL_Window *screen = SDL_CreateWindow("SimpleSDL2", 0, 0, screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!screen)
{
printf("could not create window: %s\n", SDL_GetError());
return -1;
}
SDL_Event myEvent; // SDL事件
int quit = 0;
while (!quit) // 建立事件主循环
{
// 注意:事件只针对SDL创建的窗口内有效
while (SDL_PollEvent(&myEvent)) // 从队列里取出事件
{
// printf("event=%d \n", myEvent.type);
switch (myEvent.type) // 根据事件类型分门别类去处理
{
case SDL_QUIT: // 离开事件[点击窗口关闭]
quit = 1; // quit event poll
break;
case SDL_MOUSEMOTION: // 鼠标移动
printf("mouseXY: %d,%d \n", myEvent.motion.x, myEvent.motion.y);
break;
case SDL_MOUSEBUTTONDOWN: // 鼠标点击
printf("ButtonClck:%d\n", myEvent.button.button); //0:左键,1:中键,2:右键
break;
case SDL_KEYDOWN://键盘按下
// 键值表在SDL2/SDL_keycode.h文件中定义
printf("KEY_DOWN:%d\n", myEvent.key.keysym.sym);
break;
case SDL_KEYUP://键盘释放
// 键值表在SDL2/SDL_keycode.h文件中定义
printf("KEY_UP:%d\n", myEvent.key.keysym.sym);
break;
}
}
}
printf("quit screen_monitor_thread.! \n");
exit(0);
return 0;
}