栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何使用Linux获取触摸屏原始数据的坐标

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何使用Linux获取触摸屏原始数据的坐标

基于控制台的解决方案

您可以使用

evtest
工具获取解析的坐标。

  1. 如果仅需要单点触摸坐标:查找

    ABS_X
    ABS_Y
    字段:

    type 3 (EV_ABS), pre 0 (ABS_X), value 10306

    type 3 (EV_ABS), pre 1 (ABS_Y), value 30625

  2. 如果您需要多点触控坐标:

    • 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


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/403179.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号