通过select较高效的捕获和处理鼠标键盘事件

嵌入式Linux键盘事件监听:从/dev/input到evdev的实战指南 在嵌入式Linux开发中,输入事件处理是连接用户交互与硬件控制的核心环节。Linux输入子系统通过扫描码、键码和输入事件将物理按键转换为标准数据结构,为上层应用提供统一的访问接口。理解键盘事件从硬件中断到字符流的转换原理,对于实现实时响应、非阻塞交互的嵌入式应用至关重要。通过直接读取/dev/input/event设备节点,开发者可以获取最原始的按键按下/释放状态,适用于机器人控制、交互式终端等需要精确输入捕获的场景。本文以Intel Edison平台为例,深入解析底层事件监听、termios终端控制及Py 阅读详情

select监听这些文件描述符的状态,若有一个发生变化则返回,否则阻塞。

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>      
  2. #include <stdlib.h>      
  3. #include <linux/input.h>      
  4. #include <fcntl.h>      
  5. #include <sys/time.h>      
  6. #include <sys/types.h>      
  7. #include <sys/stat.h>      
  8. #include <unistd.h>      
  9.   
  10. int main(int argc,char **argv)      
  11. {      
  12.     int fd, retval;      
  13.     char buf[6];      
  14.     fd_set readfds;      
  15.     struct timeval tv;      
  16.   
  17.     // 打开鼠标设备      
  18.     fd = open( "/dev/input/mice", O_RDONLY );      
  19.     // 判断是否打开成功      
  20.     if(fd<0) {      
  21.         printf("Failed to open \"/dev/input/mice\".\n");      
  22.         exit(1);      
  23.     } else {      
  24.         printf("open \"/dev/input/mice\" successfuly.\n");      
  25.     }      
  26.       
  27.     int fd_kb;       
  28.     struct input_event event_kb;    
  29.     fd_kb = open("/dev/input/event1", O_RDONLY); //键盘输入    
  30.     if(fd_kb <= 0)    
  31.     {    
  32.             printf("open device error\n");    
  33.             return 0;    
  34.     }  
  35.       
  36.     int fd_mouse;      
  37.     struct input_event event_mouse;         
  38.     fd_mouse = open("/dev/input/event4", O_RDONLY); //鼠标输入    
  39.     if(fd_mouse <= 0)    
  40.     {    
  41.             printf("open device error\n");    
  42.             return 0;    
  43.     }  
  44.       
  45.       
  46.     while(1) {      
  47.         // 设置最长等待时间      
  48.         tv.tv_sec = 5;      
  49.         tv.tv_usec = 0;      
  50.       
  51.         FD_ZERO( &readfds );      
  52.         FD_SET( fd, &readfds );      
  53.         FD_SET( fd_kb, &readfds );   
  54.         FD_SET( fd_mouse, &readfds );   
  55.       
  56.         int max=fd>fd_kb?(fd>fd_mouse?fd:fd_mouse):(fd_kb>fd_mouse?fd_kb:fd_mouse);  
  57.           
  58.         retval = select( max+1, &readfds, NULL, NULL, &tv );//有文件描述符的状态发生变化(变为可读)或者超时和错误就返回,否则就阻塞      
  59.         if(retval==0) {      
  60.             printf( "Time out!\n" );      
  61.         }else if(retval<0){  
  62.             printf( "error!\n" );   
  63.         }else{                      //判断是哪个文件描述符的状态发生了变化,进行处理即可  
  64.           
  65.             //鼠标位置  
  66.             if(FD_ISSET(fd,&readfds))   
  67.             {      
  68.                 // 读取鼠标设备中的数据      
  69.                 if(read(fd, buf, 6) <= 0) {      
  70.                     continue;      
  71.                 }      
  72.                 // 打印出从鼠标设备中读取到的数据      
  73.                 printf("Button type = %d, X = %d, Y = %d, Z = %d\n", (buf[0] & 0x07), buf[1], buf[2],   buf[3]);      
  74.             }    
  75.               
  76.             //键盘点击  
  77.             if(FD_ISSET(fd_kb,&readfds))   
  78.             {      
  79.                 if(read(fd_kb, &event_kb, sizeof(event_kb)) == sizeof(event_kb))    
  80.                 {    
  81.                     if (event_kb.type == EV_KEY)    
  82.                     {    
  83.                         //if (event_kb.value == 0 || event_kb.value == 1)//1表示按下,0表示释放,会检测到两次    
  84.                         if (event_kb.value == 1)//键按下    
  85.                         {    
  86.                                 //printf("key %d %s\n", event_kb.code, (event_kb.value) ? "Pressed" : "Released");    
  87.                                 if(event_kb.code == KEY_ESC)    
  88.                                         break;    
  89.                                 if(event_kb.code == KEY_Q)    
  90.                                     printf("q\n");                                     
  91.                                 if(event_kb.code == KEY_W)    
  92.                                     printf("w\n");      
  93.                                 if(event_kb.code == KEY_E)    
  94.                                     printf("e\n");      
  95.                                 if(event_kb.code == KEY_R)    
  96.                                     printf("r\n");      
  97.                         }    
  98.     
  99.                     }    
  100.                     
  101.                 }       
  102.             }    
  103.               
  104.             //鼠标点击  
  105.             if(FD_ISSET(fd_mouse,&readfds))   
  106.             {      
  107.                 if(read(fd_mouse, &event_mouse, sizeof(event_mouse)) == sizeof(event_mouse))    
  108.                 {                                       
  109.                     if(event_mouse.type = EV_REL)    
  110.                     {    
  111.                         if(event_mouse.code == REL_WHEEL)           
  112.                             printf("REL_WHEEL %d\n", event_mouse.value);//-1表示下滑,1表示上滑    
  113.                     }       
  114.          
  115.                     if(event_mouse.code == BTN_LEFT && event_mouse.value==1)//左键按下,1表示按下,0表示释放。不然会检测到两次    
  116.                         printf("left down: %d\n", event_mouse.code);    
  117.                             
  118.                     if(event_mouse.code == BTN_RIGHT && event_mouse.value==1)    
  119.                         printf("right down: %d\n", event_mouse.code);    
  120.                             
  121.                     if(event_mouse.code == BTN_MIDDLE && event_mouse.value==1)    
  122.                         printf("middle down: %d\n", event_mouse.code);    
  123.   
  124.                 }   
  125.             }     
  126.           
  127.         }         
  128.     
  129.     }      
  130.     close(fd);    
  131.     close(fd_kb);   
  132.     close(fd_mouse);      
  133.     return 0;      
  134. }   
  135.   
  136.   
  137.   
  138.   
  139.     
网页防复制技术原理与破解实战:从事件监听到网络抓取 在Web前端开发中,用户交互与内容保护是常见的需求。其核心原理通常基于浏览器的事件模型与CSS渲染机制,例如通过JavaScript监听`contextmenu`、`selectstart`、`copy`等事件,并调用`preventDefault()`方法阻止默认行为;或利用CSS属性如`user-select: none`直接禁用文本选择。这些技术旨在平衡用户体验与内容版权保护,在文档型网站、知识付费平台及内容聚合应用中尤为常见。从工程实践角度看,理解这些机制有助于开发者实现更精细的权限控制,也为技术爱 阅读详情

相关推荐

Python实战:构建基于GPT的智能输入工具,提升AI交互效率

智能输入技术通过整合人工智能模型与物理交互设备,实现了人机交互的智能化升级。其核心原理是利用系统级键盘监听捕获用户输入,通过API调用云端或本地AI模型进行实时处理,并将结果无缝回填到应用程序中。这种技术能够显著提升文本处理、代码补全、翻译等场景的工作效率。在实际工程实践中,开发者可以使用Python的pynput库实现全局键盘监听,结合requests库调用OpenAI的GPT模型,通过pyautogui和pyperclip完成文本的捕获与回填。本文以构建智能输入工具为例,详细介绍了如何将GPT模型能力集

weixin_30635053的博客 409

鼠标事件 键盘事件

一、常用的鼠标事件 鼠标事件 触发条件 onclick onmouseover onmouseoutonfocus onblur onblur onmousemove onmouseup onmousedown

m0_61700036的博客 1739

SuperCopy插件:一键解除网页复制限制的原理与实战指南

在Web前端开发中,JavaScript常被用于实现交互逻辑与用户行为控制,其中通过监听copy、contextmenu等事件并调用preventDefault()方法,是网站实现文本防复制功能的常见技术原理。这种机制虽然能保护内容,但也给用户的学习、研究和合理引用带来了不便。从工程实践角度看,浏览器扩展通过注入内容脚本,动态移除事件监听器、修改CSS的user-select属性,可以高效、非侵入性地恢复浏览器的原生复制功能,其技术价值在于平衡了版权保护与用户体验。SuperCopy作为此类工具的代表,其核

weixin_34111790的博客 405

在linux中通过select实现IO多路复用对鼠标及键盘输入的同时检测

在程序中经常会需要同时处理多路输入输出流,采用阻塞的方法会无法达成想要的效果,而采用不阻塞的方法时需要对多个输入输出信号不停的轮询会太浪费cpu时间。如果采用线程或进程的方法将产生线程或进程之间的同步与通信问题这会使程序变得复杂。解决问题相对较好的解决方法就是使用I/O多路复用的方法,实现I/O多路复用的其中一种方法就是利用select函数。

qq_41857815的博客 546

LayUi表格性能优化:解决大数据量下动态下拉框卡顿问题

在前端开发中,处理大规模数据表格时,浏览器渲染性能与JavaScript执行效率是常见的性能瓶颈。其核心原理在于DOM操作与事件绑定的开销会随着节点数量呈指数级增长,尤其在传统UI框架中,一次性渲染大量复杂表单元素会导致主线程阻塞。从技术价值看,优化此类问题能显著提升用户体验与应用响应速度,是构建高性能Web应用的关键。常见的应用场景包括后台管理系统、数据仪表盘等需要展示与编辑海量行数据的界面。本文聚焦于LayUi框架,针对其数据表格中嵌入大量动态下拉框时出现的严重卡顿现象,深入剖析了问题根源,并系统性地提

weixin_34208185的博客 368

基于OpenClaw的AI Agent实战:RPA与多模态大模型融合的自动化任务拆解

机器人流程自动化(RPA)旨在通过模拟用户操作实现软件任务的自动化执行,其核心原理是将重复性工作流程转化为可编程的脚本指令。随着多模态大模型技术的发展,RPA正与AI深度融合,通过赋予机器视觉理解和自然语言决策能力,实现从“固定脚本”到“智能体”的范式跃迁。这种融合创造了巨大的技术价值,使得自动化系统能够处理非结构化界面、适应动态变化,并完成更复杂的决策任务。在应用场景上,AI增强型RPA已从传统的财务对账、数据录入,扩展到需要实时屏幕交互的自动化测试、智能填报及辅助操作等前沿领域。本文以OpenClaw开

weixin_34115824的博客 481

Linux C : select简介和epoll 实现

也就是说,当被监控文件有事件到来时,比如socket收到数据时,ep_poll_callback()会被回调.ep_poll_callback函数主要的功能是将被监视文件的等待事件就绪时,将文件对应的epitem实例添加到就绪队列中。通过struct file的poll操作,以回调的方式返回对象的等待队列,这里设置的回调函数是ep_ptable_queue_proc。都要建立监听,accept客户端连接,把客户端连接放在一个集合中,再将集合放到模型中管理,最后遍历有事件的文件描述符,进行通信。

superSmart_Dong的博客 953

Unity跨平台Web交互实战:原生插件选型、双向通信与性能优化

在现代应用开发中,跨平台交互与混合架构是提升产品动态性和开发效率的关键技术。其核心原理在于通过桥接机制,实现原生应用与Web内容之间的数据与事件通信。这项技术的价值在于能够充分利用Web生态的快速迭代和丰富资源,同时保持原生应用的高性能和原生体验,是实现热更新、动态内容加载和复杂UI模块化的有效手段。在游戏开发、电商应用、教育软件和企业工具等场景中,它被广泛用于内嵌活动页、实时数据看板、客服系统和在线课件。本文聚焦于Unity引擎,深入探讨了如何通过原生WebView插件(如Vuplex)构建稳健的通信桥梁

weixin_33985679的博客 362

select实现对键盘的监控.c

/*select实现对键盘的监控 */# include # include # include # include # include #define STDIN 0 //标准输入设备的文件描述符为0 int main(){ struct timeval tv; //定义等待时间 fd_set readfds; //定义读文件描述符集合 while(1){ tv.tv_sec=5; //

东哥的博客 1537

C++实战项目学习指南:从入门到进阶的五大项目解析

C++作为一门工程性极强的编程语言,其核心价值在于将零散的语法知识组织起来解决实际问题。理解其底层原理,如内存管理、模板编程和RAII机制,是掌握这门语言的关键。这些技术原理支撑了高性能系统、网络服务和图形应用的开发。通过项目驱动学习,开发者能深入理解概念如何转化为实践,例如在实现智能指针时体会资源生命周期管理,在构建Web服务器时应用I/O多路复用和线程池。本文聚焦于C++新手如何通过精选实战项目,如实现STL容器、搭建高并发聊天室或开发Qt图形应用,系统性地构建工程能力,将理论知识固化为解决真实场景问题

weixin_34175509的博客 414

OpenCV-Python实战(16)——人脸追踪详解

人脸处理是人工智能中的一个热门话题,人脸处理可以使用计算机视觉算法从人脸中自动提取大量信息,例如身份、意图和情感,由于外观变化、遮挡、快速运动、运动模糊和比例变化等多种因素,人脸追踪非常具有挑战性。dlib 库实现了基于 DCF 的跟踪器,非常适合用于进行人脸追踪,本文利用此跟踪器进行面部跟踪和用于选择的其他对象的追踪。

盼小辉丶的博客 2万+

游戏外挂对抗:从模拟输入检测到服务器校验的实战指南

在游戏开发领域,客户端安全与反作弊是保障公平竞技环境的核心技术。其基本原理在于构建一个可信的计算环境,通过客户端加固、行为分析和服务器权威验证等多层防御体系,识别并阻止未经授权的第三方程序干预。这项技术的核心价值在于维护游戏的经济生态与玩家体验,防止外挂对游戏平衡性与商业模式的破坏。典型的应用场景包括多人在线竞技游戏、大型多人在线角色扮演游戏等对公平性要求极高的领域。针对日益猖獗的“模拟输入”与“画面篡改”类外挂,开发者需要深入理解其欺骗系统输入事件与渲染流程的原理,并实施从代码混淆到输入模式分析的立体化对

weixin_30915275的博客 388

键盘操作select下拉框

键盘操作select下拉框,不需要鼠标,直接用键盘就可以选择select框的标签。可以使用键盘操作下拉框

GSD Core 的 run-with-timeout 进程树清理:Windows 整树终止修复与跨 AI 执行超时保障(PR 4775 / 4601)

**导读:** 本文围绕 gsd-core 的 changeset 记录(`type: Fixed`,PR #4775,对应 issue #4601)展开,讲解 `run-with-timeout` 命令如何在超时后不再只杀死直接子进程,而是在 Windows 上整树终止命令的全部后代进程,从而堵住 `workflow.cross_ai_command` 包装的模型 CLI 在超时后继续无限运行、

gitblog_00608的博客 846

CSAPP performance lab

CSAPP 深入理解计算机系统的performance Lab

weixin_46091531的博客 1253

aubo i5 + realsense D435i识别抓取实践二

aubo i5 + realsense D435i识别抓取实践二前言一、手眼标定是什么?二、标定软件安装1.aruco_ros安装2.vision_visp安装3.easy_handeye安装4.realsense驱动安装5.安装realsense ROS软件包三、配置1.launch文件修改2.打印二维码四、手眼标定1.启动launch文件2.标定步骤3.发布tf关系 前言 前面配置好了aubo机械臂的ROS软件包,机械臂可以正常运行后,接下来我们进行机械臂与相机的手眼标定。手眼标定分为eye_on_ha

转角 6375

Python游戏开发入门:基于pygame的飞机大战项目实战

游戏开发是理解编程逻辑和面向对象设计的重要实践领域。其核心原理在于游戏循环机制,通过事件处理、状态更新和画面渲染的持续迭代,将静态代码转化为动态交互体验。在技术层面,精灵与精灵组模型是2D游戏开发的基石,它通过封装可复用对象和批量管理,大幅提升开发效率。对于Python初学者而言,pygame库提供了从图形绘制到事件响应的完整工具链,是实现游戏原型的理想选择。通过构建飞机大战这类经典项目,开发者不仅能掌握虚拟环境配置、模块化设计等工程实践,还能深入理解碰撞检测、资源管理等通用游戏开发概念。这些技能可直接迁移

weixin_34101229的博客 404

探索Vortex开源GPGPU:RISC-V SIMT架构(4-1),Execute SFU(1)

本文详细分析了Vortex RISC-V内核6级流水线中Execute阶段的SFU(特殊功能单元)模块。重点介绍了SFU的数据流结构,包含dispatch_unit、pe_switch、csr_unit、wctl_unit和gather_unit五个子模块。文章深入解析了warp控制指令wspawn和tmc的实现机制:wspawn用于激活指定数量的warp并设置新PC值,tmc则用于控制线程掩码和warp状态。通过C代码和汇编指令的对照分析,阐明了这些指令在并行计算中的关键作用,包括线程激活、状态切换和执行

weixin_55313207的博客 1364

Vue3+Vite构建自定义虚拟键盘:实现中英文输入与拼音输入法

虚拟键盘作为前端交互的核心组件,其原理在于通过JavaScript动态模拟物理键盘的输入行为,实现与输入框的无缝对接。这项技术的关键价值在于能够完全掌控输入体验的样式、布局和功能逻辑,尤其适用于信息查询终端、自助服务机等需要高度定制化或全屏运行的特定场景。在实现层面,开发者需要处理键盘布局管理、状态响应、事件分发以及与输入法的深度集成。本文聚焦于使用Vue3的组合式API进行响应式状态管理,并集成拼音输入法功能,详细阐述了从核心架构设计到拼音-汉字映射、候选词处理等关键模块的实现路径,为构建高定制化、支持复

weixin_33849215的博客 358

华三模拟器实战:3分钟搞定路由器DHCP地址池配置(附常见错误排查)

本文提供华三模拟器中路由器DHCP地址池的实战配置指南。通过分步详解,帮助用户在3分钟内完成基础设置,并深入讲解多地址池、中继配置等进阶应用。文章重点剖析了DHCP服务无法工作的常见原因,提供从客户端到服务器的系统性排错方法,助力快速定位并解决地址分配失败、获取参数错误等典型问题。

w1x2y3的博客 360

226届数字IC秋招笔试面试全攻略

本文系统介绍了数字IC设计岗位面试的核心技巧,聚焦三大关键环节:自我介绍、项目介绍和技术问题回答。在自我介绍部分,强调1-2分钟结构化表达,突出与岗位匹配的技能和量化成果;项目介绍环节提出"背景-职责-技术-难点-成果"五步框架,建议结合架构图和性能数据展示技术深度;技术问题回答策略包括理解问题、结构化思考、举例说明和诚实应对未知。文章还提供了项目包装方法,指导如何通过量化数据、架构创新展示和技术难点解决方案来突出项目亮点,并附有简历项目描述示例和技术问题回答模板,帮助面试者全方位展示专

2301_79143213的博客 1063

Playwright:从自动化测试到多智能体平台的核心交互引擎

在软件自动化领域,自动化测试框架是确保应用质量与稳定性的关键技术。其核心原理在于模拟用户操作,对软件功能进行验证。随着人工智能技术的发展,尤其是多智能体(Multi-Agent)系统的兴起,自动化框架的技术价值得到了延伸,从单纯的测试验证演变为智能体感知与操作真实世界应用(如Web界面)的关键执行层。这一转变在机器人流程自动化(RPA)、自主AI助手等应用场景中尤为重要,它使得AI能够可靠地执行复杂、长流程的任务。Playwright,作为一个现代化的跨浏览器自动化库,凭借其强大的环境感知能力(如智能等待、

weixin_30730053的博客 511

从零学懂车载 TSN(二):802.1AS、Qbv、Qbu 是如何让 Ethernet “按时发送”的?

假设有两台设备: ECU A 认为: 但 Switch B 认为: 如果我们规定: 问题就来了。ECU:Switch:整个调度立即失效。因此 TSN 要做时间调度,第一件事就是:这就是:IEEE 802.1AS 定义时间敏感网络里的:工程中通常会看到:gPTP也就是:generalized Precision Time Protocol可以先简单理解成: 核心表达:所有 TSN 节点使用共同时间。后面抓包时你会经常遇到: 刚入门时不用急着研究每个 bit。先搞清楚它们解决什么问题。两个设备连接: A 需要知

struggle_22_58的博客 50
上一篇: Android相关权限的概念
下一篇: Android 传感器hal层分析
WythePlus
博客等级 码龄11年 397粉丝 300原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值