SDL: Added a second hint SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED to control the Home button LED on Nintendo Joy-Con controllers...

From 824f2d4650582c073742efb7a354db69c184820b Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 9 Aug 2022 13:41:58 -0700
Subject: [PATCH] Added a second hint SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED
 to control the Home button LED on Nintendo Joy-Con controllers separately
 from Nintendo Switch Pro controllers

---
 include/SDL_hints.h                     | 15 +++++++++--
 src/joystick/hidapi/SDL_hidapi_switch.c | 34 ++++++++++++++++---------
 2 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 9c11eb1feb3..1cb2cc2bdd5 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -810,16 +810,27 @@ extern "C" {
 #define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH"
 
 /**
- *  \brief  A variable controlling whether the Home button LED should be turned on when a Nintendo Switch controller is opened
+ *  \brief  A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Pro controller is opened
  *
  *  This variable can be set to the following values:
  *    "0"       - home button LED is turned off
  *    "1"       - home button LED is turned on
  *
- *  By default the Home button LED state is not changed.
+ *  By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED.
  */
 #define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED "SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED"
 
+/**
+ *  \brief  A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Joy-Con controller is opened
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - home button LED is turned off
+ *    "1"       - home button LED is turned on
+ *
+ *  By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED "SDL_JOYSTICK_HIDAPI_JOYCON_HOME_LED"
+
 /**
  *  \brief  A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Nintendo Switch controller.
  *
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 29c7dfb3ee9..0779e9b5301 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -249,7 +249,6 @@ typedef struct
 typedef struct {
     SDL_HIDAPI_Device *device;
     SDL_bool m_bInputOnly;
-    SDL_bool m_bHasHomeLED;
     SDL_bool m_bUsingBluetooth;
     SDL_bool m_bIsGameCube;
     SDL_bool m_bUseButtonLabels;
@@ -304,8 +303,11 @@ typedef struct {
 
 
 static SDL_bool
-HasHomeLED(int vendor_id, int product_id)
+HasHomeLED(SDL_DriverSwitch_Context *ctx)
 {
+    Uint16 vendor_id = ctx->device->vendor_id;
+    Uint16 product_id = ctx->device->product_id;
+
     /* The Power A Nintendo Switch Pro controllers don't have a Home LED */
     if (vendor_id == 0 && product_id == 0) {
         return SDL_FALSE;
@@ -318,9 +320,7 @@ HasHomeLED(int vendor_id, int product_id)
 
     /* The Nintendo Online classic controllers don't have a Home LED */
     if (vendor_id == USB_VENDOR_NINTENDO &&
-        (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER ||
-         product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER ||
-         product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER)) {
+        ctx->m_eControllerType > k_eSwitchDeviceInfoControllerType_ProController) {
         return SDL_FALSE;
     }
 
@@ -1234,8 +1234,6 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
     /* Find out whether or not we can send output reports */
     ctx->m_bInputOnly = SDL_IsJoystickNintendoSwitchProInputOnly(device->vendor_id, device->product_id);
     if (!ctx->m_bInputOnly) {
-        ctx->m_bHasHomeLED = HasHomeLED(device->vendor_id, device->product_id);
-
         /* Initialize rumble data */
         SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]);
         SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]);
@@ -1314,9 +1312,15 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
         }
 
         /* Set the LED state */
-        if (ctx->m_bHasHomeLED) {
-            SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED,
-                                SDL_HomeLEDHintChanged, ctx);
+        if (HasHomeLED(ctx)) {
+            if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||
+                ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
+                SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED,
+                                    SDL_HomeLEDHintChanged, ctx);
+            } else {
+                SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED,
+                                    SDL_HomeLEDHintChanged, ctx);
+            }
         }
 
         /* Set the serial number */
@@ -2090,8 +2094,14 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
     SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
                         SDL_GameControllerButtonReportingHintChanged, ctx);
 
-    SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED,
-                        SDL_HomeLEDHintChanged, ctx);
+    if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||
+        ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
+        SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED,
+                            SDL_HomeLEDHintChanged, ctx);
+    } else {
+        SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED,
+                            SDL_HomeLEDHintChanged, ctx);
+    }
 
     SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED,
                         SDL_PlayerLEDHintChanged, ctx);