如何使用 Linux 获取触摸屏原始数据的坐标
How to get Coordinates of Touchscreen Rawdata using Linux
我们有一个 3m 微触摸显示屏。它通过 USB 连接到我的 Debian 系统,并被识别为人机界面 (hid)。我正在尝试访问和推送实时信息...如果它被触及,我想知道 (x,y) 的位置并通过 netcat 将其通过管道传输到另一台主机。
不幸的是,我只能使用以下方法获取原始数据:
cat /dev/input/event2 | hexdump
或
evtest
您得到了似乎无处记录的十六进制代码...
有人知道如何获取该信息吗?必须有办法从十六进制代码中提取它。不幸的是我不知道如何解释十六进制代码。我找不到任何记录它的来源...
内核有没有办法实时向我提供这些所需的信息?
作为解决方法,X-Server 是否可以告诉我解决方案?触摸屏的行为就像 X 中的鼠标。实际上我已经尝试通过 xlib 获取鼠标的 x、y 位置。但是它太慢了,不告诉我是否有人在触摸...
evtest
示例输出:
Event: time 1425319271.595631, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 51
Event: time 1425319271.595631, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10304
Event: time 1425319271.595631, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30629
Event: time 1425319271.595631, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 893
Event: time 1425319271.595631, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 414
Event: time 1425319271.595631, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1425319271.595631, type 3 (EV_ABS), code 0 (ABS_X), value 10304
Event: time 1425319271.595631, type 3 (EV_ABS), code 1 (ABS_Y), value 30629
Event: time 1425319271.595631, -------------- SYN_REPORT ------------
Event: time 1425319271.601632, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10306
Event: time 1425319271.601632, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30625
Event: time 1425319271.601632, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 962
Event: time 1425319271.601632, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 421
Event: time 1425319271.601632, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
Event: time 1425319271.601632, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 52
Event: time 1425319271.601632, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 15416
Event: time 1425319271.601632, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24159
Event: time 1425319271.601632, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 649
Event: time 1425319271.601632, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 354
Event: time 1425319271.601632, type 3 (EV_ABS), code 0 (ABS_X), value 10306
Event: time 1425319271.601632, type 3 (EV_ABS), code 1 (ABS_Y), value 30625
Event: time 1425319271.601632, -------------- SYN_REPORT ------------
Event: time 1425319271.606626, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0
Event: time 1425319271.606626, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10318
Event: time 1425319271.606626, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30609
Event: time 1425319271.606626, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 1014
Event: time 1425319271.606626, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 426
Event: time 1425319271.606626, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
Event: time 1425319271.606626, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24161
Event: time 1425319271.606626, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 681
Event: time 1425319271.606626, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 376
Event: time 1425319271.606626, type 3 (EV_ABS), code 0 (ABS_X), value 10318
Event: time 1425319271.606626, type 3 (EV_ABS), code 1 (ABS_Y), value 30609
Event: time 1425319271.606626, -------------- SYN_REPORT ------------
Event: time 1425319271.611629, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0
Event: time 1425319271.611629, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10320
Event: time 1425319271.611629, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30605
Event: time 1425319271.611629, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 1053
Event: time 1425319271.611629, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 430
Event: time 1425319271.611629, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
Event: time 1425319271.611629, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 705
Event: time 1425319271.611629, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 392
Event: time 1425319271.611629, type 3 (EV_ABS), code 0 (ABS_X), value 10320
Event: time 1425319271.611629, type 3 (EV_ABS), code 1 (ABS_Y), value 30605
基于控制台的解决方案
您可以使用evtest
工具获取解析坐标。
如果您只需要单点触摸坐标:查找 ABS_X
和 ABS_Y
字段:
type 3 (EV_ABS), code 0 (ABS_X), value 10306
type 3 (EV_ABS), code 1 (ABS_Y), value 30625
如果需要多点触控坐标:
ABS_MT_SLOT
代表手指数
ABS_MT_POSITION_X
和 ABS_MT_POSITION_Y
-- 坐标
手指#0:
type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0
type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10318
type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30609
1 号手指:
type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 20301
type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24161
比如需要通过网络发送单点触摸坐标,可以使用这样的脚本:
#!/bin/sh
# ---- Global variables ----
input=/dev/input/event0
code_prefix="ABS"
code="${code_prefix}_[XY]"
val_regex=".*(${code_prefix}_\(.\)), value \([-]\?[0-9]\+\)"
val_subst="="
# ---- Functions ----
send_axis() {
# 1. Convert axis value () from device specific units
# 2. Send this axis value via UDP packet
echo
}
process_line() {
while read line; do
axis=$(echo $line | grep "^Event:" | grep $code | \
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 1
fi
evtest $input | process_line
基于程序的解决方案
您可以编写 C 应用程序来读取您的事件文件。获得的二进制数据可以很容易地解释,参见 kernel documentation 中的第 5 节。
您可以使用 select()
系统调用等待下一个数据部分。
#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_Y
/* TODO: Close fd on SIGINT (Ctrl-C), if it's open */
int 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;
}
/* Open Device */
fd = open(EVENT_DEVICE, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "%s is not a vaild device\n", EVENT_DEVICE);
return EXIT_FAILURE;
}
/* Print Device Name */
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
printf("Reading from:\n");
printf("device file = %s\n", EVENT_DEVICE);
printf("device name = %s\n", name);
for (;;) {
const size_t ev_size = sizeof(struct input_event);
ssize_t size;
/* TODO: use select() */
size = read(fd, &ev, ev_size);
if (size < ev_size) {
fprintf(stderr, "Error size when reading\n");
goto err;
}
if (ev.type == EVENT_TYPE && (ev.code == EVENT_CODE_X
|| ev.code == EVENT_CODE_Y)) {
/* TODO: convert value to pixels */
printf("%s = %d\n", ev.code == EVENT_CODE_X ? "X" : "Y",
ev.value);
}
}
return EXIT_SUCCESS;
err:
close(fd);
return EXIT_FAILURE;
}
坐标单位
首先你需要知道接下来的事情:
- 坐标原点在哪里(即
[x=0;y=0]
)
- 您的设备使用哪些单位来表示坐标
此信息通常可以在您设备的驱动程序代码中找到。
This 是您设备的驱动程序。
所以您似乎需要将 evtest
的轴值除以 65535,然后乘以设备的宽度或高度(以像素为单位)。例如,如果你得到 X=30000,你的 LCD 面板的宽度是 1080 像素,你需要做:
X = round((30000 / 65535) * 1080) = 494 pixels
You get hexcode that seem nowhere documented...
这是由设备本身记录的,这就是 hid-multitouch
驱动程序如何解释它接收到的 USB 数据。
您可以使用以下命令查找信息:
$ lsusb # determine the bus & device numbers
...
Bus 001 Device 067: ID 1aad:000f KeeTouch
...
$ sudo usbhid-dump -a 1:67 -e d
001:067:002:DESCRIPTOR 1615651625.434241
05 0D 09 04 A1 01 85 03 09 22 09 00 15 00 26 FF
00 75 08 95 09 81 02 A1 00 05 0D 09 51 15 00 26
FF 00 75 08 95 01 81 02 05 0D 09 42 15 00 25 01
75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05
81 03 05 01 09 30 26 FF 7F 55 00 65 00 35 00 46
00 00 75 10 95 01 81 02 09 31 35 00 46 00 00 81
02 05 0D 09 48 15 00 26 FF 7F 75 10 95 01 81 02
09 49 15 00 26 FF 7F 75 10 95 01 81 02 C0 A1 00
05 0D 09 51 15 00 26 FF 00 75 08 95 01 81 02 05
0D 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81
02 09 47 81 02 95 05 81 03 05 01 09 30 26 FF 7F
55 00 65 00 35 00 46 00 00 75 10 95 01 81 02 09
31 35 00 46 00 00 81 02 05 0D 09 48 15 00 26 FF
7F 75 10 95 01 81 02 09 49 15 00 26 FF 7F 75 10
95 01 81 02 C0 A1 00 05 0D 09 51 15 00 26 FF 00
75 08 95 01 81 02 05 0D 09 42 15 00 25 01 75 01
95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03
05 01 09 30 26 FF 7F 55 00 65 00 35 00 46 00 00
75 10 95 01 81 02 09 31 35 00 46 00 00 81 02 05
0D 09 48 15 00 26 FF 7F 75 10 95 01 81 02 09 49
15 00 26 FF 7F 75 10 95 01 81 02 C0 A1 00 05 0D
09 51 15 00 26 FF 00 75 08 95 01 81 02 05 0D 09
42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09
47 81 02 95 05 81 03 05 01 09 30 26 FF 7F 55 00
65 00 35 00 46 00 00 75 10 95 01 81 02 09 31 35
00 46 00 00 81 02 05 0D 09 48 15 00 26 FF 7F 75
10 95 01 81 02 09 49 15 00 26 FF 7F 75 10 95 01
81 02 C0 A1 00 05 0D 09 51 15 00 26 FF 00 75 08
95 01 81 02 05 0D 09 42 15 00 25 01 75 01 95 01
81 02 09 32 81 02 09 47 81 02 95 05 81 03 05 01
09 30 26 FF 7F 55 00 65 00 35 00 46 00 00 75 10
95 01 81 02 09 31 35 00 46 00 00 81 02 05 0D 09
48 15 00 26 FF 7F 75 10 95 01 81 02 09 49 15 00
26 FF 7F 75 10 95 01 81 02 C0 A1 00 05 0D 09 54
15 00 25 1F 75 08 95 01 81 02 C0 09 55 85 FD 15
00 26 FF 00 75 08 95 01 B1 02 C0 05 0D 09 0E A1
01 85 FC 09 52 09 53 15 00 26 FF 00 75 08 95 02
B1 02 C0
001:067:001:DESCRIPTOR 1615651625.436655
05 01 09 02 A1 01 85 02 09 01 A1 00 06 00 FF 09
00 15 00 26 FF 00 75 08 95 09 81 02 05 01 09 30
09 31 15 00 26 FF 7F 75 10 95 02 81 02 05 09 19
01 29 08 15 00 25 01 95 08 75 01 81 02 C0 C0
001:067:000:DESCRIPTOR 1615651625.437001
06 00 FF 09 00 A1 01 09 00 85 01 A1 00 09 00 15
00 26 FF 00 35 00 46 FF 00 75 08 95 3F 81 02 C0
09 02 85 FE A1 00 09 06 15 00 26 FF 00 35 00 46
FF 00 75 08 95 3F B1 02 C0 C0
我使用 lsusb
命令确定总线和设备编号并将其传递给 usbhid-dump
命令。您可以在没有这些数字的情况下使用 dump 命令,但随后您会得到所有设备的列表。在大多数情况下可能不是您想要的。
里面的代码由内核中的hid_parser()
命令解释。只有部分设备可能无法正确识别,而这正是您需要此信息的时候。
如何解释该数据由 USB 联盟定义。此时是1.11版本,对于hid类型的设备可以找到on this page
这主要包括键盘、鼠标、触摸屏、触摸板、操纵杆,尽管一些其他类型的设备也支持它(您的电源按钮、显示器上的各种按钮等)
我们有一个 3m 微触摸显示屏。它通过 USB 连接到我的 Debian 系统,并被识别为人机界面 (hid)。我正在尝试访问和推送实时信息...如果它被触及,我想知道 (x,y) 的位置并通过 netcat 将其通过管道传输到另一台主机。
不幸的是,我只能使用以下方法获取原始数据:
cat /dev/input/event2 | hexdump
或
evtest
您得到了似乎无处记录的十六进制代码...
有人知道如何获取该信息吗?必须有办法从十六进制代码中提取它。不幸的是我不知道如何解释十六进制代码。我找不到任何记录它的来源...
内核有没有办法实时向我提供这些所需的信息?
作为解决方法,X-Server 是否可以告诉我解决方案?触摸屏的行为就像 X 中的鼠标。实际上我已经尝试通过 xlib 获取鼠标的 x、y 位置。但是它太慢了,不告诉我是否有人在触摸...
evtest
示例输出:
Event: time 1425319271.595631, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 51
Event: time 1425319271.595631, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10304
Event: time 1425319271.595631, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30629
Event: time 1425319271.595631, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 893
Event: time 1425319271.595631, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 414
Event: time 1425319271.595631, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1425319271.595631, type 3 (EV_ABS), code 0 (ABS_X), value 10304
Event: time 1425319271.595631, type 3 (EV_ABS), code 1 (ABS_Y), value 30629
Event: time 1425319271.595631, -------------- SYN_REPORT ------------
Event: time 1425319271.601632, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10306
Event: time 1425319271.601632, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30625
Event: time 1425319271.601632, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 962
Event: time 1425319271.601632, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 421
Event: time 1425319271.601632, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
Event: time 1425319271.601632, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 52
Event: time 1425319271.601632, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 15416
Event: time 1425319271.601632, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24159
Event: time 1425319271.601632, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 649
Event: time 1425319271.601632, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 354
Event: time 1425319271.601632, type 3 (EV_ABS), code 0 (ABS_X), value 10306
Event: time 1425319271.601632, type 3 (EV_ABS), code 1 (ABS_Y), value 30625
Event: time 1425319271.601632, -------------- SYN_REPORT ------------
Event: time 1425319271.606626, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0
Event: time 1425319271.606626, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10318
Event: time 1425319271.606626, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30609
Event: time 1425319271.606626, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 1014
Event: time 1425319271.606626, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 426
Event: time 1425319271.606626, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
Event: time 1425319271.606626, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24161
Event: time 1425319271.606626, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 681
Event: time 1425319271.606626, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 376
Event: time 1425319271.606626, type 3 (EV_ABS), code 0 (ABS_X), value 10318
Event: time 1425319271.606626, type 3 (EV_ABS), code 1 (ABS_Y), value 30609
Event: time 1425319271.606626, -------------- SYN_REPORT ------------
Event: time 1425319271.611629, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0
Event: time 1425319271.611629, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10320
Event: time 1425319271.611629, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30605
Event: time 1425319271.611629, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 1053
Event: time 1425319271.611629, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 430
Event: time 1425319271.611629, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1
Event: time 1425319271.611629, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 705
Event: time 1425319271.611629, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 392
Event: time 1425319271.611629, type 3 (EV_ABS), code 0 (ABS_X), value 10320
Event: time 1425319271.611629, type 3 (EV_ABS), code 1 (ABS_Y), value 30605
基于控制台的解决方案
您可以使用evtest
工具获取解析坐标。
如果您只需要单点触摸坐标:查找
ABS_X
和ABS_Y
字段:type 3 (EV_ABS), code 0 (ABS_X), value 10306 type 3 (EV_ABS), code 1 (ABS_Y), value 30625
如果需要多点触控坐标:
ABS_MT_SLOT
代表手指数ABS_MT_POSITION_X
和ABS_MT_POSITION_Y
-- 坐标
手指#0:
type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0 type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10318 type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30609
1 号手指:
type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1 type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 20301 type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24161
比如需要通过网络发送单点触摸坐标,可以使用这样的脚本:
#!/bin/sh
# ---- Global variables ----
input=/dev/input/event0
code_prefix="ABS"
code="${code_prefix}_[XY]"
val_regex=".*(${code_prefix}_\(.\)), value \([-]\?[0-9]\+\)"
val_subst="="
# ---- Functions ----
send_axis() {
# 1. Convert axis value () from device specific units
# 2. Send this axis value via UDP packet
echo
}
process_line() {
while read line; do
axis=$(echo $line | grep "^Event:" | grep $code | \
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 1
fi
evtest $input | process_line
基于程序的解决方案
您可以编写 C 应用程序来读取您的事件文件。获得的二进制数据可以很容易地解释,参见 kernel documentation 中的第 5 节。
您可以使用 select()
系统调用等待下一个数据部分。
#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_Y
/* TODO: Close fd on SIGINT (Ctrl-C), if it's open */
int 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;
}
/* Open Device */
fd = open(EVENT_DEVICE, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "%s is not a vaild device\n", EVENT_DEVICE);
return EXIT_FAILURE;
}
/* Print Device Name */
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
printf("Reading from:\n");
printf("device file = %s\n", EVENT_DEVICE);
printf("device name = %s\n", name);
for (;;) {
const size_t ev_size = sizeof(struct input_event);
ssize_t size;
/* TODO: use select() */
size = read(fd, &ev, ev_size);
if (size < ev_size) {
fprintf(stderr, "Error size when reading\n");
goto err;
}
if (ev.type == EVENT_TYPE && (ev.code == EVENT_CODE_X
|| ev.code == EVENT_CODE_Y)) {
/* TODO: convert value to pixels */
printf("%s = %d\n", ev.code == EVENT_CODE_X ? "X" : "Y",
ev.value);
}
}
return EXIT_SUCCESS;
err:
close(fd);
return EXIT_FAILURE;
}
坐标单位
首先你需要知道接下来的事情:
- 坐标原点在哪里(即
[x=0;y=0]
) - 您的设备使用哪些单位来表示坐标
此信息通常可以在您设备的驱动程序代码中找到。
This 是您设备的驱动程序。
所以您似乎需要将 evtest
的轴值除以 65535,然后乘以设备的宽度或高度(以像素为单位)。例如,如果你得到 X=30000,你的 LCD 面板的宽度是 1080 像素,你需要做:
X = round((30000 / 65535) * 1080) = 494 pixels
You get hexcode that seem nowhere documented...
这是由设备本身记录的,这就是 hid-multitouch
驱动程序如何解释它接收到的 USB 数据。
您可以使用以下命令查找信息:
$ lsusb # determine the bus & device numbers
...
Bus 001 Device 067: ID 1aad:000f KeeTouch
...
$ sudo usbhid-dump -a 1:67 -e d
001:067:002:DESCRIPTOR 1615651625.434241
05 0D 09 04 A1 01 85 03 09 22 09 00 15 00 26 FF
00 75 08 95 09 81 02 A1 00 05 0D 09 51 15 00 26
FF 00 75 08 95 01 81 02 05 0D 09 42 15 00 25 01
75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05
81 03 05 01 09 30 26 FF 7F 55 00 65 00 35 00 46
00 00 75 10 95 01 81 02 09 31 35 00 46 00 00 81
02 05 0D 09 48 15 00 26 FF 7F 75 10 95 01 81 02
09 49 15 00 26 FF 7F 75 10 95 01 81 02 C0 A1 00
05 0D 09 51 15 00 26 FF 00 75 08 95 01 81 02 05
0D 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81
02 09 47 81 02 95 05 81 03 05 01 09 30 26 FF 7F
55 00 65 00 35 00 46 00 00 75 10 95 01 81 02 09
31 35 00 46 00 00 81 02 05 0D 09 48 15 00 26 FF
7F 75 10 95 01 81 02 09 49 15 00 26 FF 7F 75 10
95 01 81 02 C0 A1 00 05 0D 09 51 15 00 26 FF 00
75 08 95 01 81 02 05 0D 09 42 15 00 25 01 75 01
95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03
05 01 09 30 26 FF 7F 55 00 65 00 35 00 46 00 00
75 10 95 01 81 02 09 31 35 00 46 00 00 81 02 05
0D 09 48 15 00 26 FF 7F 75 10 95 01 81 02 09 49
15 00 26 FF 7F 75 10 95 01 81 02 C0 A1 00 05 0D
09 51 15 00 26 FF 00 75 08 95 01 81 02 05 0D 09
42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09
47 81 02 95 05 81 03 05 01 09 30 26 FF 7F 55 00
65 00 35 00 46 00 00 75 10 95 01 81 02 09 31 35
00 46 00 00 81 02 05 0D 09 48 15 00 26 FF 7F 75
10 95 01 81 02 09 49 15 00 26 FF 7F 75 10 95 01
81 02 C0 A1 00 05 0D 09 51 15 00 26 FF 00 75 08
95 01 81 02 05 0D 09 42 15 00 25 01 75 01 95 01
81 02 09 32 81 02 09 47 81 02 95 05 81 03 05 01
09 30 26 FF 7F 55 00 65 00 35 00 46 00 00 75 10
95 01 81 02 09 31 35 00 46 00 00 81 02 05 0D 09
48 15 00 26 FF 7F 75 10 95 01 81 02 09 49 15 00
26 FF 7F 75 10 95 01 81 02 C0 A1 00 05 0D 09 54
15 00 25 1F 75 08 95 01 81 02 C0 09 55 85 FD 15
00 26 FF 00 75 08 95 01 B1 02 C0 05 0D 09 0E A1
01 85 FC 09 52 09 53 15 00 26 FF 00 75 08 95 02
B1 02 C0
001:067:001:DESCRIPTOR 1615651625.436655
05 01 09 02 A1 01 85 02 09 01 A1 00 06 00 FF 09
00 15 00 26 FF 00 75 08 95 09 81 02 05 01 09 30
09 31 15 00 26 FF 7F 75 10 95 02 81 02 05 09 19
01 29 08 15 00 25 01 95 08 75 01 81 02 C0 C0
001:067:000:DESCRIPTOR 1615651625.437001
06 00 FF 09 00 A1 01 09 00 85 01 A1 00 09 00 15
00 26 FF 00 35 00 46 FF 00 75 08 95 3F 81 02 C0
09 02 85 FE A1 00 09 06 15 00 26 FF 00 35 00 46
FF 00 75 08 95 3F B1 02 C0 C0
我使用 lsusb
命令确定总线和设备编号并将其传递给 usbhid-dump
命令。您可以在没有这些数字的情况下使用 dump 命令,但随后您会得到所有设备的列表。在大多数情况下可能不是您想要的。
里面的代码由内核中的hid_parser()
命令解释。只有部分设备可能无法正确识别,而这正是您需要此信息的时候。
如何解释该数据由 USB 联盟定义。此时是1.11版本,对于hid类型的设备可以找到on this page
这主要包括键盘、鼠标、触摸屏、触摸板、操纵杆,尽管一些其他类型的设备也支持它(您的电源按钮、显示器上的各种按钮等)