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