src/sensor/windows/SDL_windowssensor.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 20 May 2020 16:58:33 -0400
changeset 13838 02e41b30186f
parent 13776 74f7ed12a32b
child 13839 52dbeb97b294
permissions -rw-r--r--
windows: Fix calls to CoCreateInstance() so last parameter is a LPVOID *.
slouken@13710
     1
/*
slouken@13710
     2
  Simple DirectMedia Layer
slouken@13710
     3
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
slouken@13710
     4
slouken@13710
     5
  This software is provided 'as-is', without any express or implied
slouken@13710
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@13710
     7
  arising from the use of this software.
slouken@13710
     8
slouken@13710
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@13710
    10
  including commercial applications, and to alter it and redistribute it
slouken@13710
    11
  freely, subject to the following restrictions:
slouken@13710
    12
slouken@13710
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@13710
    14
     claim that you wrote the original software. If you use this software
slouken@13710
    15
     in a product, an acknowledgment in the product documentation would be
slouken@13710
    16
     appreciated but is not required.
slouken@13710
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@13710
    18
     misrepresented as being the original software.
slouken@13710
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@13710
    20
*/
slouken@13710
    21
#include "../../SDL_internal.h"
slouken@13710
    22
slouken@13710
    23
#include "SDL_config.h"
slouken@13710
    24
slouken@13710
    25
#if defined(SDL_SENSOR_WINDOWS)
slouken@13710
    26
slouken@13710
    27
#include "SDL_error.h"
slouken@13710
    28
#include "SDL_mutex.h"
slouken@13710
    29
#include "SDL_sensor.h"
slouken@13710
    30
#include "SDL_windowssensor.h"
slouken@13710
    31
#include "../SDL_syssensor.h"
slouken@13710
    32
#include "../../core/windows/SDL_windows.h"
slouken@13710
    33
slouken@13710
    34
#define COBJMACROS
slouken@13710
    35
#include <InitGuid.h>
slouken@13710
    36
#include <SensorsApi.h>
slouken@13710
    37
#include <Sensors.h>
slouken@13710
    38
slouken@13710
    39
DEFINE_GUID(CLSID_SensorManager, 0x77A1C827, 0xFCD2, 0x4689, 0x89, 0x15, 0x9D, 0x61, 0x3C, 0xC5, 0xFA, 0x3E);
slouken@13710
    40
DEFINE_GUID(IID_SensorManager, 0xBD77DB67, 0x45A8, 0x42DC, 0x8D, 0x00, 0x6D, 0xCF, 0x15, 0xF8, 0x37, 0x7A);
slouken@13710
    41
DEFINE_GUID(IID_SensorManagerEvents, 0x9B3B0B86, 0x266A, 0x4AAD, 0xB2, 0x1F, 0xFD, 0xE5, 0x50, 0x10, 0x01, 0xB7);
slouken@13710
    42
DEFINE_GUID(IID_SensorEvents, 0x5D8DCC91, 0x4641, 0x47E7, 0xB7, 0xC3, 0xB7, 0x4F, 0x48, 0xA6, 0xC3, 0x91);
slouken@13710
    43
slouken@13776
    44
/* These constants aren't available in Visual Studio 2015 or earlier Windows SDK  */
slouken@13776
    45
#if defined(_MSC_VER) && _MSC_VER <= 1900
slouken@13776
    46
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 10); //[VT_R8]
slouken@13776
    47
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 11); //[VT_R8]
slouken@13776
    48
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 12); //[VT_R8]
slouken@13776
    49
#endif
slouken@13776
    50
slouken@13710
    51
typedef struct
slouken@13710
    52
{
slouken@13716
    53
    SDL_SensorID id;
slouken@13716
    54
    ISensor *sensor;
slouken@13716
    55
    SENSOR_ID sensor_id;
slouken@13716
    56
    char *name;
slouken@13716
    57
    SDL_SensorType type;
slouken@13716
    58
    SDL_Sensor *sensor_opened;
slouken@13710
    59
slouken@13710
    60
} SDL_Windows_Sensor;
slouken@13710
    61
slouken@13710
    62
static SDL_bool SDL_windowscoinit;
slouken@13710
    63
static ISensorManager *SDL_sensor_manager;
slouken@13710
    64
static int SDL_num_sensors;
slouken@13710
    65
static SDL_Windows_Sensor *SDL_sensors;
slouken@13710
    66
slouken@13710
    67
static int ConnectSensor(ISensor *sensor);
slouken@13710
    68
static int DisconnectSensor(ISensor *sensor);
slouken@13710
    69
slouken@13710
    70
static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_QueryInterface(ISensorManagerEvents * This, REFIID riid, void **ppvObject)
slouken@13710
    71
{
slouken@13716
    72
    if (!ppvObject) {
slouken@13716
    73
        return E_INVALIDARG;
slouken@13716
    74
    }
slouken@13710
    75
slouken@13716
    76
    *ppvObject = NULL;
slouken@13716
    77
    if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_SensorManagerEvents)) {
slouken@13716
    78
        *ppvObject = This;
slouken@13716
    79
        return S_OK;
slouken@13716
    80
    }
slouken@13716
    81
    return E_NOINTERFACE;
slouken@13710
    82
}
slouken@13710
    83
slouken@13710
    84
static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_AddRef(ISensorManagerEvents * This)
slouken@13710
    85
{
slouken@13716
    86
    return 1;
slouken@13710
    87
}
slouken@13710
    88
slouken@13710
    89
static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_Release(ISensorManagerEvents * This)
slouken@13710
    90
{
slouken@13716
    91
    return 1;
slouken@13710
    92
}
slouken@13710
    93
slouken@13710
    94
static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_OnSensorEnter(ISensorManagerEvents * This, ISensor *pSensor, SensorState state)
slouken@13710
    95
{
slouken@13716
    96
    ConnectSensor(pSensor);
slouken@13716
    97
    return S_OK;
slouken@13710
    98
}
slouken@13710
    99
slouken@13710
   100
static ISensorManagerEventsVtbl sensor_manager_events_vtbl = {
slouken@13716
   101
    ISensorManagerEventsVtbl_QueryInterface,
slouken@13716
   102
    ISensorManagerEventsVtbl_AddRef,
slouken@13716
   103
    ISensorManagerEventsVtbl_Release,
slouken@13716
   104
    ISensorManagerEventsVtbl_OnSensorEnter
slouken@13710
   105
};
slouken@13710
   106
static ISensorManagerEvents sensor_manager_events = {
slouken@13716
   107
    &sensor_manager_events_vtbl
slouken@13710
   108
};
slouken@13710
   109
slouken@13710
   110
static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_QueryInterface(ISensorEvents * This, REFIID riid, void **ppvObject)
slouken@13710
   111
{
slouken@13716
   112
    if (!ppvObject) {
slouken@13716
   113
        return E_INVALIDARG;
slouken@13716
   114
    }
slouken@13710
   115
slouken@13716
   116
    *ppvObject = NULL;
slouken@13716
   117
    if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_SensorEvents)) {
slouken@13716
   118
        *ppvObject = This;
slouken@13716
   119
        return S_OK;
slouken@13716
   120
    }
slouken@13716
   121
    return E_NOINTERFACE;
slouken@13710
   122
}
slouken@13710
   123
slouken@13710
   124
static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_AddRef(ISensorEvents * This)
slouken@13710
   125
{
slouken@13716
   126
    return 1;
slouken@13710
   127
}
slouken@13710
   128
slouken@13710
   129
static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_Release(ISensorEvents * This)
slouken@13710
   130
{
slouken@13716
   131
    return 1;
slouken@13710
   132
}
slouken@13710
   133
slouken@13710
   134
static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnStateChanged(ISensorEvents * This, ISensor *pSensor, SensorState state)
slouken@13710
   135
{
slouken@13710
   136
#ifdef DEBUG_SENSORS
slouken@13716
   137
    int i;
slouken@13710
   138
slouken@13716
   139
    SDL_LockSensors();
slouken@13716
   140
    for (i = 0; i < SDL_num_sensors; ++i) {
slouken@13716
   141
        if (pSensor == SDL_sensors[i].sensor) {
slouken@13716
   142
            SDL_Log("Sensor %s state changed to %d\n", SDL_sensors[i].name, state);
slouken@13716
   143
        }
slouken@13716
   144
    }
slouken@13716
   145
    SDL_UnlockSensors();
slouken@13710
   146
#endif
slouken@13716
   147
    return S_OK;
slouken@13710
   148
}
slouken@13710
   149
slouken@13710
   150
static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnDataUpdated(ISensorEvents * This, ISensor *pSensor, ISensorDataReport *pNewData)
slouken@13710
   151
{
slouken@13716
   152
    int i;
slouken@13710
   153
slouken@13716
   154
    SDL_LockSensors();
slouken@13716
   155
    for (i = 0; i < SDL_num_sensors; ++i) {
slouken@13716
   156
        if (pSensor == SDL_sensors[i].sensor) {
slouken@13716
   157
            if (SDL_sensors[i].sensor_opened) {
slouken@13716
   158
                HRESULT hrX, hrY, hrZ;
slouken@13716
   159
                PROPVARIANT valueX, valueY, valueZ;
slouken@13710
   160
slouken@13710
   161
#ifdef DEBUG_SENSORS
slouken@13716
   162
                SDL_Log("Sensor %s data updated\n", SDL_sensors[i].name);
slouken@13710
   163
#endif
slouken@13716
   164
                switch (SDL_sensors[i].type) {
slouken@13716
   165
                case SDL_SENSOR_ACCEL:
slouken@13716
   166
                    hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_X_G, &valueX);
slouken@13716
   167
                    hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Y_G, &valueY);
slouken@13716
   168
                    hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Z_G, &valueZ);
slouken@13716
   169
                    if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) &&
slouken@13716
   170
                        valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) {
slouken@13716
   171
                        float values[3];
slouken@13710
   172
slouken@13716
   173
                        values[0] = (float)valueX.dblVal * SDL_STANDARD_GRAVITY;
slouken@13716
   174
                        values[1] = (float)valueY.dblVal * SDL_STANDARD_GRAVITY;
slouken@13716
   175
                        values[2] = (float)valueZ.dblVal * SDL_STANDARD_GRAVITY;
slouken@13716
   176
                        SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, values, 3);
slouken@13716
   177
                    }
slouken@13716
   178
                    break;
slouken@13716
   179
                case SDL_SENSOR_GYRO:
slouken@13716
   180
                    hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, &valueX);
slouken@13716
   181
                    hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, &valueY);
slouken@13716
   182
                    hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, &valueZ);
slouken@13716
   183
                    if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) &&
slouken@13716
   184
                        valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) {
slouken@13716
   185
                        const float DEGREES_TO_RADIANS = (float)(M_PI / 180.0f);
slouken@13716
   186
                        float values[3];
slouken@13710
   187
slouken@13716
   188
                        values[0] = (float)valueX.dblVal * DEGREES_TO_RADIANS;
slouken@13716
   189
                        values[1] = (float)valueY.dblVal * DEGREES_TO_RADIANS;
slouken@13716
   190
                        values[2] = (float)valueZ.dblVal * DEGREES_TO_RADIANS;
slouken@13716
   191
                        SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, values, 3);
slouken@13716
   192
                    }
slouken@13716
   193
                    break;
slouken@13716
   194
                default:
slouken@13716
   195
                    /* FIXME: Need to know how to interpret the data for this sensor */
slouken@13716
   196
                    break;
slouken@13716
   197
                }
slouken@13716
   198
            }
slouken@13716
   199
            break;
slouken@13716
   200
        }
slouken@13716
   201
    }
slouken@13716
   202
    SDL_UnlockSensors();
slouken@13710
   203
slouken@13716
   204
    return S_OK;
slouken@13710
   205
}
slouken@13710
   206
slouken@13710
   207
static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnEvent(ISensorEvents * This, ISensor *pSensor, REFGUID eventID, IPortableDeviceValues *pEventData)
slouken@13710
   208
{
slouken@13710
   209
#ifdef DEBUG_SENSORS
slouken@13716
   210
    int i;
slouken@13710
   211
slouken@13716
   212
    SDL_LockSensors();
slouken@13716
   213
    for (i = 0; i < SDL_num_sensors; ++i) {
slouken@13716
   214
        if (pSensor == SDL_sensors[i].sensor) {
slouken@13716
   215
            SDL_Log("Sensor %s event occurred\n", SDL_sensors[i].name);
slouken@13716
   216
        }
slouken@13716
   217
    }
slouken@13716
   218
    SDL_UnlockSensors();
slouken@13710
   219
#endif
slouken@13716
   220
    return S_OK;
slouken@13710
   221
}
slouken@13710
   222
slouken@13710
   223
static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnLeave(ISensorEvents * This, REFSENSOR_ID ID)
slouken@13710
   224
{
slouken@13716
   225
    int i;
slouken@13710
   226
slouken@13716
   227
    SDL_LockSensors();
slouken@13716
   228
    for (i = 0; i < SDL_num_sensors; ++i) {
slouken@13716
   229
        if (WIN_IsEqualIID(ID, &SDL_sensors[i].sensor_id)) {
slouken@13710
   230
#ifdef DEBUG_SENSORS
slouken@13716
   231
            SDL_Log("Sensor %s disconnected\n", SDL_sensors[i].name);
slouken@13710
   232
#endif
slouken@13716
   233
            DisconnectSensor(SDL_sensors[i].sensor);
slouken@13716
   234
        }
slouken@13716
   235
    }
slouken@13716
   236
    SDL_UnlockSensors();
slouken@13710
   237
slouken@13716
   238
    return S_OK;
slouken@13710
   239
}
slouken@13710
   240
slouken@13710
   241
static ISensorEventsVtbl sensor_events_vtbl = {
slouken@13716
   242
    ISensorEventsVtbl_QueryInterface,
slouken@13716
   243
    ISensorEventsVtbl_AddRef,
slouken@13716
   244
    ISensorEventsVtbl_Release,
slouken@13716
   245
    ISensorEventsVtbl_OnStateChanged,
slouken@13716
   246
    ISensorEventsVtbl_OnDataUpdated,
slouken@13716
   247
    ISensorEventsVtbl_OnEvent,
slouken@13716
   248
    ISensorEventsVtbl_OnLeave
slouken@13710
   249
};
slouken@13710
   250
static ISensorEvents sensor_events = {
slouken@13716
   251
    &sensor_events_vtbl
slouken@13710
   252
};
slouken@13710
   253
slouken@13710
   254
static int ConnectSensor(ISensor *sensor)
slouken@13710
   255
{
slouken@13716
   256
    SDL_Windows_Sensor *new_sensor, *new_sensors;
slouken@13716
   257
    HRESULT hr;
slouken@13716
   258
    SENSOR_ID sensor_id;
slouken@13716
   259
    SENSOR_TYPE_ID type_id;
slouken@13716
   260
    SDL_SensorType type;
slouken@13716
   261
    BSTR bstr_name = NULL;
slouken@13716
   262
    char *name;
slouken@13710
   263
slouken@13716
   264
    hr = ISensor_GetID(sensor, &sensor_id);
slouken@13716
   265
    if (FAILED(hr)) {
slouken@13716
   266
        return SDL_SetError("Couldn't get sensor ID: 0x%.4x", hr);
slouken@13716
   267
    }
slouken@13710
   268
slouken@13716
   269
    hr = ISensor_GetType(sensor, &type_id);
slouken@13716
   270
    if (FAILED(hr)) {
slouken@13716
   271
        return SDL_SetError("Couldn't get sensor type: 0x%.4x", hr);
slouken@13716
   272
    }
slouken@13710
   273
slouken@13716
   274
    if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_ACCELEROMETER_3D)) {
slouken@13716
   275
        type = SDL_SENSOR_ACCEL;
slouken@13716
   276
    } else if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_GYROMETER_3D)) {
slouken@13716
   277
        type = SDL_SENSOR_GYRO;
slouken@13716
   278
    } else {
slouken@13716
   279
        return SDL_SetError("Unknown sensor type");
slouken@13716
   280
    }
slouken@13710
   281
slouken@13716
   282
    hr = ISensor_GetFriendlyName(sensor, &bstr_name);
slouken@13716
   283
    if (SUCCEEDED(hr) && bstr_name) {
slouken@13716
   284
        name = WIN_StringToUTF8(bstr_name);
slouken@13716
   285
    } else {
slouken@13716
   286
        name = SDL_strdup("Unknown Sensor");
slouken@13716
   287
    }
slouken@13714
   288
    if (bstr_name != NULL) {
slouken@13714
   289
        SysFreeString(bstr_name);
slouken@13714
   290
    }
slouken@13716
   291
    if (!name) {
slouken@13716
   292
        return SDL_OutOfMemory();
slouken@13716
   293
    }
slouken@13710
   294
slouken@13716
   295
    SDL_LockSensors();
slouken@13716
   296
    new_sensors = (SDL_Windows_Sensor *)SDL_realloc(SDL_sensors, (SDL_num_sensors + 1) * sizeof(SDL_Windows_Sensor));
slouken@13716
   297
    if (new_sensors == NULL) {
slouken@13716
   298
        SDL_UnlockSensors();
slouken@13716
   299
        return SDL_OutOfMemory();
slouken@13716
   300
    }
slouken@13716
   301
slouken@13716
   302
    ISensor_AddRef(sensor);
slouken@13716
   303
    ISensor_SetEventSink(sensor, &sensor_events);
slouken@13710
   304
slouken@13716
   305
    SDL_sensors = new_sensors;
slouken@13716
   306
    new_sensor = &SDL_sensors[SDL_num_sensors];
slouken@13716
   307
    ++SDL_num_sensors;
slouken@13710
   308
slouken@13716
   309
    SDL_zerop(new_sensor);
slouken@13716
   310
    new_sensor->id = SDL_GetNextSensorInstanceID();
slouken@13716
   311
    new_sensor->sensor = sensor;
slouken@13716
   312
    new_sensor->type = type;
slouken@13716
   313
    new_sensor->name = name;
slouken@13710
   314
slouken@13716
   315
    SDL_UnlockSensors();
slouken@13710
   316
slouken@13716
   317
    return 0;
slouken@13710
   318
}
slouken@13710
   319
slouken@13710
   320
static int DisconnectSensor(ISensor *sensor)
slouken@13710
   321
{
slouken@13716
   322
    SDL_Windows_Sensor *old_sensor;
slouken@13716
   323
    int i;
slouken@13710
   324
slouken@13716
   325
    SDL_LockSensors();
slouken@13716
   326
    for (i = 0; i < SDL_num_sensors; ++i) {
slouken@13716
   327
        old_sensor = &SDL_sensors[i];
slouken@13716
   328
        if (sensor == old_sensor->sensor) {
slouken@13716
   329
            ISensor_SetEventSink(sensor, NULL);
slouken@13716
   330
            ISensor_Release(sensor);
slouken@13716
   331
            SDL_free(old_sensor->name);
slouken@13716
   332
            --SDL_num_sensors;
slouken@13716
   333
            if (i < SDL_num_sensors) {
slouken@13716
   334
                SDL_memmove(&SDL_sensors[i], &SDL_sensors[i + 1], (SDL_num_sensors - i) * sizeof(SDL_sensors[i]));
slouken@13716
   335
            }
slouken@13716
   336
            break;
slouken@13716
   337
        }
slouken@13716
   338
    }
slouken@13716
   339
    SDL_UnlockSensors();
slouken@13710
   340
slouken@13716
   341
    return 0;
slouken@13710
   342
}
slouken@13710
   343
slouken@13710
   344
static int
slouken@13710
   345
SDL_WINDOWS_SensorInit(void)
slouken@13710
   346
{
slouken@13716
   347
    HRESULT hr;
slouken@13716
   348
    ISensorCollection *sensor_collection = NULL;
slouken@13710
   349
slouken@13716
   350
    if (WIN_CoInitialize() == S_OK) {
slouken@13716
   351
        SDL_windowscoinit = SDL_TRUE;
slouken@13716
   352
    }
slouken@13710
   353
icculus@13838
   354
    hr = CoCreateInstance(&CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &IID_SensorManager, (LPVOID *) &SDL_sensor_manager);
slouken@13716
   355
    if (FAILED(hr)) {
slouken@13716
   356
        return SDL_SetError("Couldn't create the sensor manager: 0x%.4x", hr);
slouken@13716
   357
    }
slouken@13710
   358
slouken@13716
   359
    hr = ISensorManager_SetEventSink(SDL_sensor_manager, &sensor_manager_events);
slouken@13716
   360
    if (FAILED(hr)) {
slouken@13716
   361
        ISensorManager_Release(SDL_sensor_manager);
slouken@13716
   362
        return SDL_SetError("Couldn't set the sensor manager event sink: 0x%.4x", hr);
slouken@13716
   363
    }
slouken@13710
   364
slouken@13716
   365
    hr = ISensorManager_GetSensorsByCategory(SDL_sensor_manager, &SENSOR_CATEGORY_ALL, &sensor_collection);
slouken@13716
   366
    if (SUCCEEDED(hr)) {
slouken@13716
   367
        ULONG i, count;
slouken@13710
   368
slouken@13716
   369
        hr = ISensorCollection_GetCount(sensor_collection, &count);
slouken@13716
   370
        if (SUCCEEDED(hr)) {
slouken@13716
   371
            for (i = 0; i < count; ++i) {
slouken@13716
   372
                ISensor *sensor;
slouken@13710
   373
slouken@13716
   374
                hr = ISensorCollection_GetAt(sensor_collection, i, &sensor);
slouken@13716
   375
                if (SUCCEEDED(hr)) {
slouken@13716
   376
                    SensorState state;
slouken@13710
   377
slouken@13716
   378
                    hr = ISensor_GetState(sensor, &state);
slouken@13716
   379
                    if (SUCCEEDED(hr)) {
slouken@13716
   380
                        ISensorManagerEventsVtbl_OnSensorEnter(&sensor_manager_events, sensor, state);
slouken@13716
   381
                    }
slouken@13716
   382
                    ISensorManager_Release(sensor);
slouken@13716
   383
                }
slouken@13716
   384
            }
slouken@13716
   385
        }
slouken@13716
   386
        ISensorCollection_Release(sensor_collection);
slouken@13716
   387
    }
slouken@13710
   388
    return 0;
slouken@13710
   389
}
slouken@13710
   390
slouken@13710
   391
static int
slouken@13710
   392
SDL_WINDOWS_SensorGetCount(void)
slouken@13710
   393
{
slouken@13710
   394
    return SDL_num_sensors;
slouken@13710
   395
}
slouken@13710
   396
slouken@13710
   397
static void
slouken@13710
   398
SDL_WINDOWS_SensorDetect(void)
slouken@13710
   399
{
slouken@13710
   400
}
slouken@13710
   401
slouken@13710
   402
static const char *
slouken@13710
   403
SDL_WINDOWS_SensorGetDeviceName(int device_index)
slouken@13710
   404
{
slouken@13710
   405
    return SDL_sensors[device_index].name;
slouken@13710
   406
}
slouken@13710
   407
slouken@13710
   408
static SDL_SensorType
slouken@13710
   409
SDL_WINDOWS_SensorGetDeviceType(int device_index)
slouken@13710
   410
{
slouken@13716
   411
    return SDL_sensors[device_index].type;
slouken@13710
   412
}
slouken@13710
   413
slouken@13710
   414
static int
slouken@13710
   415
SDL_WINDOWS_SensorGetDeviceNonPortableType(int device_index)
slouken@13710
   416
{
slouken@13710
   417
    return -1;
slouken@13710
   418
}
slouken@13710
   419
slouken@13710
   420
static SDL_SensorID
slouken@13710
   421
SDL_WINDOWS_SensorGetDeviceInstanceID(int device_index)
slouken@13710
   422
{
slouken@13710
   423
    return SDL_sensors[device_index].id;
slouken@13710
   424
}
slouken@13710
   425
slouken@13710
   426
static int
slouken@13710
   427
SDL_WINDOWS_SensorOpen(SDL_Sensor *sensor, int device_index)
slouken@13710
   428
{
slouken@13716
   429
    SDL_sensors[device_index].sensor_opened = sensor;
slouken@13710
   430
    return 0;
slouken@13710
   431
}
slouken@13710
   432
slouken@13710
   433
static void
slouken@13710
   434
SDL_WINDOWS_SensorUpdate(SDL_Sensor *sensor)
slouken@13710
   435
{
slouken@13710
   436
}
slouken@13710
   437
slouken@13710
   438
static void
slouken@13710
   439
SDL_WINDOWS_SensorClose(SDL_Sensor *sensor)
slouken@13710
   440
{
slouken@13716
   441
    int i;
slouken@13710
   442
slouken@13716
   443
    for (i = 0; i < SDL_num_sensors; ++i) {
slouken@13716
   444
        if (sensor == SDL_sensors[i].sensor_opened) {
slouken@13716
   445
            SDL_sensors[i].sensor_opened = NULL;
slouken@13716
   446
            break;
slouken@13716
   447
        }
slouken@13716
   448
    }
slouken@13710
   449
}
slouken@13710
   450
slouken@13710
   451
static void
slouken@13710
   452
SDL_WINDOWS_SensorQuit(void)
slouken@13710
   453
{
slouken@13716
   454
    while (SDL_num_sensors > 0) {
slouken@13716
   455
        DisconnectSensor(SDL_sensors[0].sensor);
slouken@13716
   456
    }
slouken@13710
   457
slouken@13716
   458
    if (SDL_sensor_manager) {
slouken@13716
   459
        ISensorManager_SetEventSink(SDL_sensor_manager, NULL);
slouken@13716
   460
        ISensorManager_Release(SDL_sensor_manager);
slouken@13716
   461
        SDL_sensor_manager = NULL;
slouken@13716
   462
    }
slouken@13710
   463
slouken@13716
   464
    if (SDL_windowscoinit) {
slouken@13716
   465
        WIN_CoUninitialize();
slouken@13716
   466
    }
slouken@13710
   467
}
slouken@13710
   468
slouken@13710
   469
SDL_SensorDriver SDL_WINDOWS_SensorDriver =
slouken@13710
   470
{
slouken@13710
   471
    SDL_WINDOWS_SensorInit,
slouken@13710
   472
    SDL_WINDOWS_SensorGetCount,
slouken@13710
   473
    SDL_WINDOWS_SensorDetect,
slouken@13710
   474
    SDL_WINDOWS_SensorGetDeviceName,
slouken@13710
   475
    SDL_WINDOWS_SensorGetDeviceType,
slouken@13710
   476
    SDL_WINDOWS_SensorGetDeviceNonPortableType,
slouken@13710
   477
    SDL_WINDOWS_SensorGetDeviceInstanceID,
slouken@13710
   478
    SDL_WINDOWS_SensorOpen,
slouken@13710
   479
    SDL_WINDOWS_SensorUpdate,
slouken@13710
   480
    SDL_WINDOWS_SensorClose,
slouken@13710
   481
    SDL_WINDOWS_SensorQuit,
slouken@13710
   482
};
slouken@13710
   483
slouken@13710
   484
#endif /* SDL_SENSOR_WINDOWS */
slouken@13710
   485
slouken@13710
   486
/* vi: set ts=4 sw=4 expandtab: */