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