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