grab raw keyboard input from event device node

本文介绍了一个简单的C程序,用于从Linux系统的输入设备读取按键事件。程序通过打开指定的输入设备文件,如/dev/input/event0,并使用ioctl和read系统调用获取按键代码。示例展示了如何解析来自键盘的按键事件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
 
void handler (int sig)
{
  printf ("nexiting...(%d)n", sig);
  exit (0);
}
 
void perror_exit (char *error)
{
  perror (error);
  handler (9);
}
 
int main (int argc, char *argv[])
{
  struct input_event ev[64];
  int fd, rd, value, size = sizeof (struct input_event);
  char name[256] = "Unknown";
  char *device = NULL;
 
  //Setup check
  if (argv[1] == NULL){
      printf("Please specify (on the command line) the path to the dev event interface device\n");
      exit (0);
    }
 
  if ((getuid ()) != 0)
    printf ("You are not root! This may not work...\n");
 
  if (argc > 1)
    device = argv[1];
 
  //Open Device
  if ((fd = open (device, O_RDONLY)) == -1)
    printf ("%s is not a vaild device.\n", device);
 
  //Print Device Name
  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
  printf ("Reading From : %s (%s)\n", device, name);
 
  while (1){
      if ((rd = read (fd, ev, size * 64)) < size)
          perror_exit ("read()\n");      
 
      value = ev[0].value;
 
      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
       printf ("Code[%d]\n", (ev[1].code));
      }
  }
 
  return 0;
}



yantai:/home/shell.albert # ./a.out  /dev/input/event0

Reading From : /dev/input/event0 (AT Translated Set 2 keyboard)
Code[30]
aCode[48]
bCode[46]
cdCode[28]

Code[18]
eCode[33]
fCode[34]
gCode[35]
hCode[23]
iCode[36]
jCode[37]
kCode[38]
lCode[50]
mCode[49]
nCode[24]
oCode[25]
pCode[16]
qCode[19]
rCode[31]
sCode[20]
tCode[22]
uCode[47]
vCode[17]
wCode[44]
zCode[45]
xCode[21]
yCode[44]
zCode[29]
Code[46]
^C

yantai:/home/shell.albert #

by zhangshaoyan at May 20,2015.

We get the codes are same as defined in linux/input.h.



### 处理 Linux 系统中的鼠标滚轴事件 在 Linux 系统中,`/dev/input/event0` 设备文件用于表示输入设备(如键盘、鼠标)。对于鼠标的滚轮操作,可以通过读取该设备文件来捕获并解析相应的事件。 #### 解析 `/dev/input/event` 文件结构 为了理解如何处理这些事件,先了解其基本格式。每个事件由三个部分组成:时间戳、类型和代码以及值。具体来说: - 时间戳记录了自 Unix 纪元以来的时间; - 类型定义了事件类别(按键、移动等),而代码则进一步指定了特定类型的细节; - 值字段提供了关于此事件的具体信息,比如按下还是释放键位。 针对鼠标滚轮,在 `input_event` 结构体里通常会看到如下组合[^3]: - **Type**: EV_REL (相对位置变化) - **Code**: REL_WHEEL 或者 REL_HWHEEL (垂直或水平方向上的滚动) 下面是一个 Python 示例程序展示怎样监听并解释来自 `/dev/input/eventX` 的滚轮活动: ```python import struct from fcntl import ioctl import os EVIOCGRAB = 0x40044590 # Grab the device exclusively. def read_mouse_wheel_events(device_path='/dev/input/event0'): with open(device_path, 'rb') as fd: try: ioctl(fd.fileno(), EVIOCGRAB, True) # Try grabbing exclusive access. while True: data = fd.read(16) # Read next event from queue _, _, type_, code, value = struct.unpack('llHHI', data) if type_ == 2 and code in [8, 7]: # Check for wheel events direction = "up" if value > 0 else "down" print(f'Mouse Wheel Moved {direction}') except Exception as e: print(e) finally: ioctl(fd.fileno(), EVIOCGRAB, False) # Release grab on exit or error if __name__ == '__main__': read_mouse_wheel_events() ``` 这段脚本尝试独占打开指定路径下的输入设备,并持续监控是否有新的滚轮动作发生。当检测到时,则打印出滚动的方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值