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