基于控制台的解决方案
您可以使用
evtest工具获取解析的坐标。
如果仅需要单点触摸坐标:查找
ABS_X
和ABS_Y
字段:type 3 (EV_ABS), pre 0 (ABS_X), value 10306
type 3 (EV_ABS), pre 1 (ABS_Y), value 30625
如果您需要多点触控坐标:
ABS_MT_SLOT
代表手指的数量ABS_MT_POSITION_X
和ABS_MT_POSITION_Y
-坐标
手指#0:
type 3 (EV_ABS), pre 47 (ABS_MT_SLOT), value 0type 3 (EV_ABS), pre 53 (ABS_MT_POSITION_X), value 10318type 3 (EV_ABS), pre 54 (ABS_MT_POSITION_Y), value 30609
手指#1:
type 3 (EV_ABS), pre 47 (ABS_MT_SLOT), value 1type 3 (EV_ABS), pre 53 (ABS_MT_POSITION_X), value 20301type 3 (EV_ABS), pre 54 (ABS_MT_POSITION_Y), value 24161
例如,如果您需要通过网络发送单点触摸坐标,则可以使用如下脚本:
#!/bin/sh# ---- Global variables ----input=/dev/input/event0pre_prefix="ABS"pre="${pre_prefix}_[XY]"val_regex=".*(${pre_prefix}_(.)), value ([-]?[0-9]+)"val_subst="1=2"# ---- Functions ----send_axis() { # 1. Convert axis value ($1) from device specific units # 2. Send this axis value via UDP packet echo $1}process_line() { while read line; do axis=$(echo $line | grep "^Event:" | grep $pre | sed "s/$val_regex/$val_subst/") if [ -n "$axis" ]; then send_axis $axis fi done}# ---- Entry point ----if [ $(id -u) -ne 0 ]; then echo "This script must be run from root" >&2 exit 1fievtest $input | process_line基于程序的解决方案
您可以编写将读取事件文件的C应用程序。获得的二进制数据很容易解释,请参阅内核文档中的第5节。您可以使用
select()syscall
等待下一个数据部分。
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <linux/input.h>#define EVENT_DEVICE "/dev/input/event2"#define EVENT_TYPE EV_ABS#define EVENT_CODE_X ABS_X#define EVENT_CODE_Y ABS_Yint main(int argc, char *argv[]){ struct input_event ev; int fd; char name[256] = "Unknown"; if ((getuid ()) != 0) { fprintf(stderr, "You are not root! This may not work...n"); return EXIT_SUCCESS; } fd = open(EVENT_DEVICE, O_RDONLY); if (fd == -1) { fprintf(stderr, "%s is not a vaild devicen", EVENT_DEVICE); return EXIT_FAILURE; } ioctl(fd, EVIOCGNAME(sizeof(name)), name); printf("Reading from:n"); printf("device file = %sn", EVENT_DEVICE); printf("device name = %sn", name); for (;;) { const size_t ev_size = sizeof(struct input_event); ssize_t size; size = read(fd, &ev, ev_size); if (size < ev_size) { fprintf(stderr, "Error size when readingn"); goto err; } if (ev.type == EVENT_TYPE && (ev.pre == EVENT_CODE_X|| ev.pre == EVENT_CODE_Y)) { printf("%s = %dn", ev.pre == EVENT_CODE_X ? "X" : "Y", ev.value); } } return EXIT_SUCCESS;err: close(fd); return EXIT_FAILURE;}坐标单位
首先,您需要了解以下内容:
- 坐标原点在哪里(即
[x=0;y=0]
) - 您的设备使用哪些单位表示坐标
通常可以在设备的驱动程序代码中找到此信息。
这是您设备的驱动程序。
因此,似乎您需要将轴值
evtest除以65535,然后乘以设备的宽度或高度(以像素为单位)。例如,如果得到X =
30000,并且LCD面板的宽度为1080像素,则需要执行以下操作:
X = round((30000 / 65535) * 1080) = 494 pixels



