mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 08:10:30 -10:00
input: a port keeps its mouse by what the mouse is
The same as for keyboards (see "a port keeps its keyboard by what the keyboard is"): Mouse Index is a place in a list that changes when a mouse is plugged in or out, and the place was all that was kept. What is kept now for a port whose mouse was chosen is the mouse's identity (input_playerN_mouse_device) - its USB ids, or its name where it has none - and the number follows from it each time the input driver makes its list of mice. Two things differ from keyboards, and come from what Mouse Index is. Every port has a number from the start, its own, so that the first port reads the first mouse; and there is no "every mouse as one". So: - a port is pinned only when its mouse is chosen by hand - stepped to in the menu or picked from the list - never from a number it merely has. A configuration from before this stays as it was until Mouse Index is next set. Resetting the setting removes the pin; - a port whose pinned mouse is not there reads no mouse while another port has its own, and the mouse its number names otherwise. Mouse Index shows it by name, "046d:c08b (not connected)". Windows raw input and udev say what each of their mice is known by and ask the frontend which mouse a port reads (input_mouse_port_index()), in place of the setting. Under every other input driver nothing changes: no mouse has an identity, no port is pinned, the setting is read as before. Also: the pins header built an identity for the second of two devices of one model in a way gcc warned could truncate; it cannot, and is written so that the compiler sees it. No lock and no thread in any of it: the list, the pins and the lookups are all on the thread that polls. samples/input/device_pins has the mouse cases, in CI. samples/input/winraw_keyboards holds, through the real raw input driver under Wine, what the driver says its mice are known by - the two parts of one mouse told apart, in the order of their numbers - and what a pinned port then reads. The end-to-end run has a port pinned to a mouse that is away. The udev side is compiled only. Not run with two real mice.
This commit is contained in:
1 parent
d9dfddab4b
commit
afd41a82d8
16 files changed
+429
-16
No files matched your search
@@ -637,7 +637,10 @@ jobs:
|
||||
# keyboards are listed; with one unplugged the other is
|
||||
# still its own port's and the port left without reads none;
|
||||
# a single port whose keyboard is away reads every keyboard;
|
||||
# two keyboards of one model are two pins.
|
||||
# two keyboards of one model are two pins. And the same for
|
||||
# mice, which have no "every mouse": a pinned port whose
|
||||
# mouse is away reads none while another port has its own,
|
||||
# and the mouse its number names otherwise.
|
||||
make clean all
|
||||
timeout 60 make check
|
||||
make clean
|
||||
|
||||
@@ -1922,6 +1922,18 @@ static struct config_array_setting *populate_settings_array(
|
||||
SETTING_ARRAY(keyboard_keys[i], settings->arrays.input_keyboard_device[i], false, NULL, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
/* input_playerN_mouse_device: the same for the port's mouse,
|
||||
* set when a mouse is chosen for the port by hand */
|
||||
static char mouse_keys[MAX_USERS][40];
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
size_t _len = strlcpy_lit(mouse_keys[i], "input_player", sizeof(mouse_keys[i]));
|
||||
_len += snprintf(mouse_keys[i] + _len, sizeof(mouse_keys[i]) - _len, "%u", i + 1);
|
||||
strlcpy_lit(mouse_keys[i] + _len, "_mouse_device", sizeof(mouse_keys[i]) - _len);
|
||||
SETTING_ARRAY(mouse_keys[i], settings->arrays.input_mouse_device[i], false, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
SETTING_ARRAY("menu_driver", settings->arrays.menu_driver, false, NULL, true);
|
||||
|
||||
@@ -1283,6 +1283,8 @@ typedef struct settings
|
||||
/* the keyboard a port is given, by what it is: see
|
||||
* input/common/input_device_pins.h */
|
||||
char input_keyboard_device[MAX_USERS][64];
|
||||
/* and the mouse */
|
||||
char input_mouse_device[MAX_USERS][64];
|
||||
|
||||
char youtube_stream_key[PATH_MAX_LENGTH];
|
||||
char twitch_stream_key[PATH_MAX_LENGTH];
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <boolean.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
/* A port's keyboard, kept by what the keyboard is and not by where it
|
||||
* stands in a list.
|
||||
/* A port's keyboard - and its mouse - kept by what the device is and
|
||||
* not by where it stands in a list.
|
||||
*
|
||||
* A port is given a keyboard by its number in the list of keyboards
|
||||
* (Keyboard Index). The number is a place in a list that changes:
|
||||
@@ -54,6 +54,15 @@
|
||||
* - a port with a number and no pin - a setting from before pins -
|
||||
* reads that number's keyboard, and is pinned to it by the caller.
|
||||
*
|
||||
* A mouse is kept the same way (input_pins_resolve_mice()), with two
|
||||
* differences that come from what Mouse Index is. Every port has a
|
||||
* number from the start - its own, so that the first port reads the
|
||||
* first mouse - and there is no "every mouse as one". So a port is
|
||||
* pinned only when its mouse is chosen by hand, never from a number
|
||||
* it merely has; and a port whose pinned mouse is not there falls
|
||||
* back to the mouse its number names, unless another port has its
|
||||
* own mouse, when it reads none.
|
||||
*
|
||||
* No allocation and nothing of any system's:
|
||||
* samples/input/device_pins runs it on its own. */
|
||||
|
||||
@@ -81,13 +90,11 @@ static INLINE void input_pins_identities(char (*out)[INPUT_PIN_LEN],
|
||||
{
|
||||
/* room is kept for the number, so that the second of a pair
|
||||
* with a long name is not the first */
|
||||
char cut[INPUT_PIN_LEN];
|
||||
size_t len = strlen(base[i]);
|
||||
if (len > INPUT_PIN_LEN - 12)
|
||||
len = INPUT_PIN_LEN - 12;
|
||||
memcpy(cut, base[i], len);
|
||||
cut[len] = '\0';
|
||||
snprintf(out[i], INPUT_PIN_LEN, "%s#%u", cut, nth);
|
||||
memcpy(out[i], base[i], len);
|
||||
snprintf(out[i] + len, INPUT_PIN_LEN - len, "#%u", nth);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -132,4 +139,42 @@ static INLINE void input_pins_resolve(int8_t *choice,
|
||||
choice[p] = one_has_its_own ? INPUT_PIN_NONE : INPUT_PIN_ALL;
|
||||
}
|
||||
|
||||
/* what a port reads, of the mice */
|
||||
#define INPUT_PIN_NO_MOUSE (-1)
|
||||
/* 0 and up: that mouse in the list */
|
||||
|
||||
/* Says which mouse each of @ports ports reads (@choice): the one its
|
||||
* pin names; with that one away, none while another port has its own
|
||||
* and the one its number (@index) names otherwise; with no pin, the
|
||||
* one its number names. */
|
||||
static INLINE void input_pins_resolve_mice(int16_t *choice,
|
||||
const char (*pin)[INPUT_PIN_LEN], const unsigned *index,
|
||||
unsigned ports,
|
||||
const char (*ident)[INPUT_PIN_LEN], unsigned listed)
|
||||
{
|
||||
unsigned p, k;
|
||||
bool one_has_its_own = false;
|
||||
|
||||
for (p = 0; p < ports; p++)
|
||||
{
|
||||
choice[p] = (int16_t)(index[p] < 0x7FFF ? index[p] : 0x7FFF);
|
||||
if (!pin[p][0])
|
||||
continue;
|
||||
/* -2: pinned, and not there; settled below */
|
||||
choice[p] = -2;
|
||||
for (k = 0; k < listed && k < 0x7FFF; k++)
|
||||
if (ident[k][0] && !strcmp(ident[k], pin[p]))
|
||||
{
|
||||
choice[p] = (int16_t)k;
|
||||
one_has_its_own = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (p = 0; p < ports; p++)
|
||||
if (choice[p] == -2)
|
||||
choice[p] = one_has_its_own
|
||||
? INPUT_PIN_NO_MOUSE
|
||||
: (int16_t)(index[p] < 0x7FFF ? index[p] : 0x7FFF);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -729,13 +729,12 @@ static udev_input_mouse_t *udev_get_mouse(
|
||||
unsigned i;
|
||||
unsigned mouse_index = 0;
|
||||
int dev_index = -1;
|
||||
settings_t *settings = config_get_ptr();
|
||||
udev_input_mouse_t *mouse = NULL;
|
||||
|
||||
if (port >= MAX_USERS || !video_driver_has_focus())
|
||||
return NULL;
|
||||
|
||||
mouse_index = settings->uints.input_mouse_index[port];
|
||||
/* the port's Mouse Index, or where its pinned mouse is */
|
||||
mouse_index = input_mouse_port_index(port);
|
||||
if (mouse_index < MAX_INPUT_DEVICES)
|
||||
dev_index = udev->pointers[mouse_index];
|
||||
if (dev_index < 0)
|
||||
@@ -1166,7 +1165,7 @@ static udev_input_device_t *udev_get_pointer_port_dev(
|
||||
if (port >= MAX_USERS || !video_driver_has_focus())
|
||||
return NULL;
|
||||
|
||||
pointer_index = settings->uints.input_mouse_index[port];
|
||||
pointer_index = input_mouse_port_index(port);
|
||||
if (pointer_index < MAX_INPUT_DEVICES)
|
||||
dev_index = udev->pointers[pointer_index];
|
||||
if (dev_index < 0)
|
||||
@@ -3314,8 +3313,11 @@ static void udev_input_describe_device(udev_input_device_t *device,
|
||||
static void udev_input_list_pointers(udev_input_t *udev)
|
||||
{
|
||||
input_kbdev_t devs[64];
|
||||
char pins[MAX_INPUT_DEVICES][64];
|
||||
unsigned i, pass, mouse = 0, n = udev->num_devices;
|
||||
|
||||
memset(pins, 0, sizeof(pins));
|
||||
|
||||
if (n > ARRAY_SIZE(devs))
|
||||
n = ARRAY_SIZE(devs);
|
||||
for (i = 0; i < n; i++)
|
||||
@@ -3344,6 +3346,13 @@ static void udev_input_list_pointers(udev_input_t *udev)
|
||||
input_config_set_mouse_device(mouse, udev->devices[i]->kbdev.key,
|
||||
udev->devices[i]->vid, udev->devices[i]->pid, !is_mouse);
|
||||
udev->pointers[mouse] = (int32_t)i;
|
||||
/* what a port is pinned to it by: its ids, or with none its
|
||||
* name */
|
||||
if (udev->devices[i]->vid || udev->devices[i]->pid)
|
||||
snprintf(pins[mouse], sizeof(pins[mouse]), "%04x:%04x",
|
||||
udev->devices[i]->vid, udev->devices[i]->pid);
|
||||
else
|
||||
strlcpy(pins[mouse], udev->devices[i]->ident, sizeof(pins[mouse]));
|
||||
RARCH_LOG("[udev] Mouse/Touch #%u: \"%s\" (%s) %s%s.\n",
|
||||
mouse,
|
||||
udev->devices[i]->ident,
|
||||
@@ -3353,6 +3362,8 @@ static void udev_input_list_pointers(udev_input_t *udev)
|
||||
mouse++;
|
||||
}
|
||||
}
|
||||
/* the ports' mice are looked up in the new list */
|
||||
input_mouse_pins_set_devices((const char (*)[64])pins, mouse);
|
||||
}
|
||||
|
||||
/* The keyboards that are listed and numbered for the menu, and that a
|
||||
|
||||
@@ -1010,6 +1010,27 @@ static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt)
|
||||
|
||||
*mice = mice_r;
|
||||
|
||||
/* what a port is pinned to each by, in the order they are in now:
|
||||
* its USB ids, or with none what Windows calls it */
|
||||
{
|
||||
char (*pins)[64] = (char (*)[64])calloc(
|
||||
mouse_cnt_r ? mouse_cnt_r : 1, sizeof(*pins));
|
||||
if (pins)
|
||||
{
|
||||
unsigned k;
|
||||
for (k = 0; k < mouse_cnt_r && ids; k++)
|
||||
{
|
||||
if (ids[k].vid || ids[k].pid)
|
||||
snprintf(pins[k], sizeof(pins[k]), "%04x:%04x",
|
||||
ids[k].vid, ids[k].pid);
|
||||
else
|
||||
strlcpy(pins[k], ids[k].desc, sizeof(pins[k]));
|
||||
}
|
||||
input_mouse_pins_set_devices((const char (*)[64])pins, mouse_cnt_r);
|
||||
free(pins);
|
||||
}
|
||||
}
|
||||
|
||||
winraw_push_names_task(mice_r, ids, unlisted, NULL, mouse_cnt_r);
|
||||
free(ids);
|
||||
free(unlisted);
|
||||
@@ -2532,10 +2553,10 @@ static int16_t winraw_input_state(
|
||||
if (process_mouse)
|
||||
{
|
||||
unsigned i;
|
||||
settings_t *settings = config_get_ptr();
|
||||
for (i = 0; i < wr->mouse_cnt; ++i)
|
||||
{
|
||||
if (i == settings->uints.input_mouse_index[port])
|
||||
/* (the port's Mouse Index, or where its pinned mouse is) */
|
||||
if (i == input_mouse_port_index(port))
|
||||
{
|
||||
mouse = &wr->mice[i];
|
||||
if (mouse && device > RETRO_DEVICE_JOYPAD)
|
||||
|
||||
@@ -5914,6 +5914,11 @@ void *input_driver_init_wrap(input_driver_t *input, const char *name)
|
||||
sizeof(input_driver_st.keyboard_choice));
|
||||
input_driver_st.keyboard_identities = 0;
|
||||
input_driver_st.keyboard_absent = 0;
|
||||
memset(input_driver_st.mouse_identity, 0,
|
||||
sizeof(input_driver_st.mouse_identity));
|
||||
input_driver_st.mouse_identities = 0;
|
||||
input_driver_st.mouse_pinned = 0;
|
||||
input_driver_st.mouse_absent = 0;
|
||||
if ((ret = input->init(name)))
|
||||
{
|
||||
input_driver_init_joypads();
|
||||
@@ -6679,6 +6684,119 @@ void input_keyboard_pin_from_index(unsigned port)
|
||||
input_keyboard_pins_resolve();
|
||||
}
|
||||
|
||||
/* Which mouse each pinned port reads is worked out again: after the
|
||||
* list of mice was made, and after a port's setting was changed. */
|
||||
static void input_mouse_pins_resolve(void)
|
||||
{
|
||||
unsigned port;
|
||||
int16_t choice[MAX_USERS];
|
||||
input_driver_state_t *input_st = &input_driver_st;
|
||||
settings_t *settings = config_get_ptr();
|
||||
uint16_t was_absent = input_st->mouse_absent;
|
||||
|
||||
if (!settings)
|
||||
return;
|
||||
|
||||
input_pins_resolve_mice(choice,
|
||||
(const char (*)[INPUT_PIN_LEN])settings->arrays.input_mouse_device,
|
||||
settings->uints.input_mouse_index, MAX_USERS,
|
||||
(const char (*)[INPUT_PIN_LEN])input_st->mouse_identity,
|
||||
input_st->mouse_identities);
|
||||
|
||||
input_st->mouse_pinned = 0;
|
||||
input_st->mouse_absent = 0;
|
||||
for (port = 0; port < MAX_USERS; port++)
|
||||
{
|
||||
const char *pin = settings->arrays.input_mouse_device[port];
|
||||
unsigned k;
|
||||
|
||||
input_st->mouse_choice[port] = choice[port];
|
||||
if (!pin[0])
|
||||
continue;
|
||||
input_st->mouse_pinned |= (uint16_t)(1 << port);
|
||||
|
||||
for (k = 0; k < input_st->mouse_identities; k++)
|
||||
if ( input_st->mouse_identity[k][0]
|
||||
&& string_is_equal(input_st->mouse_identity[k], pin))
|
||||
break;
|
||||
if (k < input_st->mouse_identities)
|
||||
{
|
||||
/* the number shown follows the mouse */
|
||||
if (settings->uints.input_mouse_index[port] != k)
|
||||
{
|
||||
RARCH_LOG("[Input] Port %u's mouse \"%s\" is mouse %u now.\n",
|
||||
port + 1, pin, k + 1);
|
||||
settings->uints.input_mouse_index[port] = k;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(was_absent & (1 << port)))
|
||||
RARCH_LOG("[Input] Port %u's mouse \"%s\" is not there: the port"
|
||||
" reads %s.\n", port + 1, pin,
|
||||
choice[port] == INPUT_PIN_NO_MOUSE
|
||||
? "no mouse, as another port has its own"
|
||||
: "the mouse its Mouse Index names");
|
||||
input_st->mouse_absent |= (uint16_t)(1 << port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void input_mouse_pins_set_devices(const char (*base)[64], unsigned n)
|
||||
{
|
||||
input_driver_state_t *input_st = &input_driver_st;
|
||||
|
||||
if (n > MAX_INPUT_DEVICES)
|
||||
n = MAX_INPUT_DEVICES;
|
||||
memset(input_st->mouse_identity, 0, sizeof(input_st->mouse_identity));
|
||||
if (n)
|
||||
input_pins_identities(input_st->mouse_identity, base, n);
|
||||
input_st->mouse_identities = n;
|
||||
input_st->mouse_absent = 0;
|
||||
input_mouse_pins_resolve();
|
||||
}
|
||||
|
||||
unsigned input_mouse_port_index(unsigned port)
|
||||
{
|
||||
const input_driver_state_t *input_st = &input_driver_st;
|
||||
if (port >= MAX_USERS)
|
||||
return MAX_INPUT_DEVICES;
|
||||
/* a port with no pin reads by its setting, as it always did - and
|
||||
* so does every port under a driver that does not say what its
|
||||
* mice are */
|
||||
if (!(input_st->mouse_pinned & (1 << port)))
|
||||
return config_get_ptr()->uints.input_mouse_index[port];
|
||||
if (input_st->mouse_choice[port] < 0)
|
||||
return MAX_INPUT_DEVICES;
|
||||
return (unsigned)input_st->mouse_choice[port];
|
||||
}
|
||||
|
||||
bool input_mouse_pin_absent(unsigned port)
|
||||
{
|
||||
return port < MAX_USERS
|
||||
&& (input_driver_st.mouse_absent & (1 << port));
|
||||
}
|
||||
|
||||
void input_mouse_pin_from_index(unsigned port, bool pin)
|
||||
{
|
||||
input_driver_state_t *input_st = &input_driver_st;
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned idx;
|
||||
|
||||
if (!settings || port >= MAX_USERS)
|
||||
return;
|
||||
idx = settings->uints.input_mouse_index[port];
|
||||
settings->arrays.input_mouse_device[port][0] = '\0';
|
||||
if ( pin
|
||||
&& idx < input_st->mouse_identities
|
||||
&& input_st->mouse_identity[idx][0])
|
||||
strlcpy(settings->arrays.input_mouse_device[port],
|
||||
input_st->mouse_identity[idx],
|
||||
sizeof(settings->arrays.input_mouse_device[port]));
|
||||
input_st->mouse_absent &= (uint16_t)~(1 << port);
|
||||
input_mouse_pins_resolve();
|
||||
}
|
||||
|
||||
const char *input_driver_get_ident(void)
|
||||
{
|
||||
const input_driver_t *input = input_driver_st.current_driver;
|
||||
|
||||
@@ -713,6 +713,12 @@ typedef struct
|
||||
unsigned keyboard_identities;
|
||||
int8_t keyboard_choice[MAX_USERS];
|
||||
uint16_t keyboard_absent; /* a bit a port: pinned, not there */
|
||||
/* the same for the mice */
|
||||
char mouse_identity[MAX_INPUT_DEVICES][64];
|
||||
unsigned mouse_identities;
|
||||
int16_t mouse_choice[MAX_USERS];
|
||||
uint16_t mouse_pinned; /* a bit a port: mouse_choice holds */
|
||||
uint16_t mouse_absent;
|
||||
input_sensor_map_t input_sensor_map[MAX_INPUT_DEVICES];
|
||||
|
||||
/**
|
||||
@@ -932,6 +938,19 @@ void input_keyboard_pin_from_index(unsigned port);
|
||||
/* The port is pinned to a keyboard that is not there. */
|
||||
bool input_keyboard_pin_absent(unsigned port);
|
||||
|
||||
/* The same for a port's mouse. An input driver that lists mice tells
|
||||
* what it knows each by, in the order of their Mouse Index: */
|
||||
void input_mouse_pins_set_devices(const char (*base)[64], unsigned n);
|
||||
/* The mouse a port reads now, as a Mouse Index: the port's own
|
||||
* setting, the place its pinned mouse has in the list, or
|
||||
* MAX_INPUT_DEVICES for none. Read on the input path, in place of
|
||||
* the setting. */
|
||||
unsigned input_mouse_port_index(unsigned port);
|
||||
/* The port's Mouse Index was changed by hand: the port is pinned to
|
||||
* the mouse that number names. @pin false removes the pin. */
|
||||
void input_mouse_pin_from_index(unsigned port, bool pin);
|
||||
bool input_mouse_pin_absent(unsigned port);
|
||||
|
||||
/* The running input driver's name ("raw", "udev", "wayland"...), or
|
||||
* an empty string when there is none. */
|
||||
const char *input_driver_get_ident(void);
|
||||
|
||||
+2
-2
@@ -12437,7 +12437,7 @@ MSG_HASH(
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_INPUT_MOUSE_INDEX,
|
||||
"The physical mouse as recognized by RetroArch."
|
||||
"The physical mouse as recognized by RetroArch. Where the input driver can tell mice apart, a mouse chosen here is remembered by what it is, and stays this port's when mice are plugged in or out."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_INDEX,
|
||||
@@ -12447,7 +12447,7 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_INPUT_KEYBOARD_INDEX,
|
||||
"The keyboard this port's key binds are read from. 'All' reads every keyboard as one. A single keyboard can be chosen where the input driver can tell keyboards apart; it is remembered by what it is, and stays this port's when keyboards are plugged in or out. Hotkeys and the menu always answer to every keyboard."
|
||||
)
|
||||
MSG_HASH( /* The value of Keyboard Index for a port whose keyboard is not plugged in. %s is what the keyboard is known by, such as its USB ids "046d:c31c" */
|
||||
MSG_HASH( /* The value of Keyboard Index, or of Mouse Index, for a port whose keyboard or mouse is not plugged in. %s is what the device is known by, such as its USB ids "046d:c31c" */
|
||||
MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_INDEX_ABSENT,
|
||||
"%s (not connected)"
|
||||
)
|
||||
|
||||
@@ -6336,6 +6336,8 @@ static int setting_action_left_input_mouse_index(
|
||||
}
|
||||
}
|
||||
|
||||
/* the port is pinned to the mouse chosen, not to its number */
|
||||
input_mouse_pin_from_index(setting->index_offset, true);
|
||||
settings->flags |= SETTINGS_FLG_MODIFIED;
|
||||
return 0;
|
||||
}
|
||||
@@ -8850,6 +8852,8 @@ static int setting_action_start_input_mouse_index(rarch_setting_t *setting)
|
||||
configuration_set_uint(settings,
|
||||
settings->uints.input_mouse_index[setting->index_offset],
|
||||
setting->index_offset);
|
||||
/* back to the port's own number, and to no mouse in particular */
|
||||
input_mouse_pin_from_index(setting->index_offset, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9042,6 +9046,7 @@ static int setting_action_right_input_mouse_index(
|
||||
}
|
||||
}
|
||||
|
||||
input_mouse_pin_from_index(setting->index_offset, true);
|
||||
settings->flags |= SETTINGS_FLG_MODIFIED;
|
||||
return 0;
|
||||
}
|
||||
@@ -9257,6 +9262,13 @@ static size_t get_string_representation_input_mouse_index(
|
||||
|
||||
map = settings->uints.input_mouse_index[setting->index_offset];
|
||||
|
||||
/* pinned to a mouse that is not plugged in: it is named, not a
|
||||
* number that is some other mouse's now */
|
||||
if (input_mouse_pin_absent(setting->index_offset))
|
||||
return snprintf(s, len,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_INDEX_ABSENT),
|
||||
settings->arrays.input_mouse_device[setting->index_offset]);
|
||||
|
||||
if (map < MAX_INPUT_DEVICES)
|
||||
{
|
||||
const char *device_name = input_config_get_mouse_display_name(map);
|
||||
@@ -9378,6 +9390,12 @@ static void general_write_handler(rarch_setting_t *setting)
|
||||
|
||||
rarch_cmd = write_handler_get_cmd(setting);
|
||||
|
||||
/* a mouse picked for a port from the list of them: the port is
|
||||
* pinned to that mouse */
|
||||
if ( setting->enum_idx >= MENU_ENUM_LABEL_INPUT_MOUSE_INDEX
|
||||
&& setting->enum_idx <= MENU_ENUM_LABEL_INPUT_MOUSE_INDEX_LAST)
|
||||
input_mouse_pin_from_index(setting->index_offset, true);
|
||||
|
||||
switch (setting->enum_idx)
|
||||
{
|
||||
case MENU_ENUM_LABEL_VIDEO_SHADERS_ENABLE:
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
* - a port with no pin reads every keyboard; one with a number and no
|
||||
* pin (a setting from before pins) reads that number's keyboard, or
|
||||
* every keyboard when the number is past the list;
|
||||
* - two keyboards of one model are two pins. */
|
||||
* - two keyboards of one model are two pins;
|
||||
* - mice: a port with no pin reads the mouse its number names, as it
|
||||
* always did; a pinned port reads its mouse wherever it is listed;
|
||||
* with that mouse away it reads none while another port has its
|
||||
* own, and the mouse its number names otherwise. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -118,6 +122,42 @@ int main(void)
|
||||
CHECK(choice[0] == 2 && choice[1] == 1, "two keyboards of one model: %d %d, want 2 1", choice[0], choice[1]);
|
||||
printf(" ok two keyboards of one model are two pins\n");
|
||||
|
||||
/* ---- mice ------------------------------------------------------ */
|
||||
{
|
||||
int16_t mouse[PORTS];
|
||||
memset(base, 0, sizeof(base)); memset(pin, 0, sizeof(pin));
|
||||
strcpy(base[0], "1b1c:1b5a"); strcpy(base[1], "046d:c08b"); strcpy(base[2], "03f0:098f");
|
||||
input_pins_identities(ident, (const char (*)[INPUT_PIN_LEN])base, 3);
|
||||
/* every port has its own number from the start, and no pin */
|
||||
index[0] = 0; index[1] = 1; index[2] = 2; index[3] = 3;
|
||||
input_pins_resolve_mice(mouse, (const char (*)[INPUT_PIN_LEN])pin, index, PORTS,
|
||||
(const char (*)[INPUT_PIN_LEN])ident, 3);
|
||||
CHECK(mouse[0] == 0 && mouse[1] == 1 && mouse[2] == 2 && mouse[3] == 3,
|
||||
"no pins: ports read mice %d %d %d %d, want their numbers", mouse[0], mouse[1], mouse[2], mouse[3]);
|
||||
/* two ports pinned, the other way round from their numbers */
|
||||
strcpy(pin[0], "046d:c08b"); strcpy(pin[1], "1b1c:1b5a");
|
||||
input_pins_resolve_mice(mouse, (const char (*)[INPUT_PIN_LEN])pin, index, PORTS,
|
||||
(const char (*)[INPUT_PIN_LEN])ident, 3);
|
||||
CHECK(mouse[0] == 1 && mouse[1] == 0 && mouse[2] == 2,
|
||||
"two pinned ports: %d %d, and an unpinned one %d; want 1 0 2", mouse[0], mouse[1], mouse[2]);
|
||||
/* the first port's mouse unplugged: the list is one shorter */
|
||||
memset(base, 0, sizeof(base));
|
||||
strcpy(base[0], "1b1c:1b5a"); strcpy(base[1], "03f0:098f");
|
||||
input_pins_identities(ident, (const char (*)[INPUT_PIN_LEN])base, 2);
|
||||
input_pins_resolve_mice(mouse, (const char (*)[INPUT_PIN_LEN])pin, index, PORTS,
|
||||
(const char (*)[INPUT_PIN_LEN])ident, 2);
|
||||
CHECK(mouse[1] == 0, "the second port's mouse is read as %d, want 0", mouse[1]);
|
||||
CHECK(mouse[0] == INPUT_PIN_NO_MOUSE,
|
||||
"the first port, its mouse away, reads %d: it must not read the other port's", mouse[0]);
|
||||
/* a single pinned port, its mouse away: the mouse its number names */
|
||||
memset(pin, 0, sizeof(pin));
|
||||
strcpy(pin[0], "046d:c08b");
|
||||
input_pins_resolve_mice(mouse, (const char (*)[INPUT_PIN_LEN])pin, index, PORTS,
|
||||
(const char (*)[INPUT_PIN_LEN])ident, 2);
|
||||
CHECK(mouse[0] == 0, "a single pinned port whose mouse is away reads %d, want the mouse its number names (0)", mouse[0]);
|
||||
printf(" ok mice: no pin reads by number; a pinned port reads its mouse wherever it is listed; with it away, none while another port has its own, and by number otherwise\n");
|
||||
}
|
||||
|
||||
if (failures)
|
||||
{
|
||||
printf("FAIL device_pins_test: %u\n", failures);
|
||||
|
||||
@@ -351,6 +351,12 @@ EXTRA_CFG='input_player1_keyboard_index = "1"
|
||||
input_player1_keyboard_device = "dead:beef"' \
|
||||
WANT_LOG="Port 1's keyboard \"dead:beef\" is not there: the port reads every keyboard" \
|
||||
scenario "the first port pinned to a keyboard that is away" true 1 2 nomsg
|
||||
# The same for the port's mouse: pinned to one that is not plugged in,
|
||||
# with no other port having a mouse of its own, the port reads the
|
||||
# mouse its Mouse Index names, and the log says so.
|
||||
EXTRA_CFG='input_player1_mouse_device = "dead:beef"' \
|
||||
WANT_LOG="Port 1's mouse \"dead:beef\" is not there: the port reads the mouse its Mouse Index names" \
|
||||
scenario "the first port pinned to a mouse that is away" true 1 2 nomsg
|
||||
VIDEO_DRIVER=gl VIDEO_STARTED='Found GL context' WANT_VIDEO=2 WANT_WINDOW="1 1 0" \
|
||||
WANT_MENUS=1 EXTRA_CFG='ui_menubar_enable = "true"' \
|
||||
scenario "OpenGL" true 1 2 nomsg
|
||||
|
||||
@@ -68,6 +68,28 @@ int input_keyboard_port_choice(unsigned port)
|
||||
(const char (*)[INPUT_PIN_LEN])stub_pin_ident, stub_pin_listed);
|
||||
return choice[port];
|
||||
}
|
||||
|
||||
/* and its mouse, the same way */
|
||||
static char stub_mouse_ident[MAX_INPUT_DEVICES][INPUT_PIN_LEN];
|
||||
static unsigned stub_mouse_listed;
|
||||
void input_mouse_pins_set_devices(const char (*base)[64], unsigned n)
|
||||
{
|
||||
memset(stub_mouse_ident, 0, sizeof(stub_mouse_ident));
|
||||
if (n > MAX_INPUT_DEVICES)
|
||||
n = MAX_INPUT_DEVICES;
|
||||
if (n)
|
||||
input_pins_identities(stub_mouse_ident, base, n);
|
||||
stub_mouse_listed = n;
|
||||
}
|
||||
unsigned input_mouse_port_index(unsigned port)
|
||||
{
|
||||
int16_t choice[MAX_USERS];
|
||||
input_pins_resolve_mice(choice,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_settings.arrays.input_mouse_device,
|
||||
stub_settings.uints.input_mouse_index, MAX_USERS,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_mouse_ident, stub_mouse_listed);
|
||||
return choice[port] < 0 ? MAX_INPUT_DEVICES : (unsigned)choice[port];
|
||||
}
|
||||
struct menu_state *menu_state_get_ptr(void) { return &stub_menu; }
|
||||
void RARCH_LOG(const char *fmt, ...) { (void)fmt; }
|
||||
void RARCH_DBG(const char *fmt, ...) { (void)fmt; }
|
||||
|
||||
@@ -162,6 +162,28 @@ int input_keyboard_port_choice(unsigned port)
|
||||
(const char (*)[INPUT_PIN_LEN])stub_pin_ident, stub_pin_listed);
|
||||
return choice[port];
|
||||
}
|
||||
|
||||
/* and its mouse, the same way */
|
||||
static char stub_mouse_ident[MAX_INPUT_DEVICES][INPUT_PIN_LEN];
|
||||
static unsigned stub_mouse_listed;
|
||||
void input_mouse_pins_set_devices(const char (*base)[64], unsigned n)
|
||||
{
|
||||
memset(stub_mouse_ident, 0, sizeof(stub_mouse_ident));
|
||||
if (n > MAX_INPUT_DEVICES)
|
||||
n = MAX_INPUT_DEVICES;
|
||||
if (n)
|
||||
input_pins_identities(stub_mouse_ident, base, n);
|
||||
stub_mouse_listed = n;
|
||||
}
|
||||
unsigned input_mouse_port_index(unsigned port)
|
||||
{
|
||||
int16_t choice[MAX_USERS];
|
||||
input_pins_resolve_mice(choice,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_settings.arrays.input_mouse_device,
|
||||
stub_settings.uints.input_mouse_index, MAX_USERS,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_mouse_ident, stub_mouse_listed);
|
||||
return choice[port] < 0 ? MAX_INPUT_DEVICES : (unsigned)choice[port];
|
||||
}
|
||||
struct menu_state *menu_state_get_ptr(void) { return &stub_menu; }
|
||||
void RARCH_LOG(const char *fmt, ...) { (void)fmt; }
|
||||
void RARCH_DBG(const char *fmt, ...) { (void)fmt; }
|
||||
@@ -752,6 +774,36 @@ int main(void)
|
||||
"a mouse with no name of its own goes by \"%s\"", ms_names[4]);
|
||||
printf(" ok the mice on the desk come first; a keyboard's pointer part, a program's mouse and the terminal server's follow and are left out of the list\n");
|
||||
|
||||
/* ---- a mouse kept by what it is ------------------------------- */
|
||||
/* The driver says what each mouse is known by, in the order of
|
||||
* their numbers: the mouse's two parts are one model, told apart
|
||||
* as the first and "#2"; the receiver's mouse is another. */
|
||||
CHECK(stub_mouse_listed == 6
|
||||
&& !strcmp(stub_mouse_ident[0], "1b1c:1b5a")
|
||||
&& !strcmp(stub_mouse_ident[1], "1b1c:1b5a#2")
|
||||
&& !strncmp(stub_mouse_ident[2], "046d:", 5),
|
||||
"what the mice are known by: %u listed, \"%s\" \"%s\" \"%s\"",
|
||||
stub_mouse_listed, stub_mouse_ident[0], stub_mouse_ident[1], stub_mouse_ident[2]);
|
||||
/* a port with no pin reads by its number, as it always did */
|
||||
stub_settings.uints.input_mouse_index[0] = 0;
|
||||
stub_settings.uints.input_mouse_index[1] = 1;
|
||||
CHECK(input_mouse_port_index(0) == 0 && input_mouse_port_index(1) == 1,
|
||||
"ports with no pin read mice %u %u, want their numbers",
|
||||
input_mouse_port_index(0), input_mouse_port_index(1));
|
||||
/* the second port pinned to the receiver's mouse: it reads that
|
||||
* one, whatever its number says */
|
||||
strcpy(stub_settings.arrays.input_mouse_device[1], stub_mouse_ident[2]);
|
||||
CHECK(input_mouse_port_index(1) == 2, "a port pinned to the third mouse reads mouse %u", input_mouse_port_index(1));
|
||||
/* the first port pinned to a mouse that is not plugged in, while
|
||||
* the second has its own: it reads none */
|
||||
strcpy(stub_settings.arrays.input_mouse_device[0], "dead:beef");
|
||||
CHECK(input_mouse_port_index(0) == MAX_INPUT_DEVICES,
|
||||
"a port whose pinned mouse is away, another port having its own, reads mouse %u: want none",
|
||||
input_mouse_port_index(0));
|
||||
stub_settings.arrays.input_mouse_device[0][0] = '\0';
|
||||
stub_settings.arrays.input_mouse_device[1][0] = '\0';
|
||||
printf(" ok the driver says what each mouse is known by, in the order of their numbers; a pinned port reads its mouse, and none when it is away and another port has its own\n");
|
||||
|
||||
winraw_free(wr);
|
||||
if (failures)
|
||||
{
|
||||
|
||||
@@ -89,6 +89,28 @@ int input_keyboard_port_choice(unsigned port)
|
||||
(const char (*)[INPUT_PIN_LEN])stub_pin_ident, stub_pin_listed);
|
||||
return choice[port];
|
||||
}
|
||||
|
||||
/* and its mouse, the same way */
|
||||
static char stub_mouse_ident[MAX_INPUT_DEVICES][INPUT_PIN_LEN];
|
||||
static unsigned stub_mouse_listed;
|
||||
void input_mouse_pins_set_devices(const char (*base)[64], unsigned n)
|
||||
{
|
||||
memset(stub_mouse_ident, 0, sizeof(stub_mouse_ident));
|
||||
if (n > MAX_INPUT_DEVICES)
|
||||
n = MAX_INPUT_DEVICES;
|
||||
if (n)
|
||||
input_pins_identities(stub_mouse_ident, base, n);
|
||||
stub_mouse_listed = n;
|
||||
}
|
||||
unsigned input_mouse_port_index(unsigned port)
|
||||
{
|
||||
int16_t choice[MAX_USERS];
|
||||
input_pins_resolve_mice(choice,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_settings.arrays.input_mouse_device,
|
||||
stub_settings.uints.input_mouse_index, MAX_USERS,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_mouse_ident, stub_mouse_listed);
|
||||
return choice[port] < 0 ? MAX_INPUT_DEVICES : (unsigned)choice[port];
|
||||
}
|
||||
struct menu_state *menu_state_get_ptr(void) { return &stub_menu; }
|
||||
void RARCH_LOG(const char *fmt, ...) { (void)fmt; }
|
||||
void RARCH_DBG(const char *fmt, ...) { (void)fmt; }
|
||||
|
||||
@@ -84,6 +84,28 @@ int input_keyboard_port_choice(unsigned port)
|
||||
(const char (*)[INPUT_PIN_LEN])stub_pin_ident, stub_pin_listed);
|
||||
return choice[port];
|
||||
}
|
||||
|
||||
/* and its mouse, the same way */
|
||||
static char stub_mouse_ident[MAX_INPUT_DEVICES][INPUT_PIN_LEN];
|
||||
static unsigned stub_mouse_listed;
|
||||
void input_mouse_pins_set_devices(const char (*base)[64], unsigned n)
|
||||
{
|
||||
memset(stub_mouse_ident, 0, sizeof(stub_mouse_ident));
|
||||
if (n > MAX_INPUT_DEVICES)
|
||||
n = MAX_INPUT_DEVICES;
|
||||
if (n)
|
||||
input_pins_identities(stub_mouse_ident, base, n);
|
||||
stub_mouse_listed = n;
|
||||
}
|
||||
unsigned input_mouse_port_index(unsigned port)
|
||||
{
|
||||
int16_t choice[MAX_USERS];
|
||||
input_pins_resolve_mice(choice,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_settings.arrays.input_mouse_device,
|
||||
stub_settings.uints.input_mouse_index, MAX_USERS,
|
||||
(const char (*)[INPUT_PIN_LEN])stub_mouse_ident, stub_mouse_listed);
|
||||
return choice[port] < 0 ? MAX_INPUT_DEVICES : (unsigned)choice[port];
|
||||
}
|
||||
struct menu_state *menu_state_get_ptr(void) { return &stub_menu; }
|
||||
void RARCH_LOG(const char *fmt, ...) { (void)fmt; }
|
||||
void RARCH_DBG(const char *fmt, ...) { (void)fmt; }
|
||||
|
||||
Reference in new issue
Block a user