mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
more input layer tweaks
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@627 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
819ef02513
commit
f484a9fe4f
4 changed files with 165 additions and 59 deletions
|
@ -9,8 +9,9 @@ typedef struct
|
|||
{
|
||||
int drv_id;
|
||||
void *drv_data;
|
||||
int *binds;
|
||||
char *name;
|
||||
int *binds;
|
||||
int prev_result;
|
||||
int probed:1;
|
||||
} in_dev_t;
|
||||
|
||||
|
@ -154,11 +155,19 @@ int in_update(void)
|
|||
int i, result = 0;
|
||||
|
||||
for (i = 0; i < in_dev_count; i++) {
|
||||
if (in_devices[i].probed && in_devices[i].binds != NULL) {
|
||||
switch (in_devices[i].drv_id) {
|
||||
in_dev_t *dev = &in_devices[i];
|
||||
int ret;
|
||||
if (dev->probed && dev->binds != NULL) {
|
||||
switch (dev->drv_id) {
|
||||
#ifdef IN_EVDEV
|
||||
case IN_DRVID_EVDEV:
|
||||
result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
|
||||
ret = in_evdev_update(dev->drv_data, dev->binds);
|
||||
if (ret == -1) /* no change */
|
||||
result |= dev->prev_result;
|
||||
else {
|
||||
dev->prev_result = ret;
|
||||
result |= ret;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -181,6 +190,8 @@ static void **in_collect_drvdata(int drv_id, int *count)
|
|||
return data;
|
||||
}
|
||||
|
||||
static int menu_key_state = 0;
|
||||
|
||||
void in_set_blocking(int is_blocking)
|
||||
{
|
||||
int i;
|
||||
|
@ -188,16 +199,21 @@ void in_set_blocking(int is_blocking)
|
|||
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);
|
||||
in_devices[i].prev_result = 0;
|
||||
}
|
||||
|
||||
menu_key_state = 0;
|
||||
/* flush events */
|
||||
in_update_keycode(NULL, NULL, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* update with wait for a press, return keycode
|
||||
* only can use 1 drv here..
|
||||
*/
|
||||
int in_update_keycode(int *dev_id, int *is_down)
|
||||
int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms)
|
||||
{
|
||||
int result = 0;
|
||||
int result = 0, dev_id, is_down, result_menu;
|
||||
#ifdef IN_EVDEV
|
||||
void **data;
|
||||
int i, id = 0, count = 0;
|
||||
|
@ -209,48 +225,58 @@ int in_update_keycode(int *dev_id, int *is_down)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
result = in_evdev_update_keycode(data, count, &id, is_down);
|
||||
result = in_evdev_update_keycode(data, count, &id, &is_down, timeout_ms);
|
||||
|
||||
if (dev_id != NULL) {
|
||||
for (i = id; i < in_dev_count; i++) {
|
||||
if (in_devices[i].drv_data == data[id]) {
|
||||
*dev_id = i;
|
||||
break;
|
||||
}
|
||||
for (i = id; i < in_dev_count; i++) {
|
||||
if (in_devices[i].drv_data == data[id]) {
|
||||
dev_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error no menu read handlers
|
||||
#endif
|
||||
|
||||
/* keep track of menu key state, to allow mixing
|
||||
* in_update_keycode() and in_update_menu() calls */
|
||||
result_menu = DRV(in_devices[dev_id].drv_id).menu_translate(result);
|
||||
if (result_menu != 0) {
|
||||
if (is_down)
|
||||
menu_key_state |= result_menu;
|
||||
else
|
||||
menu_key_state &= ~result_menu;
|
||||
}
|
||||
|
||||
if (dev_id_out != NULL)
|
||||
*dev_id_out = dev_id;
|
||||
if (is_down_out != NULL)
|
||||
*is_down_out = is_down;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as above, only return bitfield of BTN_*
|
||||
*/
|
||||
int in_update_menu(void)
|
||||
int in_update_menu(int timeout_ms)
|
||||
{
|
||||
static int keys_active = 0;
|
||||
int keys_old = keys_active;
|
||||
int keys_old = menu_key_state;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int code, is_down = 0, dev_id = 0;
|
||||
code = in_update_keycode(&dev_id, &is_down);
|
||||
|
||||
code = in_update_keycode(&dev_id, &is_down, timeout_ms);
|
||||
code = DRV(in_devices[dev_id].drv_id).menu_translate(code);
|
||||
if (code == 0) continue;
|
||||
|
||||
if (is_down)
|
||||
keys_active |= code;
|
||||
else
|
||||
keys_active &= ~code;
|
||||
|
||||
if (keys_old != keys_active)
|
||||
if (timeout_ms != 0)
|
||||
break;
|
||||
if (code == 0)
|
||||
continue;
|
||||
if (keys_old != menu_key_state)
|
||||
break;
|
||||
}
|
||||
|
||||
return keys_active;
|
||||
return menu_key_state;
|
||||
}
|
||||
|
||||
const int *in_get_dev_binds(int dev_id)
|
||||
|
@ -288,12 +314,61 @@ const char *in_get_dev_name(int dev_id)
|
|||
return in_devices[dev_id].name;
|
||||
}
|
||||
|
||||
/* never returns NULL */
|
||||
const char *in_get_key_name(int dev_id, int keycode)
|
||||
{
|
||||
static char xname[16];
|
||||
const char *name;
|
||||
|
||||
if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
|
||||
return "Unkn0";
|
||||
|
||||
return DRV(in_devices[dev_id].drv_id).get_key_name(keycode);
|
||||
name = DRV(in_devices[dev_id].drv_id).get_key_name(keycode);
|
||||
if (name != NULL)
|
||||
return name;
|
||||
|
||||
/* assume scancode */
|
||||
if ((keycode >= '0' && keycode <= '9') || (keycode >= 'a' && keycode <= 'z')
|
||||
|| (keycode >= 'A' && keycode <= 'Z'))
|
||||
sprintf(xname, "%c", keycode);
|
||||
else
|
||||
sprintf(xname, "\\x%02X", keycode);
|
||||
return xname;
|
||||
}
|
||||
|
||||
int in_bind_key(int dev_id, int keycode, int mask, int force_unbind)
|
||||
{
|
||||
int ret, count;
|
||||
in_dev_t *dev;
|
||||
|
||||
if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
|
||||
return -1;
|
||||
dev = &in_devices[dev_id];
|
||||
|
||||
if (dev->binds == NULL) {
|
||||
if (force_unbind)
|
||||
return 0;
|
||||
dev->binds = in_alloc_binds(dev->drv_id);
|
||||
if (dev->binds == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
count = in_bind_count(dev->drv_id);
|
||||
if (keycode < 0 || keycode >= count)
|
||||
return -1;
|
||||
|
||||
if (force_unbind)
|
||||
dev->binds[keycode] &= ~mask;
|
||||
else
|
||||
dev->binds[keycode] ^= mask;
|
||||
|
||||
ret = DRV(dev->drv_id).clean_binds(dev->drv_data, dev->binds);
|
||||
if (ret == 0) {
|
||||
free(dev->binds);
|
||||
dev->binds = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns device id, or -1 on error */
|
||||
|
@ -354,11 +429,11 @@ void in_config_start(void)
|
|||
for (i = 0; i < IN_MAX_DEVS; i++) {
|
||||
int n, count, *binds, *def_binds;
|
||||
|
||||
if (in_devices[i].binds == NULL)
|
||||
binds = in_devices[i].binds;
|
||||
if (binds == NULL)
|
||||
continue;
|
||||
|
||||
count = in_bind_count(in_devices[i].drv_id);
|
||||
binds = in_devices[i].binds;
|
||||
def_binds = binds + count;
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
|
@ -369,27 +444,46 @@ void in_config_start(void)
|
|||
|
||||
int in_config_bind_key(int dev_id, const char *key, int binds)
|
||||
{
|
||||
int kc;
|
||||
int count, kc;
|
||||
in_dev_t *dev;
|
||||
|
||||
if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
|
||||
return -1;
|
||||
dev = &in_devices[dev_id];
|
||||
|
||||
if (in_devices[dev_id].binds == NULL) {
|
||||
in_devices[dev_id].binds = in_alloc_binds(in_devices[dev_id].drv_id);
|
||||
if (in_devices[dev_id].binds == NULL)
|
||||
return -1;
|
||||
in_config_start();
|
||||
count = in_bind_count(dev->drv_id);
|
||||
|
||||
/* maybe a raw code? */
|
||||
if (key[0] == '\\' && key[1] == 'x') {
|
||||
char *p = NULL;
|
||||
kc = (int)strtoul(key + 2, &p, 16);
|
||||
if (p == NULL || *p != 0)
|
||||
kc = -1;
|
||||
}
|
||||
else {
|
||||
/* device specific key name */
|
||||
if (dev->binds == NULL) {
|
||||
dev->binds = in_alloc_binds(dev->drv_id);
|
||||
if (dev->binds == NULL)
|
||||
return -1;
|
||||
in_config_start();
|
||||
}
|
||||
|
||||
kc = DRV(dev->drv_id).get_key_code(key);
|
||||
if (kc < 0 && strlen(key) == 1) {
|
||||
/* assume scancode */
|
||||
kc = key[0];
|
||||
}
|
||||
}
|
||||
|
||||
kc = DRV(in_devices[dev_id].drv_id).get_key_code(key);
|
||||
if (kc < 0) {
|
||||
if (kc < 0 || kc >= count) {
|
||||
printf("input: bad key: %s\n", key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in_devices[dev_id].binds[kc] == -1)
|
||||
in_devices[dev_id].binds[kc] = 0;
|
||||
in_devices[dev_id].binds[kc] |= binds;
|
||||
if (dev->binds[kc] == -1)
|
||||
dev->binds[kc] = 0;
|
||||
dev->binds[kc] |= binds;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -400,26 +494,27 @@ void in_config_end(void)
|
|||
|
||||
for (i = 0; i < IN_MAX_DEVS; i++) {
|
||||
int n, ret, count, *binds, *def_binds;
|
||||
in_dev_t *dev = &in_devices[i];
|
||||
|
||||
if (in_devices[i].binds == NULL)
|
||||
if (dev->binds == NULL)
|
||||
continue;
|
||||
|
||||
count = in_bind_count(in_devices[i].drv_id);
|
||||
binds = in_devices[i].binds;
|
||||
count = in_bind_count(dev->drv_id);
|
||||
binds = dev->binds;
|
||||
def_binds = binds + count;
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
if (binds[n] == -1)
|
||||
binds[n] = def_binds[n];
|
||||
|
||||
if (in_devices[i].drv_data == NULL)
|
||||
if (dev->drv_data == NULL)
|
||||
continue;
|
||||
|
||||
ret = DRV(in_devices[i].drv_id).clean_binds(in_devices[i].drv_data, binds);
|
||||
ret = DRV(dev->drv_id).clean_binds(dev->drv_data, binds);
|
||||
if (ret == 0) {
|
||||
/* no useable binds */
|
||||
free(binds);
|
||||
in_devices[i].binds = NULL;
|
||||
free(dev->binds);
|
||||
dev->binds = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,14 +27,14 @@ void in_init(void);
|
|||
void in_probe(void);
|
||||
int in_update(void);
|
||||
void in_set_blocking(int is_blocking);
|
||||
int in_update_keycode(int *dev_id, int *is_down);
|
||||
int in_update_menu(void);
|
||||
int in_update_keycode(int *dev_id, int *is_down, int timeout_ms);
|
||||
int in_update_menu(int timeout_ms);
|
||||
int in_get_dev_bind_count(int dev_id);
|
||||
void in_config_start(void);
|
||||
int in_config_parse_dev(const char *dev_name);
|
||||
int in_config_bind_key(int dev_id, const char *key, int mask);
|
||||
void in_config_end(void);
|
||||
int in_bind_key(int dev_id, int keycode, int mask);
|
||||
int in_bind_key(int dev_id, int keycode, int mask, int force_unbind);
|
||||
void in_debug_dump(void);
|
||||
|
||||
const int *in_get_dev_binds(int dev_id);
|
||||
|
|
|
@ -165,6 +165,8 @@ static int in_evdev_get_bind_count(void)
|
|||
return KEY_MAX + 1;
|
||||
}
|
||||
|
||||
/* returns bitfield of active binds or -1 if nothing
|
||||
* changed from previous time */
|
||||
int in_evdev_update(void *drv_data, int *binds)
|
||||
{
|
||||
struct input_event ev[16];
|
||||
|
@ -184,24 +186,20 @@ int in_evdev_update(void *drv_data, int *binds)
|
|||
changed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
if (!changed)
|
||||
return 0;
|
||||
*/
|
||||
return -1;
|
||||
|
||||
ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
|
||||
if (ret == -1) {
|
||||
perror("in_evdev: ioctl failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("#%d: ", fd);
|
||||
for (u = 0; u < KEY_MAX + 1; u++) {
|
||||
if (KEYBITS_BIT(u)) {
|
||||
printf(" %d", u);
|
||||
result |= binds[u];
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -225,11 +223,21 @@ static void in_evdev_set_blocking(void *data, int y)
|
|||
perror("in_evdev: F_SETFL fcntl failed");
|
||||
}
|
||||
|
||||
int in_evdev_update_keycode(void **data, int dcount, int *which, int *is_down)
|
||||
int in_evdev_update_keycode(void **data, int dcount, int *which, int *is_down, int timeout_ms)
|
||||
{
|
||||
const int *fds = (const int *)data;
|
||||
struct timeval tv, *timeout = NULL;
|
||||
int i, fdmax = -1;
|
||||
|
||||
if (timeout_ms > 0) {
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
timeout = &tv;
|
||||
}
|
||||
|
||||
if (is_down != NULL)
|
||||
*is_down = 0;
|
||||
|
||||
for (i = 0; i < dcount; i++)
|
||||
if (fds[i] > fdmax) fdmax = fds[i];
|
||||
|
||||
|
@ -243,7 +251,7 @@ int in_evdev_update_keycode(void **data, int dcount, int *which, int *is_down)
|
|||
for (i = 0; i < dcount; i++)
|
||||
FD_SET(fds[i], &fdset);
|
||||
|
||||
ret = select(fdmax + 1, &fdset, NULL, NULL, NULL);
|
||||
ret = select(fdmax + 1, &fdset, NULL, NULL, timeout);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("in_evdev: select failed");
|
||||
|
@ -251,6 +259,9 @@ int in_evdev_update_keycode(void **data, int dcount, int *which, int *is_down)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
return 0; /* timeout */
|
||||
|
||||
for (i = 0; i < dcount; i++)
|
||||
if (FD_ISSET(fds[i], &fdset))
|
||||
*which = i, fd = fds[i];
|
||||
|
@ -267,7 +278,7 @@ int in_evdev_update_keycode(void **data, int dcount, int *which, int *is_down)
|
|||
if (ev[i].type != EV_KEY || ev[i].value < 0 || ev[i].value > 1)
|
||||
continue;
|
||||
|
||||
if (is_down)
|
||||
if (is_down != NULL)
|
||||
*is_down = ev[i].value;
|
||||
return ev[i].code;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
int in_evdev_update(void *drv_data, int *binds);
|
||||
int in_evdev_update_keycode(void **data, int count, int *which, int *is_down);
|
||||
int in_evdev_update_keycode(void **data, int count, int *which, int *is_down, int timeout_ms);
|
||||
void in_evdev_init(void *vdrv);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue