Abhinav jayaswal
Abhinav jayaswal

Reputation: 31

In android how to find what /dev/input/event* is used for touchscreen using c function

I am trying to read touchscreen event, in my device /dev/input/event4 is used for touchscreen, while in some other phone, event7 is used for touchscreen.

I am looking for a c function that can help me to find that touchscreen event.

Upvotes: 2

Views: 4318

Answers (3)

sanandane-codeguru
sanandane-codeguru

Reputation: 11

adb shell dumpsys input - this will show the list of all event nodes with the details that you are looking for

Upvotes: 0

Glärbo
Glärbo

Reputation: 146

Each input event device has a corresponding entry in the /sys/class/input/ pseudo-file hierarchy. (See Linux Input Subsystem userspace API in the Linux kernel documentation for further details.) For example, the name of the device corresponding to event7 is in /sys/class/input/event7/device/name.

When you open the event character device (/dev/input/event7), you can use the EVIOCGBIT(type, bits) ioctl to check which kind of events the device can produce. Touchpads will produce EV_ABS events ABS_X and ABS_Y, and EV_KEY event BTN_TOUCH.

Therefore, if you glob /dev/input/event*, open each device in turn, and check if they report the abovementioned three events, you are likely to find the device you look for. For example:

#define  _POSIX_C_SOURCE  200809L
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <linux/input.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <glob.h>
#include <errno.h>
#include <stdio.h>

#ifndef  ULONG_BITS
#define  ULONG_BITS   (CHAR_BIT * sizeof (unsigned long))
#endif

static inline int  has_bit(const unsigned long  data[], const size_t  bit)
{
    return !!(data[bit / ULONG_BITS] & (1uL << (bit % ULONG_BITS)));
}

char *touchscreen_event_device(size_t skip)
{
    glob_t  files;
    int     result;

    result = glob("/dev/input/event*", 0, NULL, &files);
    if (result) {
        if (result == GLOB_NOSPACE) {
            errno = ENOMEM;
            return NULL;
        } else
        if (result == GLOB_NOMATCH) {
            errno = ENOENT;
            return NULL;
        } else {
            errno = EACCES;
            return NULL;
        }
    }

    for (size_t  i = 0;  i < files.gl_pathc;  i++) {
        int  fd = open(files.gl_pathv[i], O_RDONLY);
        if (fd != -1) {
            unsigned long  absbits[1 + ABS_MAX / ULONG_BITS] = { 0 };
            unsigned long  keybits[1 + KEY_MAX / ULONG_BITS] = { 0 };
            if (ioctl(fd, EVIOCGBIT(EV_ABS, ABS_MAX+1), &absbits) != -1 &&
                ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX+1), &keybits) != -1) {
                if (has_bit(absbits, ABS_X) &&
                    has_bit(absbits, ABS_Y) &&
                    has_bit(keybits, BTN_TOUCH)) {
                    /* Device reports ABS_X, ABS_Y and BTN_TOUCH,
                       and therefore is a touchpad device. */
                    if (!skip) {
                        char *devpath = strdup(files.gl_pathv[i]);
                        close(fd);
                        globfree(&files);
                        if (!devpath)
                            errno = ENOMEM;
                        return devpath;
                    } else {
                        skip--;
                    }
                }
            }
            close(fd);
        }
    }
    globfree(&files);

    errno = ENOENT;
    return NULL;
}

int main(void)
{
    size_t  i = 0;

    while (1) {
        char *devpath = touchscreen_event_device(i);
        if (!devpath) {
            if (i)
                break;
            fprintf(stderr, "No touchscreen input event devices found: %s.\n", strerror(errno));
            return EXIT_FAILURE;
        }
        printf("Found touchscreen input event device '%s'\n", devpath);
        free(devpath);
        i++;
    }

    return EXIT_SUCCESS;
}

Compile using e.g. gcc -Wall -Wextra -O2 example.c -o example, and run with root privileges, and it will list the paths to the input event devices it believes are touch screens.

Upvotes: 4

emandt
emandt

Reputation: 2716

An answer for a complete code could be difficult because it's a long/heavy work. I'll point you in right directions:

  • read "Input Event Codes": https://www.kernel.org/doc/html/v4.14/input/event-codes.html
  • then you have to list all /dev/input/* files
  • open each of them using "fd = open("/dev/input/xxxxx", O_RDONLY);"
  • call "ioctl(fd, EVIOCGBIT(EV_REL, sizeof(maskbit)), maskbit)" (calling this changing "EV_REL" with others "Input Event Codes"
  • analize "maskbit" by searching for some specific Values that only Touchscreen has

A possibile example could find here: https://android.googlesource.com/device/generic/brillo/+/d1917142dc905d808519023d80a664c066104600/examples/keyboard/keyboard_example.cpp in which the author looking for an Input that supports "KEY_B" Event Code.

Touchscreens should have:

  • for EV_ABS:
    • ABS_X
    • ABS_Y
    • ABS_MT_SLOT
    • ABS_MT_POSITION_X
    • ABS_MT_POSITION_Y
    • ABS_MT_TRACKING_ID

If the Input has all these Bit it is a Touchscreen (reference: https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt)

Upvotes: 0

Related Questions