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