How to get Coordinates of Touchscreen Rawdata using Linux

痞子三分冷 提交于 2019-11-28 08:41:35

Console-based solution

You can obtain parsed coordinates using evtest tool.

  1. If you only need single-touch coordinates: look for ABS_X and ABS_Y fields:

    type 3 (EV_ABS), code 0 (ABS_X), value 10306
    type 3 (EV_ABS), code 1 (ABS_Y), value 30625
    
  2. If you need multi-touch coordinates:

    • ABS_MT_SLOT represents number of finger
    • ABS_MT_POSITION_X and ABS_MT_POSITION_Y -- coordinates

    Finger #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
    

    Finger #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

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:

  • where is coordinates origin point (i.e. [x=0;y=0])
  • which units your device is using for representing coordinates

This information usually can be found in driver code for your device.

This is the driver for your device.

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!