Last active
August 16, 2024 08:10
-
-
Save zhustec/792f5ed5e24a7d5e9ca11ffa87fea732 to your computer and use it in GitHub Desktop.
Linux input event, including Mouse, Keyboard, Touchpad.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <fcntl.h> | |
| #include <errno.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <sys/select.h> | |
| #include <linux/input.h> | |
| #define KEYBOARD_DEVPATH "/dev/input/event3" | |
| #define MOUSE_DEVPATH "/dev/input/event5" | |
| #define TOUCHPAD_DEVPATH "/dev/input/event11" | |
| extern int errno; | |
| fd_set fds; | |
| int keyboard_fd, mouse_fd, touchpad_fd; | |
| int open_devpath(int *pfd, char *path) | |
| { | |
| int fd; | |
| fd = open(path, O_RDONLY | O_NONBLOCK); | |
| if (fd <= 0) | |
| { | |
| fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); | |
| return -1; | |
| } | |
| else | |
| { | |
| *pfd = fd; | |
| return 0; | |
| } | |
| } | |
| void reset_fdset() | |
| { | |
| FD_ZERO(&fds); | |
| FD_SET(keyboard_fd, &fds); | |
| FD_SET(mouse_fd, &fds); | |
| FD_SET(touchpad_fd, &fds); | |
| } | |
| void handle_keyboard_event(const struct input_event *piev) | |
| { | |
| printf("Keyboard Event - "); | |
| switch (piev->type) | |
| { | |
| // 键盘按键按压或释放事 | |
| case EV_KEY: | |
| printf("%d %s", piev->code, piev->value ? "Pressed" : "Released"); | |
| break; | |
| // 键盘按键持续按压不释放会一直产生此事件,且 piev->value 为持续按下的按键编号 | |
| case EV_MSC: | |
| printf("stay pressed: %d %d", piev->code, piev->value); | |
| break; | |
| // 同步事件 | |
| case EV_SYN: | |
| printf("---------------------------------------------------------"); | |
| break; | |
| default: | |
| printf("Unkown Event: %d, %d, %d", piev->type, piev->code, piev->value); | |
| } | |
| printf("\n"); | |
| } | |
| void handle_mouse_event(const struct input_event *piev) | |
| { | |
| printf(" Mouse Event - "); | |
| switch (piev->type) | |
| { | |
| // 鼠标左键、右键、中键等按键按压或释放 | |
| case EV_KEY: | |
| switch (piev->code) | |
| { | |
| case BTN_LEFT: | |
| printf("left is %s", piev->value ? "Pressed" : "Released"); | |
| break; | |
| case BTN_RIGHT: | |
| printf("right is %s", piev->value ? "Pressed" : "Released"); | |
| break; | |
| case BTN_MIDDLE: | |
| printf("middle is %s", piev->value ? "Pressed" : "Released"); | |
| break; | |
| // 其他按键未列出 | |
| default: | |
| printf("unkown EV_KEY: %d %d", piev->code, piev->value); | |
| } | |
| break; | |
| // 鼠标移动或滚轮滚动时产生事件 | |
| case EV_REL: | |
| switch (piev->code) | |
| { | |
| // 鼠标左右移动 | |
| case REL_X: | |
| if (piev->value > 0) | |
| printf("right %d", piev->value); | |
| else if (piev->value < 0) | |
| printf("left %d", -piev->value); | |
| break; | |
| // 鼠标上下移动 | |
| case REL_Y: | |
| if (piev->value > 0) | |
| printf("down %d", piev->value); | |
| else if (piev->value < 0) | |
| printf("up %d", -piev->value); | |
| break; | |
| // 鼠标滚轮上下滚动 | |
| case REL_WHEEL: | |
| if (piev->value == 1) | |
| printf("scroll up\n"); | |
| else if (piev->value == -1) | |
| printf("scroll down\n"); | |
| else | |
| printf("scoll unkown\n"); | |
| break; | |
| default: | |
| printf("unkown EV_REL: %d %d", piev->code, piev->value); | |
| } | |
| break; | |
| // 鼠标按键按下或释放同时产生此事件,value 值 - 左:589825,右:589826,中:589827,不知是不是 Magic Number | |
| case EV_MSC: | |
| printf("stay pressed: %d %d", piev->code, piev->value); | |
| break; | |
| // 同步事件 | |
| case EV_SYN: | |
| printf("---------------------------------------------------------"); | |
| break; | |
| default: | |
| printf("Unkown Event: %d, %d, %d", piev->type, piev->code, piev->value); | |
| } | |
| printf("\n"); | |
| } | |
| void handle_touchpad_event(const struct input_event *piev) | |
| { | |
| printf("Touchpad Event - "); | |
| switch (piev->type) | |
| { | |
| // 触摸板按键及触摸 | |
| case EV_KEY: | |
| switch (piev->code) | |
| { | |
| // 触摸板下面按键触发,可通过用手指甲触发来避免 BTN_TOUCH 事件 | |
| case BTN_LEFT: | |
| printf("left %s", piev->value ? "Pressed" : "Released"); | |
| break; | |
| // 只要有手指触碰,就会产生此事件 | |
| case BTN_TOUCH: | |
| printf("touch %s", piev->value ? "Pressed" : "Release"); | |
| break; | |
| // 1 指 | |
| case BTN_TOOL_FINGER: | |
| printf("1 finger %s", piev->value ? "Pressed" : "Release"); | |
| break; | |
| // 2 指 | |
| case BTN_TOOL_DOUBLETAP: | |
| printf("2 finger %s", piev->value ? "Pressed" : "Release"); | |
| break; | |
| // 3 指 | |
| case BTN_TOOL_TRIPLETAP: | |
| printf("3 finger %s", piev->value ? "Pressed" : "Release"); | |
| break; | |
| // 4 指 | |
| case BTN_TOOL_QUADTAP: | |
| printf("4 finger %s", piev->value ? "Pressed" : "Release"); | |
| break; | |
| // 5 指 | |
| case BTN_TOOL_QUINTTAP: | |
| printf("5 finger %s", piev->value ? "Pressed" : "Release"); | |
| break; | |
| default: | |
| printf("unkown EV_KEY: %d %d", piev->code, piev->value); | |
| } | |
| break; | |
| case EV_ABS: | |
| switch (piev->code) | |
| { | |
| // 多指操作时产生多个事件,每个之后紧跟一对 ABS_MT_POSITION_{X, Y} 事件 | |
| case ABS_MT_SLOT: | |
| printf("ABS_SLOT: %d", piev->value); | |
| break; | |
| // 当前手指 x 向绝对位置 | |
| case ABS_MT_POSITION_X: | |
| printf("position x: %d", piev->value); | |
| break; | |
| // 当前手指 y 向绝对位置 | |
| case ABS_MT_POSITION_Y: | |
| printf("position y: %d", piev->value); | |
| break; | |
| // 当前 x 向绝对位置,指示第一个检测出来的手指 | |
| case ABS_X: | |
| printf("x: %d", piev->value); | |
| break; | |
| // 当前 y 向绝对位置,指示第一个检测出来的手指 | |
| case ABS_Y: | |
| printf("y: %d", piev->value); | |
| break; | |
| // 手指释放时产生此事件,且 value 恒为 -1 | |
| case ABS_MT_TRACKING_ID: | |
| printf("ABS_MT_TRACKING_ID: %d", piev->value); | |
| break; | |
| default: | |
| printf("unkown EV_ABS: %d %d", piev->code, piev->value); | |
| } | |
| break; | |
| case EV_MSC: | |
| switch (piev->code) | |
| { | |
| // 每次都会产生,为一个时间戳,暂未搞清 | |
| case MSC_TIMESTAMP: | |
| printf("timestamp: %d", piev->value); | |
| break; | |
| default: | |
| printf("unkown EV_MSC: %d %d", piev->code, piev->value); | |
| } | |
| break; | |
| // 同步事件 | |
| case EV_SYN: | |
| printf("---------------------------------------------------------"); | |
| break; | |
| default: | |
| printf("Unkown Event: %d, %d, %d", piev->type, piev->code, piev->value); | |
| } | |
| printf("\n"); | |
| } | |
| int main(int argc, char const *argv[]) | |
| { | |
| struct input_event iev; | |
| open_devpath(&keyboard_fd, KEYBOARD_DEVPATH); | |
| open_devpath(&mouse_fd, MOUSE_DEVPATH); | |
| open_devpath(&touchpad_fd, TOUCHPAD_DEVPATH); | |
| reset_fdset(); | |
| while (select(6, &fds, NULL, NULL, NULL) > 0) | |
| { | |
| if (FD_ISSET(keyboard_fd, &fds)) | |
| { | |
| if (read(keyboard_fd, &iev, sizeof(iev)) == sizeof(iev)) | |
| handle_keyboard_event(&iev); | |
| } | |
| else if (FD_ISSET(mouse_fd, &fds)) | |
| { | |
| if (read(mouse_fd, &iev, sizeof(iev)) == sizeof(iev)) | |
| handle_mouse_event(&iev); | |
| } | |
| else if (FD_ISSET(touchpad_fd, &fds)) | |
| { | |
| if (read(touchpad_fd, &iev, sizeof(iev)) == sizeof(iev)) | |
| handle_touchpad_event(&iev); | |
| } | |
| reset_fdset(); | |
| } | |
| close(keyboard_fd); | |
| close(mouse_fd); | |
| close(touchpad_fd); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment