src/joystick/windowsrt/SDL_xinputjoystick.c
changeset 8473 218549868b0b
parent 8471 456c005ec72c
     1.1 --- a/src/joystick/windowsrt/SDL_xinputjoystick.c	Mon May 20 11:09:08 2013 -0400
     1.2 +++ b/src/joystick/windowsrt/SDL_xinputjoystick.c	Tue May 21 20:08:53 2013 -0400
     1.3 @@ -37,6 +37,7 @@
     1.4  #include "../SDL_sysjoystick.h"
     1.5  #include "../SDL_joystick_c.h"
     1.6  #include "SDL_events.h"
     1.7 +#include "../../events/SDL_events_c.h"
     1.8  
     1.9  #include <Windows.h>
    1.10  #include <Xinput.h>
    1.11 @@ -46,6 +47,7 @@
    1.12      DWORD userIndex;    // The XInput device index, in the range [0, XUSER_MAX_COUNT-1] (probably [0,3]).
    1.13      XINPUT_STATE XInputState;   // the last-read in XInputState, kept around to compare old and new values
    1.14      SDL_bool isDeviceConnected; // was the device connected (on the last polling, or during backend-initialization)?
    1.15 +    SDL_bool isDeviceRemovalEventPending;   // was the device removed, and is the associated removal event pending?
    1.16  };
    1.17  
    1.18  /* Keep track of data on all XInput devices, regardless of whether or not
    1.19 @@ -96,11 +98,67 @@
    1.20  
    1.21  void SDL_SYS_JoystickDetect()
    1.22  {
    1.23 +    DWORD i;
    1.24 +    XINPUT_STATE tempXInputState;
    1.25 +    HRESULT result;
    1.26 +    SDL_Event event;
    1.27 +
    1.28 +    /* Iterate through each possible XInput device, seeing if any devices
    1.29 +       have been connected, or if they were removed.
    1.30 +     */
    1.31 +    for (i = 0; i < XUSER_MAX_COUNT; ++i) {
    1.32 +        /* See if any new devices are connected. */
    1.33 +        if (!g_XInputData[i].isDeviceConnected && !g_XInputData[i].isDeviceRemovalEventPending) {
    1.34 +            result = XInputGetState(i, &tempXInputState);
    1.35 +            if (result == ERROR_SUCCESS) {
    1.36 +                /* Yup, a device is connected.  Mark the device as connected,
    1.37 +                   then tell others about it (via an SDL_JOYDEVICEADDED event.)
    1.38 +                 */
    1.39 +                g_XInputData[i].isDeviceConnected = SDL_TRUE;
    1.40 +
    1.41 +#if !SDL_EVENTS_DISABLED
    1.42 +                SDL_zero(event);
    1.43 +                event.type = SDL_JOYDEVICEADDED;
    1.44 +                
    1.45 +                if (SDL_GetEventState(event.type) == SDL_ENABLE) {
    1.46 +                    event.jdevice.which = i;
    1.47 +                    if ((SDL_EventOK == NULL)
    1.48 +                        || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
    1.49 +                        SDL_PushEvent(&event);
    1.50 +                    }
    1.51 +                }
    1.52 +#endif
    1.53 +            }
    1.54 +        } else if (g_XInputData[i].isDeviceRemovalEventPending) {
    1.55 +            /* A device was previously marked as removed (by
    1.56 +               SDL_SYS_JoystickUpdate).  Tell others about the device removal.
    1.57 +            */
    1.58 +
    1.59 +            g_XInputData[i].isDeviceRemovalEventPending = SDL_FALSE;
    1.60 +
    1.61 +#if !SDL_EVENTS_DISABLED
    1.62 +            SDL_zero(event);
    1.63 +            event.type = SDL_JOYDEVICEREMOVED;
    1.64 +                
    1.65 +            if (SDL_GetEventState(event.type) == SDL_ENABLE) {
    1.66 +                event.jdevice.which = i; //joystick->hwdata->userIndex;
    1.67 +                if ((SDL_EventOK == NULL)
    1.68 +                    || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
    1.69 +                    SDL_PushEvent(&event);
    1.70 +                }
    1.71 +            }
    1.72 +#endif
    1.73 +        }
    1.74 +    }
    1.75  }
    1.76  
    1.77  SDL_bool SDL_SYS_JoystickNeedsPolling()
    1.78  {
    1.79 -    return SDL_FALSE;
    1.80 +    /* Since XInput, or WinRT, provides any events to indicate when a game
    1.81 +       controller gets connected, and instead indicates device availability
    1.82 +       solely through polling, we'll poll (for new devices).
    1.83 +     */
    1.84 +    return SDL_TRUE;
    1.85  }
    1.86  
    1.87  /* Internal function to retreive device capabilities.
    1.88 @@ -261,12 +319,11 @@
    1.89      /* Poll for new data */
    1.90      result = XInputGetState(joystick->hwdata->userIndex, &joystick->hwdata->XInputState);
    1.91      if (result == ERROR_DEVICE_NOT_CONNECTED) {
    1.92 -        /* TODO, WinRT: set a flag to indicate that a device-removal event
    1.93 -           needs to be emitted.
    1.94 -         */
    1.95 -        //joystick->hwdata->send_remove_event = 1;
    1.96 -        //joystick->hwdata->removed = 1;
    1.97 -        joystick->hwdata->isDeviceConnected = SDL_FALSE;
    1.98 +        if (joystick->hwdata->isDeviceConnected) {
    1.99 +            joystick->hwdata->isDeviceConnected = SDL_FALSE;
   1.100 +            joystick->hwdata->isDeviceRemovalEventPending = SDL_TRUE;
   1.101 +            /* TODO, WinRT: make sure isDeviceRemovalEventPending gets cleared as appropriate, and that quick re-plugs don't cause trouble */
   1.102 +        }
   1.103          return;
   1.104      }
   1.105