/* Copyright (C) 2007-2008 The Android Open Source Project ** ** This software is licensed under the terms of the GNU General Public ** License version 2, as published by the Free Software Foundation, and ** may be copied, distributed, and modified under those terms. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. */ #include "android/hw-events.h" #include "android/utils/bufprint.h" #include #include typedef struct { const char* name; int value; } EventInfo; #define EV_TYPE(n,v) { "EV_" STRINGIFY(n), (v) }, #define BTN_CODE(n,v) { "BTN_" STRINGIFY(n), (v) }, #define KEY_CODE(n,v) { "KEY_" STRINGIFY(n), (v) }, #define REL_CODE(n,v) { "REL_" STRINGIFY(n), (v) }, #define ABS_CODE(n,v) { "ABS_" STRINGIFY(n), (v) }, #define END_CODE { NULL, 0 } static const EventInfo _ev_types_tab[] = { EVENT_TYPE_LIST END_CODE }; static const EventInfo _key_codes_list[] = { EVENT_KEY_LIST EVENT_BTN_LIST END_CODE }; static const EventInfo _rel_codes_list[] = { EVENT_REL_LIST END_CODE }; static const EventInfo _abs_codes_list[] = { EVENT_ABS_LIST END_CODE }; #undef EV_TYPE #undef BTN_CODE #undef KEY_CODE #undef REL_CODE #undef ABS_CODE typedef const EventInfo* EventList; typedef struct { int type; const EventInfo* table; } EventCodeList; static const EventCodeList _codes[] = { { EV_KEY, _key_codes_list }, { EV_REL, _rel_codes_list }, { EV_ABS, _abs_codes_list }, { -1, NULL } }; static EventList eventList_findByType( int type ) { int nn; for (nn = 0; _codes[nn].type >= 0; nn++) { if (_codes[nn].type == type) return _codes[nn].table; } return NULL; } static int eventList_getCount( EventList list ) { int nn; if (list == NULL) return 0; for (nn = 0; list[nn].name != NULL; nn++) { /* nothing */ } return nn; } static int eventList_findCodeByName( EventList list, const char* name, int namelen ) { if (namelen <= 0) return -1; for ( ; list->name != NULL; list += 1 ) { if ( !memcmp(name, list->name, namelen) && list->name[namelen] == 0 ) { return list->value; } } return -1; } static char* eventList_bufprintCode( EventList list, int index, char* buf, char* bufend ) { if (list == NULL) return buf; return bufprint(buf, bufend, "%s", list[index].name); } int android_event_from_str( const char* name, int *ptype, int *pcode, int *pvalue ) { const char* p; const char* pend; const char* q; EventList list; char* end; *ptype = 0; *pcode = 0; *pvalue = 0; p = name; pend = p + strcspn(p, " \t"); q = strchr(p, ':'); if (q == NULL || q > pend) q = pend; *ptype = eventList_findCodeByName( _ev_types_tab, p, q-p ); if (*ptype < 0) { *ptype = (int) strtol( p, &end, 0 ); if (end != q) return -1; } if (*q != ':') return 0; p = q + 1; q = strchr(p, ':'); if (q == NULL || q > pend) q = pend; list = eventList_findByType( *ptype ); if (list == NULL) { *pcode = -1; } else { *pcode = eventList_findCodeByName( list, p, q-p ); } if (*pcode < 0) { *pcode = (int) strtol( p, &end, 0 ); if (end != q) return -2; } if (*q != ':') return 0; p = q + 1; q = strchr(p, ':'); if (q == NULL || q > pend) q = pend; *pvalue = (int)strtol( p, &end, 0 ); if (end != q) return -3; return 0; } int android_event_get_type_count( void ) { return eventList_getCount( _ev_types_tab ); } char* android_event_bufprint_type_str( char* buff, char* end, int type_index ) { return eventList_bufprintCode( _ev_types_tab, type_index, buff, end ); } /* returns the list of valid event code string aliases for a given event type */ int android_event_get_code_count( int type ) { EventList list = eventList_findByType(type); return eventList_getCount(list); } char* android_event_bufprint_code_str( char* buff, char* end, int type, int code_index ) { EventList list = eventList_findByType(type); return eventList_bufprintCode(list, code_index, buff, end); }