6 #include <stdlib.h> /* abs() */
7 #include <linux/input.h> /* struct input_event */
8 #include <sys/select.h>
10 #include <sys/types.h>
12 #include "pnd_device.h"
13 #include "pnd_io_evdev.h"
23 static pnd_evmap_t evmap [ pnd_evdev_max ];
24 static unsigned char evmap_first = 1;
25 static pnd_evdev_e evmapback [ 10 ]; // map fd back to which device
27 unsigned char pnd_evdev_open ( pnd_evdev_e device ) {
29 // if first, reset global struct
31 evmap_first = 0; // don't repeat
33 for ( i = 0; i < pnd_evdev_max; i++ ) {
34 evmap [ i ].fd = -1; // not opened
42 if ( ( evmap [ pnd_evdev_dpads ].fd = pnd_evdev_open_by_name ( PND_EVDEV_GPIO ) ) >= 0 ) {
43 evmapback [ evmap [ pnd_evdev_dpads ].fd ] = pnd_evdev_dpads;
49 if ( ( evmap [ pnd_evdev_nub1 ].fd = pnd_evdev_open_by_name ( PND_EVDEV_NUB1 ) ) >= 0 ) {
50 evmapback [ evmap [ pnd_evdev_nub1 ].fd ] = pnd_evdev_nub1;
56 if ( ( evmap [ pnd_evdev_nub2 ].fd = pnd_evdev_open_by_name ( PND_EVDEV_NUB2 ) ) >= 0 ) {
57 evmapback [ evmap [ pnd_evdev_nub2 ].fd ] = pnd_evdev_nub2;
63 if ( ( evmap [ pnd_evdev_power ].fd = pnd_evdev_open_by_name ( PND_EVDEV_POWER ) ) >= 0 ) {
64 evmapback [ evmap [ pnd_evdev_power ].fd ] = pnd_evdev_power;
70 return ( 0 ); // shutup gcc
73 // error opening, or not supported in this bit of code, or wtf
77 void pnd_evdev_close ( pnd_evdev_e device ) {
79 if ( evmap [ device ].fd >= 0 ) {
80 close ( evmap [ device ].fd ); // close it
81 evmap [ device ].fd = -1; // flag as closed
86 void pnd_evdev_closeall ( void ) {
89 for ( i = 0; i < pnd_evdev_max; i++ ) {
90 pnd_evdev_close ( i );
96 int pnd_evdev_get_fd ( unsigned char device ) {
97 return ( evmap [ device ].fd );
100 int pnd_evdev_open_by_name ( char *devname ) {
103 char name[256] = { 0, };
106 // keep opening event# devices until we run out
107 for ( id = 0; ; id++ ) {
110 snprintf ( fname, sizeof ( fname ), "/dev/input/event%i", id );
112 // try open, or bail out if no more
113 if ( ( fd = open ( fname, O_RDONLY | O_NDELAY ) ) < 0 ) {
117 // fetch the devices name
118 if ( ioctl (fd, EVIOCGNAME(sizeof(name)), name ) < 0 ) {
119 close ( fd ); // couldn't get the name?!
120 continue; // pretty odd to not have a name, but maybe the next device does..
124 if ( strcmp ( name, devname ) == 0 ) {
132 return ( -1 ); // couldn't find it
135 unsigned char pnd_evdev_catchup ( unsigned char blockp ) {
140 // if not blocking, we want a zero duration timeout
143 bzero ( &tv, sizeof(struct timeval) ); // set to 0s, ie: return immediately
154 // for all our open evdev's, flag them in the watch fd list
155 for ( i = 0; i < pnd_evdev_max; i++ ) {
156 if ( evmap [ i ].fd >= 0 ) {
157 // set the fd into the select set
158 FD_SET( evmap [ i ].fd, &fdset );
159 // select(2) needs to know the highest fd
160 if ( evmap [ i ].fd > maxfd ) {
161 maxfd = evmap [ i ].fd;
167 return ( 0 ); // nothing to do
172 ret = select ( maxfd + 1, &fdset, NULL, NULL, ptv );
175 return ( 0 ); // something bad
176 } else if ( ret == 0 ) {
177 return ( 1 ); // all good, nothing here
180 // all good, and something in the queue..
181 for ( i = 0; i < pnd_evdev_max; i++ ) {
183 if ( evmap [ i ].fd >= 0 ) {
184 // if pending in the queue
185 if ( FD_ISSET ( evmap [ i ].fd, &fdset ) ) {
189 struct input_event ev[64];
193 // pull events from the queue; max 64 events
194 rd = read ( fd, ev, sizeof(struct input_event) * 64 );
195 if ( rd < (int) sizeof(struct input_event) ) {
196 // less than a whole event-struct? bad!
200 // for each event in the pulled events, parse it
201 for (j = 0; j < rd / sizeof(struct input_event); j++ ) {
204 if ( ev[j].type == EV_SYN ) {
207 } else if ( ev[j].type == EV_KEY ) {
208 // KEY event -- including dpads
211 // keycode: ev[j].code -> keycode, see linux/input.h
212 // state val: ev[j].value -> 0keyup, 1keydown
214 #if 0 // as of mid-March; notaz did a recent keycode change so had to refigure it out
215 printf ( "evdev\tkey %d\tvalue %d\n", ev[j].code, ev[j].value );
216 // a 102 b 107 x 109 y 104
217 // ltrigger 54 rtrigger 97
218 // start 56 select 29 pandora 139
221 unsigned int state = evmap [ pnd_evdev_dpads ].state.buttons;
223 switch ( ev[j].code ) {
225 case KEY_UP: state &= ~pnd_evdev_up; if ( ev[j].value ) state |= pnd_evdev_up; break;
226 case KEY_DOWN: state &= ~pnd_evdev_down; if ( ev[j].value ) state |= pnd_evdev_down; break;
227 case KEY_LEFT: state &= ~pnd_evdev_left; if ( ev[j].value ) state |= pnd_evdev_left; break;
228 case KEY_RIGHT: state &= ~pnd_evdev_right; if ( ev[j].value ) state |= pnd_evdev_right; break;
229 case KEY_PAGEDOWN: /*KEY_X*/ state &= ~pnd_evdev_x; if ( ev[j].value ) state |= pnd_evdev_x; break;
230 case KEY_PAGEUP: /*KEY_Y*/ state &= ~pnd_evdev_y; if ( ev[j].value ) state |= pnd_evdev_y; break;
231 case KEY_HOME: /*KEY_A*/ state &= ~pnd_evdev_a; if ( ev[j].value ) state |= pnd_evdev_a; break;
232 case KEY_END: /*KEY_B*/ state &= ~pnd_evdev_b; if ( ev[j].value ) state |= pnd_evdev_b; break;
234 case KEY_RIGHTSHIFT: // ltrigger
235 state &= ~pnd_evdev_ltrigger; if ( ev[j].value ) state |= pnd_evdev_ltrigger; break;
236 case KEY_RIGHTCTRL: // rtrigger
237 state &= ~pnd_evdev_rtrigger; if ( ev[j].value ) state |= pnd_evdev_rtrigger; break;
242 case KEY_LEFTALT: state &= ~pnd_evdev_start; if ( ev[j].value ) state |= pnd_evdev_start; break;
243 case KEY_LEFTCTRL: state &= ~pnd_evdev_select; if ( ev[j].value ) state |= pnd_evdev_select; break;
244 case KEY_MENU: state &= ~pnd_evdev_pandora; if ( ev[j].value ) state |= pnd_evdev_pandora; break;
248 evmap [ pnd_evdev_dpads ].state.buttons = state;
250 } else if ( ev[j].type == EV_SW ) {
253 } else if ( ev[j].type == EV_ABS ) {
256 // vsense66 -> nub1 (left)
257 // vsense67 -> nub2 (right)
258 pnd_nubstate_t *pn = NULL;
259 if ( evmapback [ fd ] == pnd_evdev_nub1 ) {
260 pn = &( evmap [ pnd_evdev_nub1 ].state.nub );
262 pn = &( evmap [ pnd_evdev_nub2 ].state.nub );
265 if ( ev[j].code == ABS_X ) {
266 pn -> x = ev[j].value;
267 } else if ( ev[j].code == ABS_Y ) {
268 pn -> y = ev[j].value;
270 //printf("unexpected EV_ABS code: %i\n", ev[i].code);
278 } // for each pulled event
282 } // for all device..
287 unsigned int pnd_evdev_dpad_state ( pnd_evdev_e device ) {
288 if ( evmap [ device ].fd < 0 ) {
291 return ( evmap [ device ].state.buttons );
294 int pnd_evdev_nub_state ( pnd_evdev_e nubdevice, pnd_nubstate_t *r_nubstate ) {
295 if ( evmap [ nubdevice ].fd < 0 ) {
298 memcpy ( r_nubstate, &(evmap [ nubdevice ].state.nub), sizeof(pnd_nubstate_t) );