diff --git a/input.cpp b/input.cpp index 496bb8f..5e9ca5c 100644 --- a/input.cpp +++ b/input.cpp @@ -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;