21 #include "../../SDL_internal.h"
23 #ifdef SDL_JOYSTICK_HIDAPI
31 #include "../../thread/SDL_systhread.h"
34 typedef struct SDL_HIDAPI_RumbleRequest
39 struct SDL_HIDAPI_RumbleRequest *prev;
41 } SDL_HIDAPI_RumbleRequest;
43 typedef struct SDL_HIDAPI_RumbleContext
50 SDL_HIDAPI_RumbleRequest *requests_head;
51 SDL_HIDAPI_RumbleRequest *requests_tail;
52 } SDL_HIDAPI_RumbleContext;
54 static SDL_HIDAPI_RumbleContext rumble_context;
56 static int SDL_HIDAPI_RumbleThread(
void *
data)
58 SDL_HIDAPI_RumbleContext *
ctx = (SDL_HIDAPI_RumbleContext *)
data;
63 SDL_HIDAPI_RumbleRequest *request =
NULL;
68 request =
ctx->requests_tail;
70 if (request ==
ctx->requests_head) {
73 ctx->requests_tail = request->prev;
79 if (request->device->dev) {
80 hid_write( request->device->dev, request->data, request->size );
91 SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *
ctx)
107 if (
ctx->request_sem) {
121 SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *
ctx)
125 SDL_HIDAPI_StopRumbleThread(
ctx);
130 if (!
ctx->request_sem) {
131 SDL_HIDAPI_StopRumbleThread(
ctx);
138 SDL_HIDAPI_StopRumbleThread(
ctx);
144 int SDL_HIDAPI_LockRumble(
void)
146 SDL_HIDAPI_RumbleContext *
ctx = &rumble_context;
149 if (SDL_HIDAPI_StartRumbleThread(
ctx) < 0) {
159 SDL_HIDAPI_RumbleContext *
ctx = &rumble_context;
160 SDL_HIDAPI_RumbleRequest *request;
162 for (request =
ctx->requests_tail; request; request = request->prev) {
163 if (request->device ==
device) {
164 *
data = request->data;
165 *
size = &request->size;
166 *maximum_size =
sizeof(request->data);
175 SDL_HIDAPI_RumbleContext *
ctx = &rumble_context;
176 SDL_HIDAPI_RumbleRequest *request;
178 if (
size >
sizeof(request->data)) {
179 SDL_HIDAPI_UnlockRumble();
180 return SDL_SetError(
"Couldn't send rumble, size %d is greater than %d",
size, (
int)
sizeof(request->data));
183 request = (SDL_HIDAPI_RumbleRequest *)
SDL_calloc(1,
sizeof(*request));
185 SDL_HIDAPI_UnlockRumble();
190 request->size =
size;
194 if (
ctx->requests_head) {
195 ctx->requests_head->prev = request;
197 ctx->requests_tail = request;
199 ctx->requests_head = request;
202 SDL_HIDAPI_UnlockRumble();
209 void SDL_HIDAPI_UnlockRumble(
void)
211 SDL_HIDAPI_RumbleContext *
ctx = &rumble_context;
222 if (SDL_HIDAPI_LockRumble() < 0) {
227 if (SDL_HIDAPI_GetPendingRumbleLocked(
device, &pending_data, &pending_size, &maximum_size)) {
228 if (
size > maximum_size) {
229 SDL_HIDAPI_UnlockRumble();
230 return SDL_SetError(
"Couldn't send rumble, size %d is greater than %d",
size, maximum_size);
234 *pending_size =
size;
235 SDL_HIDAPI_UnlockRumble();
242 void SDL_HIDAPI_QuitRumble(
void)
244 SDL_HIDAPI_RumbleContext *
ctx = &rumble_context;
247 SDL_HIDAPI_StopRumbleThread(
ctx);