问题描述
具有3m的触摸显示屏.它通过USB连接到我的debian系统,并重新识别为人机界面(hid).我正在尝试访问和推送实时信息...如果被触摸,我想知道(x,y)的位置,并将其通过netcat通过管道传递到另一台主机.
wie have a 3m microtouch display. Its connected to my debian system via usb and recongnized as human interface (hid). I am trying to access and push realtime information... if its getting touched I want to know where (x,y) and pipe it throught netcat to another host.
不幸的是,我只能使用
cat /dev/input/event2 | hexdump
或evtest
您得到的十六进制代码似乎无处记载...
You get hexcode that seem nowhere documented...
有人知道如何获取这些信息吗?必须有一种从十六进制代码中提取它的方法.不幸的是,我不知道如何解释十六进制代码.我找不到它记录的任何来源...
Does anybody have a clue how to get those information? There must be a way to extract it from the hexcode. Unfortunately I have no idea how to interpret the hexcode. I couldnt find any source where its documented...
内核是否可以实时向我提供这些所需信息?作为一个工作环境,也许可以找到X-Server可以告诉我的解决方案?触摸屏的行为就像X中的鼠标.实际上,我已经准备好尝试通过xlib获取鼠标的x,y位置.但这太慢了,无法告诉我是否有人在触摸……
Is there a way the Kernel could provide me those desired information in realtime?As a workarround is there maybe a solution Where the X-Server could tell me? The touchscreen behaves like a mouse in X. I actually allready tried to get x,y-position of the mouse via xlib. But it was too slow and wouldnt tell me if somebody is touching or not...
提前谢谢!
evtest示例输出:
evtest sample output:
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
工具获取解析的坐标.
Console-based solution
You can obtain parsed coordinates using evtest
tool.
-
如果只需要单点触摸坐标:查找
ABS_X
和ABS_Y
字段:
type 3 (EV_ABS), code 0 (ABS_X), value 10306
type 3 (EV_ABS), code 1 (ABS_Y), value 30625
如果您需要多点触摸坐标:
If you need multi-touch coordinates:
-
ABS_MT_SLOT
代表手指的数量 -
ABS_MT_POSITION_X
和ABS_MT_POSITION_Y
-坐标
ABS_MT_SLOT
represents number of fingerABS_MT_POSITION_X
andABS_MT_POSITION_Y
-- coordinates
#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
例如,如果您需要通过网络发送单点触摸坐标,则可以使用如下脚本:
For example, if you need to send single-touch coordinates via network, you can use script like this:
#!/bin/sh
# ---- Global variables ----
input=/dev/input/event0
code_prefix="ABS"
code="${code_prefix}_[XY]"
val_regex=".*(${code_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 $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应用程序.可以很容易地解释获得的二进制数据,请参阅内核文档中的第5节.您可以使用select()
syscall等待下一个数据部分.
Program-based solution
You can write C application that will read your event file. Obtained binary data can be easily interpreted, see section 5 in kernel documentation.You can wait for next data portion using 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_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;
}
坐标单位
首先,您需要了解接下来的事情:
Coordinates units
First of all you need to know next things:
- 哪里是坐标原点(即
[x=0;y=0]
) - 您的设备用来表示坐标的单位
通常可以在设备的驱动程序代码中找到此信息.
This information usually can be found in driver code for your device.
这是您的驱动程序设备.
This is the driver for your device.
因此,似乎您需要将evtest
的轴值除以65535,然后乘以设备的宽度或高度(以像素为单位).例如,如果您得到X = 30000,并且LCD面板的宽度为1080像素,则需要执行以下操作:
So it seems like you need to divide your axis value from evtest
by 65535 and multiply it by width or height of device (in pixels). For example, if you get X=30000, and width of your LCD panel is 1080 pixels, you need to do:
X = round((30000 / 65535) * 1080) = 494 pixels
这篇关于如何使用Linux获取触摸屏原始数据的坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!