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 <dirent.h> 18#include <errno.h> 19#include <fcntl.h> 20#include <linux/input.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <sys/epoll.h> 25#include <sys/ioctl.h> 26#include <unistd.h> 27 28#include <functional> 29 30#include "minui/minui.h" 31 32#define MAX_DEVICES 16 33#define MAX_MISC_FDS 16 34 35#define BITS_PER_LONG (sizeof(unsigned long) * 8) 36#define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG) 37 38struct fd_info { 39 int fd; 40 ev_callback cb; 41}; 42 43static int g_epoll_fd; 44static epoll_event polledevents[MAX_DEVICES + MAX_MISC_FDS]; 45static int npolledevents; 46 47static fd_info ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS]; 48 49static unsigned ev_count = 0; 50static unsigned ev_dev_count = 0; 51static unsigned ev_misc_count = 0; 52 53static bool test_bit(size_t bit, unsigned long* array) { // NOLINT 54 return (array[bit/BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0; 55} 56 57int ev_init(ev_callback input_cb, bool allow_touch_inputs) { 58 g_epoll_fd = epoll_create(MAX_DEVICES + MAX_MISC_FDS); 59 if (g_epoll_fd == -1) { 60 return -1; 61 } 62 63 bool epollctlfail = false; 64 DIR* dir = opendir("/dev/input"); 65 if (dir != nullptr) { 66 dirent* de; 67 while ((de = readdir(dir))) { 68 if (strncmp(de->d_name, "event", 5)) continue; 69 int fd = openat(dirfd(dir), de->d_name, O_RDONLY); 70 if (fd == -1) continue; 71 72 // Use unsigned long to match ioctl's parameter type. 73 unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT 74 75 // Read the evbits of the input device. 76 if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { 77 close(fd); 78 continue; 79 } 80 81 // We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also 82 // allowed if allow_touch_inputs is set. 83 if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) { 84 if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) { 85 close(fd); 86 continue; 87 } 88 } 89 90 epoll_event ev; 91 ev.events = EPOLLIN | EPOLLWAKEUP; 92 ev.data.ptr = &ev_fdinfo[ev_count]; 93 if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) { 94 close(fd); 95 epollctlfail = true; 96 continue; 97 } 98 99 ev_fdinfo[ev_count].fd = fd; 100 ev_fdinfo[ev_count].cb = std::move(input_cb); 101 ev_count++; 102 ev_dev_count++; 103 if (ev_dev_count == MAX_DEVICES) break; 104 } 105 106 closedir(dir); 107 } 108 109 if (epollctlfail && !ev_count) { 110 close(g_epoll_fd); 111 g_epoll_fd = -1; 112 return -1; 113 } 114 115 return 0; 116} 117 118int ev_get_epollfd(void) { 119 return g_epoll_fd; 120} 121 122int ev_add_fd(int fd, ev_callback cb) { 123 if (ev_misc_count == MAX_MISC_FDS || cb == NULL) { 124 return -1; 125 } 126 127 epoll_event ev; 128 ev.events = EPOLLIN | EPOLLWAKEUP; 129 ev.data.ptr = static_cast<void*>(&ev_fdinfo[ev_count]); 130 int ret = epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev); 131 if (!ret) { 132 ev_fdinfo[ev_count].fd = fd; 133 ev_fdinfo[ev_count].cb = std::move(cb); 134 ev_count++; 135 ev_misc_count++; 136 } 137 138 return ret; 139} 140 141void ev_exit(void) { 142 while (ev_count > 0) { 143 close(ev_fdinfo[--ev_count].fd); 144 } 145 ev_misc_count = 0; 146 ev_dev_count = 0; 147 close(g_epoll_fd); 148} 149 150int ev_wait(int timeout) { 151 npolledevents = epoll_wait(g_epoll_fd, polledevents, ev_count, timeout); 152 if (npolledevents <= 0) { 153 return -1; 154 } 155 return 0; 156} 157 158void ev_dispatch(void) { 159 for (int n = 0; n < npolledevents; n++) { 160 fd_info* fdi = static_cast<fd_info*>(polledevents[n].data.ptr); 161 const ev_callback& cb = fdi->cb; 162 if (cb) { 163 cb(fdi->fd, polledevents[n].events); 164 } 165 } 166} 167 168int ev_get_input(int fd, uint32_t epevents, input_event* ev) { 169 if (epevents & EPOLLIN) { 170 ssize_t r = TEMP_FAILURE_RETRY(read(fd, ev, sizeof(*ev))); 171 if (r == sizeof(*ev)) { 172 return 0; 173 } 174 } 175 return -1; 176} 177 178int ev_sync_key_state(const ev_set_key_callback& set_key_cb) { 179 // Use unsigned long to match ioctl's parameter type. 180 unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT 181 unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT 182 183 for (size_t i = 0; i < ev_dev_count; ++i) { 184 memset(ev_bits, 0, sizeof(ev_bits)); 185 memset(key_bits, 0, sizeof(key_bits)); 186 187 if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { 188 continue; 189 } 190 if (!test_bit(EV_KEY, ev_bits)) { 191 continue; 192 } 193 if (ioctl(ev_fdinfo[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits) == -1) { 194 continue; 195 } 196 197 for (int code = 0; code <= KEY_MAX; code++) { 198 if (test_bit(code, key_bits)) { 199 set_key_cb(code, 1); 200 } 201 } 202 } 203 204 return 0; 205} 206 207void ev_iterate_available_keys(const std::function<void(int)>& f) { 208 // Use unsigned long to match ioctl's parameter type. 209 unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT 210 unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT 211 212 for (size_t i = 0; i < ev_dev_count; ++i) { 213 memset(ev_bits, 0, sizeof(ev_bits)); 214 memset(key_bits, 0, sizeof(key_bits)); 215 216 // Does this device even have keys? 217 if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { 218 continue; 219 } 220 if (!test_bit(EV_KEY, ev_bits)) { 221 continue; 222 } 223 224 int rc = ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits); 225 if (rc == -1) { 226 continue; 227 } 228 229 for (int key_code = 0; key_code <= KEY_MAX; ++key_code) { 230 if (test_bit(key_code, key_bits)) { 231 f(key_code); 232 } 233 } 234 } 235} 236 237void ev_iterate_touch_inputs(const std::function<void(int)>& action) { 238 for (size_t i = 0; i < ev_dev_count; ++i) { 239 // Use unsigned long to match ioctl's parameter type. 240 unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)] = {}; // NOLINT 241 if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { 242 continue; 243 } 244 if (!test_bit(EV_ABS, ev_bits)) { 245 continue; 246 } 247 248 unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)] = {}; // NOLINT 249 if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_ABS, KEY_MAX), key_bits) == -1) { 250 continue; 251 } 252 253 for (int key_code = 0; key_code <= KEY_MAX; ++key_code) { 254 if (test_bit(key_code, key_bits)) { 255 action(key_code); 256 } 257 } 258 } 259} 260