Home | History | Annotate | Download | only in android
      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