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
eventList_findByType(int type)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
eventList_getCount(EventList list)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
eventList_findCodeByName(EventList list,const char * name,int namelen)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*
eventList_bufprintCode(EventList list,int index,char * buf,char * bufend)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
android_event_from_str(const char * name,int * ptype,int * pcode,int * pvalue)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
android_event_get_type_count(void)197 android_event_get_type_count( void )
198 {
199 return eventList_getCount( _ev_types_tab );
200 }
201
202 char*
android_event_bufprint_type_str(char * buff,char * end,int type_index)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
android_event_get_code_count(int type)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*
android_event_bufprint_code_str(char * buff,char * end,int type,int code_index)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