/* * Add or update an entry into the Mappings Database */ int SDL_GameControllerAddMapping(const char *mappingString) { char *pchGUID; char *pchName; char *pchMapping; SDL_JoystickGUID jGUID; ControllerMapping_t *pControllerMapping; SDL_bool is_xinput_mapping = SDL_FALSE; pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString); if (!pchGUID) { return SDL_SetError("Couldn't parse GUID from %s", mappingString); } if (!SDL_strcasecmp(pchGUID, "xinput")) { is_xinput_mapping = SDL_TRUE; } jGUID = SDL_JoystickGetGUIDFromString(pchGUID); SDL_free(pchGUID); pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString); if (!pchName) { return SDL_SetError("Couldn't parse name from %s", mappingString); } pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString); if (!pchMapping) { SDL_free(pchName); return SDL_SetError("Couldn't parse %s", mappingString); } pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID); if (pControllerMapping) { /* Update existing mapping */ SDL_free(pControllerMapping->name); pControllerMapping->name = pchName; SDL_free(pControllerMapping->mapping); pControllerMapping->mapping = pchMapping; /* refresh open controllers */ SDL_PrivateGameControllerRefreshMapping(pControllerMapping); return 0; } else { pControllerMapping = SDL_malloc(sizeof(*pControllerMapping)); if (!pControllerMapping) { SDL_free(pchName); SDL_free(pchMapping); return SDL_OutOfMemory(); } if (is_xinput_mapping) { s_pXInputMapping = pControllerMapping; } pControllerMapping->guid = jGUID; pControllerMapping->name = pchName; pControllerMapping->mapping = pchMapping; pControllerMapping->next = s_pSupportedControllers; s_pSupportedControllers = pControllerMapping; return 1; } }
/* * Helper function to add a mapping for a guid */ static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority) { char *pchName; char *pchMapping; ControllerMapping_t *pControllerMapping; pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString); if (!pchName) { SDL_SetError("Couldn't parse name from %s", mappingString); return NULL; } pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString); if (!pchMapping) { SDL_free(pchName); SDL_SetError("Couldn't parse %s", mappingString); return NULL; } pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID); if (pControllerMapping) { /* Only overwrite the mapping if the priority is the same or higher. */ if (pControllerMapping->priority <= priority) { /* Update existing mapping */ SDL_free(pControllerMapping->name); pControllerMapping->name = pchName; SDL_free(pControllerMapping->mapping); pControllerMapping->mapping = pchMapping; pControllerMapping->priority = priority; /* refresh open controllers */ SDL_PrivateGameControllerRefreshMapping(pControllerMapping); } *existing = SDL_TRUE; } else { pControllerMapping = SDL_malloc(sizeof(*pControllerMapping)); if (!pControllerMapping) { SDL_free(pchName); SDL_free(pchMapping); SDL_OutOfMemory(); return NULL; } pControllerMapping->guid = jGUID; pControllerMapping->name = pchName; pControllerMapping->mapping = pchMapping; pControllerMapping->next = s_pSupportedControllers; pControllerMapping->priority = priority; s_pSupportedControllers = pControllerMapping; *existing = SDL_FALSE; } return pControllerMapping; }