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 != 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 *pcode = eventList_findCodeByName( list, p, q-p );
171 if (*pcode < 0) {
172 *pcode = (int) strtol( p, &end, 0 );
173 if (end != q)
174 return -2;
175 }
176
177 if (*q != ':')
178 return 0;
179
180 p = q + 1;
181 q = strchr(p, ':');
182 if (q == NULL || q > pend)
183 q = pend;
184
185 *pvalue = (int)strtol( p, &end, 0 );
186 if (end != q)
187 return -3;
188
189 return 0;
190 }
191
192 int
android_event_get_type_count(void)193 android_event_get_type_count( void )
194 {
195 return eventList_getCount( _ev_types_tab );
196 }
197
198 char*
android_event_bufprint_type_str(char * buff,char * end,int type_index)199 android_event_bufprint_type_str( char* buff, char* end, int type_index )
200 {
201 return eventList_bufprintCode( _ev_types_tab, type_index, buff, end );
202 }
203
204 /* returns the list of valid event code string aliases for a given event type */
205 int
android_event_get_code_count(int type)206 android_event_get_code_count( int type )
207 {
208 EventList list = eventList_findByType(type);
209
210 return eventList_getCount(list);
211 }
212
213 char*
android_event_bufprint_code_str(char * buff,char * end,int type,int code_index)214 android_event_bufprint_code_str( char* buff, char* end, int type, int code_index )
215 {
216 EventList list = eventList_findByType(type);
217
218 return eventList_bufprintCode(list, code_index, buff, end);
219 }
220
221