SDL  2.0
SDL_sensor.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../SDL_internal.h"
22 
23 /* This is the sensor API for Simple DirectMedia Layer */
24 
25 #include "SDL.h"
26 #include "SDL_atomic.h"
27 #include "SDL_events.h"
28 #include "SDL_syssensor.h"
29 #include "SDL_assert.h"
30 
31 #if !SDL_EVENTS_DISABLED
32 #include "../events/SDL_events_c.h"
33 #endif
34 
36 #ifdef SDL_SENSOR_ANDROID
38 #endif
39 #ifdef SDL_SENSOR_COREMOTION
41 #endif
42 #if defined(SDL_SENSOR_DUMMY) || defined(SDL_SENSOR_DISABLED)
44 #endif
45 };
46 static SDL_Sensor *SDL_sensors = NULL;
48 static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
50 
51 static void
53 {
54  if (SDL_sensor_lock) {
56  }
57 }
58 
59 static void
61 {
62  if (SDL_sensor_lock) {
64  }
65 }
66 
67 
68 int
70 {
71  int i, status;
72 
73  /* Create the sensor list lock */
74  if (!SDL_sensor_lock) {
76  }
77 
78 #if !SDL_EVENTS_DISABLED
80  return -1;
81  }
82 #endif /* !SDL_EVENTS_DISABLED */
83 
84  status = -1;
85  for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
86  if (SDL_sensor_drivers[i]->Init() >= 0) {
87  status = 0;
88  }
89  }
90  return status;
91 }
92 
93 /*
94  * Count the number of sensors attached to the system
95  */
96 int
98 {
99  int i, total_sensors = 0;
100  SDL_LockSensors();
101  for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
102  total_sensors += SDL_sensor_drivers[i]->GetCount();
103  }
105  return total_sensors;
106 }
107 
108 /*
109  * Return the next available sensor instance ID
110  * This may be called by drivers from multiple threads, unprotected by any locks
111  */
113 {
115 }
116 
117 /*
118  * Get the driver and device index for an API device index
119  * This should be called while the sensor lock is held, to prevent another thread from updating the list
120  */
121 static SDL_bool
122 SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index)
123 {
124  int i, num_sensors, total_sensors = 0;
125 
126  if (device_index >= 0) {
127  for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
128  num_sensors = SDL_sensor_drivers[i]->GetCount();
129  if (device_index < num_sensors) {
130  *driver = SDL_sensor_drivers[i];
131  *driver_index = device_index;
132  return SDL_TRUE;
133  }
134  device_index -= num_sensors;
135  total_sensors += num_sensors;
136  }
137  }
138 
139  SDL_SetError("There are %d sensors available", total_sensors);
140  return SDL_FALSE;
141 }
142 
143 /*
144  * Get the implementation dependent name of a sensor
145  */
146 const char *
147 SDL_SensorGetDeviceName(int device_index)
148 {
149  SDL_SensorDriver *driver;
150  const char *name = NULL;
151 
152  SDL_LockSensors();
153  if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
154  name = driver->GetDeviceName(device_index);
155  }
157 
158  /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
159  return name;
160 }
161 
163 SDL_SensorGetDeviceType(int device_index)
164 {
165  SDL_SensorDriver *driver;
167 
168  SDL_LockSensors();
169  if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
170  type = driver->GetDeviceType(device_index);
171  }
173 
174  return type;
175 }
176 
179 {
180  SDL_SensorDriver *driver;
181  int type = -1;
182 
183  SDL_LockSensors();
184  if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
185  type = driver->GetDeviceNonPortableType(device_index);
186  }
188 
189  return type;
190 }
191 
194 {
195  SDL_SensorDriver *driver;
196  SDL_SensorID instance_id = -1;
197 
198  SDL_LockSensors();
199  if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
200  instance_id = driver->GetDeviceInstanceID(device_index);
201  }
203 
204  return instance_id;
205 }
206 
207 /*
208  * Open a sensor for use - the index passed as an argument refers to
209  * the N'th sensor on the system. This index is the value which will
210  * identify this sensor in future sensor events.
211  *
212  * This function returns a sensor identifier, or NULL if an error occurred.
213  */
214 SDL_Sensor *
215 SDL_SensorOpen(int device_index)
216 {
217  SDL_SensorDriver *driver;
218  SDL_SensorID instance_id;
219  SDL_Sensor *sensor;
220  SDL_Sensor *sensorlist;
221  const char *sensorname = NULL;
222 
223  SDL_LockSensors();
224 
225  if (!SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
227  return NULL;
228  }
229 
230  sensorlist = SDL_sensors;
231  /* If the sensor is already open, return it
232  * it is important that we have a single sensor * for each instance id
233  */
234  instance_id = driver->GetDeviceInstanceID(device_index);
235  while (sensorlist) {
236  if (instance_id == sensorlist->instance_id) {
237  sensor = sensorlist;
238  ++sensor->ref_count;
240  return sensor;
241  }
242  sensorlist = sensorlist->next;
243  }
244 
245  /* Create and initialize the sensor */
246  sensor = (SDL_Sensor *) SDL_calloc(sizeof(*sensor), 1);
247  if (sensor == NULL) {
248  SDL_OutOfMemory();
250  return NULL;
251  }
252  sensor->driver = driver;
253  sensor->instance_id = instance_id;
254  sensor->type = driver->GetDeviceType(device_index);
255  sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index);
256 
257  if (driver->Open(sensor, device_index) < 0) {
258  SDL_free(sensor);
260  return NULL;
261  }
262 
263  sensorname = driver->GetDeviceName(device_index);
264  if (sensorname) {
265  sensor->name = SDL_strdup(sensorname);
266  } else {
267  sensor->name = NULL;
268  }
269 
270  /* Add sensor to list */
271  ++sensor->ref_count;
272  /* Link the sensor in the list */
273  sensor->next = SDL_sensors;
274  SDL_sensors = sensor;
275 
277 
278  driver->Update(sensor);
279 
280  return sensor;
281 }
282 
283 /*
284  * Find the SDL_Sensor that owns this instance id
285  */
286 SDL_Sensor *
288 {
289  SDL_Sensor *sensor;
290 
291  SDL_LockSensors();
292  for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
293  if (sensor->instance_id == instance_id) {
294  break;
295  }
296  }
298  return sensor;
299 }
300 
301 /*
302  * Checks to make sure the sensor is valid.
303  */
304 static int
305 SDL_PrivateSensorValid(SDL_Sensor * sensor)
306 {
307  int valid;
308 
309  if (sensor == NULL) {
310  SDL_SetError("Sensor hasn't been opened yet");
311  valid = 0;
312  } else {
313  valid = 1;
314  }
315 
316  return valid;
317 }
318 
319 /*
320  * Get the friendly name of this sensor
321  */
322 const char *
323 SDL_SensorGetName(SDL_Sensor * sensor)
324 {
325  if (!SDL_PrivateSensorValid(sensor)) {
326  return NULL;
327  }
328 
329  return sensor->name;
330 }
331 
332 /*
333  * Get the type of this sensor
334  */
336 SDL_SensorGetType(SDL_Sensor * sensor)
337 {
338  if (!SDL_PrivateSensorValid(sensor)) {
339  return SDL_SENSOR_INVALID;
340  }
341 
342  return sensor->type;
343 }
344 
345 /*
346  * Get the platform dependent type of this sensor
347  */
348 int
349 SDL_SensorGetNonPortableType(SDL_Sensor * sensor)
350 {
351  if (!SDL_PrivateSensorValid(sensor)) {
352  return -1;
353  }
354 
355  return sensor->non_portable_type;
356 }
357 
358 /*
359  * Get the instance id for this opened sensor
360  */
362 SDL_SensorGetInstanceID(SDL_Sensor * sensor)
363 {
364  if (!SDL_PrivateSensorValid(sensor)) {
365  return -1;
366  }
367 
368  return sensor->instance_id;
369 }
370 
371 /*
372  * Get the current state of this sensor
373  */
374 int
375 SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values)
376 {
377  if (!SDL_PrivateSensorValid(sensor)) {
378  return -1;
379  }
380 
381  num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
382  SDL_memcpy(data, sensor->data, num_values*sizeof(*data));
383  return 0;
384 }
385 
386 /*
387  * Close a sensor previously opened with SDL_SensorOpen()
388  */
389 void
390 SDL_SensorClose(SDL_Sensor * sensor)
391 {
392  SDL_Sensor *sensorlist;
393  SDL_Sensor *sensorlistprev;
394 
395  if (!SDL_PrivateSensorValid(sensor)) {
396  return;
397  }
398 
399  SDL_LockSensors();
400 
401  /* First decrement ref count */
402  if (--sensor->ref_count > 0) {
404  return;
405  }
406 
407  if (SDL_updating_sensor) {
409  return;
410  }
411 
412  sensor->driver->Close(sensor);
413  sensor->hwdata = NULL;
414 
415  sensorlist = SDL_sensors;
416  sensorlistprev = NULL;
417  while (sensorlist) {
418  if (sensor == sensorlist) {
419  if (sensorlistprev) {
420  /* unlink this entry */
421  sensorlistprev->next = sensorlist->next;
422  } else {
423  SDL_sensors = sensor->next;
424  }
425  break;
426  }
427  sensorlistprev = sensorlist;
428  sensorlist = sensorlist->next;
429  }
430 
431  SDL_free(sensor->name);
432 
433  /* Free the data associated with this sensor */
434  SDL_free(sensor);
435 
437 }
438 
439 void
441 {
442  int i;
443 
444  /* Make sure we're not getting called in the middle of updating sensors */
446 
447  SDL_LockSensors();
448 
449  /* Stop the event polling */
450  while (SDL_sensors) {
451  SDL_sensors->ref_count = 1;
453  }
454 
455  /* Quit the sensor setup */
456  for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
458  }
459 
461 
462 #if !SDL_EVENTS_DISABLED
464 #endif
465 
466  if (SDL_sensor_lock) {
469  }
470 }
471 
472 
473 /* These are global for SDL_syssensor.c and SDL_events.c */
474 
475 int
476 SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values)
477 {
478  int posted;
479 
480  /* Allow duplicate events, for things like steps and heartbeats */
481 
482  /* Update internal sensor state */
483  num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
484  SDL_memcpy(sensor->data, data, num_values*sizeof(*data));
485 
486  /* Post the event, if desired */
487  posted = 0;
488 #if !SDL_EVENTS_DISABLED
491  event.type = SDL_SENSORUPDATE;
492  event.sensor.which = sensor->instance_id;
493  num_values = SDL_min(num_values, SDL_arraysize(event.sensor.data));
494  SDL_memset(event.sensor.data, 0, sizeof(event.sensor.data));
495  SDL_memcpy(event.sensor.data, data, num_values*sizeof(*data));
496  posted = SDL_PushEvent(&event) == 1;
497  }
498 #endif /* !SDL_EVENTS_DISABLED */
499  return posted;
500 }
501 
502 void
504 {
505  int i;
506  SDL_Sensor *sensor;
507 
508  SDL_LockSensors();
509 
510  if (SDL_updating_sensor) {
511  /* The sensors are already being updated */
513  return;
514  }
515 
517 
518  /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
520 
521  for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
522  sensor->driver->Update(sensor);
523  }
524 
525  SDL_LockSensors();
526 
528 
529  /* If any sensors were closed while updating, free them here */
530  for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
531  if (sensor->ref_count <= 0) {
532  SDL_SensorClose(sensor);
533  }
534  }
535 
536  /* this needs to happen AFTER walking the sensor list above, so that any
537  dangling hardware data from removed devices can be free'd
538  */
539  for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
541  }
542 
544 }
545 
546 /* vi: set ts=4 sw=4 expandtab: */
SDL.h
SDL_SensorDriver::Quit
void(* Quit)(void)
Definition: SDL_syssensor.h:94
SDL_SensorDriver::GetDeviceName
const char *(* GetDeviceName)(int device_index)
Definition: SDL_syssensor.h:66
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_PrivateSensorUpdate
int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values)
Definition: SDL_sensor.c:476
SDL_events.h
SDL_updating_sensor
static SDL_bool SDL_updating_sensor
Definition: SDL_sensor.c:47
SDL_SensorDriver::GetDeviceNonPortableType
int(* GetDeviceNonPortableType)(int device_index)
Definition: SDL_syssensor.h:72
SDL_SensorDriver
Definition: SDL_syssensor.h:52
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
SDL_atomic.h
NULL
#define NULL
Definition: begin_code.h:164
SDL_DUMMY_SensorDriver
SDL_SensorDriver SDL_DUMMY_SensorDriver
SDL_LockSensors
static void SDL_LockSensors(void)
Definition: SDL_sensor.c:52
SDL_SensorDriver::GetDeviceInstanceID
SDL_SensorID(* GetDeviceInstanceID)(int device_index)
Definition: SDL_syssensor.h:75
SDL_INIT_EVENTS
#define SDL_INIT_EVENTS
Definition: SDL.h:83
SDL_mutex
Definition: SDL_sysmutex.c:30
SDL_SensorInit
int SDL_SensorInit(void)
Definition: SDL_sensor.c:69
SDL_AtomicIncRef
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
Definition: SDL_atomic.h:234
SDL_QuitSubSystem
#define SDL_QuitSubSystem
Definition: SDL_dynapi_overrides.h:56
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
SDL_SensorGetDeviceName
const char * SDL_SensorGetDeviceName(int device_index)
Get the implementation dependent name of a sensor.
Definition: SDL_sensor.c:147
SDL_syssensor.h
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:756
SDL_GetDriverAndSensorIndex
static SDL_bool SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index)
Definition: SDL_sensor.c:122
SDL_InitSubSystem
#define SDL_InitSubSystem
Definition: SDL_dynapi_overrides.h:55
SDL_SensorGetName
const char * SDL_SensorGetName(SDL_Sensor *sensor)
Get the implementation dependent name of a sensor.
Definition: SDL_sensor.c:323
SDL_SensorDriver::GetDeviceType
SDL_SensorType(* GetDeviceType)(int device_index)
Definition: SDL_syssensor.h:69
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_SensorQuit
void SDL_SensorQuit(void)
Definition: SDL_sensor.c:440
SDL_SensorFromInstanceID
SDL_Sensor * SDL_SensorFromInstanceID(SDL_SensorID instance_id)
Definition: SDL_sensor.c:287
SDL_SensorType
SDL_SensorType
Definition: SDL_sensor.h:70
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_SensorUpdate
void SDL_SensorUpdate(void)
Definition: SDL_sensor.c:503
SDL_SensorGetDeviceType
SDL_SensorType SDL_SensorGetDeviceType(int device_index)
Get the type of a sensor.
Definition: SDL_sensor.c:163
SDL_SensorDriver::Detect
void(* Detect)(void)
Definition: SDL_syssensor.h:63
SDL_COREMOTION_SensorDriver
SDL_SensorDriver SDL_COREMOTION_SensorDriver
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:769
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_SENSORUPDATE
@ SDL_SENSORUPDATE
Definition: SDL_events.h:151
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:125
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
SDL_SensorDriver::Open
int(* Open)(SDL_Sensor *sensor, int device_index)
Definition: SDL_syssensor.h:81
SDL_assert.h
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
SDL_JOYAXISMOTION
@ SDL_JOYAXISMOTION
Definition: SDL_events.h:111
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_SensorGetInstanceID
SDL_SensorID SDL_SensorGetInstanceID(SDL_Sensor *sensor)
Get the instance ID of a sensor.
Definition: SDL_sensor.c:362
SDL_SENSOR_INVALID
@ SDL_SENSOR_INVALID
Definition: SDL_sensor.h:71
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_SensorGetDeviceInstanceID
SDL_SensorID SDL_SensorGetDeviceInstanceID(int device_index)
Get the instance ID of a sensor.
Definition: SDL_sensor.c:193
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_ANDROID_SensorDriver
SDL_SensorDriver SDL_ANDROID_SensorDriver
SDL_sensor_drivers
static SDL_SensorDriver * SDL_sensor_drivers[]
Definition: SDL_sensor.c:35
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_next_sensor_instance_id
static SDL_atomic_t SDL_next_sensor_instance_id
Definition: SDL_sensor.c:49
SDL_SensorClose
void SDL_SensorClose(SDL_Sensor *sensor)
Definition: SDL_sensor.c:390
SDL_SensorGetDeviceNonPortableType
SDL_SensorType SDL_SensorGetDeviceNonPortableType(int device_index)
Get the platform dependent type of a sensor.
Definition: SDL_sensor.c:178
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_atomic_t
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
Definition: SDL_atomic.h:198
SDL_sensors
static SDL_Sensor * SDL_sensors
Definition: SDL_sensor.c:46
SDL_PrivateSensorValid
static int SDL_PrivateSensorValid(SDL_Sensor *sensor)
Definition: SDL_sensor.c:305
SDL_DestroyMutex
#define SDL_DestroyMutex
Definition: SDL_dynapi_overrides.h:263
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_sensor_lock
static SDL_mutex * SDL_sensor_lock
Definition: SDL_sensor.c:48
SDL_SensorOpen
SDL_Sensor * SDL_SensorOpen(int device_index)
Open a sensor for use.
Definition: SDL_sensor.c:215
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_SensorDriver::GetCount
int(* GetCount)(void)
Definition: SDL_syssensor.h:60
SDL_NumSensors
int SDL_NumSensors(void)
Count the number of sensors attached to the system right now.
Definition: SDL_sensor.c:97
SDL_GetNextSensorInstanceID
SDL_SensorID SDL_GetNextSensorInstanceID()
Definition: SDL_sensor.c:112
SDL_Event
General event structure.
Definition: SDL_events.h:558
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_SensorGetData
int SDL_SensorGetData(SDL_Sensor *sensor, float *data, int num_values)
Definition: SDL_sensor.c:375
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_SensorGetNonPortableType
int SDL_SensorGetNonPortableType(SDL_Sensor *sensor)
Get the platform dependent type of a sensor.
Definition: SDL_sensor.c:349
SDL_UnlockSensors
static void SDL_UnlockSensors(void)
Definition: SDL_sensor.c:60
SDL_SensorGetType
SDL_SensorType SDL_SensorGetType(SDL_Sensor *sensor)
Get the type of a sensor.
Definition: SDL_sensor.c:336
SDL_SensorDriver::Update
void(* Update)(SDL_Sensor *sensor)
Definition: SDL_syssensor.h:88
SDL_SensorID
Sint32 SDL_SensorID
Definition: SDL_sensor.h:60