static const char *device_path = "/dev/input";
然後 ..
scan_device(device_path)
scan_device 找所有 /dev/input 下面的 node
int EventHub::scan_dir(const char *dirname)
{
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
while((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
(de->d_name[1] == '\0' ||
(de->d_name[1] == '.' && de->d_name[2] == '\0')))
continue;
strcpy(filename, de->d_name);
open_device(devname);
}
closedir(dir);
return 0;
}
呼叫 open_device,把 node 加到 mFD[] 中。
在 kernel 的部份, /dev/input 是由 /driver/input/input.c 註冊的:
static int __init input_init(void)
{
int err;
input_init_abs_bypass();
err = class_register(&input_class);
if (err) {
printk(KERN_ERR "input: unable to register input_dev class\n");
return err;
}
err = input_proc_init();
if (err)
goto fail1;
err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
if (err) {
printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
goto fail2;
}
return 0;
fail2: input_proc_exit();
fail1: class_unregister(&input_class);
return err;
}
最上層 EventHub.cpp 中,poll input device 的 function :
bool EventHub::getEvent
用 bionic -- libc 的 poll function ..
release_wake_lock(WAKE_LOCK_ID);
pollres = poll(mFDs, mFDCount, -1);
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
if (pollres <= 0) {
if (errno != EINTR) {
LOGW("select failed (errno=%d)\n", errno);
usleep(100000);
}
continue;
}
//printf("poll %d, returned %d\n", mFDCount, pollres);
// mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
for(i = 1; i < mFDCount; i++) {
......
一次poll所有的 input device,timeout 是 -1 ,所以是 block。
也就是說,要任一個 device 有資料才 return.
然後...判斷 有 update 的 device,read data:
if(mFDs[i].revents & POLLIN) {
res = read(mFDs[i].fd, &iev, sizeof(iev));
iev 內容就是 keyscan code.touch 的 interface 也在這裡。
沒有留言:
張貼留言