input: use another way to merge the devices.

This commit is contained in:
sorgelig
2020-02-17 06:57:55 +08:00
parent 9a5e615331
commit 5357fa018b

189
input.cpp
View File

@@ -1028,7 +1028,7 @@ typedef struct
int bind;
char devname[32];
char uniq[32];
char id[32];
char name[128];
} devInput;
@@ -2557,6 +2557,106 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
static struct pollfd pool[NUMDEV + 3];
void mergedevs()
{
for (int i = 0; i < NUMDEV; i++)
{
memset(input[i].id, 0, sizeof(input[i].id));
}
FILE *f = fopen("/proc/bus/input/devices", "r");
if (!f)
{
printf("Failed to open /proc/bus/input/devices\n");
return;
}
static char str[1024];
char id[32] = {};
while (fgets(str, sizeof(str), f))
{
int len = strlen(str);
if (!len) id[0] = 0;
else
{
if (!strncmp("S: ", str, 3))
{
char *p = strcasestr(str, "/input/");
if (p)
{
*p = 0;
p = strrchr(str, '/');
if (p)
{
p++;
int len = strlen(p);
if (len > 30) p += len - 30;
strcpy(id, p);
}
}
}
else if (!strncmp("H: ", str, 3) && id[0])
{
char *handlers = strchr(str, '=');
if (handlers)
{
handlers++;
for (int i = 0; i < NUMDEV; i++)
{
if (pool[i].fd >= 0)
{
char *dev = strrchr(input[i].devname, '/');
if (dev)
{
char idsp[32];
strcpy(idsp, dev+1);
strcat(idsp, " ");
if (strstr(handlers, idsp)) strcpy(input[i].id, id);
}
}
}
}
}
}
}
fclose(f);
// merge multifunctional devices by id
for (int i = 0; i < NUMDEV; i++)
{
input[i].bind = i;
if (input[i].id[0] && !input[i].mouse)
{
for (int j = 0; j < i; j++)
{
if (!strcmp(input[i].id, input[j].id))
{
input[i].bind = j;
break;
}
}
}
}
//copy missing fields to mouseX
for (int i = 0; i < NUMDEV; i++) if (input[i].mouse)
{
for (int j = 0; j < NUMDEV; j++) if (!input[j].mouse)
{
if (!strcmp(input[i].id, input[j].id))
{
input[i].bind = j;
input[i].vid = input[j].vid;
input[i].pid = input[j].pid;
input[i].quirk = input[j].quirk;
memcpy(input[i].name, input[j].name, sizeof(input[i].name));
break;
}
}
}
}
int input_test(int getchar)
{
static char cur_leds = 0;
@@ -2614,6 +2714,7 @@ int input_test(int getchar)
pool[n].events = POLLIN;
input[n].mouse = !strncmp(de->d_name, "mouse", 5);
char uniq[32] = {};
if (!input[n].mouse)
{
struct input_id id;
@@ -2622,7 +2723,7 @@ int input_test(int getchar)
input[n].vid = id.vendor;
input[n].pid = id.product;
ioctl(pool[n].fd, EVIOCGUNIQ(sizeof(input[n].uniq)), input[n].uniq);
ioctl(pool[n].fd, EVIOCGUNIQ(sizeof(uniq)), uniq);
ioctl(pool[n].fd, EVIOCGNAME(sizeof(input[n].name)), input[n].name);
input[n].led = has_led(pool[n].fd);
}
@@ -2673,7 +2774,6 @@ int input_test(int getchar)
if (input[n].vid == 0x0079 && input[n].pid == 0x1802)
{
strcpy(input[n].uniq, "Mayflash 1802");
input[n].lightgun = 1;
input[n].num = 2; // force mayflash mode 1/2 as second joystick.
}
@@ -2705,13 +2805,6 @@ int input_test(int getchar)
}
}
// Raphnet devices: clear uniq to prevent merging the ports
// bliss-box adapters need this as well
if (input[n].vid == 0x289b || input[n].vid == 0x16d0)
{
memset(input[n].uniq, 0, sizeof(input[n].uniq));
}
//Ultimarc lightgun
if (input[n].vid == 0xd209 && input[n].pid == 0x1601)
{
@@ -2719,16 +2812,10 @@ int input_test(int getchar)
}
//Madcatz Arcade Stick 360
if (input[n].vid == 0x0738 && input[n].pid == 0x4758)
{
input[n].quirk = QUIRK_MADCATZ360;
}
if (input[n].vid == 0x0738 && input[n].pid == 0x4758) input[n].quirk = QUIRK_MADCATZ360;
if (!strcasecmp(input[n].uniq, "MiSTer PD/SP v1"))
{
input[n].quirk = QUIRK_PDSP;
memset(input[n].uniq, 0, sizeof(input[n].uniq));
}
//mr.Spinner
if (!strcasecmp(uniq, "MiSTer PD/SP v1")) input[n].quirk = QUIRK_PDSP;
ioctl(pool[n].fd, EVIOCGRAB, (grabbed | user_io_osd_is_visible()) ? 1 : 0);
@@ -2739,70 +2826,10 @@ int input_test(int getchar)
}
closedir(d);
// merge multifunctional devices using uniq field
mergedevs();
for (int i = 0; i < n; i++)
{
input[i].bind = i;
if (input[i].uniq[0] && !input[i].mouse)
{
for (int j = 0; j < i; j++)
{
if (!memcmp(input[i].uniq, input[j].uniq, sizeof(input[0].uniq)))
{
input[i].bind = j;
break;
}
}
}
}
//mouseX to eventX mapping
FILE *f = fopen("/proc/bus/input/devices", "r");
if (f)
{
static char str[256];
while (fgets(str, sizeof(str) - 1, f))
{
if (!strncmp(str, "H: Handlers=", 12))
{
for (int i = 0; i < n; i++) if(input[i].mouse)
{
char *mname = strrchr(input[i].devname, '/');
if (mname)
{
mname++;
if (strstr(str + 12, mname))
{
for (int j = 0; j < n; j++) if (!input[j].mouse)
{
char *ename = strrchr(input[j].devname, '/');
if (ename)
{
ename++;
if (strstr(str + 12, ename))
{
input[i].bind = j;
input[i].vid = input[j].vid;
input[i].pid = input[j].pid;
input[i].quirk = input[j].quirk;
memcpy(input[i].name, input[j].name, sizeof(input[i].name));
memcpy(input[i].uniq, input[j].uniq, sizeof(input[i].uniq));
break;
}
}
}
}
}
}
}
}
fclose(f);
}
for (int i = 0; i < n; i++)
{
printf("opened %d(%2d): %s (%04x:%04x) %d \"%s\" \"%s\"\n", i, input[i].bind, input[i].devname, input[i].vid, input[i].pid, input[i].quirk, input[i].uniq, input[i].name);
printf("opened %d(%2d): %s (%04x:%04x) %d \"%s\" \"%s\"\n", i, input[i].bind, input[i].devname, input[i].vid, input[i].pid, input[i].quirk, input[i].id, input[i].name);
}
}
cur_leds |= 0x80;