1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <fcntl.h> 20 #include <dirent.h> 21 #include <sys/poll.h> 22 23 #include <linux/input.h> 24 25 #include "minui.h" 26 27 #define MAX_DEVICES 16 28 #define MAX_MISC_FDS 16 29 30 #define BITS_PER_LONG (sizeof(unsigned long) * 8) 31 #define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG) 32 33 #define test_bit(bit, array) \ 34 ((array)[(bit)/BITS_PER_LONG] & (1 << ((bit) % BITS_PER_LONG))) 35 36 struct fd_info { 37 ev_callback cb; 38 void *data; 39 }; 40 41 static struct pollfd ev_fds[MAX_DEVICES + MAX_MISC_FDS]; 42 static struct fd_info ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS]; 43 44 static unsigned ev_count = 0; 45 static unsigned ev_dev_count = 0; 46 static unsigned ev_misc_count = 0; 47 48 int ev_init(ev_callback input_cb, void *data) 49 { 50 DIR *dir; 51 struct dirent *de; 52 int fd; 53 54 dir = opendir("/dev/input"); 55 if(dir != 0) { 56 while((de = readdir(dir))) { 57 unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; 58 59 // fprintf(stderr,"/dev/input/%s\n", de->d_name); 60 if(strncmp(de->d_name,"event",5)) continue; 61 fd = openat(dirfd(dir), de->d_name, O_RDONLY); 62 if(fd < 0) continue; 63 64 /* read the evbits of the input device */ 65 if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) < 0) { 66 close(fd); 67 continue; 68 } 69 70 /* TODO: add ability to specify event masks. For now, just assume 71 * that only EV_KEY and EV_REL event types are ever needed. */ 72 if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits)) { 73 close(fd); 74 continue; 75 } 76 77 ev_fds[ev_count].fd = fd; 78 ev_fds[ev_count].events = POLLIN; 79 ev_fdinfo[ev_count].cb = input_cb; 80 ev_fdinfo[ev_count].data = data; 81 ev_count++; 82 ev_dev_count++; 83 if(ev_dev_count == MAX_DEVICES) break; 84 } 85 } 86 87 return 0; 88 } 89 90 int ev_add_fd(int fd, ev_callback cb, void *data) 91 { 92 if (ev_misc_count == MAX_MISC_FDS || cb == NULL) 93 return -1; 94 95 ev_fds[ev_count].fd = fd; 96 ev_fds[ev_count].events = POLLIN; 97 ev_fdinfo[ev_count].cb = cb; 98 ev_fdinfo[ev_count].data = data; 99 ev_count++; 100 ev_misc_count++; 101 return 0; 102 } 103 104 void ev_exit(void) 105 { 106 while (ev_count > 0) { 107 close(ev_fds[--ev_count].fd); 108 } 109 ev_misc_count = 0; 110 ev_dev_count = 0; 111 } 112 113 int ev_wait(int timeout) 114 { 115 int r; 116 117 r = poll(ev_fds, ev_count, timeout); 118 if (r <= 0) 119 return -1; 120 return 0; 121 } 122 123 void ev_dispatch(void) 124 { 125 unsigned n; 126 int ret; 127 128 for (n = 0; n < ev_count; n++) { 129 ev_callback cb = ev_fdinfo[n].cb; 130 if (cb && (ev_fds[n].revents & ev_fds[n].events)) 131 cb(ev_fds[n].fd, ev_fds[n].revents, ev_fdinfo[n].data); 132 } 133 } 134 135 int ev_get_input(int fd, short revents, struct input_event *ev) 136 { 137 int r; 138 139 if (revents & POLLIN) { 140 r = read(fd, ev, sizeof(*ev)); 141 if (r == sizeof(*ev)) 142 return 0; 143 } 144 return -1; 145 } 146 147 int ev_sync_key_state(ev_set_key_callback set_key_cb, void *data) 148 { 149 unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; 150 unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; 151 unsigned i; 152 int ret; 153 154 for (i = 0; i < ev_dev_count; i++) { 155 int code; 156 157 memset(key_bits, 0, sizeof(key_bits)); 158 memset(ev_bits, 0, sizeof(ev_bits)); 159 160 ret = ioctl(ev_fds[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits); 161 if (ret < 0 || !test_bit(EV_KEY, ev_bits)) 162 continue; 163 164 ret = ioctl(ev_fds[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits); 165 if (ret < 0) 166 continue; 167 168 for (code = 0; code <= KEY_MAX; code++) { 169 if (test_bit(code, key_bits)) 170 set_key_cb(code, 1, data); 171 } 172 } 173 174 return 0; 175 } 176