19
19
3. This notice may not be removed or altered from any source distribution.
20
20
*/
21
21
22
+ /* Define standard library functions in terms of SDL */
23
+ #define HIDAPI_USING_SDL_RUNTIME
24
+ #define free SDL_free
25
+ #define iconv_t SDL_iconv_t
26
+ #define ICONV_CONST
27
+ #define iconv SDL_iconv
28
+ #define iconv_open SDL_iconv_open
29
+ #define iconv_close SDL_iconv_close
30
+ #define malloc SDL_malloc
31
+ #define realloc SDL_realloc
32
+ #define setlocale (X , Y ) NULL
33
+ #define snprintf SDL_snprintf
34
+ #define strcmp SDL_strcmp
35
+ #define strdup SDL_strdup
36
+ #define strncpy SDL_strlcpy
37
+ #define tolower SDL_tolower
38
+ #define wcsdup SDL_wcsdup
39
+
40
+
22
41
#ifndef __FreeBSD__
23
42
/* this is awkwardly inlined, so we need to re-implement it here
24
43
* so we can override the libusb_control_transfer call */
@@ -32,5 +51,192 @@ static int SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
32
51
#define libusb_get_string_descriptor SDL_libusb_get_string_descriptor
33
52
#endif /* __FreeBSD__ */
34
53
54
+ #define HIDAPI_THREAD_STATE_DEFINED
55
+
56
+ /* Barrier implementation because Android/Bionic don't have pthread_barrier.
57
+ This implementation came from Brent Priddy and was posted on
58
+ StackOverflow. It is used with his permission. */
59
+
60
+ typedef struct _SDL_ThreadBarrier
61
+ {
62
+ SDL_Mutex * mutex ;
63
+ SDL_Condition * cond ;
64
+ Uint32 count ;
65
+ Uint32 trip_count ;
66
+ } SDL_ThreadBarrier ;
67
+
68
+ static int SDL_CreateThreadBarrier (SDL_ThreadBarrier * barrier , Uint32 count )
69
+ {
70
+ SDL_assert (barrier != NULL );
71
+ SDL_assert (count != 0 );
72
+
73
+ barrier -> mutex = SDL_CreateMutex ();
74
+ if (barrier -> mutex == NULL ) {
75
+ return -1 ; /* Error set by CreateMutex */
76
+ }
77
+ barrier -> cond = SDL_CreateCondition ();
78
+ if (barrier -> cond == NULL ) {
79
+ return -1 ; /* Error set by CreateCond */
80
+ }
81
+
82
+ barrier -> trip_count = count ;
83
+ barrier -> count = 0 ;
84
+
85
+ return 0 ;
86
+ }
87
+
88
+ static void SDL_DestroyThreadBarrier (SDL_ThreadBarrier * barrier )
89
+ {
90
+ SDL_DestroyCondition (barrier -> cond );
91
+ SDL_DestroyMutex (barrier -> mutex );
92
+ }
93
+
94
+ static int SDL_WaitThreadBarrier (SDL_ThreadBarrier * barrier )
95
+ {
96
+ SDL_LockMutex (barrier -> mutex );
97
+ barrier -> count += 1 ;
98
+ if (barrier -> count >= barrier -> trip_count ) {
99
+ barrier -> count = 0 ;
100
+ SDL_BroadcastCondition (barrier -> cond );
101
+ SDL_UnlockMutex (barrier -> mutex );
102
+ return 1 ;
103
+ }
104
+ SDL_WaitCondition (barrier -> cond , barrier -> mutex );
105
+ SDL_UnlockMutex (barrier -> mutex );
106
+ return 0 ;
107
+ }
108
+
109
+ #include "../thread/SDL_systhread.h"
110
+
111
+ #define THREAD_STATE_WAIT_TIMED_OUT SDL_MUTEX_TIMEDOUT
112
+
113
+ typedef struct
114
+ {
115
+ SDL_Thread * thread ;
116
+ SDL_Mutex * mutex ; /* Protects input_reports */
117
+ SDL_Condition * condition ;
118
+ SDL_ThreadBarrier barrier ; /* Ensures correct startup sequence */
119
+
120
+ } hid_device_thread_state ;
121
+
122
+ static void thread_state_init (hid_device_thread_state * state )
123
+ {
124
+ state -> mutex = SDL_CreateMutex ();
125
+ state -> condition = SDL_CreateCondition ();
126
+ SDL_CreateThreadBarrier (& state -> barrier , 2 );
127
+ }
128
+
129
+ static void thread_state_free (hid_device_thread_state * state )
130
+ {
131
+ SDL_DestroyThreadBarrier (& state -> barrier );
132
+ SDL_DestroyCondition (state -> condition );
133
+ SDL_DestroyMutex (state -> mutex );
134
+ }
135
+
136
+ static SDL_TLSID libusb_thread_cleanup_routine ;
137
+
138
+ static void thread_state_push_cleanup (void (* routine )(void * ), void * arg )
139
+ {
140
+ /* This is only called in one place, so we can set a single thread-local value */
141
+ if (!libusb_thread_cleanup_routine ) {
142
+ libusb_thread_cleanup_routine = SDL_TLSCreate ();
143
+ }
144
+ SDL_TLSSet (libusb_thread_cleanup_routine , arg , routine );
145
+ }
146
+
147
+ static void thread_state_pop_cleanup (int execute )
148
+ {
149
+ SDL_TLSSet (libusb_thread_cleanup_routine , NULL , NULL );
150
+ }
151
+
152
+ static void thread_state_lock (hid_device_thread_state * state )
153
+ {
154
+ SDL_LockMutex (state -> mutex );
155
+ }
156
+
157
+ static void thread_state_unlock (hid_device_thread_state * state )
158
+ {
159
+ SDL_UnlockMutex (state -> mutex );
160
+ }
161
+
162
+ static void thread_state_wait_condition (hid_device_thread_state * state )
163
+ {
164
+ SDL_WaitCondition (state -> condition , state -> mutex );
165
+ }
166
+
167
+ static int thread_state_wait_condition_timeout (hid_device_thread_state * state , struct timespec * ts )
168
+ {
169
+ Uint64 end_time ;
170
+ Sint64 timeout_ns ;
171
+ Sint32 timeout_ms ;
172
+
173
+ end_time = ts -> tv_sec ;
174
+ end_time *= 1000000000L ;
175
+ end_time += ts -> tv_nsec ;
176
+ timeout_ns = (Sint64 )(end_time - SDL_GetTicksNS ());
177
+ if (timeout_ns <= 0 ) {
178
+ timeout_ms = 0 ;
179
+ } else {
180
+ timeout_ms = (Sint32 )SDL_NS_TO_MS (timeout_ns );
181
+ }
182
+ return SDL_WaitConditionTimeout (state -> condition , state -> mutex , timeout_ms );
183
+ }
184
+
185
+ static void thread_state_signal_condition (hid_device_thread_state * state )
186
+ {
187
+ SDL_SignalCondition (state -> condition );
188
+ }
189
+
190
+ static void thread_state_broadcast_condition (hid_device_thread_state * state )
191
+ {
192
+ SDL_BroadcastCondition (state -> condition );
193
+ }
194
+
195
+ static void thread_state_wait_barrier (hid_device_thread_state * state )
196
+ {
197
+ SDL_WaitThreadBarrier (& state -> barrier );
198
+ }
199
+
200
+ typedef struct
201
+ {
202
+ void * (* func )(void * );
203
+ void * func_arg ;
204
+
205
+ } RunInputThreadParam ;
206
+
207
+ static int RunInputThread (void * param )
208
+ {
209
+ RunInputThreadParam * data = (RunInputThreadParam * )param ;
210
+ void * (* func )(void * ) = data -> func ;
211
+ void * func_arg = data -> func_arg ;
212
+ SDL_free (data );
213
+ func (func_arg );
214
+ return 0 ;
215
+ }
216
+
217
+ static void thread_state_create_thread (hid_device_thread_state * state , void * (* func )(void * ), void * func_arg )
218
+ {
219
+ RunInputThreadParam * param = (RunInputThreadParam * )malloc (sizeof (* param ));
220
+ /* Note that the hidapi code didn't check for thread creation failure.
221
+ * We'll crash if malloc() fails
222
+ */
223
+ param -> func = func ;
224
+ param -> func_arg = func_arg ;
225
+ state -> thread = SDL_CreateThreadInternal (RunInputThread , "libusb" , 0 , param );
226
+ }
227
+
228
+ static void thread_state_join_thread (hid_device_thread_state * state )
229
+ {
230
+ SDL_WaitThread (state -> thread , NULL );
231
+ }
232
+
233
+ static void thread_state_get_current_time (struct timespec * ts )
234
+ {
235
+ Uint64 ns = SDL_GetTicksNS ();
236
+
237
+ ts -> tv_sec = ns / 1000000000L ;
238
+ ts -> tv_nsec = ns % 1000000000L ;
239
+ }
240
+
35
241
#undef HIDAPI_H__
36
242
#include "libusb/hid.c"
0 commit comments