我正在尝试读取触摸屏事件,在我的设备中,/dev/input/event4用于触摸屏,而在其他一些手机中,event7用于触摸屏。
我正在寻找一个可以帮助我找到触摸屏事件的c函数。
发布于 2021-03-09 19:06:48
每个输入事件设备在/sys/class/input/伪文件层次结构中都有相应的条目。(有关详细信息,请参阅Linux内核文档中的Linux Input Subsystem userspace API。)例如,event7对应的设备名称在/sys/class/input/event7/device/name中。
当您打开事件字符设备(/dev/input/event7)时,您可以使用EVIOCGBIT(类型,位) ioctl来检查设备可以产生哪些类型的事件。触摸板将产生EV_ABS event ABS_X和ABS_Y,以及EV_KEY event BTN_TOUCH。
因此,如果您glob /dev/input/event*,依次打开每个设备,并检查它们是否报告了上述三个事件,您很可能会找到您要查找的设备。例如:
#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;
}例如,使用gcc -Wall -Wextra -O2 example.c -o example进行编译,并以根权限运行,它将列出它认为是触摸屏的输入事件设备的路径。
发布于 2021-03-09 16:34:57
完整代码的答案可能很困难,因为这是一项冗长/繁重的工作。我会给你指明正确的方向:
maskbit读取“输入事件代码”:https://www.kernel.org/doc/html/v4.14/input/event-codes.html
/xxxxx”,O_RDONLY);"
(
的特定值,将此更改称为"EV_REL”)来打开每个文件
一个可能的例子可以在这里找到:作者在其中寻找支持"KEY_B“事件代码的输入的https://android.googlesource.com/device/generic/brillo/+/d1917142dc905d808519023d80a664c066104600/examples/keyboard/keyboard_example.cpp。
触摸屏应具备:
适用于EV_ABS的
如果输入具有所有这些位,则它是触摸屏(参考:https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt)
https://stackoverflow.com/questions/66541256
复制相似问题