Commit e6ad29aec8fe89731475c89c35a74e21effb39a3

Ryan C. Gordon 2015-11-14T12:35:45

Added SDL_JoystickFromInstanceID() and SDL_GameControllerFromInstanceID().

diff --git a/WhatsNew.txt b/WhatsNew.txt
index 79a6ae9..1f1067c 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -34,6 +34,8 @@ General:
 * Added a hint SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN to prevent window interaction while cursor is hidden
 * Added SDL_GetDisplayDPI() to get the DPI information for a display
 * Added SDL_JoystickCurrentPowerLevel() to get the battery level of a joystick
+* Added SDL_JoystickFromInstanceID(), as a helper function, to get the SDL_Joystick* that an event is referring to.
+* Added SDL_GameControllerFromInstanceID(), as a helper function, to get the SDL_GameController* that an event is referring to.
 
 Windows:
 * Added support for Windows Phone 8.1
diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h
index 72fba60..5459387 100644
--- a/include/SDL_gamecontroller.h
+++ b/include/SDL_gamecontroller.h
@@ -172,6 +172,11 @@ extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_
 extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index);
 
 /**
+ * Return the SDL_GameController associated with an instance id.
+ */
+extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid);
+
+/**
  *  Return the name for this currently opened controller
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h
index a707e6c..88bb80a 100644
--- a/include/SDL_joystick.h
+++ b/include/SDL_joystick.h
@@ -107,6 +107,11 @@ extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index);
 extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index);
 
 /**
+ * Return the SDL_Joystick associated with an instance id.
+ */
+extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID joyid);
+
+/**
  *  Return the name for this currently opened joystick.
  *  If no name can be found, this function returns NULL.
  */
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 6daacd7..75f31ce 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -595,3 +595,5 @@
 #define SDL_GetGrabbedWindow SDL_GetGrabbedWindow_REAL
 #define SDL_SetWindowsMessageHook SDL_SetWindowsMessageHook_REAL
 #define SDL_JoystickCurrentPowerLevel SDL_JoystickCurrentPowerLevel_REAL
+#define SDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID_REAL
+#define SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index f864a13..57bbba6 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -629,3 +629,5 @@ SDL_DYNAPI_PROC(void,SDL_SetWindowsMessageHook,(SDL_WindowsMessageHook a, void *
 #endif
 SDL_DYNAPI_PROC(int,SDL_GetDisplayDPI,(int a, float *b, float *c, float *d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(SDL_JoystickPowerLevel,SDL_JoystickCurrentPowerLevel,(SDL_Joystick *a),(a),return)
+SDL_DYNAPI_PROC(SDL_GameController*,SDL_GameControllerFromInstanceID,(SDL_JoystickID a),(a),return)
+SDL_DYNAPI_PROC(SDL_Joystick*,SDL_JoystickFromInstanceID,(SDL_JoystickID a),(a),return)
diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index bfa8abe..37e0a8b 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -1046,6 +1046,25 @@ SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
     return gamecontroller->joystick;
 }
 
+
+/*
+ * Find the SDL_GameController that owns this instance id
+ */
+SDL_GameController *
+SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
+{
+    SDL_GameController *gamecontroller = SDL_gamecontrollers;
+    while (gamecontroller) {
+        if (gamecontroller->joystick->instance_id == joyid) {
+            return gamecontroller;
+        }
+        gamecontroller = gamecontroller->next;
+    }
+
+    return NULL;
+}
+
+
 /**
  * Get the SDL joystick layer binding for this controller axis mapping
  */
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 532748c..8516c03 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -374,6 +374,23 @@ SDL_JoystickInstanceID(SDL_Joystick * joystick)
 }
 
 /*
+ * Find the SDL_Joystick that owns this instance id
+ */
+SDL_Joystick *
+SDL_JoystickFromInstanceID(SDL_JoystickID joyid)
+{
+    SDL_Joystick *joystick = SDL_joysticks;
+    while (joystick) {
+        if (joystick->instance_id == joyid) {
+            return joystick;
+        }
+        joystick = joystick->next;
+    }
+
+    return NULL;
+}
+
+/*
  * Get the friendly name of this joystick
  */
 const char *
diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c
index a825e03..9af9653 100644
--- a/test/testgamecontroller.c
+++ b/test/testgamecontroller.c
@@ -291,6 +291,11 @@ main(int argc, char *argv[])
                                       guid, sizeof (guid));
             SDL_Log("Attempting to open device %i, guid %s\n", device, guid);
             gamecontroller = SDL_GameControllerOpen(device);
+
+            if (gamecontroller != NULL) {
+                SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
+            }
+
             while (keepGoing) {
                 if (gamecontroller == NULL) {
                     if (!reportederror) {
@@ -316,6 +321,9 @@ main(int argc, char *argv[])
                         keepGoing = SDL_FALSE;
                     } else if (event.type == SDL_CONTROLLERDEVICEADDED) {
                         gamecontroller = SDL_GameControllerOpen(event.cdevice.which);
+                        if (gamecontroller != NULL) {
+                            SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
+                        }
                         break;
                     }
                 }
diff --git a/test/testjoystick.c b/test/testjoystick.c
index da9d96f..7355eec 100644
--- a/test/testjoystick.c
+++ b/test/testjoystick.c
@@ -265,6 +265,7 @@ main(int argc, char *argv[])
                     SDL_GetError());
         } else {
             char guid[64];
+            SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick);
             SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick),
                                       guid, sizeof (guid));
             SDL_Log("       axes: %d\n", SDL_JoystickNumAxes(joystick));
@@ -292,6 +293,9 @@ main(int argc, char *argv[])
         device = atoi(argv[1]);
 #endif
         joystick = SDL_JoystickOpen(device);
+        if (joystick != NULL) {
+            SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick);
+        }
 
         while ( keepGoing ) {
             if (joystick == NULL) {
@@ -317,6 +321,9 @@ main(int argc, char *argv[])
                     keepGoing = SDL_FALSE;
                 } else if (event.type == SDL_JOYDEVICEADDED) {
                     joystick = SDL_JoystickOpen(device);
+                    if (joystick != NULL) {
+                        SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick);
+                    }
                     break;
                 }
             }