1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #include "android/hw-events.h" 13 #include "android/utils/bufprint.h" 14 #include <stdlib.h> 15 #include <string.h> 16 17 typedef struct { 18 const char* name; 19 int value; 20 } EventInfo; 21 22 #define EV_TYPE(n,v) { "EV_" STRINGIFY(n), (v) }, 23 24 #define BTN_CODE(n,v) { "BTN_" STRINGIFY(n), (v) }, 25 #define KEY_CODE(n,v) { "KEY_" STRINGIFY(n), (v) }, 26 #define REL_CODE(n,v) { "REL_" STRINGIFY(n), (v) }, 27 #define ABS_CODE(n,v) { "ABS_" STRINGIFY(n), (v) }, 28 #define END_CODE { NULL, 0 } 29 30 static const EventInfo _ev_types_tab[] = 31 { 32 EVENT_TYPE_LIST 33 END_CODE 34 }; 35 36 static const EventInfo _key_codes_list[] = 37 { 38 EVENT_KEY_LIST 39 EVENT_BTN_LIST 40 END_CODE 41 }; 42 43 static const EventInfo _rel_codes_list[] = 44 { 45 EVENT_REL_LIST 46 END_CODE 47 }; 48 static const EventInfo _abs_codes_list[] = 49 { 50 EVENT_ABS_LIST 51 END_CODE 52 }; 53 54 #undef EV_TYPE 55 #undef BTN_CODE 56 #undef KEY_CODE 57 #undef REL_CODE 58 #undef ABS_CODE 59 60 typedef const EventInfo* EventList; 61 62 typedef struct { 63 int type; 64 const EventInfo* table; 65 } EventCodeList; 66 67 68 static const EventCodeList _codes[] = { 69 { EV_KEY, _key_codes_list }, 70 { EV_REL, _rel_codes_list }, 71 { EV_ABS, _abs_codes_list }, 72 { -1, NULL } 73 }; 74 75 static EventList 76 eventList_findByType( int type ) 77 { 78 int nn; 79 80 for (nn = 0; _codes[nn].type >= 0; nn++) { 81 if (_codes[nn].type == type) 82 return _codes[nn].table; 83 } 84 return NULL; 85 } 86 87 static int 88 eventList_getCount( EventList list ) 89 { 90 int nn; 91 92 if (list == NULL) 93 return 0; 94 95 for (nn = 0; list[nn].name != NULL; nn++) { 96 /* nothing */ 97 } 98 return nn; 99 } 100 101 static int 102 eventList_findCodeByName( EventList list, 103 const char* name, 104 int namelen ) 105 { 106 if (namelen <= 0) 107 return -1; 108 109 for ( ; list->name != NULL; list += 1 ) { 110 if ( !memcmp(name, list->name, namelen) && 111 list->name[namelen] == 0 ) 112 { 113 return list->value; 114 } 115 } 116 return -1; 117 } 118 119 static char* 120 eventList_bufprintCode( EventList list, 121 int index, 122 char* buf, 123 char* bufend ) 124 { 125 if (list == NULL) 126 return buf; 127 128 return bufprint(buf, bufend, "%s", list[index].name); 129 } 130 131 132 int 133 android_event_from_str( const char* name, 134 int *ptype, 135 int *pcode, 136 int *pvalue ) 137 { 138 const char* p; 139 const char* pend; 140 const char* q; 141 EventList list; 142 char* end; 143 144 *ptype = 0; 145 *pcode = 0; 146 *pvalue = 0; 147 148 p = name; 149 pend = p + strcspn(p, " \t"); 150 q = strchr(p, ':'); 151 if (q == NULL || q > pend) 152 q = pend; 153 154 *ptype = eventList_findCodeByName( _ev_types_tab, p, q-p ); 155 if (*ptype < 0) { 156 *ptype = (int) strtol( p, &end, 0 ); 157 if (end != q) 158 return -1; 159 } 160 161 if (*q != ':') 162 return 0; 163 164 p = q + 1; 165 q = strchr(p, ':'); 166 if (q == NULL || q > pend) 167 q = pend; 168 169 list = eventList_findByType( *ptype ); 170 if (list == NULL) { 171 *pcode = -1; 172 } else { 173 *pcode = eventList_findCodeByName( list, p, q-p ); 174 } 175 if (*pcode < 0) { 176 *pcode = (int) strtol( p, &end, 0 ); 177 if (end != q) 178 return -2; 179 } 180 181 if (*q != ':') 182 return 0; 183 184 p = q + 1; 185 q = strchr(p, ':'); 186 if (q == NULL || q > pend) 187 q = pend; 188 189 *pvalue = (int)strtol( p, &end, 0 ); 190 if (end != q) 191 return -3; 192 193 return 0; 194 } 195 196 int 197 android_event_get_type_count( void ) 198 { 199 return eventList_getCount( _ev_types_tab ); 200 } 201 202 char* 203 android_event_bufprint_type_str( char* buff, char* end, int type_index ) 204 { 205 return eventList_bufprintCode( _ev_types_tab, type_index, buff, end ); 206 } 207 208 /* returns the list of valid event code string aliases for a given event type */ 209 int 210 android_event_get_code_count( int type ) 211 { 212 EventList list = eventList_findByType(type); 213 214 return eventList_getCount(list); 215 } 216 217 char* 218 android_event_bufprint_code_str( char* buff, char* end, int type, int code_index ) 219 { 220 EventList list = eventList_findByType(type); 221 222 return eventList_bufprintCode(list, code_index, buff, end); 223 } 224 225