#include "../gp2x/gp2x.h"
-#define PBTN_UP 0
-#define PBTN_DOWN 0
-#define PBTN_LEFT 0
-#define PBTN_RIGHT 0
-
-#define PBTN_NORTH 0
-#define PBTN_SOUTH 0
-#define PBTN_WEST 0
-#define PBTN_EAST 0
-#define PBTN_L 0
-#define PBTN_R 0
+#define PBTN_UP (1 << 0)
+#define PBTN_DOWN (1 << 1)
+#define PBTN_LEFT (1 << 2)
+#define PBTN_RIGHT (1 << 3)
+
+#define PBTN_NORTH (1 << 4)
+#define PBTN_SOUTH (1 << 5)
+#define PBTN_WEST (1 << 6)
+#define PBTN_EAST (1 << 7)
+#define PBTN_L (1 << 8)
+#define PBTN_R (1 << 9)
unsigned long wait_for_input(unsigned long interesting);
void gp2x_pd_clone_buffer2(void);
#include <string.h>
#include "input.h"
-#include "../linux/event.h"
+#include "../linux/in_evdev.h"
typedef struct
{
static int in_bind_count(int drv_id)
{
int count = 0;
-#ifdef IN_EVDEV
if (drv_id == IN_DRVID_EVDEV)
count = in_evdev_bind_count();
-#endif
if (count <= 0)
printf("input: failed to get bind count for drv %d\n", drv_id);
static void in_free(in_dev_t *dev)
{
if (dev->probed) {
-#ifdef IN_EVDEV
if (dev->drv_id == IN_DRVID_EVDEV)
in_evdev_free(dev->drv_data);
-#endif
}
dev->probed = 0;
dev->drv_data = NULL;
for (i = 0; i < in_dev_count; i++)
in_devices[i].probed = 0;
-#ifdef IN_EVDEV
in_evdev_probe();
-#endif
/* get rid of devs without binds and probes */
for (i = 0; i < in_dev_count; i++) {
for (i = 0; i < in_dev_count; i++) {
if (in_devices[i].probed && in_devices[i].binds != NULL) {
-#ifdef IN_EVDEV
- result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
-#endif
+ if (in_devices[i].drv_id == IN_DRVID_EVDEV)
+ result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
}
}
return result;
}
+/*
+ * update with wait for a press, return bitfield of BTN_*
+ * only can use 1 drv here..
+ */
+int in_update_menu(void)
+{
+ int result = 0;
+#ifdef IN_EVDEV
+ void *data[IN_MAX_DEVS];
+ int i, count = 0;
+
+ for (i = 0; i < in_dev_count; i++) {
+ if (in_devices[i].probed)
+ data[count++] = in_devices[i].drv_data;
+ }
+
+ if (count == 0) {
+ /* don't deadlock, fail */
+ printf("input: failed to find devices to read\n");
+ exit(1);
+ }
+
+ result = in_evdev_update_menu(data, count);
+#else
+#error no menu read handlers
+#endif
+
+ return result;
+}
+
void in_init(void)
{
memset(in_devices, 0, sizeof(in_devices));
int main(void)
{
+ int ret;
+
in_init();
in_probe();
while (1) {
- in_update();
+ ret = in_update_menu();
+ printf("%08x\n", ret);
sleep(1);
}
-#define IN_DRVID_EVDEV 1
+enum {
+ IN_DRVID_EVDEV = 1,
+};
/* to be called by drivers */
void in_register(const char *nname, int drv_id, void *drv_data);
#include <linux/input.h>
#include <errno.h>
+#include "../common/common.h"
#include "../common/input.h"
-#include "event.h"
+#include "in_evdev.h"
#define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
(1 << ((x) & (sizeof(keybits[0])*8-1))))
return result;
}
+int in_evdev_update_menu(void **data, int count)
+{
+ const int *fds = (const int *)data;
+ static int result = 0;
+ int i, ret, fdmax = -1;
+ int oldresult = result;
+ long flags;
+
+ /* switch to blocking mode */
+ for (i = 0; i < count; i++) {
+ if (fds[i] > fdmax) fdmax = fds[i];
+
+ flags = (long)fcntl(fds[i], F_GETFL);
+ if ((int)flags == -1) {
+ perror("in_evdev: F_GETFL fcntl failed");
+ continue;
+ }
+ flags &= ~O_NONBLOCK;
+ ret = fcntl(fds[i], F_SETFL, flags);
+ if (ret == -1)
+ perror("in_evdev: F_SETFL fcntl failed");
+ }
+
+ while (1)
+ {
+ struct input_event ev[64];
+ int fd, rd;
+ fd_set fdset;
+
+ FD_ZERO(&fdset);
+ for (i = 0; i < count; i++)
+ FD_SET(fds[i], &fdset);
+
+ ret = select(fdmax + 1, &fdset, NULL, NULL, NULL);
+ if (ret == -1)
+ {
+ perror("in_evdev: select failed");
+ sleep(1);
+ return 0;
+ }
+
+ for (i = 0; i < count; i++)
+ if (FD_ISSET(fds[i], &fdset))
+ fd = fds[i];
+
+ rd = read(fd, ev, sizeof(ev[0]) * 64);
+ if (rd < (int) sizeof(ev[0])) {
+ perror("in_evdev: error reading");
+ sleep(1);
+ return 0;
+ }
+
+ #define mapkey(o,k) \
+ case o: \
+ if (ev[i].value) result |= k; \
+ else result &= ~k; \
+ break
+ for (i = 0; i < rd / sizeof(ev[0]); i++)
+ {
+ if (ev[i].type != EV_KEY || ev[i].value < 0 || ev[i].value > 1)
+ continue;
+
+ switch (ev[i].code) {
+ /* keyboards */
+ mapkey(KEY_UP, PBTN_UP);
+ mapkey(KEY_DOWN, PBTN_DOWN);
+ mapkey(KEY_LEFT, PBTN_LEFT);
+ mapkey(KEY_RIGHT, PBTN_RIGHT);
+ mapkey(KEY_ENTER, PBTN_EAST);
+ mapkey(KEY_ESC, PBTN_SOUTH);
+ }
+ }
+ #undef mapkey
+
+ if (oldresult != result) break;
+ }
+
+ /* switch back to non-blocking mode */
+ for (i = 0; i < count; i++) {
+ if (fds[i] > fdmax) fdmax = fds[i];
+
+ flags = (long)fcntl(fds[i], F_GETFL);
+ if ((int)flags == -1) {
+ perror("in_evdev: F_GETFL fcntl failed");
+ continue;
+ }
+ flags |= O_NONBLOCK;
+ ret = fcntl(fds[i], F_SETFL, flags);
+ if (ret == -1)
+ perror("in_evdev: F_SETFL fcntl failed");
+ }
+
+ return result;
+}
+
+
+#ifdef IN_EVDEV
+
int in_evdev_probe(void);
void in_evdev_free(void *drv_data);
int in_evdev_bind_count(void);
int in_evdev_update(void *drv_data, int *binds);
+
+#else
+
+#define in_evdev_probe() -1
+#define in_evdev_free(x)
+#define in_evdev_bind_count() 0
+#define in_evdev_update(x,y) 0
+
+#endif
+
+int in_evdev_update_menu(void **data, int count);
+