mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 12:44:56 +00:00 
			
		
		
		
	Sort controllers by the js* index on Linux
Also fixed the initial scan to directly scan devices instead of using udev so they can be sorted, as intended. Fixes https://github.com/libsdl-org/SDL/issues/4688
This commit is contained in:
		
							parent
							
								
									0249df9d96
								
							
						
					
					
						commit
						7ea1b69dd4
					
				| 
						 | 
					@ -606,6 +606,26 @@ LINUX_InotifyJoystickDetect(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* HAVE_INOTIFY */
 | 
					#endif /* HAVE_INOTIFY */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_event_joystick_index(int event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int joystick_index = -1;
 | 
				
			||||||
 | 
					    int i, count;
 | 
				
			||||||
 | 
					    struct dirent **entries;
 | 
				
			||||||
 | 
					    char path[PATH_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
 | 
				
			||||||
 | 
					    count = scandir(path, &entries, NULL, alphasort);
 | 
				
			||||||
 | 
					    for (i = 0; i < count; ++i) {
 | 
				
			||||||
 | 
					        if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) {
 | 
				
			||||||
 | 
					            joystick_index = SDL_atoi(entries[i]->d_name+2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        free(entries[i]); /* This should NOT be SDL_free() */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    free(entries); /* This should NOT be SDL_free() */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return joystick_index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Detect devices by reading /dev/input. In the inotify code path we
 | 
					/* Detect devices by reading /dev/input. In the inotify code path we
 | 
				
			||||||
 * have to do this the first time, to detect devices that already existed
 | 
					 * have to do this the first time, to detect devices that already existed
 | 
				
			||||||
 * before we started; in the non-inotify code path we do this repeatedly
 | 
					 * before we started; in the non-inotify code path we do this repeatedly
 | 
				
			||||||
| 
						 | 
					@ -618,10 +638,35 @@ filter_entries(const struct dirent *entry)
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
sort_entries(const struct dirent **a, const struct dirent **b)
 | 
					sort_entries(const struct dirent **a, const struct dirent **b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int numA = SDL_atoi((*a)->d_name+5);
 | 
					    int numA, numB;
 | 
				
			||||||
    int numB = SDL_atoi((*b)->d_name+5);
 | 
					    int offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (SDL_classic_joysticks) {
 | 
				
			||||||
 | 
					        offset = 2; /* strlen("js") */
 | 
				
			||||||
 | 
					        numA = SDL_atoi((*a)->d_name+offset);
 | 
				
			||||||
 | 
					        numB = SDL_atoi((*b)->d_name+offset);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        offset = 5; /* strlen("event") */
 | 
				
			||||||
 | 
					        numA = SDL_atoi((*a)->d_name+offset);
 | 
				
			||||||
 | 
					        numB = SDL_atoi((*b)->d_name+offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* See if we can get the joystick ordering */
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int jsA = get_event_joystick_index(numA);
 | 
				
			||||||
 | 
					            int jsB = get_event_joystick_index(numB);
 | 
				
			||||||
 | 
					            if (jsA >= 0 && jsB >= 0) {
 | 
				
			||||||
 | 
					                numA = jsA;
 | 
				
			||||||
 | 
					                numB = jsB;
 | 
				
			||||||
 | 
					            } else if (jsA >= 0) {
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            } else if (jsB >= 0) {
 | 
				
			||||||
 | 
					                return 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return (numA - numB);
 | 
					    return (numA - numB);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
LINUX_FallbackJoystickDetect(void)
 | 
					LINUX_FallbackJoystickDetect(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -684,29 +729,7 @@ LINUX_JoystickInit(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
 | 
					    SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SDL_USE_LIBUDEV
 | 
					    enumeration_method = ENUMERATION_UNSET;
 | 
				
			||||||
    if (enumeration_method == ENUMERATION_UNSET) {
 | 
					 | 
				
			||||||
        if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
 | 
					 | 
				
			||||||
            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
					 | 
				
			||||||
                         "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
 | 
					 | 
				
			||||||
            enumeration_method = ENUMERATION_FALLBACK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else if (access("/.flatpak-info", F_OK) == 0
 | 
					 | 
				
			||||||
                 || access("/run/host/container-manager", F_OK) == 0) {
 | 
					 | 
				
			||||||
            /* Explicitly check `/.flatpak-info` because, for old versions of
 | 
					 | 
				
			||||||
             * Flatpak, this was the only available way to tell if we were in
 | 
					 | 
				
			||||||
             * a Flatpak container. */
 | 
					 | 
				
			||||||
            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
					 | 
				
			||||||
                         "Container detected, disabling udev integration");
 | 
					 | 
				
			||||||
            enumeration_method = ENUMERATION_FALLBACK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
					 | 
				
			||||||
                         "Using udev for joystick device discovery");
 | 
					 | 
				
			||||||
            enumeration_method = ENUMERATION_LIBUDEV;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* First see if the user specified one or more joysticks to use */
 | 
					    /* First see if the user specified one or more joysticks to use */
 | 
				
			||||||
    if (devices != NULL) {
 | 
					    if (devices != NULL) {
 | 
				
			||||||
| 
						 | 
					@ -735,6 +758,28 @@ LINUX_JoystickInit(void)
 | 
				
			||||||
    LINUX_JoystickDetect();
 | 
					    LINUX_JoystickDetect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SDL_USE_LIBUDEV
 | 
					#if SDL_USE_LIBUDEV
 | 
				
			||||||
 | 
					    if (enumeration_method == ENUMERATION_UNSET) {
 | 
				
			||||||
 | 
					        if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
 | 
				
			||||||
 | 
					            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
				
			||||||
 | 
					                         "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
 | 
				
			||||||
 | 
					            enumeration_method = ENUMERATION_FALLBACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else if (access("/.flatpak-info", F_OK) == 0
 | 
				
			||||||
 | 
					                 || access("/run/host/container-manager", F_OK) == 0) {
 | 
				
			||||||
 | 
					            /* Explicitly check `/.flatpak-info` because, for old versions of
 | 
				
			||||||
 | 
					             * Flatpak, this was the only available way to tell if we were in
 | 
				
			||||||
 | 
					             * a Flatpak container. */
 | 
				
			||||||
 | 
					            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
				
			||||||
 | 
					                         "Container detected, disabling udev integration");
 | 
				
			||||||
 | 
					            enumeration_method = ENUMERATION_FALLBACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
				
			||||||
 | 
					                         "Using udev for joystick device discovery");
 | 
				
			||||||
 | 
					            enumeration_method = ENUMERATION_LIBUDEV;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (enumeration_method == ENUMERATION_LIBUDEV) {
 | 
					    if (enumeration_method == ENUMERATION_LIBUDEV) {
 | 
				
			||||||
        if (SDL_UDEV_Init() < 0) {
 | 
					        if (SDL_UDEV_Init() < 0) {
 | 
				
			||||||
            return SDL_SetError("Could not initialize UDEV");
 | 
					            return SDL_SetError("Could not initialize UDEV");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue