SDL  2.0
SDL_joystick.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 joystick API for Simple DirectMedia Layer */
24 
25 #include "SDL.h"
26 #include "SDL_atomic.h"
27 #include "SDL_events.h"
28 #include "SDL_sysjoystick.h"
29 #include "SDL_hints.h"
30 
31 #if !SDL_EVENTS_DISABLED
32 #include "../events/SDL_events_c.h"
33 #endif
34 #include "../video/SDL_sysvideo.h"
36 
37 /* This is included in only one place because it has a large static list of controllers */
38 #include "controller_type.h"
39 
40 #ifdef __WIN32__
41 /* Needed for checking for input remapping programs */
42 #include "../core/windows/SDL_windows.h"
43 
44 #undef UNICODE /* We want ASCII functions */
45 #include <tlhelp32.h>
46 #endif
47 
48 #if SDL_JOYSTICK_VIRTUAL
50 #endif
51 
53 #ifdef SDL_JOYSTICK_HIDAPI /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
55 #endif
56 #ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
58 #endif
59 #if defined(SDL_JOYSTICK_WGI)
61 #endif
62 #if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
64 #endif
65 #ifdef SDL_JOYSTICK_LINUX
67 #endif
68 #ifdef SDL_JOYSTICK_IOKIT
70 #endif
71 #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)) && !defined(SDL_JOYSTICK_DISABLED)
73 #endif
74 #ifdef SDL_JOYSTICK_ANDROID
76 #endif
77 #ifdef SDL_JOYSTICK_EMSCRIPTEN
79 #endif
80 #ifdef SDL_JOYSTICK_HAIKU
82 #endif
83 #ifdef SDL_JOYSTICK_USBHID /* !!! FIXME: "USBHID" is a generic name, and doubly-confusing with HIDAPI next to it. This is the *BSD interface, rename this. */
85 #endif
86 #ifdef SDL_JOYSTICK_VIRTUAL
88 #endif
89 #if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
91 #endif
92 };
94 static SDL_Joystick *SDL_joysticks = NULL;
96 static SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */
100 
101 void
103 {
104  if (SDL_joystick_lock) {
106  }
107 }
108 
109 void
111 {
112  if (SDL_joystick_lock) {
114  }
115 }
116 
117 static int
119 {
120  int player_index;
121 
122  for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) {
123  if (SDL_joystick_players[player_index] == -1) {
124  return player_index;
125  }
126  }
127  return player_index;
128 }
129 
130 static int
132 {
133  int player_index;
134 
135  for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) {
136  if (instance_id == SDL_joystick_players[player_index]) {
137  break;
138  }
139  }
140  if (player_index == SDL_joystick_player_count) {
141  player_index = -1;
142  }
143  return player_index;
144 }
145 
146 static SDL_JoystickID
148 {
149  if (player_index < 0 || player_index >= SDL_joystick_player_count) {
150  return -1;
151  }
152  return SDL_joystick_players[player_index];
153 }
154 
155 static SDL_bool
156 SDL_SetJoystickIDForPlayerIndex(int player_index, SDL_JoystickID instance_id)
157 {
158  SDL_JoystickID existing_instance = SDL_GetJoystickIDForPlayerIndex(player_index);
159  SDL_JoystickDriver *driver;
160  int device_index;
161  int existing_player_index;
162 
163  if (player_index < 0) {
164  return SDL_FALSE;
165  }
166  if (player_index >= SDL_joystick_player_count) {
167  SDL_JoystickID *new_players = (SDL_JoystickID *)SDL_realloc(SDL_joystick_players, (player_index + 1)*sizeof(*SDL_joystick_players));
168  if (!new_players) {
169  SDL_OutOfMemory();
170  return SDL_FALSE;
171  }
172 
173  SDL_joystick_players = new_players;
175  SDL_joystick_player_count = player_index + 1;
176  } else if (SDL_joystick_players[player_index] == instance_id) {
177  /* Joystick is already assigned the requested player index */
178  return SDL_TRUE;
179  }
180 
181  /* Clear the old player index */
182  existing_player_index = SDL_GetPlayerIndexForJoystickID(instance_id);
183  if (existing_player_index >= 0) {
184  SDL_joystick_players[existing_player_index] = -1;
185  }
186 
187  SDL_joystick_players[player_index] = instance_id;
188 
189  /* Update the driver with the new index */
190  device_index = SDL_JoystickGetDeviceIndexFromInstanceID(instance_id);
191  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
192  driver->SetDevicePlayerIndex(device_index, player_index);
193  }
194 
195  /* Move any existing joystick to another slot */
196  if (existing_instance >= 0) {
198  }
199  return SDL_TRUE;
200 }
201 
202 static void SDLCALL
203 SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
204 {
205  if (hint && *hint == '1') {
207  } else {
209  }
210 }
211 
212 int
214 {
215  int i, status;
216 
218 
219  /* Create the joystick list lock */
220  if (!SDL_joystick_lock) {
222  }
223 
224  /* See if we should allow joystick events while in the background */
227 
228 #if !SDL_EVENTS_DISABLED
230  return -1;
231  }
232 #endif /* !SDL_EVENTS_DISABLED */
233 
234  status = -1;
235  for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
236  if (SDL_joystick_drivers[i]->Init() >= 0) {
237  status = 0;
238  }
239  }
240  return status;
241 }
242 
243 /*
244  * Count the number of joysticks attached to the system
245  */
246 int
248 {
249  int i, total_joysticks = 0;
251  for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
252  total_joysticks += SDL_joystick_drivers[i]->GetCount();
253  }
255  return total_joysticks;
256 }
257 
258 /*
259  * Return the next available joystick instance ID
260  * This may be called by drivers from multiple threads, unprotected by any locks
261  */
263 {
265 }
266 
267 /*
268  * Get the driver and device index for an API device index
269  * This should be called while the joystick lock is held, to prevent another thread from updating the list
270  */
271 SDL_bool
272 SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int *driver_index)
273 {
274  int i, num_joysticks, total_joysticks = 0;
275 
276  if (device_index >= 0) {
277  for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
278  num_joysticks = SDL_joystick_drivers[i]->GetCount();
279  if (device_index < num_joysticks) {
280  *driver = SDL_joystick_drivers[i];
281  *driver_index = device_index;
282  return SDL_TRUE;
283  }
284  device_index -= num_joysticks;
285  total_joysticks += num_joysticks;
286  }
287  }
288 
289  SDL_SetError("There are %d joysticks available", total_joysticks);
290  return SDL_FALSE;
291 }
292 
293 /*
294  * Get the implementation dependent name of a joystick
295  */
296 const char *
297 SDL_JoystickNameForIndex(int device_index)
298 {
299  SDL_JoystickDriver *driver;
300  const char *name = NULL;
301 
303  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
304  name = driver->GetDeviceName(device_index);
305  }
307 
308  /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
309  return name;
310 }
311 
312 /*
313  * Get the player index of a joystick, or -1 if it's not available
314  */
315 int
317 {
318  int player_index;
319 
323 
324  return player_index;
325 }
326 
327 /*
328  * Return true if this joystick is known to have all axes centered at zero
329  * This isn't generally needed unless the joystick never generates an initial axis value near zero,
330  * e.g. it's emulating axes with digital buttons
331  */
332 static SDL_bool
334 {
335  static Uint32 zero_centered_joysticks[] = {
336  MAKE_VIDPID(0x0e8f, 0x3013), /* HuiJia SNES USB adapter */
337  MAKE_VIDPID(0x05a0, 0x3232), /* 8Bitdo Zero Gamepad */
338  };
339 
340  int i;
343 
344 /*printf("JOYSTICK '%s' VID/PID 0x%.4x/0x%.4x AXES: %d\n", joystick->name, vendor, product, joystick->naxes);*/
345 
346  if (joystick->naxes == 2) {
347  /* Assume D-pad or thumbstick style axes are centered at 0 */
348  return SDL_TRUE;
349  }
350 
351  for (i = 0; i < SDL_arraysize(zero_centered_joysticks); ++i) {
352  if (id == zero_centered_joysticks[i]) {
353  return SDL_TRUE;
354  }
355  }
356  return SDL_FALSE;
357 }
358 
359 /*
360  * Open a joystick for use - the index passed as an argument refers to
361  * the N'th joystick on the system. This index is the value which will
362  * identify this joystick in future joystick events.
363  *
364  * This function returns a joystick identifier, or NULL if an error occurred.
365  */
366 SDL_Joystick *
367 SDL_JoystickOpen(int device_index)
368 {
369  SDL_JoystickDriver *driver;
370  SDL_JoystickID instance_id;
371  SDL_Joystick *joystick;
372  SDL_Joystick *joysticklist;
373  const char *joystickname = NULL;
374 
376 
377  if (!SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
379  return NULL;
380  }
381 
382  joysticklist = SDL_joysticks;
383  /* If the joystick is already open, return it
384  * it is important that we have a single joystick * for each instance id
385  */
386  instance_id = driver->GetDeviceInstanceID(device_index);
387  while (joysticklist) {
388  if (instance_id == joysticklist->instance_id) {
389  joystick = joysticklist;
390  ++joystick->ref_count;
392  return joystick;
393  }
394  joysticklist = joysticklist->next;
395  }
396 
397  /* Create and initialize the joystick */
398  joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1);
399  if (joystick == NULL) {
400  SDL_OutOfMemory();
402  return NULL;
403  }
404  joystick->driver = driver;
405  joystick->instance_id = instance_id;
406  joystick->attached = SDL_TRUE;
407  joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
408 
409  if (driver->Open(joystick, device_index) < 0) {
412  return NULL;
413  }
414 
415  joystickname = driver->GetDeviceName(device_index);
416  if (joystickname) {
417  joystick->name = SDL_strdup(joystickname);
418  } else {
419  joystick->name = NULL;
420  }
421 
422  joystick->guid = driver->GetDeviceGUID(device_index);
423 
424  if (joystick->naxes > 0) {
426  }
427  if (joystick->nhats > 0) {
428  joystick->hats = (Uint8 *) SDL_calloc(joystick->nhats, sizeof(Uint8));
429  }
430  if (joystick->nballs > 0) {
431  joystick->balls = (struct balldelta *) SDL_calloc(joystick->nballs, sizeof(*joystick->balls));
432  }
433  if (joystick->nbuttons > 0) {
434  joystick->buttons = (Uint8 *) SDL_calloc(joystick->nbuttons, sizeof(Uint8));
435  }
436  if (((joystick->naxes > 0) && !joystick->axes)
437  || ((joystick->nhats > 0) && !joystick->hats)
438  || ((joystick->nballs > 0) && !joystick->balls)
439  || ((joystick->nbuttons > 0) && !joystick->buttons)) {
440  SDL_OutOfMemory();
443  return NULL;
444  }
445 
446  /* If this joystick is known to have all zero centered axes, skip the auto-centering code */
448  int i;
449 
450  for (i = 0; i < joystick->naxes; ++i) {
451  joystick->axes[i].has_initial_value = SDL_TRUE;
452  }
453  }
454 
455  joystick->is_game_controller = SDL_IsGameController(device_index);
456 
457  /* Add joystick to list */
458  ++joystick->ref_count;
459  /* Link the joystick in the list */
460  joystick->next = SDL_joysticks;
462 
464 
465  driver->Update(joystick);
466 
467  return joystick;
468 }
469 
470 int
472  int naxes, int nbuttons, int nhats)
473 {
474 #if SDL_JOYSTICK_VIRTUAL
475  return SDL_JoystickAttachVirtualInner(type, naxes, nbuttons, nhats);
476 #else
477  return SDL_SetError("SDL not built with virtual-joystick support");
478 #endif
479 }
480 
481 int
482 SDL_JoystickDetachVirtual(int device_index)
483 {
484 #if SDL_JOYSTICK_VIRTUAL
485  SDL_JoystickDriver *driver;
486 
488  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
489  if (driver == &SDL_VIRTUAL_JoystickDriver) {
490  const int result = SDL_JoystickDetachVirtualInner(device_index);
492  return result;
493  }
494  }
496 
497  return SDL_SetError("Virtual joystick not found at provided index");
498 #else
499  return SDL_SetError("SDL not built with virtual-joystick support");
500 #endif
501 }
502 
503 SDL_bool
504 SDL_JoystickIsVirtual(int device_index)
505 {
506 #if SDL_JOYSTICK_VIRTUAL
507  SDL_JoystickDriver *driver;
508  int driver_device_index;
509  SDL_bool is_virtual = SDL_FALSE;
510 
512  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &driver_device_index)) {
513  if (driver == &SDL_VIRTUAL_JoystickDriver) {
514  is_virtual = SDL_TRUE;
515  }
516  }
518 
519  return is_virtual;
520 #else
521  return SDL_FALSE;
522 #endif
523 }
524 
525 int
527 {
528 #if SDL_JOYSTICK_VIRTUAL
529  return SDL_JoystickSetVirtualAxisInner(joystick, axis, value);
530 #else
531  return SDL_SetError("SDL not built with virtual-joystick support");
532 #endif
533 }
534 
535 int
537 {
538 #if SDL_JOYSTICK_VIRTUAL
539  return SDL_JoystickSetVirtualButtonInner(joystick, button, value);
540 #else
541  return SDL_SetError("SDL not built with virtual-joystick support");
542 #endif
543 }
544 
545 int
547 {
548 #if SDL_JOYSTICK_VIRTUAL
549  return SDL_JoystickSetVirtualHatInner(joystick, hat, value);
550 #else
551  return SDL_SetError("SDL not built with virtual-joystick support");
552 #endif
553 }
554 
555 /*
556  * Checks to make sure the joystick is valid.
557  */
558 SDL_bool
560 {
561  SDL_bool valid;
562 
563  if (joystick == NULL) {
564  SDL_SetError("Joystick hasn't been opened yet");
565  valid = SDL_FALSE;
566  } else {
567  valid = SDL_TRUE;
568  }
569 
570  return valid;
571 }
572 
573 SDL_bool
575 {
576  SDL_JoystickDriver *driver;
577  SDL_bool is_ok = SDL_FALSE;
578 
580  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
581  is_ok = driver->GetGamepadMapping(device_index, out);
582  }
584 
585  return is_ok;
586 }
587 
588 /*
589  * Get the number of multi-dimensional axis controls on a joystick
590  */
591 int
593 {
595  return -1;
596  }
597  return joystick->naxes;
598 }
599 
600 /*
601  * Get the number of hats on a joystick
602  */
603 int
605 {
607  return -1;
608  }
609  return joystick->nhats;
610 }
611 
612 /*
613  * Get the number of trackballs on a joystick
614  */
615 int
617 {
619  return -1;
620  }
621  return joystick->nballs;
622 }
623 
624 /*
625  * Get the number of buttons on a joystick
626  */
627 int
629 {
631  return -1;
632  }
633  return joystick->nbuttons;
634 }
635 
636 /*
637  * Get the current state of an axis control on a joystick
638  */
639 Sint16
640 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)
641 {
642  Sint16 state;
643 
645  return 0;
646  }
647  if (axis < joystick->naxes) {
648  state = joystick->axes[axis].value;
649  } else {
650  SDL_SetError("Joystick only has %d axes", joystick->naxes);
651  state = 0;
652  }
653  return state;
654 }
655 
656 /*
657  * Get the initial state of an axis control on a joystick
658  */
659 SDL_bool
661 {
663  return SDL_FALSE;
664  }
665  if (axis >= joystick->naxes) {
666  SDL_SetError("Joystick only has %d axes", joystick->naxes);
667  return SDL_FALSE;
668  }
669  if (state) {
670  *state = joystick->axes[axis].initial_value;
671  }
672  return joystick->axes[axis].has_initial_value;
673 }
674 
675 /*
676  * Get the current state of a hat on a joystick
677  */
678 Uint8
679 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat)
680 {
681  Uint8 state;
682 
684  return 0;
685  }
686  if (hat < joystick->nhats) {
687  state = joystick->hats[hat];
688  } else {
689  SDL_SetError("Joystick only has %d hats", joystick->nhats);
690  state = 0;
691  }
692  return state;
693 }
694 
695 /*
696  * Get the ball axis change since the last poll
697  */
698 int
699 SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
700 {
701  int retval;
702 
704  return -1;
705  }
706 
707  retval = 0;
708  if (ball < joystick->nballs) {
709  if (dx) {
710  *dx = joystick->balls[ball].dx;
711  }
712  if (dy) {
713  *dy = joystick->balls[ball].dy;
714  }
715  joystick->balls[ball].dx = 0;
716  joystick->balls[ball].dy = 0;
717  } else {
718  return SDL_SetError("Joystick only has %d balls", joystick->nballs);
719  }
720  return retval;
721 }
722 
723 /*
724  * Get the current state of a button on a joystick
725  */
726 Uint8
728 {
729  Uint8 state;
730 
732  return 0;
733  }
734  if (button < joystick->nbuttons) {
735  state = joystick->buttons[button];
736  } else {
737  SDL_SetError("Joystick only has %d buttons", joystick->nbuttons);
738  state = 0;
739  }
740  return state;
741 }
742 
743 /*
744  * Return if the joystick in question is currently attached to the system,
745  * \return SDL_FALSE if not plugged in, SDL_TRUE if still present.
746  */
747 SDL_bool
749 {
751  return SDL_FALSE;
752  }
753 
754  return joystick->attached;
755 }
756 
757 /*
758  * Get the instance id for this opened joystick
759  */
762 {
764  return -1;
765  }
766 
767  return joystick->instance_id;
768 }
769 
770 /*
771  * Return the SDL_Joystick associated with an instance id.
772  */
773 SDL_Joystick *
775 {
776  SDL_Joystick *joystick;
777 
779  for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
780  if (joystick->instance_id == instance_id) {
781  break;
782  }
783  }
785  return joystick;
786 }
787 
788 /**
789  * Return the SDL_Joystick associated with a player index.
790  */
791 SDL_Joystick *
793 {
794  SDL_JoystickID instance_id;
795  SDL_Joystick *joystick;
796 
798  instance_id = SDL_GetJoystickIDForPlayerIndex(player_index);
799  for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
800  if (joystick->instance_id == instance_id) {
801  break;
802  }
803  }
805  return joystick;
806 }
807 
808 /*
809  * Get the friendly name of this joystick
810  */
811 const char *
813 {
815  return NULL;
816  }
817 
818  return joystick->name;
819 }
820 
821 /**
822  * Get the player index of an opened joystick, or -1 if it's not available
823  */
824 int
826 {
827  int player_index;
828 
830  return -1;
831  }
832 
834  player_index = SDL_GetPlayerIndexForJoystickID(joystick->instance_id);
836 
837  return player_index;
838 }
839 
840 /**
841  * Set the player index of an opened joystick
842  */
843 void
844 SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index)
845 {
847  return;
848  }
849 
851  SDL_SetJoystickIDForPlayerIndex(player_index, joystick->instance_id);
853 }
854 
855 int
856 SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
857 {
858  int result;
859 
861  return -1;
862  }
863 
865  if (low_frequency_rumble == joystick->low_frequency_rumble &&
866  high_frequency_rumble == joystick->high_frequency_rumble) {
867  /* Just update the expiration */
868  result = 0;
869  } else {
870  result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
871  }
872 
873  /* Save the rumble value regardless of success, so we don't spam the driver */
874  joystick->low_frequency_rumble = low_frequency_rumble;
875  joystick->high_frequency_rumble = high_frequency_rumble;
876 
877  if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
878  joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
879  if (!joystick->rumble_expiration) {
880  joystick->rumble_expiration = 1;
881  }
882  } else {
883  joystick->rumble_expiration = 0;
884  }
886 
887  return result;
888 }
889 
890 int
891 SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms)
892 {
893  int result;
894 
896  return -1;
897  }
898 
900  if (left_rumble == joystick->left_trigger_rumble && right_rumble == joystick->right_trigger_rumble) {
901  /* Just update the expiration */
902  result = 0;
903  } else {
904  result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble);
905  }
906 
907  /* Save the rumble value regardless of success, so we don't spam the driver */
908  joystick->left_trigger_rumble = left_rumble;
909  joystick->right_trigger_rumble = right_rumble;
910 
911  if ((left_rumble || right_rumble) && duration_ms) {
912  joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
913  if (!joystick->trigger_rumble_expiration) {
914  joystick->trigger_rumble_expiration = 1;
915  }
916  } else {
917  joystick->trigger_rumble_expiration = 0;
918  }
920 
921  return result;
922 }
923 
924 SDL_bool
926 {
928 
930  return SDL_FALSE;
931  }
932 
934 
935  result = joystick->driver->HasLED(joystick);
936 
938 
939  return result;
940 }
941 
942 int
944 {
945  int result;
946 
948  return -1;
949  }
950 
952 
953  if (red == joystick->led_red &&
954  green == joystick->led_green &&
955  blue == joystick->led_blue) {
956  /* Avoid spamming the driver */
957  result = 0;
958  } else {
959  result = joystick->driver->SetLED(joystick, red, green, blue);
960  }
961 
962  /* Save the LED value regardless of success, so we don't spam the driver */
963  joystick->led_red = red;
964  joystick->led_green = green;
965  joystick->led_blue = blue;
966 
968 
969  return result;
970 }
971 
972 /*
973  * Close a joystick previously opened with SDL_JoystickOpen()
974  */
975 void
977 {
978  SDL_Joystick *joysticklist;
979  SDL_Joystick *joysticklistprev;
980  int i;
981 
983  return;
984  }
985 
987 
988  /* First decrement ref count */
989  if (--joystick->ref_count > 0) {
991  return;
992  }
993 
994  if (SDL_updating_joystick) {
996  return;
997  }
998 
999  if (joystick->rumble_expiration) {
1000  SDL_JoystickRumble(joystick, 0, 0, 0);
1001  }
1002  if (joystick->trigger_rumble_expiration) {
1004  }
1005 
1006  joystick->driver->Close(joystick);
1007  joystick->hwdata = NULL;
1008 
1009  joysticklist = SDL_joysticks;
1010  joysticklistprev = NULL;
1011  while (joysticklist) {
1012  if (joystick == joysticklist) {
1013  if (joysticklistprev) {
1014  /* unlink this entry */
1015  joysticklistprev->next = joysticklist->next;
1016  } else {
1017  SDL_joysticks = joystick->next;
1018  }
1019  break;
1020  }
1021  joysticklistprev = joysticklist;
1022  joysticklist = joysticklist->next;
1023  }
1024 
1025  SDL_free(joystick->name);
1026  SDL_free(joystick->serial);
1027 
1028  /* Free the data associated with this joystick */
1029  SDL_free(joystick->axes);
1030  SDL_free(joystick->hats);
1031  SDL_free(joystick->balls);
1032  SDL_free(joystick->buttons);
1033  for (i = 0; i < joystick->ntouchpads; i++) {
1034  SDL_JoystickTouchpadInfo *touchpad = &joystick->touchpads[i];
1035  SDL_free(touchpad->fingers);
1036  }
1037  SDL_free(joystick->touchpads);
1038  SDL_free(joystick->sensors);
1039  SDL_free(joystick);
1040 
1042 }
1043 
1044 void
1046 {
1047  int i;
1048 
1049  /* Make sure we're not getting called in the middle of updating joysticks */
1051  while (SDL_updating_joystick) {
1053  SDL_Delay(1);
1055  }
1056 
1057  /* Stop the event polling */
1058  while (SDL_joysticks) {
1059  SDL_joysticks->ref_count = 1;
1061  }
1062 
1063  /* Quit the joystick setup */
1064  for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
1066  }
1067 
1068  if (SDL_joystick_players) {
1072  }
1074 
1075 #if !SDL_EVENTS_DISABLED
1077 #endif
1078 
1081 
1082  if (SDL_joystick_lock) {
1086  }
1087 
1089 }
1090 
1091 
1092 static SDL_bool
1094 {
1096  return SDL_FALSE;
1097  }
1098 
1099  if (SDL_HasWindows() && SDL_GetKeyboardFocus() == NULL) {
1100  /* We have windows but we don't have focus, ignore the event. */
1101  return SDL_TRUE;
1102  }
1103  return SDL_FALSE;
1104 }
1105 
1106 /* These are global for SDL_sysjoystick.c and SDL_events.c */
1107 
1108 void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
1109 {
1110  int ntouchpads = joystick->ntouchpads + 1;
1111  SDL_JoystickTouchpadInfo *touchpads = (SDL_JoystickTouchpadInfo *)SDL_realloc(joystick->touchpads, (ntouchpads * sizeof(SDL_JoystickTouchpadInfo)));
1112  if (touchpads) {
1113  SDL_JoystickTouchpadInfo *touchpad = &touchpads[ntouchpads - 1];
1115 
1116  if (fingers) {
1117  touchpad->nfingers = nfingers;
1118  touchpad->fingers = fingers;
1119  } else {
1120  /* Out of memory, this touchpad won't be active */
1121  touchpad->nfingers = 0;
1122  touchpad->fingers = NULL;
1123  }
1124 
1125  joystick->ntouchpads = ntouchpads;
1126  joystick->touchpads = touchpads;
1127  }
1128 }
1129 
1131 {
1132  int nsensors = joystick->nsensors + 1;
1133  SDL_JoystickSensorInfo *sensors = (SDL_JoystickSensorInfo *)SDL_realloc(joystick->sensors, (nsensors * sizeof(SDL_JoystickSensorInfo)));
1134  if (sensors) {
1135  SDL_JoystickSensorInfo *sensor = &sensors[nsensors - 1];
1136 
1137  SDL_zerop(sensor);
1138  sensor->type = type;
1139 
1140  joystick->nsensors = nsensors;
1141  joystick->sensors = sensors;
1142  }
1143 }
1144 
1146 {
1147  SDL_JoystickDriver *driver;
1148  int driver_device_index;
1149  int player_index = -1;
1150  int device_index = SDL_JoystickGetDeviceIndexFromInstanceID(device_instance);
1151  if (device_index < 0) {
1152  return;
1153  }
1154 
1156  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &driver_device_index)) {
1157  player_index = driver->GetDevicePlayerIndex(driver_device_index);
1158  }
1159  if (player_index < 0 && SDL_IsGameController(device_index)) {
1160  player_index = SDL_FindFreePlayerIndex();
1161  }
1162  if (player_index >= 0) {
1163  SDL_SetJoystickIDForPlayerIndex(player_index, device_instance);
1164  }
1166 
1167 #if !SDL_EVENTS_DISABLED
1168  {
1169  SDL_Event event;
1170 
1171  event.type = SDL_JOYDEVICEADDED;
1172 
1173  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
1174  event.jdevice.which = device_index;
1175  SDL_PushEvent(&event);
1176  }
1177  }
1178 #endif /* !SDL_EVENTS_DISABLED */
1179 }
1180 
1181 /*
1182  * If there is an existing add event in the queue, it needs to be modified
1183  * to have the right value for which, because the number of controllers in
1184  * the system is now one less.
1185  */
1186 static void UpdateEventsForDeviceRemoval(int device_index)
1187 {
1188  int i, num_events;
1189  SDL_Event *events;
1190  SDL_bool isstack;
1191 
1193  if (num_events <= 0) {
1194  return;
1195  }
1196 
1197  events = SDL_small_alloc(SDL_Event, num_events, &isstack);
1198  if (!events) {
1199  return;
1200  }
1201 
1203  for (i = 0; i < num_events; ++i) {
1204  if (events[i].cdevice.which < device_index) {
1205  /* No change for index values lower than the removed device */
1206  }
1207  else if (events[i].cdevice.which == device_index) {
1208  /* Drop this event entirely */
1209  SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1)));
1210  --num_events;
1211  --i;
1212  }
1213  else {
1214  /* Fix up the device index if greater than the removed device */
1215  --events[i].cdevice.which;
1216  }
1217  }
1218  SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
1219 
1220  SDL_small_free(events, isstack);
1221 }
1222 
1223 static void
1225 {
1226  int i, j;
1227 
1228  /* Tell the app that everything is centered/unpressed... */
1229  for (i = 0; i < joystick->naxes; i++) {
1230  if (joystick->axes[i].has_initial_value) {
1231  SDL_PrivateJoystickAxis(joystick, i, joystick->axes[i].zero);
1232  }
1233  }
1234 
1235  for (i = 0; i < joystick->nbuttons; i++) {
1237  }
1238 
1239  for (i = 0; i < joystick->nhats; i++) {
1241  }
1242 
1243  for (i = 0; i < joystick->ntouchpads; i++) {
1244  SDL_JoystickTouchpadInfo *touchpad = &joystick->touchpads[i];
1245 
1246  for (j = 0; j < touchpad->nfingers; ++j) {
1247  SDL_PrivateJoystickTouchpad(joystick, i, j, SDL_RELEASED, 0.0f, 0.0f, 0.0f);
1248  }
1249  }
1250 
1251 }
1252 
1254 {
1255  SDL_Joystick *joystick = NULL;
1256  int player_index;
1257  int device_index;
1258 #if !SDL_EVENTS_DISABLED
1259  SDL_Event event;
1260 #endif
1261 
1262  /* Find this joystick... */
1263  device_index = 0;
1264  for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
1265  if (joystick->instance_id == device_instance) {
1267  joystick->attached = SDL_FALSE;
1268  break;
1269  }
1270 
1271  ++device_index;
1272  }
1273 
1274 #if !SDL_EVENTS_DISABLED
1275  SDL_zero(event);
1276  event.type = SDL_JOYDEVICEREMOVED;
1277 
1278  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
1279  event.jdevice.which = device_instance;
1280  SDL_PushEvent(&event);
1281  }
1282 
1283  UpdateEventsForDeviceRemoval(device_index);
1284 #endif /* !SDL_EVENTS_DISABLED */
1285 
1287  player_index = SDL_GetPlayerIndexForJoystickID(device_instance);
1288  if (player_index >= 0) {
1289  SDL_joystick_players[player_index] = -1;
1290  }
1292 }
1293 
1294 int
1296 {
1297  int posted;
1298  SDL_JoystickAxisInfo *info;
1299 
1300  /* Make sure we're not getting garbage or duplicate events */
1301  if (axis >= joystick->naxes) {
1302  return 0;
1303  }
1304 
1305  info = &joystick->axes[axis];
1306  if (!info->has_initial_value ||
1307  (!info->has_second_value && (info->initial_value <= -32767 || info->initial_value == 32767) && SDL_abs(value) < (SDL_JOYSTICK_AXIS_MAX / 4))) {
1308  info->initial_value = value;
1309  info->value = value;
1310  info->zero = value;
1311  info->has_initial_value = SDL_TRUE;
1312  } else if (value == info->value) {
1313  return 0;
1314  } else {
1315  info->has_second_value = SDL_TRUE;
1316  }
1317  if (!info->sent_initial_value) {
1318  /* Make sure we don't send motion until there's real activity on this axis */
1319  const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */
1320  if (SDL_abs(value - info->value) <= MAX_ALLOWED_JITTER) {
1321  return 0;
1322  }
1323  info->sent_initial_value = SDL_TRUE;
1324  info->value = ~value; /* Just so we pass the check above */
1326  }
1327 
1328  /* We ignore events if we don't have keyboard focus, except for centering
1329  * events.
1330  */
1332  if ((value > info->zero && value >= info->value) ||
1334  return 0;
1335  }
1336  }
1337 
1338  /* Update internal joystick state */
1339  info->value = value;
1340 
1341  /* Post the event, if desired */
1342  posted = 0;
1343 #if !SDL_EVENTS_DISABLED
1345  SDL_Event event;
1346  event.type = SDL_JOYAXISMOTION;
1347  event.jaxis.which = joystick->instance_id;
1348  event.jaxis.axis = axis;
1349  event.jaxis.value = value;
1350  posted = SDL_PushEvent(&event) == 1;
1351  }
1352 #endif /* !SDL_EVENTS_DISABLED */
1353  return posted;
1354 }
1355 
1356 int
1358 {
1359  int posted;
1360 
1361  /* Make sure we're not getting garbage or duplicate events */
1362  if (hat >= joystick->nhats) {
1363  return 0;
1364  }
1365  if (value == joystick->hats[hat]) {
1366  return 0;
1367  }
1368 
1369  /* We ignore events if we don't have keyboard focus, except for centering
1370  * events.
1371  */
1373  if (value != SDL_HAT_CENTERED) {
1374  return 0;
1375  }
1376  }
1377 
1378  /* Update internal joystick state */
1379  joystick->hats[hat] = value;
1380 
1381  /* Post the event, if desired */
1382  posted = 0;
1383 #if !SDL_EVENTS_DISABLED
1385  SDL_Event event;
1386  event.jhat.type = SDL_JOYHATMOTION;
1387  event.jhat.which = joystick->instance_id;
1388  event.jhat.hat = hat;
1389  event.jhat.value = value;
1390  posted = SDL_PushEvent(&event) == 1;
1391  }
1392 #endif /* !SDL_EVENTS_DISABLED */
1393  return posted;
1394 }
1395 
1396 int
1398  Sint16 xrel, Sint16 yrel)
1399 {
1400  int posted;
1401 
1402  /* Make sure we're not getting garbage events */
1403  if (ball >= joystick->nballs) {
1404  return 0;
1405  }
1406 
1407  /* We ignore events if we don't have keyboard focus. */
1409  return 0;
1410  }
1411 
1412  /* Update internal mouse state */
1413  joystick->balls[ball].dx += xrel;
1414  joystick->balls[ball].dy += yrel;
1415 
1416  /* Post the event, if desired */
1417  posted = 0;
1418 #if !SDL_EVENTS_DISABLED
1420  SDL_Event event;
1421  event.jball.type = SDL_JOYBALLMOTION;
1422  event.jball.which = joystick->instance_id;
1423  event.jball.ball = ball;
1424  event.jball.xrel = xrel;
1425  event.jball.yrel = yrel;
1426  posted = SDL_PushEvent(&event) == 1;
1427  }
1428 #endif /* !SDL_EVENTS_DISABLED */
1429  return posted;
1430 }
1431 
1432 int
1434 {
1435  int posted;
1436 #if !SDL_EVENTS_DISABLED
1437  SDL_Event event;
1438 
1439  switch (state) {
1440  case SDL_PRESSED:
1441  event.type = SDL_JOYBUTTONDOWN;
1442  break;
1443  case SDL_RELEASED:
1444  event.type = SDL_JOYBUTTONUP;
1445  break;
1446  default:
1447  /* Invalid state -- bail */
1448  return 0;
1449  }
1450 #endif /* !SDL_EVENTS_DISABLED */
1451 
1452  /* Make sure we're not getting garbage or duplicate events */
1453  if (button >= joystick->nbuttons) {
1454  return 0;
1455  }
1456  if (state == joystick->buttons[button]) {
1457  return 0;
1458  }
1459 
1460  /* We ignore events if we don't have keyboard focus, except for button
1461  * release. */
1463  if (state == SDL_PRESSED) {
1464  return 0;
1465  }
1466  }
1467 
1468  /* Update internal joystick state */
1469  joystick->buttons[button] = state;
1470 
1471  /* Post the event, if desired */
1472  posted = 0;
1473 #if !SDL_EVENTS_DISABLED
1474  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
1475  event.jbutton.which = joystick->instance_id;
1476  event.jbutton.button = button;
1477  event.jbutton.state = state;
1478  posted = SDL_PushEvent(&event) == 1;
1479  }
1480 #endif /* !SDL_EVENTS_DISABLED */
1481  return posted;
1482 }
1483 
1484 void
1486 {
1487  int i;
1488  SDL_Joystick *joystick, *next;
1489 
1491  return;
1492  }
1493 
1495 
1496  if (SDL_updating_joystick) {
1497  /* The joysticks are already being updated */
1499  return;
1500  }
1501 
1503 
1504  /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
1506 
1507 #ifdef SDL_JOYSTICK_HIDAPI
1508  /* Special function for HIDAPI devices, as a single device can provide multiple SDL_Joysticks */
1510 #endif /* SDL_JOYSTICK_HIDAPI */
1511 
1512  for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
1513  if (joystick->attached) {
1514  /* This should always be true, but seeing a crash in the wild...? */
1515  if (joystick->driver) {
1516  joystick->driver->Update(joystick);
1517  }
1518 
1519  if (joystick->delayed_guide_button) {
1521  }
1522  }
1523 
1524  if (joystick->rumble_expiration) {
1526  /* Double check now that the lock is held */
1527  if (joystick->rumble_expiration &&
1528  SDL_TICKS_PASSED(SDL_GetTicks(), joystick->rumble_expiration)) {
1529  SDL_JoystickRumble(joystick, 0, 0, 0);
1530  }
1532  }
1533 
1534  if (joystick->trigger_rumble_expiration) {
1536  /* Double check now that the lock is held */
1537  if (joystick->trigger_rumble_expiration &&
1538  SDL_TICKS_PASSED(SDL_GetTicks(), joystick->trigger_rumble_expiration)) {
1540  }
1542  }
1543  }
1544 
1546 
1548 
1549  /* If any joysticks were closed while updating, free them here */
1550  for (joystick = SDL_joysticks; joystick; joystick = next) {
1551  next = joystick->next;
1552  if (joystick->ref_count <= 0) {
1554  }
1555  }
1556 
1557  /* this needs to happen AFTER walking the joystick list above, so that any
1558  dangling hardware data from removed devices can be free'd
1559  */
1560  for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
1562  }
1563 
1565 }
1566 
1567 int
1569 {
1570 #if SDL_EVENTS_DISABLED
1571  return SDL_DISABLE;
1572 #else
1573  const Uint32 event_list[] = {
1576  };
1577  unsigned int i;
1578 
1579  switch (state) {
1580  case SDL_QUERY:
1581  state = SDL_DISABLE;
1582  for (i = 0; i < SDL_arraysize(event_list); ++i) {
1583  state = SDL_EventState(event_list[i], SDL_QUERY);
1584  if (state == SDL_ENABLE) {
1585  break;
1586  }
1587  }
1588  break;
1589  default:
1590  for (i = 0; i < SDL_arraysize(event_list); ++i) {
1591  SDL_EventState(event_list[i], state);
1592  }
1593  break;
1594  }
1595  return state;
1596 #endif /* SDL_EVENTS_DISABLED */
1597 }
1598 
1599 void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
1600 {
1601  Uint16 *guid16 = (Uint16 *)guid.data;
1602 
1603  /* If the GUID fits the form of BUS 0000 VENDOR 0000 PRODUCT 0000, return the data */
1604  if (/* guid16[0] is device bus type */
1605  guid16[1] == 0x0000 &&
1606  /* guid16[2] is vendor ID */
1607  guid16[3] == 0x0000 &&
1608  /* guid16[4] is product ID */
1609  guid16[5] == 0x0000
1610  /* guid16[6] is product version */
1611  ) {
1612  if (vendor) {
1613  *vendor = guid16[2];
1614  }
1615  if (product) {
1616  *product = guid16[4];
1617  }
1618  if (version) {
1619  *version = guid16[6];
1620  }
1621  } else {
1622  if (vendor) {
1623  *vendor = 0;
1624  }
1625  if (product) {
1626  *product = 0;
1627  }
1628  if (version) {
1629  *version = 0;
1630  }
1631  }
1632 }
1633 
1634 static int
1635 PrefixMatch(const char *a, const char *b)
1636 {
1637  int matchlen = 0;
1638  while (*a && *b) {
1639  if (SDL_tolower(*a++) == SDL_tolower(*b++)) {
1640  ++matchlen;
1641  } else {
1642  break;
1643  }
1644  }
1645  return matchlen;
1646 }
1647 
1648 char *
1649 SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
1650 {
1651  static struct {
1652  const char *prefix;
1653  const char *replacement;
1654  } replacements[] = {
1655  { "NVIDIA Corporation ", "" },
1656  { "Performance Designed Products", "PDP" },
1657  { "HORI CO.,LTD.", "HORI" },
1658  { "HORI CO.,LTD", "HORI" },
1659  };
1660  const char *custom_name;
1661  char *name;
1662  size_t i, len;
1663 
1664  custom_name = GuessControllerName(vendor, product);
1665  if (custom_name) {
1666  return SDL_strdup(custom_name);
1667  }
1668 
1669  if (!vendor_name) {
1670  vendor_name = "";
1671  }
1672  if (!product_name) {
1673  product_name = "";
1674  }
1675 
1676  while (*vendor_name == ' ') {
1677  ++vendor_name;
1678  }
1679  while (*product_name == ' ') {
1680  ++product_name;
1681  }
1682 
1683  if (*vendor_name && *product_name) {
1684  len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
1685  name = (char *)SDL_malloc(len);
1686  if (!name) {
1687  return NULL;
1688  }
1689  SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
1690  } else if (*product_name) {
1691  name = SDL_strdup(product_name);
1692  } else if (vendor || product) {
1693  len = (6 + 1 + 6 + 1);
1694  name = (char *)SDL_malloc(len);
1695  if (!name) {
1696  return NULL;
1697  }
1698  SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
1699  } else {
1700  name = SDL_strdup("Controller");
1701  }
1702 
1703  /* Trim trailing whitespace */
1704  for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
1705  /* continue */
1706  }
1707  name[len] = '\0';
1708 
1709  /* Compress duplicate spaces */
1710  for (i = 0; i < (len - 1); ) {
1711  if (name[i] == ' ' && name[i+1] == ' ') {
1712  SDL_memmove(&name[i], &name[i+1], (len - i));
1713  --len;
1714  } else {
1715  ++i;
1716  }
1717  }
1718 
1719  /* Remove duplicate manufacturer or product in the name */
1720  for (i = 1; i < (len - 1); ++i) {
1721  int matchlen = PrefixMatch(name, &name[i]);
1722  if (matchlen > 0 && name[matchlen-1] == ' ') {
1723  SDL_memmove(name, name+matchlen, len-matchlen+1);
1724  len -= matchlen;
1725  break;
1726  } else if (matchlen > 0 && name[matchlen] == ' ') {
1727  SDL_memmove(name, name+matchlen+1, len-matchlen);
1728  len -= (matchlen + 1);
1729  break;
1730  }
1731  }
1732 
1733  /* Perform any manufacturer replacements */
1734  for (i = 0; i < SDL_arraysize(replacements); ++i) {
1735  size_t prefixlen = SDL_strlen(replacements[i].prefix);
1736  if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
1737  size_t replacementlen = SDL_strlen(replacements[i].replacement);
1738  SDL_memcpy(name, replacements[i].replacement, replacementlen);
1739  SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1));
1740  break;
1741  }
1742  }
1743 
1744  return name;
1745 }
1746 
1749 {
1750  return SDL_GetJoystickGameControllerType(NULL, vendor, product, -1, 0, 0, 0);
1751 }
1752 
1755 {
1757  Uint16 vendor, product;
1758 
1759  SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
1760  type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0);
1762  if (SDL_IsJoystickXInput(guid)) {
1763  /* This is probably an Xbox One controller */
1765  }
1766  }
1767  return type;
1768 }
1769 
1771 SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
1772 {
1773  static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
1774  static const int XB360_IFACE_SUBCLASS = 93;
1775  static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
1776  static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
1777  static const int XBONE_IFACE_SUBCLASS = 71;
1778  static const int XBONE_IFACE_PROTOCOL = 208;
1779 
1781 
1782  /* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
1783  if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
1784  interface_subclass == XB360_IFACE_SUBCLASS &&
1785  (interface_protocol == XB360_IFACE_PROTOCOL ||
1786  interface_protocol == XB360W_IFACE_PROTOCOL)) {
1787 
1788  static const int SUPPORTED_VENDORS[] = {
1789  0x0079, /* GPD Win 2 */
1790  0x044f, /* Thrustmaster */
1791  0x045e, /* Microsoft */
1792  0x046d, /* Logitech */
1793  0x056e, /* Elecom */
1794  0x06a3, /* Saitek */
1795  0x0738, /* Mad Catz */
1796  0x07ff, /* Mad Catz */
1797  0x0e6f, /* PDP */
1798  0x0f0d, /* Hori */
1799  0x1038, /* SteelSeries */
1800  0x11c9, /* Nacon */
1801  0x12ab, /* Unknown */
1802  0x1430, /* RedOctane */
1803  0x146b, /* BigBen */
1804  0x1532, /* Razer Sabertooth */
1805  0x15e4, /* Numark */
1806  0x162e, /* Joytech */
1807  0x1689, /* Razer Onza */
1808  0x1bad, /* Harmonix */
1809  0x24c6, /* PowerA */
1810  };
1811 
1812  int i;
1813  for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
1814  if (vendor == SUPPORTED_VENDORS[i]) {
1816  break;
1817  }
1818  }
1819  }
1820 
1821  if (interface_number == 0 &&
1822  interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
1823  interface_subclass == XBONE_IFACE_SUBCLASS &&
1824  interface_protocol == XBONE_IFACE_PROTOCOL) {
1825 
1826  static const int SUPPORTED_VENDORS[] = {
1827  0x045e, /* Microsoft */
1828  0x0738, /* Mad Catz */
1829  0x0e6f, /* PDP */
1830  0x0f0d, /* Hori */
1831  0x1532, /* Razer Wildcat */
1832  0x24c6, /* PowerA */
1833  0x2e24, /* Hyperkin */
1834  };
1835 
1836  int i;
1837  for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
1838  if (vendor == SUPPORTED_VENDORS[i]) {
1840  break;
1841  }
1842  }
1843  }
1844 
1846  if (vendor == 0x0000 && product == 0x0000) {
1847  /* Some devices are only identifiable by their name */
1848  if (name &&
1849  (SDL_strcmp(name, "Lic Pro Controller") == 0 ||
1850  SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
1851  SDL_strcmp(name, "Wireless Gamepad") == 0)) {
1852  /* HORI or PowerA Switch Pro Controller clone */
1854  } else if (name && SDL_strcmp(name, "Virtual Joystick") == 0) {
1856  } else {
1858  }
1859 
1860  } else if (vendor == 0x0001 && product == 0x0001) {
1862 
1863  } else {
1864  switch (GuessControllerType(vendor, product)) {
1867  break;
1870  break;
1873  break;
1876  break;
1879  break;
1883  break;
1884  default:
1886  break;
1887  }
1888  }
1889  }
1890  return type;
1891 }
1892 
1893 SDL_bool
1895 {
1896  if (vendor_id == USB_VENDOR_MICROSOFT) {
1897  if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 ||
1898  product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 ||
1900  return SDL_TRUE;
1901  }
1902  }
1903  return SDL_FALSE;
1904 }
1905 
1906 SDL_bool
1908 {
1909  if (vendor_id == USB_VENDOR_MICROSOFT) {
1910  if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X ||
1912  return SDL_TRUE;
1913  }
1914  }
1915  return SDL_FALSE;
1916 }
1917 
1918 SDL_bool
1919 SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id)
1920 {
1921  EControllerType eType = GuessControllerType(vendor_id, product_id);
1922  return (eType == k_eControllerType_PS4Controller);
1923 }
1924 
1925 SDL_bool
1926 SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id)
1927 {
1928  EControllerType eType = GuessControllerType(vendor_id, product_id);
1929  return (eType == k_eControllerType_PS5Controller);
1930 }
1931 
1932 SDL_bool
1934 {
1935  EControllerType eType = GuessControllerType(vendor_id, product_id);
1936  return (eType == k_eControllerType_SwitchProController ||
1938 }
1939 
1940 SDL_bool
1942 {
1943  EControllerType eType = GuessControllerType(vendor_id, product_id);
1945 }
1946 
1947 SDL_bool
1949 {
1950  EControllerType eType = GuessControllerType(vendor_id, product_id);
1951  return (eType == k_eControllerType_SteamController ||
1953 }
1954 
1955 SDL_bool
1957 {
1958  return (guid.data[14] == 'x') ? SDL_TRUE : SDL_FALSE;
1959 }
1960 
1961 SDL_bool
1963 {
1964  return (guid.data[14] == 'w') ? SDL_TRUE : SDL_FALSE;
1965 }
1966 
1967 SDL_bool
1969 {
1970  return (guid.data[14] == 'h') ? SDL_TRUE : SDL_FALSE;
1971 }
1972 
1973 SDL_bool
1975 {
1976  return (guid.data[14] == 'r') ? SDL_TRUE : SDL_FALSE;
1977 }
1978 
1979 SDL_bool
1981 {
1982  return (guid.data[14] == 'v') ? SDL_TRUE : SDL_FALSE;
1983 }
1984 
1986 {
1987  static Uint32 wheel_joysticks[] = {
1988  MAKE_VIDPID(0x046d, 0xc294), /* Logitech generic wheel */
1989  MAKE_VIDPID(0x046d, 0xc295), /* Logitech Momo Force */
1990  MAKE_VIDPID(0x046d, 0xc298), /* Logitech Driving Force Pro */
1991  MAKE_VIDPID(0x046d, 0xc299), /* Logitech G25 */
1992  MAKE_VIDPID(0x046d, 0xc29a), /* Logitech Driving Force GT */
1993  MAKE_VIDPID(0x046d, 0xc29b), /* Logitech G27 */
1994  MAKE_VIDPID(0x046d, 0xc24f), /* Logitech G29 */
1995  MAKE_VIDPID(0x046d, 0xc261), /* Logitech G920 (initial mode) */
1996  MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */
1997  MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
1998  MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
1999  MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */
2000  MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
2001  MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
2002  };
2003  int i;
2004 
2005  for (i = 0; i < SDL_arraysize(wheel_joysticks); ++i) {
2006  if (vidpid == wheel_joysticks[i]) {
2007  return SDL_TRUE;
2008  }
2009  }
2010  return SDL_FALSE;
2011 }
2012 
2014 {
2015  static Uint32 flightstick_joysticks[] = {
2016  MAKE_VIDPID(0x044f, 0x0402), /* HOTAS Warthog Joystick */
2017  MAKE_VIDPID(0x0738, 0x2221), /* Saitek Pro Flight X-56 Rhino Stick */
2018  };
2019  int i;
2020 
2021  for (i = 0; i < SDL_arraysize(flightstick_joysticks); ++i) {
2022  if (vidpid == flightstick_joysticks[i]) {
2023  return SDL_TRUE;
2024  }
2025  }
2026  return SDL_FALSE;
2027 }
2028 
2030 {
2031  static Uint32 throttle_joysticks[] = {
2032  MAKE_VIDPID(0x044f, 0x0404), /* HOTAS Warthog Throttle */
2033  MAKE_VIDPID(0x0738, 0xa221), /* Saitek Pro Flight X-56 Rhino Throttle */
2034  };
2035  int i;
2036 
2037  for (i = 0; i < SDL_arraysize(throttle_joysticks); ++i) {
2038  if (vidpid == throttle_joysticks[i]) {
2039  return SDL_TRUE;
2040  }
2041  }
2042  return SDL_FALSE;
2043 }
2044 
2046 {
2047  Uint16 vendor;
2048  Uint16 product;
2049  Uint32 vidpid;
2050 
2051  if (SDL_IsJoystickXInput(guid)) {
2052  /* XInput GUID, get the type based on the XInput device subtype */
2053  switch (guid.data[15]) {
2054  case 0x01: /* XINPUT_DEVSUBTYPE_GAMEPAD */
2056  case 0x02: /* XINPUT_DEVSUBTYPE_WHEEL */
2057  return SDL_JOYSTICK_TYPE_WHEEL;
2058  case 0x03: /* XINPUT_DEVSUBTYPE_ARCADE_STICK */
2060  case 0x04: /* XINPUT_DEVSUBTYPE_FLIGHT_STICK */
2062  case 0x05: /* XINPUT_DEVSUBTYPE_DANCE_PAD */
2064  case 0x06: /* XINPUT_DEVSUBTYPE_GUITAR */
2065  case 0x07: /* XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE */
2066  case 0x0B: /* XINPUT_DEVSUBTYPE_GUITAR_BASS */
2067  return SDL_JOYSTICK_TYPE_GUITAR;
2068  case 0x08: /* XINPUT_DEVSUBTYPE_DRUM_KIT */
2070  case 0x13: /* XINPUT_DEVSUBTYPE_ARCADE_PAD */
2072  default:
2074  }
2075  }
2076 
2077  if (SDL_IsJoystickWGI(guid)) {
2078  return (SDL_JoystickType)guid.data[15];
2079  }
2080 
2081  if (SDL_IsJoystickVirtual(guid)) {
2082  return (SDL_JoystickType)guid.data[15];
2083  }
2084 
2085  SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
2086  vidpid = MAKE_VIDPID(vendor, product);
2087 
2088  if (SDL_IsJoystickProductWheel(vidpid)) {
2089  return SDL_JOYSTICK_TYPE_WHEEL;
2090  }
2091 
2092  if (SDL_IsJoystickProductFlightStick(vidpid)) {
2094  }
2095 
2096  if (SDL_IsJoystickProductThrottle(vidpid)) {
2098  }
2099 
2102  }
2103 
2105 }
2106 
2108 {
2109 #ifdef __WIN32__
2110  const char *mapper_processes[] = {
2111  "DS4Windows.exe",
2112  "InputMapper.exe",
2113  };
2114  int i;
2115  PROCESSENTRY32 pe32;
2116  SDL_bool found = SDL_FALSE;
2117 
2118  /* Take a snapshot of all processes in the system */
2119  HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
2120  if (hProcessSnap != INVALID_HANDLE_VALUE) {
2121  pe32.dwSize = sizeof(PROCESSENTRY32);
2122  if (Process32First(hProcessSnap, &pe32)) {
2123  do
2124  {
2125  for (i = 0; i < SDL_arraysize(mapper_processes); ++i) {
2126  if (SDL_strcasecmp(pe32.szExeFile, mapper_processes[i]) == 0) {
2127  found = SDL_TRUE;
2128  }
2129  }
2130  } while (Process32Next(hProcessSnap, &pe32) && !found);
2131  }
2132  CloseHandle(hProcessSnap);
2133  }
2134  return found;
2135 #else
2136  return SDL_FALSE;
2137 #endif
2138 }
2139 
2141 {
2142  /* This list is taken from:
2143  https://raw.githubusercontent.com/denilsonsa/udev-joystick-blacklist/master/generate_rules.py
2144  */
2145  static Uint32 joystick_blacklist[] = {
2146  /* Microsoft Microsoft Wireless Optical Desktop 2.10 */
2147  /* Microsoft Wireless Desktop - Comfort Edition */
2148  MAKE_VIDPID(0x045e, 0x009d),
2149 
2150  /* Microsoft Microsoft Digital Media Pro Keyboard */
2151  /* Microsoft Corp. Digital Media Pro Keyboard */
2152  MAKE_VIDPID(0x045e, 0x00b0),
2153 
2154  /* Microsoft Microsoft Digital Media Keyboard */
2155  /* Microsoft Corp. Digital Media Keyboard 1.0A */
2156  MAKE_VIDPID(0x045e, 0x00b4),
2157 
2158  /* Microsoft Microsoft Digital Media Keyboard 3000 */
2159  MAKE_VIDPID(0x045e, 0x0730),
2160 
2161  /* Microsoft Microsoft 2.4GHz Transceiver v6.0 */
2162  /* Microsoft Microsoft 2.4GHz Transceiver v8.0 */
2163  /* Microsoft Corp. Nano Transceiver v1.0 for Bluetooth */
2164  /* Microsoft Wireless Mobile Mouse 1000 */
2165  /* Microsoft Wireless Desktop 3000 */
2166  MAKE_VIDPID(0x045e, 0x0745),
2167 
2168  /* Microsoft SideWinder(TM) 2.4GHz Transceiver */
2169  MAKE_VIDPID(0x045e, 0x0748),
2170 
2171  /* Microsoft Corp. Wired Keyboard 600 */
2172  MAKE_VIDPID(0x045e, 0x0750),
2173 
2174  /* Microsoft Corp. Sidewinder X4 keyboard */
2175  MAKE_VIDPID(0x045e, 0x0768),
2176 
2177  /* Microsoft Corp. Arc Touch Mouse Transceiver */
2178  MAKE_VIDPID(0x045e, 0x0773),
2179 
2180  /* Microsoft 2.4GHz Transceiver v9.0 */
2181  /* Microsoft Nano Transceiver v2.1 */
2182  /* Microsoft Sculpt Ergonomic Keyboard (5KV-00001) */
2183  MAKE_VIDPID(0x045e, 0x07a5),
2184 
2185  /* Microsoft Nano Transceiver v1.0 */
2186  /* Microsoft Wireless Keyboard 800 */
2187  MAKE_VIDPID(0x045e, 0x07b2),
2188 
2189  /* Microsoft Nano Transceiver v2.0 */
2190  MAKE_VIDPID(0x045e, 0x0800),
2191 
2192  MAKE_VIDPID(0x046d, 0xc30a), /* Logitech, Inc. iTouch Composite keboard */
2193 
2194  MAKE_VIDPID(0x04d9, 0xa0df), /* Tek Syndicate Mouse (E-Signal USB Gaming Mouse) */
2195 
2196  /* List of Wacom devices at: http://linuxwacom.sourceforge.net/wiki/index.php/Device_IDs */
2197  MAKE_VIDPID(0x056a, 0x0010), /* Wacom ET-0405 Graphire */
2198  MAKE_VIDPID(0x056a, 0x0011), /* Wacom ET-0405A Graphire2 (4x5) */
2199  MAKE_VIDPID(0x056a, 0x0012), /* Wacom ET-0507A Graphire2 (5x7) */
2200  MAKE_VIDPID(0x056a, 0x0013), /* Wacom CTE-430 Graphire3 (4x5) */
2201  MAKE_VIDPID(0x056a, 0x0014), /* Wacom CTE-630 Graphire3 (6x8) */
2202  MAKE_VIDPID(0x056a, 0x0015), /* Wacom CTE-440 Graphire4 (4x5) */
2203  MAKE_VIDPID(0x056a, 0x0016), /* Wacom CTE-640 Graphire4 (6x8) */
2204  MAKE_VIDPID(0x056a, 0x0017), /* Wacom CTE-450 Bamboo Fun (4x5) */
2205  MAKE_VIDPID(0x056a, 0x0018), /* Wacom CTE-650 Bamboo Fun 6x8 */
2206  MAKE_VIDPID(0x056a, 0x0019), /* Wacom CTE-631 Bamboo One */
2207  MAKE_VIDPID(0x056a, 0x00d1), /* Wacom Bamboo Pen and Touch CTH-460 */
2208  MAKE_VIDPID(0x056a, 0x030e), /* Wacom Intuos Pen (S) CTL-480 */
2209 
2210  MAKE_VIDPID(0x09da, 0x054f), /* A4 Tech Co., G7 750 mouse */
2211  MAKE_VIDPID(0x09da, 0x1410), /* A4 Tech Co., Ltd Bloody AL9 mouse */
2212  MAKE_VIDPID(0x09da, 0x3043), /* A4 Tech Co., Ltd Bloody R8A Gaming Mouse */
2213  MAKE_VIDPID(0x09da, 0x31b5), /* A4 Tech Co., Ltd Bloody TL80 Terminator Laser Gaming Mouse */
2214  MAKE_VIDPID(0x09da, 0x3997), /* A4 Tech Co., Ltd Bloody RT7 Terminator Wireless */
2215  MAKE_VIDPID(0x09da, 0x3f8b), /* A4 Tech Co., Ltd Bloody V8 mouse */
2216  MAKE_VIDPID(0x09da, 0x51f4), /* Modecom MC-5006 Keyboard */
2217  MAKE_VIDPID(0x09da, 0x5589), /* A4 Tech Co., Ltd Terminator TL9 Laser Gaming Mouse */
2218  MAKE_VIDPID(0x09da, 0x7b22), /* A4 Tech Co., Ltd Bloody V5 */
2219  MAKE_VIDPID(0x09da, 0x7f2d), /* A4 Tech Co., Ltd Bloody R3 mouse */
2220  MAKE_VIDPID(0x09da, 0x8090), /* A4 Tech Co., Ltd X-718BK Oscar Optical Gaming Mouse */
2221  MAKE_VIDPID(0x09da, 0x9033), /* A4 Tech Co., X7 X-705K */
2222  MAKE_VIDPID(0x09da, 0x9066), /* A4 Tech Co., Sharkoon Fireglider Optical */
2223  MAKE_VIDPID(0x09da, 0x9090), /* A4 Tech Co., Ltd XL-730K / XL-750BK / XL-755BK Laser Mouse */
2224  MAKE_VIDPID(0x09da, 0x90c0), /* A4 Tech Co., Ltd X7 G800V keyboard */
2225  MAKE_VIDPID(0x09da, 0xf012), /* A4 Tech Co., Ltd Bloody V7 mouse */
2226  MAKE_VIDPID(0x09da, 0xf32a), /* A4 Tech Co., Ltd Bloody B540 keyboard */
2227  MAKE_VIDPID(0x09da, 0xf613), /* A4 Tech Co., Ltd Bloody V2 mouse */
2228  MAKE_VIDPID(0x09da, 0xf624), /* A4 Tech Co., Ltd Bloody B120 Keyboard */
2229 
2230  MAKE_VIDPID(0x1b1c, 0x1b3c), /* Corsair Harpoon RGB gaming mouse */
2231 
2232  MAKE_VIDPID(0x1d57, 0xad03), /* [T3] 2.4GHz and IR Air Mouse Remote Control */
2233 
2234  MAKE_VIDPID(0x1e7d, 0x2e4a), /* Roccat Tyon Mouse */
2235 
2236  MAKE_VIDPID(0x20a0, 0x422d), /* Winkeyless.kr Keyboards */
2237 
2238  MAKE_VIDPID(0x2516, 0x001f), /* Cooler Master Storm Mizar Mouse */
2239  MAKE_VIDPID(0x2516, 0x0028), /* Cooler Master Storm Alcor Mouse */
2240  };
2241 
2242  unsigned int i;
2243  Uint32 id;
2244  Uint16 vendor;
2245  Uint16 product;
2247 
2248  SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
2249 
2250  /* Check the joystick blacklist */
2251  id = MAKE_VIDPID(vendor, product);
2252  for (i = 0; i < SDL_arraysize(joystick_blacklist); ++i) {
2253  if (id == joystick_blacklist[i]) {
2254  return SDL_TRUE;
2255  }
2256  }
2257 
2258  type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0);
2260  return SDL_TRUE;
2261  }
2262 
2265  return SDL_TRUE;
2266  }
2267 
2268  return SDL_FALSE;
2269 }
2270 
2271 /* return the guid for this index */
2273 {
2274  SDL_JoystickDriver *driver;
2275  SDL_JoystickGUID guid;
2276 
2278  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
2279  guid = driver->GetDeviceGUID(device_index);
2280  } else {
2281  SDL_zero(guid);
2282  }
2284 
2285  return guid;
2286 }
2287 
2289 {
2290  Uint16 vendor;
2291  SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
2292 
2293  SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL);
2294  return vendor;
2295 }
2296 
2298 {
2299  Uint16 product;
2300  SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
2301 
2302  SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL);
2303  return product;
2304 }
2305 
2307 {
2308  Uint16 version;
2309  SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
2310 
2311  SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version);
2312  return version;
2313 }
2314 
2316 {
2318  SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
2319 
2320  type = SDL_GetJoystickGUIDType(guid);
2322  if (SDL_IsGameController(device_index)) {
2324  }
2325  }
2326  return type;
2327 }
2328 
2330 {
2331  SDL_JoystickDriver *driver;
2332  SDL_JoystickID instance_id = -1;
2333 
2335  if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
2336  instance_id = driver->GetDeviceInstanceID(device_index);
2337  }
2339 
2340  return instance_id;
2341 }
2342 
2344 {
2345  int i, num_joysticks, device_index = -1;
2346 
2348  num_joysticks = SDL_NumJoysticks();
2349  for (i = 0; i < num_joysticks; ++i) {
2350  if (SDL_JoystickGetDeviceInstanceID(i) == instance_id) {
2351  device_index = i;
2352  break;
2353  }
2354  }
2356 
2357  return device_index;
2358 }
2359 
2361 {
2363  SDL_JoystickGUID emptyGUID;
2364  SDL_zero(emptyGUID);
2365  return emptyGUID;
2366  }
2367  return joystick->guid;
2368 }
2369 
2371 {
2372  Uint16 vendor;
2374 
2375  SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL);
2376  return vendor;
2377 }
2378 
2380 {
2381  Uint16 product;
2383 
2384  SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL);
2385  return product;
2386 }
2387 
2389 {
2390  Uint16 version;
2392 
2393  SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version);
2394  return version;
2395 }
2396 
2397 const char *SDL_JoystickGetSerial(SDL_Joystick *joystick)
2398 {
2400  return NULL;
2401  }
2402  return joystick->serial;
2403 }
2404 
2406 {
2409 
2410  type = SDL_GetJoystickGUIDType(guid);
2412  if (joystick && joystick->is_game_controller) {
2414  }
2415  }
2416  return type;
2417 }
2418 
2419 /* convert the guid to a printable string */
2420 void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
2421 {
2422  static const char k_rgchHexToASCII[] = "0123456789abcdef";
2423  int i;
2424 
2425  if ((pszGUID == NULL) || (cbGUID <= 0)) {
2426  return;
2427  }
2428 
2429  for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) {
2430  /* each input byte writes 2 ascii chars, and might write a null byte. */
2431  /* If we don't have room for next input byte, stop */
2432  unsigned char c = guid.data[i];
2433 
2434  *pszGUID++ = k_rgchHexToASCII[c >> 4];
2435  *pszGUID++ = k_rgchHexToASCII[c & 0x0F];
2436  }
2437  *pszGUID = '\0';
2438 }
2439 
2440 /*-----------------------------------------------------------------------------
2441  * Purpose: Returns the 4 bit nibble for a hex character
2442  * Input : c -
2443  * Output : unsigned char
2444  *-----------------------------------------------------------------------------*/
2445 static unsigned char nibble(char c)
2446 {
2447  if ((c >= '0') && (c <= '9')) {
2448  return (unsigned char)(c - '0');
2449  }
2450 
2451  if ((c >= 'A') && (c <= 'F')) {
2452  return (unsigned char)(c - 'A' + 0x0a);
2453  }
2454 
2455  if ((c >= 'a') && (c <= 'f')) {
2456  return (unsigned char)(c - 'a' + 0x0a);
2457  }
2458 
2459  /* received an invalid character, and no real way to return an error */
2460  /* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */
2461  return 0;
2462 }
2463 
2464 /* convert the string version of a joystick guid to the struct */
2466 {
2467  SDL_JoystickGUID guid;
2468  int maxoutputbytes= sizeof(guid);
2469  size_t len = SDL_strlen(pchGUID);
2470  Uint8 *p;
2471  size_t i;
2472 
2473  /* Make sure it's even */
2474  len = (len) & ~0x1;
2475 
2476  SDL_memset(&guid, 0x00, sizeof(guid));
2477 
2478  p = (Uint8 *)&guid;
2479  for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) {
2480  *p = (nibble(pchGUID[i]) << 4) | nibble(pchGUID[i+1]);
2481  }
2482 
2483  return guid;
2484 }
2485 
2486 /* update the power level for this joystick */
2488 {
2489  joystick->epowerlevel = ePowerLevel;
2490 }
2491 
2492 /* return its power level */
2494 {
2497  }
2498  return joystick->epowerlevel;
2499 }
2500 
2501 int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure)
2502 {
2503  SDL_JoystickTouchpadInfo *touchpad_info;
2504  SDL_JoystickTouchpadFingerInfo *finger_info;
2505  int posted;
2506 #if !SDL_EVENTS_DISABLED
2507  Uint32 event_type;
2508 #endif
2509 
2510  if (touchpad < 0 || touchpad >= joystick->ntouchpads) {
2511  return 0;
2512  }
2513 
2514  touchpad_info = &joystick->touchpads[touchpad];
2515  if (finger < 0 || finger >= touchpad_info->nfingers) {
2516  return 0;
2517  }
2518 
2519  finger_info = &touchpad_info->fingers[finger];
2520 
2521  if (!state) {
2522  if (x == 0.0f && y == 0.0f) {
2523  x = finger_info->x;
2524  y = finger_info->y;
2525  }
2526  pressure = 0.0f;
2527  }
2528 
2529  if (x < 0.0f) {
2530  x = 0.0f;
2531  } else if (x > 1.0f) {
2532  x = 1.0f;
2533  }
2534  if (y < 0.0f) {
2535  y = 0.0f;
2536  } else if (y > 1.0f) {
2537  y = 1.0f;
2538  }
2539  if (pressure < 0.0f) {
2540  pressure = 0.0f;
2541  } else if (pressure > 1.0f) {
2542  pressure = 1.0f;
2543  }
2544 
2545  if (state == finger_info->state) {
2546  if (!state ||
2547  (x == finger_info->x && y == finger_info->y && pressure == finger_info->pressure)) {
2548  return 0;
2549  }
2550  }
2551 
2552 #if !SDL_EVENTS_DISABLED
2553  if (state == finger_info->state) {
2554  event_type = SDL_CONTROLLERTOUCHPADMOTION;
2555  } else if (state) {
2556  event_type = SDL_CONTROLLERTOUCHPADDOWN;
2557  } else {
2558  event_type = SDL_CONTROLLERTOUCHPADUP;
2559  }
2560 #endif
2561 
2562  /* Update internal joystick state */
2563  finger_info->state = state;
2564  finger_info->x = x;
2565  finger_info->y = y;
2566  finger_info->pressure = pressure;
2567 
2568  /* Post the event, if desired */
2569  posted = 0;
2570 #if !SDL_EVENTS_DISABLED
2571  if (SDL_GetEventState(event_type) == SDL_ENABLE) {
2572  SDL_Event event;
2573  event.type = event_type;
2574  event.ctouchpad.which = joystick->instance_id;
2575  event.ctouchpad.touchpad = touchpad;
2576  event.ctouchpad.finger = finger;
2577  event.ctouchpad.x = x;
2578  event.ctouchpad.y = y;
2579  event.ctouchpad.pressure = pressure;
2580  posted = SDL_PushEvent(&event) == 1;
2581  }
2582 #endif /* !SDL_EVENTS_DISABLED */
2583  return posted;
2584 }
2585 
2586 int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const float *data, int num_values)
2587 {
2588  int i;
2589  int posted = 0;
2590 
2591  for (i = 0; i < joystick->nsensors; ++i) {
2592  SDL_JoystickSensorInfo *sensor = &joystick->sensors[i];
2593 
2594  if (sensor->type == type) {
2595  if (sensor->enabled) {
2596  num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
2597  if (SDL_memcmp(data, sensor->data, num_values*sizeof(*data)) != 0) {
2598 
2599  /* Update internal sensor state */
2600  SDL_memcpy(sensor->data, data, num_values*sizeof(*data));
2601 
2602  /* Post the event, if desired */
2603 #if !SDL_EVENTS_DISABLED
2605  SDL_Event event;
2606  event.type = SDL_CONTROLLERSENSORUPDATE;
2607  event.csensor.which = joystick->instance_id;
2608  event.csensor.sensor = type;
2609  num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data));
2610  SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data));
2611  SDL_memcpy(event.csensor.data, data, num_values*sizeof(*data));
2612  posted = SDL_PushEvent(&event) == 1;
2613  }
2614 #endif /* !SDL_EVENTS_DISABLED */
2615  }
2616  }
2617  break;
2618  }
2619  }
2620  return posted;
2621 }
2622 
2623 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_INIT_JOYSTICK
Definition: SDL.h:83
#define SDL_INIT_EVENTS
Definition: SDL.h:86
#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_abs
#define SDL_DelHintCallback
#define SDL_PushEvent
#define SDL_GetKeyboardFocus
#define SDL_WasInit
#define SDL_LockMutex
#define SDL_malloc
#define SDL_strlen
#define SDL_realloc
#define SDL_strcasecmp
#define SDL_EventState
#define SDL_CreateMutex
#define SDL_free
#define SDL_strdup
#define SDL_strcmp
#define SDL_memcmp
#define SDL_Delay
#define SDL_PeepEvents
#define SDL_memcpy
#define SDL_DestroyMutex
#define SDL_AddHintCallback
#define SDL_tolower
#define SDL_snprintf
#define SDL_QuitSubSystem
#define SDL_memmove
#define SDL_calloc
#define SDL_strncasecmp
#define SDL_UnlockMutex
#define SDL_IsGameController
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
@ SDL_JOYDEVICEADDED
Definition: SDL_events.h:118
@ SDL_CONTROLLERTOUCHPADDOWN
Definition: SDL_events.h:128
@ SDL_JOYBUTTONDOWN
Definition: SDL_events.h:116
@ SDL_JOYDEVICEREMOVED
Definition: SDL_events.h:119
@ SDL_CONTROLLERTOUCHPADMOTION
Definition: SDL_events.h:129
@ SDL_JOYBUTTONUP
Definition: SDL_events.h:117
@ SDL_JOYBALLMOTION
Definition: SDL_events.h:114
@ SDL_CONTROLLERTOUCHPADUP
Definition: SDL_events.h:130
@ SDL_JOYAXISMOTION
Definition: SDL_events.h:113
@ SDL_CONTROLLERSENSORUPDATE
Definition: SDL_events.h:131
@ SDL_JOYHATMOTION
Definition: SDL_events.h:115
#define SDL_QUERY
Definition: SDL_events.h:792
#define SDL_GetEventState(type)
Definition: SDL_events.h:808
#define SDL_DISABLE
Definition: SDL_events.h:794
@ SDL_ADDEVENT
Definition: SDL_events.h:651
@ SDL_PEEKEVENT
Definition: SDL_events.h:652
@ SDL_GETEVENT
Definition: SDL_events.h:653
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_ENABLE
Definition: SDL_events.h:795
#define SDL_PRESSED
Definition: SDL_events.h:50
void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
void SDL_GameControllerQuitMappings(void)
SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
int SDL_GameControllerInitMappings(void)
SDL_GameControllerType
@ SDL_CONTROLLER_TYPE_VIRTUAL
@ SDL_CONTROLLER_TYPE_XBOX360
@ SDL_CONTROLLER_TYPE_PS4
@ SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO
@ SDL_CONTROLLER_TYPE_PS3
@ SDL_CONTROLLER_TYPE_PS5
@ SDL_CONTROLLER_TYPE_XBOXONE
@ SDL_CONTROLLER_TYPE_UNKNOWN
const GLubyte GLuint red
Definition: SDL_glfuncs.h:80
void HIDAPI_UpdateDevices(void)
#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
A variable that lets you enable joystick (and gamecontroller) events even when your app is in the bac...
Definition: SDL_hints.h:583
#define SDLCALL
Definition: SDL_internal.h:49
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
SDL_bool SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state)
Definition: SDL_joystick.c:660
static void UpdateEventsForDeviceRemoval(int device_index)
SDL_JoystickID SDL_JoystickGetDeviceInstanceID(int device_index)
Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure)
static int SDL_FindFreePlayerIndex()
Definition: SDL_joystick.c:118
int SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick)
Definition: SDL_joystick.c:825
static int SDL_GetPlayerIndexForJoystickID(SDL_JoystickID instance_id)
Definition: SDL_joystick.c:131
int SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms)
Definition: SDL_joystick.c:891
static int PrefixMatch(const char *a, const char *b)
SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index)
SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product)
Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button)
Definition: SDL_joystick.c:727
static SDL_JoystickDriver * SDL_joystick_drivers[]
Definition: SDL_joystick.c:52
static SDL_bool SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
Definition: SDL_joystick.c:333
SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick *joystick)
Definition: SDL_joystick.c:761
int SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value)
Definition: SDL_joystick.c:526
int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel)
const char * SDL_JoystickName(SDL_Joystick *joystick)
Definition: SDL_joystick.c:812
static int SDL_joystick_player_count
Definition: SDL_joystick.c:98
SDL_bool SDL_JoystickHasLED(SDL_Joystick *joystick)
Definition: SDL_joystick.c:925
int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
Definition: SDL_joystick.c:699
SDL_bool SDL_IsJoystickVirtual(SDL_JoystickGUID guid)
SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick)
static SDL_bool SDL_PrivateJoystickShouldIgnoreEvent()
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
SDL_bool SDL_JoystickIsVirtual(int device_index)
Definition: SDL_joystick.c:504
static unsigned char nibble(char c)
int SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value)
Definition: SDL_joystick.c:536
static SDL_JoystickID SDL_GetJoystickIDForPlayerIndex(int player_index)
Definition: SDL_joystick.c:147
int SDL_NumJoysticks(void)
Definition: SDL_joystick.c:247
static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid)
void SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index)
Definition: SDL_joystick.c:844
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Uint16 SDL_JoystickGetDeviceProduct(int device_index)
Uint16 SDL_JoystickGetDeviceProductVersion(int device_index)
SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_JoystickInit(void)
Definition: SDL_joystick.c:213
SDL_bool SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int *driver_index)
Definition: SDL_joystick.c:272
SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id)
Uint16 SDL_JoystickGetDeviceVendor(int device_index)
SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id)
SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
static void SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
Definition: SDL_joystick.c:203
int SDL_JoystickNumBalls(SDL_Joystick *joystick)
Definition: SDL_joystick.c:616
int SDL_JoystickNumHats(SDL_Joystick *joystick)
Definition: SDL_joystick.c:604
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
void SDL_JoystickQuit(void)
SDL_bool SDL_IsJoystickWGI(SDL_JoystickGUID guid)
int SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value)
Definition: SDL_joystick.c:546
void SDL_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_joystick.c:976
static SDL_JoystickID * SDL_joystick_players
Definition: SDL_joystick.c:99
SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickRAWINPUT(SDL_JoystickGUID guid)
int SDL_JoystickGetDevicePlayerIndex(int device_index)
Definition: SDL_joystick.c:316
SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(int device_index, SDL_GamepadMapping *out)
Definition: SDL_joystick.c:574
int SDL_JoystickDetachVirtual(int device_index)
Definition: SDL_joystick.c:482
void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
SDL_bool SDL_JoystickGetAttached(SDL_Joystick *joystick)
Definition: SDL_joystick.c:748
SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name)
Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick)
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
void SDL_LockJoysticks(void)
Definition: SDL_joystick.c:102
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
static SDL_bool SDL_IsJoystickProductThrottle(Uint32 vidpid)
static SDL_bool SDL_joystick_allows_background_events
Definition: SDL_joystick.c:93
const char * SDL_JoystickGetSerial(SDL_Joystick *joystick)
static SDL_mutex * SDL_joystick_lock
Definition: SDL_joystick.c:96
SDL_Joystick * SDL_JoystickOpen(int device_index)
Definition: SDL_joystick.c:367
int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const float *data, int num_values)
static void SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick)
Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick)
SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
static SDL_bool SDL_updating_joystick
Definition: SDL_joystick.c:95
int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
Definition: SDL_joystick.c:856
void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type)
void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
int SDL_JoystickAttachVirtual(SDL_JoystickType type, int naxes, int nbuttons, int nhats)
Definition: SDL_joystick.c:471
void SDL_UnlockJoysticks(void)
Definition: SDL_joystick.c:110
Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat)
Definition: SDL_joystick.c:679
static SDL_bool SDL_IsPS4RemapperRunning(void)
void SDL_JoystickUpdate(void)
int SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
Definition: SDL_joystick.c:943
int SDL_JoystickEventState(int state)
static SDL_Joystick * SDL_joysticks
Definition: SDL_joystick.c:94
static SDL_bool SDL_SetJoystickIDForPlayerIndex(int player_index, SDL_JoystickID instance_id)
Definition: SDL_joystick.c:156
SDL_JoystickType SDL_JoystickGetDeviceType(int device_index)
static SDL_atomic_t SDL_next_joystick_instance_id
Definition: SDL_joystick.c:97
int SDL_JoystickNumAxes(SDL_Joystick *joystick)
Definition: SDL_joystick.c:592
SDL_bool SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id)
SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id)
SDL_Joystick * SDL_JoystickFromInstanceID(SDL_JoystickID instance_id)
Definition: SDL_joystick.c:774
static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
Definition: SDL_joystick.c:262
Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)
Definition: SDL_joystick.c:640
const char * SDL_JoystickNameForIndex(int device_index)
Definition: SDL_joystick.c:297
int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id)
SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid)
SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id)
SDL_bool SDL_PrivateJoystickValid(SDL_Joystick *joystick)
Definition: SDL_joystick.c:559
SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
int SDL_JoystickNumButtons(SDL_Joystick *joystick)
Definition: SDL_joystick.c:628
SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id)
char * SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
SDL_Joystick * SDL_JoystickFromPlayerIndex(int player_index)
Definition: SDL_joystick.c:792
SDL_JoystickType
Definition: SDL_joystick.h:84
@ SDL_JOYSTICK_TYPE_DANCE_PAD
Definition: SDL_joystick.h:90
@ SDL_JOYSTICK_TYPE_ARCADE_PAD
Definition: SDL_joystick.h:93
@ SDL_JOYSTICK_TYPE_UNKNOWN
Definition: SDL_joystick.h:85
@ SDL_JOYSTICK_TYPE_ARCADE_STICK
Definition: SDL_joystick.h:88
@ SDL_JOYSTICK_TYPE_WHEEL
Definition: SDL_joystick.h:87
@ SDL_JOYSTICK_TYPE_THROTTLE
Definition: SDL_joystick.h:94
@ SDL_JOYSTICK_TYPE_GUITAR
Definition: SDL_joystick.h:91
@ SDL_JOYSTICK_TYPE_FLIGHT_STICK
Definition: SDL_joystick.h:89
@ SDL_JOYSTICK_TYPE_GAMECONTROLLER
Definition: SDL_joystick.h:86
@ SDL_JOYSTICK_TYPE_DRUM_KIT
Definition: SDL_joystick.h:92
SDL_JoystickPowerLevel
Definition: SDL_joystick.h:98
@ SDL_JOYSTICK_POWER_UNKNOWN
Definition: SDL_joystick.h:99
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:386
#define SDL_JOYSTICK_AXIS_MAX
Definition: SDL_joystick.h:358
SDL_JoystickDriver SDL_IOS_JoystickDriver
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
GLboolean GLboolean GLboolean b
struct _cl_event * event
GLbyte GLbyte blue
GLuint64EXT * result
GLuint id
GLenum GLsizei len
GLboolean GLboolean GLboolean GLboolean a
const GLubyte * c
GLuint const GLchar * name
GLfloat GLfloat p
GLbyte green
GLsizei const GLfloat * value
SDL_SensorType
Definition: SDL_sensor.h:70
uint16_t Uint16
Definition: SDL_stdinc.h:197
int16_t Sint16
Definition: SDL_stdinc.h:191
#define SDL_zero(x)
Definition: SDL_stdinc.h:426
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
uint8_t Uint8
Definition: SDL_stdinc.h:185
#define SDL_zerop(x)
Definition: SDL_stdinc.h:427
#define SDL_min(x, y)
Definition: SDL_stdinc.h:412
uint32_t Uint32
Definition: SDL_stdinc.h:209
SDL_JoystickDriver SDL_BSD_JoystickDriver
SDL_JoystickDriver SDL_WGI_JoystickDriver
SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver
SDL_JoystickDriver SDL_ANDROID_JoystickDriver
#define SDL_MAX_RUMBLE_DURATION_MS
SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver
SDL_JoystickDriver SDL_DUMMY_JoystickDriver
SDL_JoystickDriver SDL_LINUX_JoystickDriver
SDL_JoystickDriver SDL_HIDAPI_JoystickDriver
SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver
SDL_JoystickDriver SDL_DARWIN_JoystickDriver
#define MAKE_VIDPID(VID, PID)
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver
SDL_JoystickDriver SDL_HAIKU_JoystickDriver
SDL_bool SDL_HasWindows(void)
Definition: SDL_video.c:1822
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
struct xkb_state * state
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
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 int in j)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:163
EControllerType
@ k_eControllerType_SteamController
@ k_eControllerType_PS3Controller
@ k_eControllerType_SteamControllerV2
@ k_eControllerType_PS5Controller
@ k_eControllerType_SwitchProController
@ k_eControllerType_PS4Controller
@ k_eControllerType_XBox360Controller
@ k_eControllerType_XBoxOneController
@ k_eControllerType_UnknownNonSteamController
@ k_eControllerType_SwitchInputOnlyController
static SDL_INLINE EControllerType GuessControllerType(int nVID, int nPID)
static SDL_INLINE const char * GuessControllerName(int nVID, int nPID)
static const double zero
Definition: e_atan2.c:44
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
SDL_JoystickGUID(* GetDeviceGUID)(int device_index)
void(* Detect)(void)
void(* SetDevicePlayerIndex)(int device_index, int player_index)
SDL_bool(* GetGamepadMapping)(int device_index, SDL_GamepadMapping *out)
SDL_JoystickID(* GetDeviceInstanceID)(int device_index)
int(* GetCount)(void)
void(* Update)(SDL_Joystick *joystick)
void(* Quit)(void)
int(* GetDevicePlayerIndex)(int device_index)
int(* Open)(SDL_Joystick *joystick, int device_index)
const char *(* GetDeviceName)(int device_index)
Uint8 data[16]
Definition: SDL_joystick.h:71
SDL_JoystickTouchpadFingerInfo * fingers
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
Definition: SDL_atomic.h:216
SDL_Texture * button
SDL_Texture * axis
SDL_bool retval
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:39
static SDL_Joystick * joystick
Definition: testjoystick.c:37
static SDL_mutex * mutex
Definition: testlock.c:23
General event structure.
Definition: SDL_events.h:592
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:610
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2
Definition: usb_ids.h:48
#define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH
Definition: usb_ids.h:54
#define USB_VENDOR_MICROSOFT
Definition: usb_ids.h:29
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH
Definition: usb_ids.h:49
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1
Definition: usb_ids.h:47
#define USB_PRODUCT_XBOX_ONE_SERIES_X
Definition: usb_ids.h:53