当前位置: 首页 > news >正文

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

键盘检测指令: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;// 初始化SDLif (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 pollbreak;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;
}

 

http://www.lryc.cn/news/140139.html

相关文章:

  • 户外跑步用什么耳机、户外运动耳机推荐
  • ubuntu设置系统代理
  • java定时任务如何取消
  • gitlab 9.05 版本获取合并请求的API接口报错404是为什么
  • 微服务(多级缓存)
  • 阿里云配置MySQL-server 8.0远程登录
  • 清洁能源使用的社会发展意义
  • 针对论坛系统进行功能测试和性能测试
  • Android App的设计规范
  • paddleclas ImportError: cannot import name ‘Identity‘ from ‘paddle.nn‘
  • Debezium系列之:深入理解Debezium Server Operator和实际应用Debezium Server Operator案例详解
  • ansible批量创建crontab文件并添加到定时任务
  • 什么是 API ?
  • CSS实现内凹圆角,从而实现圆角边框
  • Spring中的自定义注解
  • 前端需要理解的设计模式知识
  • 1、攻防世界第一天
  • 分布式事务(7):SpringCloud2.0整合LCN
  • 机器学习实战14-在日本福岛核电站排放污水的背景下,核电站对人口影响的分析实践
  • 4G智慧电力物联网:建设高效智能,引领电力行业革新!
  • 安防视频监控平台EasyCVR视频集中存储平台接入RTSP设备出现离线情况的问题解决方案
  • 达梦数据库分区表介绍
  • Python爬虫库之urllib使用详解
  • SpringCloud学习笔记(八)_使用Apollo做配置中心
  • jvs-rules(规则引擎)更新:新增功能介绍
  • 消息队列的消息异常处理
  • APP上线为什么要提前部署安全产品呢?
  • SQL注入之HTTP头部注入
  • 软考高级系统架构设计师系列论文九十七:论软件三层结构的设计
  • 【C++心愿便利店】No.2---函数重载、引用