mirror of
https://github.com/RaySollium99/libpicofe.git
synced 2025-09-05 14:57:46 -04:00
asyn-only dev support + in_gp2x driver
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@637 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
7f022a8d57
commit
13b692eb4e
9 changed files with 334 additions and 36 deletions
104
common/input.c
104
common/input.c
|
@ -5,6 +5,7 @@
|
|||
#include "common.h"
|
||||
#include "input.h"
|
||||
#include "../linux/in_evdev.h"
|
||||
#include "../gp2x/in_gp2x.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -19,9 +20,11 @@ typedef struct
|
|||
static in_drv_t in_drivers[IN_DRVID_COUNT];
|
||||
static in_dev_t in_devices[IN_MAX_DEVS];
|
||||
static int in_dev_count = 0;
|
||||
static int in_have_async_devs = 0;
|
||||
|
||||
#define DRV(id) in_drivers[(unsigned)(id) < IN_DRVID_COUNT ? (id) : 0]
|
||||
|
||||
|
||||
static int in_bind_count(int drv_id)
|
||||
{
|
||||
int count = DRV(drv_id).get_bind_count();
|
||||
|
@ -61,7 +64,8 @@ static void in_free(in_dev_t *dev)
|
|||
dev->binds = NULL;
|
||||
}
|
||||
|
||||
/* to be called by drivers */
|
||||
/* to be called by drivers
|
||||
* async devices must set drv_fd_hnd to -1 */
|
||||
void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data)
|
||||
{
|
||||
int i, ret, dupe_count = 0, *binds;
|
||||
|
@ -133,6 +137,8 @@ update:
|
|||
void in_probe(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
in_have_async_devs = 0;
|
||||
for (i = 0; i < in_dev_count; i++)
|
||||
in_devices[i].probed = 0;
|
||||
|
||||
|
@ -148,8 +154,16 @@ void in_probe(void)
|
|||
memmove(&in_devices[i], &in_devices[i+1],
|
||||
(in_dev_count - i) * sizeof(in_devices[0]));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_devices[i].probed && in_devices[i].drv_fd_hnd == -1)
|
||||
in_have_async_devs = 1;
|
||||
}
|
||||
|
||||
if (in_have_async_devs)
|
||||
printf("input: async-only devices detected..\n");
|
||||
}
|
||||
|
||||
/* async update */
|
||||
|
@ -165,6 +179,11 @@ int in_update(void)
|
|||
case IN_DRVID_EVDEV:
|
||||
result |= in_evdev_update(dev->drv_data, dev->binds);
|
||||
break;
|
||||
#endif
|
||||
#ifdef IN_GP2X
|
||||
case IN_DRVID_GP2X:
|
||||
result |= in_gp2x_update(dev->drv_data, dev->binds);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -177,23 +196,69 @@ static int menu_key_state = 0;
|
|||
|
||||
void in_set_blocking(int is_blocking)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < in_dev_count; i++) {
|
||||
if (in_devices[i].probed)
|
||||
DRV(in_devices[i].drv_id).set_blocking(in_devices[i].drv_data, is_blocking);
|
||||
/* have_async_devs means we will have to do all reads async anyway.. */
|
||||
if (!in_have_async_devs) {
|
||||
for (i = 0; i < in_dev_count; i++) {
|
||||
if (in_devices[i].probed)
|
||||
DRV(in_devices[i].drv_id).set_blocking(in_devices[i].drv_data, is_blocking);
|
||||
}
|
||||
}
|
||||
|
||||
menu_key_state = 0;
|
||||
|
||||
/* flush events */
|
||||
in_update_keycode(NULL, NULL, 0);
|
||||
do {
|
||||
ret = in_update_keycode(NULL, NULL, 0);
|
||||
} while (ret >= 0);
|
||||
}
|
||||
|
||||
/* TODO: move.. */
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
static int in_update_kc_async(int *dev_id_out, int *is_down_out, int timeout_ms)
|
||||
{
|
||||
struct timeval start, now;
|
||||
int i, is_down, result;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
|
||||
while (1)
|
||||
{
|
||||
for (i = 0; i < in_dev_count; i++) {
|
||||
in_dev_t *d = &in_devices[i];
|
||||
if (!d->probed)
|
||||
continue;
|
||||
|
||||
result = DRV(d->drv_id).update_keycode(d->drv_data, &is_down);
|
||||
if (result == -1)
|
||||
continue;
|
||||
|
||||
if (dev_id_out)
|
||||
*dev_id_out = i;
|
||||
if (is_down_out)
|
||||
*is_down_out = is_down;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (timeout_ms >= 0) {
|
||||
gettimeofday(&now, NULL);
|
||||
if ((now.tv_sec - start.tv_sec) * 1000 +
|
||||
(now.tv_usec - start.tv_usec) / 1000 > timeout_ms)
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* update with wait for a press, always return some keycode
|
||||
* wait for a press, always return some keycode or -1 on timeout or error
|
||||
*/
|
||||
int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms)
|
||||
{
|
||||
|
@ -202,6 +267,14 @@ int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms)
|
|||
int i, ret, count = 0;
|
||||
in_drv_t *drv;
|
||||
|
||||
if (in_have_async_devs) {
|
||||
result = in_update_kc_async(&dev_id, &is_down, timeout_ms);
|
||||
if (result == -1)
|
||||
return -1;
|
||||
drv = &DRV(in_devices[dev_id].drv_id);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
for (i = 0; i < in_dev_count; i++) {
|
||||
if (in_devices[i].probed)
|
||||
fds_hnds[count++] = in_devices[i].drv_fd_hnd;
|
||||
|
@ -237,11 +310,11 @@ again:
|
|||
{
|
||||
perror("input: select failed");
|
||||
sleep(1);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
return 0; /* timeout */
|
||||
return -1; /* timeout */
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (FD_ISSET(fds_hnds[i], &fdset))
|
||||
|
@ -258,12 +331,13 @@ again:
|
|||
drv = &DRV(in_devices[dev_id].drv_id);
|
||||
result = drv->update_keycode(in_devices[dev_id].drv_data, &is_down);
|
||||
|
||||
/* update_keycode() might return 0 when some not interesting
|
||||
/* update_keycode() might return -1 when some not interesting
|
||||
* event happened, like sync event for evdev.
|
||||
* XXX: timeout restarts.. */
|
||||
if (result == 0)
|
||||
if (result == -1)
|
||||
goto again;
|
||||
|
||||
finish:
|
||||
/* keep track of menu key state, to allow mixing
|
||||
* in_update_keycode() and in_menu_wait_any() calls */
|
||||
result_menu = drv->menu_translate(result);
|
||||
|
@ -291,11 +365,12 @@ int in_menu_wait_any(int timeout_ms)
|
|||
int code, is_down = 0, dev_id = 0;
|
||||
|
||||
code = in_update_keycode(&dev_id, &is_down, timeout_ms);
|
||||
code = DRV(in_devices[dev_id].drv_id).menu_translate(code);
|
||||
if (code >= 0)
|
||||
code = DRV(in_devices[dev_id].drv_id).menu_translate(code);
|
||||
|
||||
if (timeout_ms >= 0)
|
||||
break;
|
||||
if (code == 0)
|
||||
if (code < 0)
|
||||
continue;
|
||||
if (keys_old != menu_key_state)
|
||||
break;
|
||||
|
@ -633,6 +708,9 @@ void in_init(void)
|
|||
in_drivers[i].get_key_name = in_def_get_key_name;
|
||||
}
|
||||
|
||||
#ifdef IN_GP2X
|
||||
in_gp2x_init(&in_drivers[IN_DRVID_GP2X]);
|
||||
#endif
|
||||
#ifdef IN_EVDEV
|
||||
in_evdev_init(&in_drivers[IN_DRVID_EVDEV]);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue