WinRT: merged with SDL 2.0.1 codebase
This commit is contained in:
commit
59df93166d
344 changed files with 12745 additions and 7248 deletions
|
@ -52,7 +52,7 @@ struct _SDL_HatMapping
|
|||
*/
|
||||
#define k_nMaxHatEntries 0x3f + 1
|
||||
|
||||
/* our in memory mapping db between joystick objects and controller mappings*/
|
||||
/* our in memory mapping db between joystick objects and controller mappings */
|
||||
struct _SDL_ControllerMapping
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
|
@ -758,7 +758,7 @@ SDL_GameControllerLoadHints()
|
|||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
|
||||
if ( hint && hint[0] ) {
|
||||
int nchHints = SDL_strlen( hint );
|
||||
size_t nchHints = SDL_strlen( hint );
|
||||
char *pUserMappings = SDL_malloc( nchHints + 1 );
|
||||
char *pTempMappings = pUserMappings;
|
||||
SDL_memcpy( pUserMappings, hint, nchHints );
|
||||
|
|
|
@ -437,22 +437,13 @@ SDL_JoystickClose(SDL_Joystick * joystick)
|
|||
joysticklist = joysticklist->next;
|
||||
}
|
||||
|
||||
if (joystick->name)
|
||||
SDL_free(joystick->name);
|
||||
SDL_free(joystick->name);
|
||||
|
||||
/* Free the data associated with this joystick */
|
||||
if (joystick->axes) {
|
||||
SDL_free(joystick->axes);
|
||||
}
|
||||
if (joystick->hats) {
|
||||
SDL_free(joystick->hats);
|
||||
}
|
||||
if (joystick->balls) {
|
||||
SDL_free(joystick->balls);
|
||||
}
|
||||
if (joystick->buttons) {
|
||||
SDL_free(joystick->buttons);
|
||||
}
|
||||
SDL_free(joystick->axes);
|
||||
SDL_free(joystick->hats);
|
||||
SDL_free(joystick->balls);
|
||||
SDL_free(joystick->buttons);
|
||||
SDL_free(joystick);
|
||||
}
|
||||
|
||||
|
@ -488,14 +479,14 @@ SDL_PrivateJoystickShouldIgnoreEvent()
|
|||
|
||||
if (SDL_WasInit(SDL_INIT_VIDEO)) {
|
||||
if (SDL_GetKeyboardFocus() == NULL) {
|
||||
// Video is initialized and we don't have focus, ignore the event.
|
||||
/* Video is initialized and we don't have focus, ignore the event. */
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Video subsystem wasn't initialized, always allow the event
|
||||
/* Video subsystem wasn't initialized, always allow the event */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
@ -772,6 +763,11 @@ SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index)
|
|||
/* return the guid for this opened device */
|
||||
SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick * joystick)
|
||||
{
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
SDL_JoystickGUID emptyGUID;
|
||||
SDL_zero( emptyGUID );
|
||||
return emptyGUID;
|
||||
}
|
||||
return SDL_SYS_JoystickGetGUID( joystick );
|
||||
}
|
||||
|
||||
|
@ -785,7 +781,7 @@ void SDL_JoystickGetGUIDString( SDL_JoystickGUID guid, char *pszGUID, int cbGUID
|
|||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < sizeof(guid.data) && i < (cbGUID-1); i++ )
|
||||
for ( i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++ )
|
||||
{
|
||||
/* each input byte writes 2 ascii chars, and might write a null byte. */
|
||||
/* If we don't have room for next input byte, stop */
|
||||
|
@ -834,7 +830,7 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
|
|||
{
|
||||
SDL_JoystickGUID guid;
|
||||
int maxoutputbytes= sizeof(guid);
|
||||
int len = SDL_strlen( pchGUID );
|
||||
size_t len = SDL_strlen( pchGUID );
|
||||
Uint8 *p;
|
||||
int i;
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick);
|
|||
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
|
||||
/* Function to get the current instance id of the joystick located at device_index */
|
||||
extern SDL_bool SDL_SYS_IsXInputDeviceIndex( int device_index );
|
||||
extern SDL_bool SDL_SYS_IsXInputJoystick(SDL_Joystick * joystick);
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -231,12 +231,8 @@ extern "C"
|
|||
if (joystick->hwdata) {
|
||||
joystick->hwdata->stick->Close();
|
||||
delete joystick->hwdata->stick;
|
||||
if (joystick->hwdata->new_hats) {
|
||||
SDL_free(joystick->hwdata->new_hats);
|
||||
}
|
||||
if (joystick->hwdata->new_axes) {
|
||||
SDL_free(joystick->hwdata->new_axes);
|
||||
}
|
||||
SDL_free(joystick->hwdata->new_hats);
|
||||
SDL_free(joystick->hwdata->new_axes);
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
|
|
|
@ -446,48 +446,47 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
|
|||
static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
|
||||
|
||||
if (joy->hwdata->type == BSDJOY_JOY) {
|
||||
if (read(joy->hwdata->fd, &gameport, sizeof gameport) !=
|
||||
sizeof gameport)
|
||||
return;
|
||||
if (abs(x - gameport.x) > 8) {
|
||||
x = gameport.x;
|
||||
if (x < xmin) {
|
||||
xmin = x;
|
||||
while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
|
||||
if (abs(x - gameport.x) > 8) {
|
||||
x = gameport.x;
|
||||
if (x < xmin) {
|
||||
xmin = x;
|
||||
}
|
||||
if (x > xmax) {
|
||||
xmax = x;
|
||||
}
|
||||
if (xmin == xmax) {
|
||||
xmin--;
|
||||
xmax++;
|
||||
}
|
||||
v = (Sint32) x;
|
||||
v -= (xmax + xmin + 1) / 2;
|
||||
v *= 32768 / ((xmax - xmin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 0, v);
|
||||
}
|
||||
if (x > xmax) {
|
||||
xmax = x;
|
||||
if (abs(y - gameport.y) > 8) {
|
||||
y = gameport.y;
|
||||
if (y < ymin) {
|
||||
ymin = y;
|
||||
}
|
||||
if (y > ymax) {
|
||||
ymax = y;
|
||||
}
|
||||
if (ymin == ymax) {
|
||||
ymin--;
|
||||
ymax++;
|
||||
}
|
||||
v = (Sint32) y;
|
||||
v -= (ymax + ymin + 1) / 2;
|
||||
v *= 32768 / ((ymax - ymin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 1, v);
|
||||
}
|
||||
if (xmin == xmax) {
|
||||
xmin--;
|
||||
xmax++;
|
||||
if (gameport.b1 != joy->buttons[0]) {
|
||||
SDL_PrivateJoystickButton(joy, 0, gameport.b1);
|
||||
}
|
||||
v = (Sint32) x;
|
||||
v -= (xmax + xmin + 1) / 2;
|
||||
v *= 32768 / ((xmax - xmin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 0, v);
|
||||
}
|
||||
if (abs(y - gameport.y) > 8) {
|
||||
y = gameport.y;
|
||||
if (y < ymin) {
|
||||
ymin = y;
|
||||
if (gameport.b2 != joy->buttons[1]) {
|
||||
SDL_PrivateJoystickButton(joy, 1, gameport.b2);
|
||||
}
|
||||
if (y > ymax) {
|
||||
ymax = y;
|
||||
}
|
||||
if (ymin == ymax) {
|
||||
ymin--;
|
||||
ymax++;
|
||||
}
|
||||
v = (Sint32) y;
|
||||
v -= (ymax + ymin + 1) / 2;
|
||||
v *= 32768 / ((ymax - ymin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 1, v);
|
||||
}
|
||||
if (gameport.b1 != joy->buttons[0]) {
|
||||
SDL_PrivateJoystickButton(joy, 0, gameport.b1);
|
||||
}
|
||||
if (gameport.b2 != joy->buttons[1]) {
|
||||
SDL_PrivateJoystickButton(joy, 1, gameport.b2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -495,65 +494,62 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
|
|||
|
||||
rep = &joy->hwdata->inreport;
|
||||
|
||||
if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) {
|
||||
return;
|
||||
}
|
||||
while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
|
||||
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
|
||||
#else
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
|
||||
#endif
|
||||
if (hdata == NULL) {
|
||||
fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);
|
||||
return;
|
||||
}
|
||||
if (hdata == NULL) {
|
||||
/*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
|
||||
continue;
|
||||
}
|
||||
|
||||
for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
|
||||
switch (hitem.kind) {
|
||||
case hid_input:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
{
|
||||
unsigned usage = HID_USAGE(hitem.usage);
|
||||
int joyaxe = usage_to_joyaxe(usage);
|
||||
if (joyaxe >= 0) {
|
||||
naxe = joy->hwdata->axis_map[joyaxe];
|
||||
/* scaleaxe */
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
v -= (hitem.logical_maximum +
|
||||
hitem.logical_minimum + 1) / 2;
|
||||
v *= 32768 /
|
||||
((hitem.logical_maximum -
|
||||
hitem.logical_minimum + 1) / 2);
|
||||
if (v != joy->axes[naxe]) {
|
||||
SDL_PrivateJoystickAxis(joy, naxe, v);
|
||||
for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
|
||||
switch (hitem.kind) {
|
||||
case hid_input:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
{
|
||||
unsigned usage = HID_USAGE(hitem.usage);
|
||||
int joyaxe = usage_to_joyaxe(usage);
|
||||
if (joyaxe >= 0) {
|
||||
naxe = joy->hwdata->axis_map[joyaxe];
|
||||
/* scaleaxe */
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
v -= (hitem.logical_maximum +
|
||||
hitem.logical_minimum + 1) / 2;
|
||||
v *= 32768 /
|
||||
((hitem.logical_maximum -
|
||||
hitem.logical_minimum + 1) / 2);
|
||||
if (v != joy->axes[naxe]) {
|
||||
SDL_PrivateJoystickAxis(joy, naxe, v);
|
||||
}
|
||||
} else if (usage == HUG_HAT_SWITCH) {
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0,
|
||||
hatval_to_sdl(v) -
|
||||
hitem.logical_minimum);
|
||||
}
|
||||
} else if (usage == HUG_HAT_SWITCH) {
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0,
|
||||
hatval_to_sdl(v) -
|
||||
hitem.logical_minimum);
|
||||
break;
|
||||
}
|
||||
case HUP_BUTTON:
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
if (joy->buttons[nbutton] != v) {
|
||||
SDL_PrivateJoystickButton(joy, nbutton, v);
|
||||
}
|
||||
nbutton++;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
case HUP_BUTTON:
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
if (joy->buttons[nbutton] != v) {
|
||||
SDL_PrivateJoystickButton(joy, nbutton, v);
|
||||
}
|
||||
nbutton++;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hid_end_parse(hdata);
|
||||
}
|
||||
hid_end_parse(hdata);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
|
@ -577,10 +573,8 @@ SDL_SYS_JoystickQuit(void)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < MAX_JOYS; i++) {
|
||||
if (joynames[i] != NULL)
|
||||
SDL_free(joynames[i]);
|
||||
if (joydevnames[i] != NULL)
|
||||
SDL_free(joydevnames[i]);
|
||||
SDL_free(joynames[i]);
|
||||
SDL_free(joydevnames[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -657,9 +651,7 @@ report_alloc(struct report *r, struct report_desc *rd, int repind)
|
|||
static void
|
||||
report_free(struct report *r)
|
||||
{
|
||||
if (r->buf != NULL) {
|
||||
SDL_free(r->buf);
|
||||
}
|
||||
SDL_free(r->buf);
|
||||
r->status = SREPORT_UNINIT;
|
||||
}
|
||||
|
||||
|
|
|
@ -589,7 +589,6 @@ HIDBuildDevice(io_object_t hidDevice)
|
|||
if (kIOReturnSuccess == result) {
|
||||
HIDGetDeviceInfo(hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */
|
||||
HIDGetCollectionElements(hidProperties, pDevice);
|
||||
pDevice->instance_id = ++s_joystick_instance_id;
|
||||
} else {
|
||||
DisposePtr((Ptr) pDevice);
|
||||
pDevice = NULL;
|
||||
|
@ -678,6 +677,9 @@ AddDeviceHelper( io_object_t ioHIDDeviceObject )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate an instance ID for this device */
|
||||
device->instance_id = ++s_joystick_instance_id;
|
||||
|
||||
/* We have to do some storage of the io_service_t for
|
||||
* SDL_HapticOpenFromJoystick */
|
||||
if (FFIsForceFeedback(ioHIDDeviceObject) == FF_OK) {
|
||||
|
@ -771,7 +773,7 @@ SDL_SYS_JoystickInit(void)
|
|||
("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
|
||||
}
|
||||
|
||||
/*/ Now search I/O Registry for matching devices. */
|
||||
/* Now search I/O Registry for matching devices. */
|
||||
result =
|
||||
IOServiceGetMatchingServices(masterPort, hidMatchDictionary,
|
||||
&hidObjectIterator);
|
||||
|
|
|
@ -106,7 +106,7 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
[[SDLUIAccelerationDelegate sharedDelegate] setHasNewData: NO];
|
||||
|
||||
SDL_PrivateJoystickAxis(joystick, 0, orientation[0]);
|
||||
SDL_PrivateJoystickAxis(joystick, 1, orientation[1]);
|
||||
SDL_PrivateJoystickAxis(joystick, 1, -orientation[1]);
|
||||
SDL_PrivateJoystickAxis(joystick, 2, orientation[2]);
|
||||
|
||||
}
|
||||
|
|
|
@ -52,124 +52,13 @@
|
|||
#define SYN_DROPPED 3
|
||||
#endif
|
||||
|
||||
/*
|
||||
* !!! FIXME: move all the udev stuff to src/core/linux, so I can reuse it
|
||||
* !!! FIXME: for audio hardware disconnects.
|
||||
*/
|
||||
#ifdef HAVE_LIBUDEV_H
|
||||
#define SDL_USE_LIBUDEV 1
|
||||
#include "SDL_loadso.h"
|
||||
#include <libudev.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
/* we never link directly to libudev. */
|
||||
/* !!! FIXME: can we generalize this? ALSA, etc, do the same things. */
|
||||
static const char *udev_library = "libudev.so.0";
|
||||
static void *udev_handle = NULL;
|
||||
|
||||
/* !!! FIXME: this is kinda ugly. */
|
||||
static SDL_bool
|
||||
load_udev_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(udev_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
/* Don't call SDL_SetError(): SDL_LoadFunction already did. */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* libudev entry points... */
|
||||
static const char *(*UDEV_udev_device_get_action)(struct udev_device *) = NULL;
|
||||
static const char *(*UDEV_udev_device_get_devnode)(struct udev_device *) = NULL;
|
||||
static const char *(*UDEV_udev_device_get_property_value)(struct udev_device *, const char *) = NULL;
|
||||
static struct udev_device *(*UDEV_udev_device_new_from_syspath)(struct udev *, const char *) = NULL;
|
||||
static void (*UDEV_udev_device_unref)(struct udev_device *) = NULL;
|
||||
static int (*UDEV_udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *) = NULL;
|
||||
static int (*UDEV_udev_enumerate_add_match_subsystem)(struct udev_enumerate *, const char *) = NULL;
|
||||
static struct udev_list_entry *(*UDEV_udev_enumerate_get_list_entry)(struct udev_enumerate *) = NULL;
|
||||
static struct udev_enumerate *(*UDEV_udev_enumerate_new)(struct udev *) = NULL;
|
||||
static int (*UDEV_udev_enumerate_scan_devices)(struct udev_enumerate *) = NULL;
|
||||
static void (*UDEV_udev_enumerate_unref)(struct udev_enumerate *) = NULL;
|
||||
static const char *(*UDEV_udev_list_entry_get_name)(struct udev_list_entry *) = NULL;
|
||||
static struct udev_list_entry *(*UDEV_udev_list_entry_get_next)(struct udev_list_entry *) = NULL;
|
||||
static int (*UDEV_udev_monitor_enable_receiving)(struct udev_monitor *) = NULL;
|
||||
static int (*UDEV_udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor *, const char *, const char *) = NULL;
|
||||
static int (*UDEV_udev_monitor_get_fd)(struct udev_monitor *) = NULL;
|
||||
static struct udev_monitor *(*UDEV_udev_monitor_new_from_netlink)(struct udev *, const char *) = NULL;
|
||||
static struct udev_device *(*UDEV_udev_monitor_receive_device)(struct udev_monitor *) = NULL;
|
||||
static void (*UDEV_udev_monitor_unref)(struct udev_monitor *) = NULL;
|
||||
static struct udev *(*UDEV_udev_new)(void) = NULL;
|
||||
static void (*UDEV_udev_unref)(struct udev *) = NULL;
|
||||
|
||||
static int
|
||||
load_udev_syms(void)
|
||||
{
|
||||
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
|
||||
#define SDL_UDEV_SYM(x) \
|
||||
if (!load_udev_sym(#x, (void **) (char *) &UDEV_##x)) return -1
|
||||
|
||||
SDL_UDEV_SYM(udev_device_get_action);
|
||||
SDL_UDEV_SYM(udev_device_get_devnode);
|
||||
SDL_UDEV_SYM(udev_device_get_property_value);
|
||||
SDL_UDEV_SYM(udev_device_new_from_syspath);
|
||||
SDL_UDEV_SYM(udev_device_unref);
|
||||
SDL_UDEV_SYM(udev_enumerate_add_match_property);
|
||||
SDL_UDEV_SYM(udev_enumerate_add_match_subsystem);
|
||||
SDL_UDEV_SYM(udev_enumerate_get_list_entry);
|
||||
SDL_UDEV_SYM(udev_enumerate_new);
|
||||
SDL_UDEV_SYM(udev_enumerate_scan_devices);
|
||||
SDL_UDEV_SYM(udev_enumerate_unref);
|
||||
SDL_UDEV_SYM(udev_list_entry_get_name);
|
||||
SDL_UDEV_SYM(udev_list_entry_get_next);
|
||||
SDL_UDEV_SYM(udev_monitor_enable_receiving);
|
||||
SDL_UDEV_SYM(udev_monitor_filter_add_match_subsystem_devtype);
|
||||
SDL_UDEV_SYM(udev_monitor_get_fd);
|
||||
SDL_UDEV_SYM(udev_monitor_new_from_netlink);
|
||||
SDL_UDEV_SYM(udev_monitor_receive_device);
|
||||
SDL_UDEV_SYM(udev_monitor_unref);
|
||||
SDL_UDEV_SYM(udev_new);
|
||||
SDL_UDEV_SYM(udev_unref);
|
||||
|
||||
#undef SDL_UDEV_SYM
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
UnloadUDEVLibrary(void)
|
||||
{
|
||||
if (udev_handle != NULL) {
|
||||
SDL_UnloadObject(udev_handle);
|
||||
udev_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
LoadUDEVLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (udev_handle == NULL) {
|
||||
udev_handle = SDL_LoadObject(udev_library);
|
||||
if (udev_handle == NULL) {
|
||||
retval = -1;
|
||||
/* Don't call SDL_SetError(): SDL_LoadObject already did. */
|
||||
} else {
|
||||
retval = load_udev_syms();
|
||||
if (retval < 0) {
|
||||
UnloadUDEVLibrary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct udev *udev = NULL;
|
||||
static struct udev_monitor *udev_mon = NULL;
|
||||
#endif
|
||||
static int MaybeAddDevice(const char *path);
|
||||
#if SDL_USE_LIBUDEV
|
||||
static int MaybeRemoveDevice(const char *path);
|
||||
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
|
||||
/* A linked list of available joysticks */
|
||||
|
@ -246,6 +135,30 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||
{
|
||||
if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch( udev_type )
|
||||
{
|
||||
case SDL_UDEV_DEVICEADDED:
|
||||
MaybeAddDevice(devpath);
|
||||
break;
|
||||
|
||||
case SDL_UDEV_DEVICEREMOVED:
|
||||
MaybeRemoveDevice(devpath);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
|
||||
/* !!! FIXME: I would love to dump this code and use libudev instead. */
|
||||
static int
|
||||
|
@ -257,6 +170,9 @@ MaybeAddDevice(const char *path)
|
|||
char namebuf[128];
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_joylist_item *item;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
#endif
|
||||
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
|
@ -314,6 +230,19 @@ MaybeAddDevice(const char *path)
|
|||
SDL_joylist_tail = item;
|
||||
}
|
||||
|
||||
/* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = numjoysticks;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
return numjoysticks++;
|
||||
}
|
||||
|
||||
|
@ -324,6 +253,9 @@ MaybeRemoveDevice(const char *path)
|
|||
{
|
||||
SDL_joylist_item *item;
|
||||
SDL_joylist_item *prev = NULL;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
#endif
|
||||
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
|
@ -345,6 +277,20 @@ MaybeRemoveDevice(const char *path)
|
|||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEREMOVED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = item->device_instance;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
|
@ -380,40 +326,19 @@ JoystickInitWithoutUdev(void)
|
|||
static int
|
||||
JoystickInitWithUdev(void)
|
||||
{
|
||||
struct udev_enumerate *enumerate = NULL;
|
||||
struct udev_list_entry *devs = NULL;
|
||||
struct udev_list_entry *item = NULL;
|
||||
|
||||
SDL_assert(udev == NULL);
|
||||
udev = UDEV_udev_new();
|
||||
if (udev == NULL) {
|
||||
return SDL_SetError("udev_new() failed");
|
||||
if (SDL_UDEV_Init() < 0) {
|
||||
return SDL_SetError("Could not initialize UDEV");
|
||||
}
|
||||
|
||||
udev_mon = UDEV_udev_monitor_new_from_netlink(udev, "udev");
|
||||
if (udev_mon != NULL) { /* okay if it's NULL, we just lose hotplugging. */
|
||||
UDEV_udev_monitor_filter_add_match_subsystem_devtype(udev_mon,
|
||||
"input", NULL);
|
||||
UDEV_udev_monitor_enable_receiving(udev_mon);
|
||||
/* Set up the udev callback */
|
||||
if ( SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
|
||||
SDL_UDEV_Quit();
|
||||
return SDL_SetError("Could not set up joystick <-> udev callback");
|
||||
}
|
||||
|
||||
enumerate = UDEV_udev_enumerate_new(udev);
|
||||
if (enumerate == NULL) {
|
||||
return SDL_SetError("udev_enumerate_new() failed");
|
||||
}
|
||||
|
||||
UDEV_udev_enumerate_add_match_subsystem(enumerate, "input");
|
||||
UDEV_udev_enumerate_add_match_property(enumerate, "ID_INPUT_JOYSTICK", "1");
|
||||
UDEV_udev_enumerate_scan_devices(enumerate);
|
||||
devs = UDEV_udev_enumerate_get_list_entry(enumerate);
|
||||
for (item = devs; item; item = UDEV_udev_list_entry_get_next(item)) {
|
||||
const char *path = UDEV_udev_list_entry_get_name(item);
|
||||
struct udev_device *dev = UDEV_udev_device_new_from_syspath(udev, path);
|
||||
MaybeAddDevice(UDEV_udev_device_get_devnode(dev));
|
||||
UDEV_udev_device_unref(dev);
|
||||
}
|
||||
|
||||
UDEV_udev_enumerate_unref(enumerate);
|
||||
|
||||
/* Force a scan to build the initial device list */
|
||||
SDL_UDEV_Scan();
|
||||
|
||||
return numjoysticks;
|
||||
}
|
||||
|
@ -439,9 +364,7 @@ SDL_SYS_JoystickInit(void)
|
|||
}
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (LoadUDEVLibrary() == 0) { /* okay if this fails, FOR NOW. */
|
||||
return JoystickInitWithUdev();
|
||||
}
|
||||
return JoystickInitWithUdev();
|
||||
#endif
|
||||
|
||||
return JoystickInitWithoutUdev();
|
||||
|
@ -452,99 +375,21 @@ int SDL_SYS_NumJoysticks()
|
|||
return numjoysticks;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HotplugUpdateAvailable(void)
|
||||
{
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (udev_mon != NULL) {
|
||||
const int fd = UDEV_udev_monitor_get_fd(udev_mon);
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if ((select(fd+1, &fds, NULL, NULL, &tv) > 0) && (FD_ISSET(fd, &fds))) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
void SDL_SYS_JoystickDetect()
|
||||
{
|
||||
#if SDL_USE_LIBUDEV
|
||||
struct udev_device *dev = NULL;
|
||||
const char *devnode = NULL;
|
||||
const char *action = NULL;
|
||||
const char *val = NULL;
|
||||
|
||||
while (HotplugUpdateAvailable()) {
|
||||
dev = UDEV_udev_monitor_receive_device(udev_mon);
|
||||
if (dev == NULL) {
|
||||
break;
|
||||
}
|
||||
val = UDEV_udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
|
||||
if ((!val) || (SDL_strcmp(val, "1") != 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
action = UDEV_udev_device_get_action(dev);
|
||||
devnode = UDEV_udev_device_get_devnode(dev);
|
||||
|
||||
if (SDL_strcmp(action, "add") == 0) {
|
||||
const int device_index = MaybeAddDevice(devnode);
|
||||
if (device_index != -1) {
|
||||
/* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = device_index;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
}
|
||||
} else if (SDL_strcmp(action, "remove") == 0) {
|
||||
const int inst = MaybeRemoveDevice(devnode);
|
||||
if (inst != -1) {
|
||||
/* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
event.type = SDL_JOYDEVICEREMOVED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = inst;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
}
|
||||
}
|
||||
UDEV_udev_device_unref(dev);
|
||||
}
|
||||
SDL_UDEV_Poll();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
SDL_bool SDL_SYS_JoystickNeedsPolling()
|
||||
{
|
||||
/*
|
||||
* This results in a select() call, so technically we're polling to
|
||||
* decide if we should poll, but I think this function is here because
|
||||
* Windows has to do an enormous amount of work to detect new sticks,
|
||||
* whereas libudev just needs to see if there's more data available on
|
||||
* a socket...so this should be acceptable, I hope.
|
||||
*/
|
||||
return HotplugUpdateAvailable();
|
||||
#if SDL_USE_LIBUDEV
|
||||
return SDL_TRUE;
|
||||
#endif
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_joylist_item *
|
||||
|
@ -772,7 +617,7 @@ SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
|||
return !joystick->closed && (joystick->hwdata->item != NULL);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
static SDL_INLINE void
|
||||
HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value)
|
||||
{
|
||||
struct hwdata_hat *the_hat;
|
||||
|
@ -798,14 +643,14 @@ HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value)
|
|||
}
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
static SDL_INLINE void
|
||||
HandleBall(SDL_Joystick * stick, Uint8 ball, int axis, int value)
|
||||
{
|
||||
stick->hwdata->balls[ball].axis[axis] += value;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ int
|
||||
static SDL_INLINE int
|
||||
AxisCorrect(SDL_Joystick * joystick, int which, int value)
|
||||
{
|
||||
struct axis_correct *correct;
|
||||
|
@ -834,7 +679,7 @@ AxisCorrect(SDL_Joystick * joystick, int which, int value)
|
|||
return value;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
static SDL_INLINE void
|
||||
PollAllValues(SDL_Joystick * joystick)
|
||||
{
|
||||
struct input_absinfo absinfo;
|
||||
|
@ -872,7 +717,7 @@ PollAllValues(SDL_Joystick * joystick)
|
|||
}
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
static SDL_INLINE void
|
||||
HandleInputEvents(SDL_Joystick * joystick)
|
||||
{
|
||||
struct input_event events[32];
|
||||
|
@ -1011,15 +856,8 @@ SDL_SYS_JoystickQuit(void)
|
|||
instance_counter = 0;
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (udev_mon != NULL) {
|
||||
UDEV_udev_monitor_unref(udev_mon);
|
||||
udev_mon = NULL;
|
||||
}
|
||||
if (udev != NULL) {
|
||||
UDEV_udev_unref(udev);
|
||||
udev = NULL;
|
||||
}
|
||||
UnloadUDEVLibrary();
|
||||
SDL_UDEV_DelCallback(joystick_udev_callback);
|
||||
SDL_UDEV_Quit();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ static point c = { 78, 32767 };
|
|||
static point d = { 128, 32767 };
|
||||
|
||||
/* simple linear interpolation between two points */
|
||||
static __inline__ void lerp (point *dest, point *a, point *b, float t)
|
||||
static SDL_INLINE void lerp (point *dest, point *a, point *b, float t)
|
||||
{
|
||||
dest->x = a->x + (b->x - a->x)*t;
|
||||
dest->y = a->y + (b->y - a->y)*t;
|
||||
|
|
|
@ -46,40 +46,17 @@
|
|||
#include "../../events/SDL_events_c.h"
|
||||
#endif
|
||||
|
||||
/* The latest version of mingw-w64 defines IID_IWbemLocator in wbemcli.h
|
||||
instead of declaring it like Visual Studio and other mingw32 compilers.
|
||||
So, we need to take care of this here before we define INITGUID.
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#define __IWbemLocator_INTERFACE_DEFINED__
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
|
||||
#include "SDL_dxjoystick_c.h"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* And now that we've included wbemcli.h we need to declare these interfaces */
|
||||
typedef struct IWbemLocatorVtbl {
|
||||
BEGIN_INTERFACE
|
||||
HRESULT (WINAPI *QueryInterface)(IWbemLocator *This,REFIID riid,void **ppvObject);
|
||||
ULONG (WINAPI *AddRef)(IWbemLocator *This);
|
||||
ULONG (WINAPI *Release)(IWbemLocator *This);
|
||||
HRESULT (WINAPI *ConnectServer)(IWbemLocator *This,const BSTR strNetworkResource,const BSTR strUser,const BSTR strPassword,const BSTR strLocale,LONG lSecurityFlags,const BSTR strAuthority,IWbemContext *pCtx,IWbemServices **ppNamespace);
|
||||
END_INTERFACE
|
||||
} IWbemLocatorVtbl;
|
||||
struct IWbemLocator {
|
||||
CONST_VTBL struct IWbemLocatorVtbl *lpVtbl;
|
||||
};
|
||||
#define IWbemLocator_ConnectServer(This,strNetworkResource,strUser,strPassword,strLocale,lSecurityFlags,strAuthority,pCtx,ppNamespace) (This)->lpVtbl->ConnectServer(This,strNetworkResource,strUser,strPassword,strLocale,lSecurityFlags,strAuthority,pCtx,ppNamespace)
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
#ifndef DIDFT_OPTIONAL
|
||||
#define DIDFT_OPTIONAL 0x80000000
|
||||
#endif
|
||||
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_HID, 0x4D1E55B2L, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30);
|
||||
|
||||
|
||||
#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
|
||||
#define MAX_JOYSTICKS 8
|
||||
#define AXIS_MIN -32768 /* minimum value for axis coordinate */
|
||||
#define AXIS_MAX 32767 /* maximum value for axis coordinate */
|
||||
#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */
|
||||
|
@ -94,7 +71,6 @@ static LPDIRECTINPUT8 dinput = NULL;
|
|||
static SDL_bool s_bDeviceAdded = SDL_FALSE;
|
||||
static SDL_bool s_bDeviceRemoved = SDL_FALSE;
|
||||
static SDL_JoystickID s_nInstanceID = -1;
|
||||
static GUID *s_pKnownJoystickGUIDs = NULL;
|
||||
static SDL_cond *s_condJoystickThread = NULL;
|
||||
static SDL_mutex *s_mutexJoyStickEnum = NULL;
|
||||
static SDL_Thread *s_threadJoystick = NULL;
|
||||
|
@ -396,156 +372,74 @@ SetDIerror(const char *function, HRESULT code)
|
|||
} \
|
||||
}
|
||||
|
||||
DEFINE_GUID(CLSID_WbemLocator, 0x4590f811,0x1d3a,0x11d0,0x89,0x1F,0x00,0xaa,0x00,0x4b,0x2e,0x24);
|
||||
DEFINE_GUID(IID_IWbemLocator, 0xdc12a687,0x737f,0x11cf,0x88,0x4d,0x00,0xaa,0x00,0x4b,0x2e,0x24);
|
||||
|
||||
DEFINE_GUID(IID_ValveStreamingGamepad, MAKELONG( 0x28DE, 0x11FF ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
|
||||
DEFINE_GUID(IID_X360WiredGamepad, MAKELONG( 0x045E, 0x02A1 ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
|
||||
DEFINE_GUID(IID_X360WirelessGamepad, MAKELONG( 0x045E, 0x028E ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
*
|
||||
* code from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx
|
||||
*
|
||||
* Enum each PNP device using WMI and check each device ID to see if it contains
|
||||
* "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
|
||||
* Unfortunately this information can not be found by just using DirectInput
|
||||
*-----------------------------------------------------------------------------*/
|
||||
BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
|
||||
static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
|
||||
static UINT SDL_RawDevListCount = 0;
|
||||
|
||||
static SDL_bool
|
||||
SDL_IsXInputDevice( const GUID* pGuidProductFromDirectInput )
|
||||
{
|
||||
static const GUID *s_XInputProductGUID[] = {
|
||||
&IID_ValveStreamingGamepad
|
||||
&IID_ValveStreamingGamepad,
|
||||
&IID_X360WiredGamepad, /* Microsoft's wired X360 controller for Windows. */
|
||||
&IID_X360WirelessGamepad /* Microsoft's wireless X360 controller for Windows. */
|
||||
};
|
||||
IWbemLocator* pIWbemLocator = NULL;
|
||||
IEnumWbemClassObject* pEnumDevices = NULL;
|
||||
IWbemClassObject* pDevices[20];
|
||||
IWbemServices* pIWbemServices = NULL;
|
||||
DWORD uReturned = 0;
|
||||
BSTR bstrNamespace = NULL;
|
||||
BSTR bstrDeviceID = NULL;
|
||||
BSTR bstrClassName = NULL;
|
||||
SDL_bool bIsXinputDevice= SDL_FALSE;
|
||||
UINT iDevice = 0;
|
||||
VARIANT var;
|
||||
HRESULT hr;
|
||||
DWORD bCleanupCOM;
|
||||
|
||||
if (!s_bXInputEnabled)
|
||||
{
|
||||
size_t iDevice;
|
||||
UINT i;
|
||||
|
||||
if (!s_bXInputEnabled) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
// Check for well known XInput device GUIDs
|
||||
// We need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list.
|
||||
/* Check for well known XInput device GUIDs */
|
||||
/* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */
|
||||
for ( iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice ) {
|
||||
if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_memset( pDevices, 0x0, sizeof(pDevices) );
|
||||
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
||||
/* Cache this if we end up using it. */
|
||||
if (SDL_RawDevList == NULL) {
|
||||
if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof (RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
|
||||
return SDL_FALSE; /* oh well. */
|
||||
}
|
||||
|
||||
/* CoInit if needed */
|
||||
hr = CoInitialize(NULL);
|
||||
bCleanupCOM = SUCCEEDED(hr);
|
||||
SDL_RawDevList = (PRAWINPUTDEVICELIST) SDL_malloc(sizeof (RAWINPUTDEVICELIST) * SDL_RawDevListCount);
|
||||
if (SDL_RawDevList == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Create WMI */
|
||||
hr = CoCreateInstance( &CLSID_WbemLocator,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IWbemLocator,
|
||||
(LPVOID*) &pIWbemLocator);
|
||||
if( FAILED(hr) || pIWbemLocator == NULL )
|
||||
goto LCleanup;
|
||||
|
||||
bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup;
|
||||
bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup;
|
||||
bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup;
|
||||
|
||||
/* Connect to WMI */
|
||||
hr = IWbemLocator_ConnectServer( pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
|
||||
0L, NULL, NULL, &pIWbemServices );
|
||||
if( FAILED(hr) || pIWbemServices == NULL )
|
||||
goto LCleanup;
|
||||
|
||||
/* Switch security level to IMPERSONATE. */
|
||||
CoSetProxyBlanket( (IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
||||
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
|
||||
|
||||
hr = IWbemServices_CreateInstanceEnum( pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices );
|
||||
if( FAILED(hr) || pEnumDevices == NULL )
|
||||
goto LCleanup;
|
||||
|
||||
/* Loop over all devices */
|
||||
for( ;; )
|
||||
{
|
||||
/* Get 20 at a time */
|
||||
hr = IEnumWbemClassObject_Next( pEnumDevices, 10000, 20, pDevices, &uReturned );
|
||||
if( FAILED(hr) )
|
||||
goto LCleanup;
|
||||
if( uReturned == 0 )
|
||||
break;
|
||||
|
||||
for( iDevice=0; iDevice<uReturned; iDevice++ )
|
||||
{
|
||||
/* For each device, get its device ID */
|
||||
hr = IWbemClassObject_Get( pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL );
|
||||
if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL )
|
||||
{
|
||||
/* Check if the device ID contains "IG_". If it does, then it's an XInput device */
|
||||
/* This information can not be found from DirectInput */
|
||||
char *pDeviceString = WIN_StringToUTF8( var.bstrVal );
|
||||
if( SDL_strstr( pDeviceString, "IG_" ) )
|
||||
{
|
||||
/* If it does, then get the VID/PID from var.bstrVal */
|
||||
long dwPid = 0, dwVid = 0;
|
||||
char * strPid = NULL;
|
||||
DWORD dwVidPid = 0;
|
||||
char * strVid = SDL_strstr( pDeviceString, "VID_" );
|
||||
if( strVid )
|
||||
{
|
||||
dwVid = SDL_strtol( strVid + 4, NULL, 16 );
|
||||
}
|
||||
strPid = SDL_strstr( pDeviceString, "PID_" );
|
||||
if( strPid )
|
||||
{
|
||||
dwPid = SDL_strtol( strPid + 4, NULL, 16 );
|
||||
}
|
||||
|
||||
/* Compare the VID/PID to the DInput device */
|
||||
dwVidPid = MAKELONG( dwVid, dwPid );
|
||||
if( dwVidPid == pGuidProductFromDirectInput->Data1 )
|
||||
{
|
||||
bIsXinputDevice = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
if ( pDeviceString )
|
||||
SDL_free( pDeviceString );
|
||||
|
||||
if ( bIsXinputDevice )
|
||||
break;
|
||||
}
|
||||
SAFE_RELEASE( pDevices[iDevice] );
|
||||
if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof (RAWINPUTDEVICELIST)) == -1) {
|
||||
SDL_free(SDL_RawDevList);
|
||||
SDL_RawDevList = NULL;
|
||||
return SDL_FALSE; /* oh well. */
|
||||
}
|
||||
}
|
||||
|
||||
LCleanup:
|
||||
for (i = 0; i < SDL_RawDevListCount; i++) {
|
||||
RID_DEVICE_INFO rdi;
|
||||
char devName[128];
|
||||
UINT rdiSize = sizeof (rdi);
|
||||
UINT nameSize = SDL_arraysize(devName);
|
||||
|
||||
for( iDevice=0; iDevice<20; iDevice++ )
|
||||
SAFE_RELEASE( pDevices[iDevice] );
|
||||
SAFE_RELEASE( pEnumDevices );
|
||||
SAFE_RELEASE( pIWbemLocator );
|
||||
SAFE_RELEASE( pIWbemServices );
|
||||
rdi.cbSize = sizeof (rdi);
|
||||
if ( (SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
|
||||
(GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
|
||||
(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
|
||||
(GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
|
||||
(SDL_strstr(devName, "IG_") != NULL) ) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bstrNamespace )
|
||||
SysFreeString( bstrNamespace );
|
||||
if ( bstrClassName )
|
||||
SysFreeString( bstrClassName );
|
||||
if ( bstrDeviceID )
|
||||
SysFreeString( bstrDeviceID );
|
||||
|
||||
if( bCleanupCOM )
|
||||
CoUninitialize();
|
||||
|
||||
return bIsXinputDevice;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -586,10 +480,10 @@ SDL_JoystickThread(void *_data)
|
|||
HWND messageWindow = 0;
|
||||
HDEVNOTIFY hNotify = 0;
|
||||
DEV_BROADCAST_DEVICEINTERFACE dbh;
|
||||
SDL_bool bOpenedXInputDevices[4];
|
||||
SDL_bool bOpenedXInputDevices[SDL_XINPUT_MAX_DEVICES];
|
||||
WNDCLASSEX wincl;
|
||||
|
||||
SDL_memset( bOpenedXInputDevices, 0x0, sizeof(bOpenedXInputDevices) );
|
||||
SDL_zero(bOpenedXInputDevices);
|
||||
|
||||
WIN_CoInitialize();
|
||||
|
||||
|
@ -610,11 +504,11 @@ SDL_JoystickThread(void *_data)
|
|||
return SDL_SetError("Failed to create message window for joystick autodetect.", GetLastError());
|
||||
}
|
||||
|
||||
SDL_memset(&dbh, 0x0, sizeof(dbh));
|
||||
SDL_zero(dbh);
|
||||
|
||||
dbh.dbcc_size = sizeof(dbh);
|
||||
dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
dbh.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
|
||||
dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;
|
||||
|
||||
hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE );
|
||||
if ( !hNotify )
|
||||
|
@ -626,9 +520,8 @@ SDL_JoystickThread(void *_data)
|
|||
while ( s_bJoystickThreadQuit == SDL_FALSE )
|
||||
{
|
||||
MSG messages;
|
||||
Uint8 userId;
|
||||
int nCurrentOpenedXInputDevices = 0;
|
||||
int nNewOpenedXInputDevices = 0;
|
||||
SDL_bool bXInputChanged = SDL_FALSE;
|
||||
|
||||
SDL_CondWaitTimeout( s_condJoystickThread, s_mutexJoyStickEnum, 300 );
|
||||
|
||||
while ( s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) )
|
||||
|
@ -639,33 +532,24 @@ SDL_JoystickThread(void *_data)
|
|||
}
|
||||
}
|
||||
|
||||
if ( s_bXInputEnabled && XINPUTGETCAPABILITIES )
|
||||
{
|
||||
if ( s_bXInputEnabled && XINPUTGETCAPABILITIES ) {
|
||||
/* scan for any change in XInput devices */
|
||||
for ( userId = 0; userId < 4; userId++ )
|
||||
{
|
||||
Uint8 userId;
|
||||
for (userId = 0; userId < SDL_XINPUT_MAX_DEVICES; userId++) {
|
||||
XINPUT_CAPABILITIES capabilities;
|
||||
DWORD result;
|
||||
|
||||
if ( bOpenedXInputDevices[userId] == SDL_TRUE )
|
||||
nCurrentOpenedXInputDevices++;
|
||||
|
||||
result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
|
||||
if ( result == ERROR_SUCCESS )
|
||||
{
|
||||
bOpenedXInputDevices[userId] = SDL_TRUE;
|
||||
nNewOpenedXInputDevices++;
|
||||
}
|
||||
else
|
||||
{
|
||||
bOpenedXInputDevices[userId] = SDL_FALSE;
|
||||
const DWORD result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
|
||||
const SDL_bool available = (result == ERROR_SUCCESS);
|
||||
if (bOpenedXInputDevices[userId] != available) {
|
||||
bXInputChanged = SDL_TRUE;
|
||||
bOpenedXInputDevices[userId] = available;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( s_pKnownJoystickGUIDs && ( s_bWindowsDeviceChanged || nNewOpenedXInputDevices != nCurrentOpenedXInputDevices ) )
|
||||
{
|
||||
if (s_bWindowsDeviceChanged || bXInputChanged) {
|
||||
SDL_UnlockMutex( s_mutexJoyStickEnum ); /* let main thread go while we SDL_Delay(). */
|
||||
SDL_Delay( 300 ); /* wait for direct input to find out about this device */
|
||||
SDL_LockMutex( s_mutexJoyStickEnum );
|
||||
|
||||
s_bDeviceRemoved = SDL_TRUE;
|
||||
s_bDeviceAdded = SDL_TRUE;
|
||||
|
@ -730,15 +614,16 @@ SDL_SYS_JoystickInit(void)
|
|||
return SetDIerror("IDirectInput::Initialize", result);
|
||||
}
|
||||
|
||||
s_mutexJoyStickEnum = SDL_CreateMutex();
|
||||
s_condJoystickThread = SDL_CreateCond();
|
||||
s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
|
||||
SDL_SYS_JoystickDetect();
|
||||
|
||||
if ((s_bXInputEnabled) && (WIN_LoadXInputDLL() == -1)) {
|
||||
s_bXInputEnabled = SDL_FALSE; /* oh well. */
|
||||
}
|
||||
|
||||
s_mutexJoyStickEnum = SDL_CreateMutex();
|
||||
s_condJoystickThread = SDL_CreateCond();
|
||||
s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
|
||||
|
||||
SDL_SYS_JoystickDetect();
|
||||
|
||||
if ( !s_threadJoystick )
|
||||
{
|
||||
s_bJoystickThreadQuit = SDL_FALSE;
|
||||
|
@ -767,15 +652,17 @@ int SDL_SYS_NumJoysticks()
|
|||
return nJoysticks;
|
||||
}
|
||||
|
||||
static int s_iNewGUID = 0;
|
||||
|
||||
/* helper function for direct input, gets called for each connected joystick */
|
||||
static BOOL CALLBACK
|
||||
EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||
{
|
||||
JoyStick_DeviceData *pNewJoystick;
|
||||
JoyStick_DeviceData *pPrevJoystick = NULL;
|
||||
SDL_bool bXInputDevice;
|
||||
|
||||
if (SDL_IsXInputDevice( &pdidInstance->guidProduct )) {
|
||||
return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */
|
||||
}
|
||||
|
||||
pNewJoystick = *(JoyStick_DeviceData **)pContext;
|
||||
while ( pNewJoystick )
|
||||
{
|
||||
|
@ -794,58 +681,109 @@ static BOOL CALLBACK
|
|||
pNewJoystick->pNext = SYS_Joystick;
|
||||
SYS_Joystick = pNewJoystick;
|
||||
|
||||
s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
|
||||
s_iNewGUID++;
|
||||
if ( s_iNewGUID < MAX_JOYSTICKS )
|
||||
return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
|
||||
else
|
||||
return DIENUM_STOP;
|
||||
return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
|
||||
}
|
||||
|
||||
pPrevJoystick = pNewJoystick;
|
||||
pNewJoystick = pNewJoystick->pNext;
|
||||
}
|
||||
|
||||
s_bDeviceAdded = SDL_TRUE;
|
||||
|
||||
bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct );
|
||||
|
||||
pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) );
|
||||
|
||||
if ( bXInputDevice )
|
||||
{
|
||||
pNewJoystick->bXInputDevice = SDL_TRUE;
|
||||
pNewJoystick->XInputUserId = INVALID_XINPUT_USERID;
|
||||
if (!pNewJoystick) {
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewJoystick->bXInputDevice = SDL_FALSE;
|
||||
|
||||
SDL_zerop(pNewJoystick);
|
||||
pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
|
||||
if (!pNewJoystick->joystickname) {
|
||||
SDL_free(pNewJoystick);
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
|
||||
SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
|
||||
sizeof(DIDEVICEINSTANCE));
|
||||
|
||||
pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
|
||||
pNewJoystick->XInputUserId = INVALID_XINPUT_USERID;
|
||||
pNewJoystick->send_add_event = 1;
|
||||
pNewJoystick->nInstanceID = ++s_nInstanceID;
|
||||
SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) );
|
||||
pNewJoystick->pNext = NULL;
|
||||
|
||||
if ( SYS_Joystick )
|
||||
{
|
||||
pNewJoystick->pNext = SYS_Joystick;
|
||||
}
|
||||
pNewJoystick->pNext = SYS_Joystick;
|
||||
SYS_Joystick = pNewJoystick;
|
||||
|
||||
s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
|
||||
s_iNewGUID++;
|
||||
s_bDeviceAdded = SDL_TRUE;
|
||||
|
||||
if ( s_iNewGUID < MAX_JOYSTICKS )
|
||||
return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
|
||||
else
|
||||
return DIENUM_STOP;
|
||||
return DIENUM_CONTINUE; /* get next device, please */
|
||||
}
|
||||
|
||||
static void
|
||||
AddXInputDevice(const Uint8 userid, JoyStick_DeviceData **pContext)
|
||||
{
|
||||
char name[32];
|
||||
JoyStick_DeviceData *pPrevJoystick = NULL;
|
||||
JoyStick_DeviceData *pNewJoystick = *pContext;
|
||||
|
||||
while (pNewJoystick) {
|
||||
if ((pNewJoystick->bXInputDevice) && (pNewJoystick->XInputUserId == userid)) {
|
||||
/* if we are replacing the front of the list then update it */
|
||||
if (pNewJoystick == *pContext) {
|
||||
*pContext = pNewJoystick->pNext;
|
||||
} else if (pPrevJoystick) {
|
||||
pPrevJoystick->pNext = pNewJoystick->pNext;
|
||||
}
|
||||
|
||||
pNewJoystick->pNext = SYS_Joystick;
|
||||
SYS_Joystick = pNewJoystick;
|
||||
return; /* already in the list. */
|
||||
}
|
||||
|
||||
pPrevJoystick = pNewJoystick;
|
||||
pNewJoystick = pNewJoystick->pNext;
|
||||
}
|
||||
|
||||
pNewJoystick = (JoyStick_DeviceData *) SDL_malloc(sizeof (JoyStick_DeviceData));
|
||||
if (!pNewJoystick) {
|
||||
return; /* better luck next time? */
|
||||
}
|
||||
SDL_zerop(pNewJoystick);
|
||||
|
||||
SDL_snprintf(name, sizeof (name), "XInput Controller #%u", ((unsigned int) userid) + 1);
|
||||
pNewJoystick->joystickname = SDL_strdup(name);
|
||||
if (!pNewJoystick->joystickname) {
|
||||
SDL_free(pNewJoystick);
|
||||
return; /* better luck next time? */
|
||||
}
|
||||
|
||||
pNewJoystick->bXInputDevice = SDL_TRUE;
|
||||
pNewJoystick->XInputUserId = userid;
|
||||
pNewJoystick->send_add_event = 1;
|
||||
pNewJoystick->nInstanceID = ++s_nInstanceID;
|
||||
pNewJoystick->pNext = SYS_Joystick;
|
||||
SYS_Joystick = pNewJoystick;
|
||||
|
||||
s_bDeviceAdded = SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
EnumXInputDevices(JoyStick_DeviceData **pContext)
|
||||
{
|
||||
if (s_bXInputEnabled) {
|
||||
int iuserid;
|
||||
/* iterate in reverse, so these are in the final list in ascending numeric order. */
|
||||
for (iuserid = SDL_XINPUT_MAX_DEVICES-1; iuserid >= 0; iuserid--) {
|
||||
const Uint8 userid = (Uint8) iuserid;
|
||||
XINPUT_CAPABILITIES capabilities;
|
||||
if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
|
||||
/* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */
|
||||
/* !!! FIXME: we might want to support steering wheels or guitars or whatever laster. */
|
||||
if (capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD) {
|
||||
AddXInputDevice(userid, pContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* detect any new joysticks being inserted into the system */
|
||||
void SDL_SYS_JoystickDetect()
|
||||
{
|
||||
|
@ -853,25 +791,27 @@ void SDL_SYS_JoystickDetect()
|
|||
/* only enum the devices if the joystick thread told us something changed */
|
||||
if ( s_bDeviceAdded || s_bDeviceRemoved )
|
||||
{
|
||||
SDL_LockMutex( s_mutexJoyStickEnum );
|
||||
|
||||
s_bDeviceAdded = SDL_FALSE;
|
||||
s_bDeviceRemoved = SDL_FALSE;
|
||||
|
||||
pCurList = SYS_Joystick;
|
||||
SYS_Joystick = NULL;
|
||||
s_iNewGUID = 0;
|
||||
SDL_LockMutex( s_mutexJoyStickEnum );
|
||||
|
||||
if ( !s_pKnownJoystickGUIDs )
|
||||
s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS );
|
||||
|
||||
SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS );
|
||||
|
||||
/* Look for joysticks, wheels, head trackers, gamepads, etc.. */
|
||||
/* Look for DirectInput joysticks, wheels, head trackers, gamepads, etc.. */
|
||||
IDirectInput8_EnumDevices(dinput,
|
||||
DI8DEVCLASS_GAMECTRL,
|
||||
EnumJoysticksCallback,
|
||||
&pCurList, DIEDFL_ATTACHEDONLY);
|
||||
|
||||
SDL_free(SDL_RawDevList); /* in case we used this in DirectInput enumerator. */
|
||||
SDL_RawDevList = NULL;
|
||||
SDL_RawDevListCount = 0;
|
||||
|
||||
/* Look for XInput devices. Do this last, so they're first in the final list. */
|
||||
EnumXInputDevices(&pCurList);
|
||||
|
||||
SDL_UnlockMutex( s_mutexJoyStickEnum );
|
||||
}
|
||||
|
||||
|
@ -895,7 +835,7 @@ void SDL_SYS_JoystickDetect()
|
|||
|
||||
pListNext = pCurList->pNext;
|
||||
SDL_free(pCurList->joystickname);
|
||||
SDL_free( pCurList );
|
||||
SDL_free(pCurList);
|
||||
pCurList = pListNext;
|
||||
}
|
||||
|
||||
|
@ -974,17 +914,11 @@ int
|
|||
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
{
|
||||
HRESULT result;
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
DIPROPDWORD dipdw;
|
||||
JoyStick_DeviceData *joystickdevice = SYS_Joystick;
|
||||
|
||||
for (; device_index > 0; device_index--)
|
||||
joystickdevice = joystickdevice->pNext;
|
||||
|
||||
SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD));
|
||||
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
|
||||
/* allocate memory for system specific hardware data */
|
||||
joystick->instance_id = joystickdevice->nInstanceID;
|
||||
joystick->closed = 0;
|
||||
|
@ -993,71 +927,50 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
if (joystick->hwdata == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata));
|
||||
joystick->hwdata->buffered = 1;
|
||||
joystick->hwdata->removed = 0;
|
||||
joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
|
||||
joystick->hwdata->guid = joystickdevice->guid;
|
||||
SDL_zerop(joystick->hwdata);
|
||||
|
||||
if ( joystickdevice->bXInputDevice )
|
||||
{
|
||||
if (joystickdevice->bXInputDevice) {
|
||||
const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4));
|
||||
const Uint8 userId = joystickdevice->XInputUserId;
|
||||
XINPUT_CAPABILITIES capabilities;
|
||||
Uint8 userId = 0;
|
||||
DWORD result;
|
||||
JoyStick_DeviceData *joysticklist = SYS_Joystick;
|
||||
/* scan the opened joysticks and pick the next free xinput userid for this one */
|
||||
for( ; joysticklist; joysticklist = joysticklist->pNext)
|
||||
{
|
||||
if ( joysticklist->bXInputDevice && joysticklist->XInputUserId == userId )
|
||||
userId++;
|
||||
}
|
||||
|
||||
if ( s_bXInputEnabled && XINPUTGETCAPABILITIES )
|
||||
{
|
||||
result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
|
||||
if ( result == ERROR_SUCCESS )
|
||||
{
|
||||
const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4));
|
||||
SDL_bool bIsSupported = SDL_FALSE;
|
||||
/* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */
|
||||
bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD );
|
||||
SDL_assert(s_bXInputEnabled);
|
||||
SDL_assert(XINPUTGETCAPABILITIES);
|
||||
SDL_assert(userId >= 0);
|
||||
SDL_assert(userId < SDL_XINPUT_MAX_DEVICES);
|
||||
|
||||
if ( !bIsSupported )
|
||||
{
|
||||
joystickdevice->bXInputDevice = SDL_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* valid */
|
||||
joystick->hwdata->bXInputDevice = SDL_TRUE;
|
||||
if ((!bIs14OrLater) || (capabilities.Flags & XINPUT_CAPS_FFB_SUPPORTED)) {
|
||||
joystick->hwdata->bXInputHaptic = SDL_TRUE;
|
||||
}
|
||||
SDL_memset( joystick->hwdata->XInputState, 0x0, sizeof(joystick->hwdata->XInputState) );
|
||||
joystickdevice->XInputUserId = userId;
|
||||
joystick->hwdata->userid = userId;
|
||||
joystick->hwdata->currentXInputSlot = 0;
|
||||
/* The XInput API has a hard coded button/axis mapping, so we just match it */
|
||||
joystick->naxes = 6;
|
||||
joystick->nbuttons = 15;
|
||||
joystick->nballs = 0;
|
||||
joystick->nhats = 0;
|
||||
}
|
||||
joystick->hwdata->bXInputDevice = SDL_TRUE;
|
||||
|
||||
if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?");
|
||||
} else {
|
||||
/* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */
|
||||
SDL_assert(capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD);
|
||||
if ((!bIs14OrLater) || (capabilities.Flags & XINPUT_CAPS_FFB_SUPPORTED)) {
|
||||
joystick->hwdata->bXInputHaptic = SDL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
joystickdevice->bXInputDevice = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
joystickdevice->bXInputDevice = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
joystick->hwdata->userid = userId;
|
||||
|
||||
if ( joystickdevice->bXInputDevice == SDL_FALSE )
|
||||
{
|
||||
joystick->hwdata->bXInputDevice = SDL_FALSE;
|
||||
/* The XInput API has a hard coded button/axis mapping, so we just match it */
|
||||
joystick->naxes = 6;
|
||||
joystick->nbuttons = 15;
|
||||
joystick->nballs = 0;
|
||||
joystick->nhats = 0;
|
||||
}
|
||||
} else { /* use DirectInput, not XInput. */
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
DIPROPDWORD dipdw;
|
||||
|
||||
joystick->hwdata->buffered = 1;
|
||||
joystick->hwdata->removed = 0;
|
||||
joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
|
||||
joystick->hwdata->guid = joystickdevice->guid;
|
||||
|
||||
SDL_zero(dipdw);
|
||||
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
|
||||
result =
|
||||
IDirectInput8_CreateDevice(dinput,
|
||||
|
@ -1642,29 +1555,13 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
if ( joystick->hwdata->bXInputDevice )
|
||||
{
|
||||
JoyStick_DeviceData *joysticklist = SYS_Joystick;
|
||||
/* scan the opened joysticks and clear the userid for this instance */
|
||||
for( ; joysticklist; joysticklist = joysticklist->pNext)
|
||||
{
|
||||
if ( joysticklist->bXInputDevice && joysticklist->nInstanceID == joystick->instance_id )
|
||||
{
|
||||
joysticklist->XInputUserId = INVALID_XINPUT_USERID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!joystick->hwdata->bXInputDevice) {
|
||||
IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
|
||||
IDirectInputDevice8_Release(joystick->hwdata->InputDevice);
|
||||
}
|
||||
|
||||
if (joystick->hwdata != NULL) {
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
}
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
@ -1709,18 +1606,11 @@ SDL_SYS_JoystickQuit(void)
|
|||
coinitialized = SDL_FALSE;
|
||||
}
|
||||
|
||||
if ( s_pKnownJoystickGUIDs )
|
||||
{
|
||||
SDL_free( s_pKnownJoystickGUIDs );
|
||||
s_pKnownJoystickGUIDs = NULL;
|
||||
}
|
||||
|
||||
if (s_bXInputEnabled) {
|
||||
WIN_UnloadXInputDLL();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* return the stable device guid for this device index */
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
|
@ -1750,6 +1640,12 @@ SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index)
|
|||
return device->bXInputDevice;
|
||||
}
|
||||
|
||||
/* return SDL_TRUE if this device was opened with XInput */
|
||||
SDL_bool SDL_SYS_IsXInputJoystick(SDL_Joystick * joystick)
|
||||
{
|
||||
return joystick->hwdata->bXInputDevice;
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_DINPUT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -42,7 +42,18 @@
|
|||
#include <xinput.h>
|
||||
#include <devguid.h>
|
||||
#include <dbt.h>
|
||||
#include <xinput.h>
|
||||
|
||||
|
||||
#ifndef XUSER_MAX_COUNT
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#endif
|
||||
#ifndef XUSER_INDEX_ANY
|
||||
#define XUSER_INDEX_ANY 0x000000FF
|
||||
#endif
|
||||
#ifndef XINPUT_CAPS_FFB_SUPPORTED
|
||||
#define XINPUT_CAPS_FFB_SUPPORTED 0x0001
|
||||
#endif
|
||||
|
||||
|
||||
/* typedef's for XInput structs we use */
|
||||
typedef struct
|
||||
|
@ -94,13 +105,8 @@ extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */
|
|||
#define XINPUTGETSTATE SDL_XInputGetState
|
||||
#define XINPUTSETSTATE SDL_XInputSetState
|
||||
#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities
|
||||
#define INVALID_XINPUT_USERID 255
|
||||
#define SDL_XINPUT_MAX_DEVICES 4
|
||||
|
||||
#ifndef XINPUT_CAPS_FFB_SUPPORTED
|
||||
#define XINPUT_CAPS_FFB_SUPPORTED 0x0001
|
||||
#endif
|
||||
|
||||
#define INVALID_XINPUT_USERID XUSER_INDEX_ANY
|
||||
#define SDL_XINPUT_MAX_DEVICES XUSER_MAX_COUNT
|
||||
|
||||
#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */
|
||||
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#ifdef REGSTR_VAL_JOYOEMNAME
|
||||
#undef REGSTR_VAL_JOYOEMNAME
|
||||
#endif
|
||||
#define REGSTR_VAL_JOYOEMNAME "OEMName"
|
||||
|
||||
#define MAX_JOYSTICKS 16
|
||||
#define MAX_AXES 6 /* each joystick can have up to 6 axes */
|
||||
#define MAX_BUTTONS 32 /* and 32 buttons */
|
||||
|
@ -45,7 +50,7 @@
|
|||
|
||||
/* array to hold joystick ID values */
|
||||
static UINT SYS_JoystickID[MAX_JOYSTICKS];
|
||||
static JOYCAPS SYS_Joystick[MAX_JOYSTICKS];
|
||||
static JOYCAPSA SYS_Joystick[MAX_JOYSTICKS];
|
||||
static char *SYS_JoystickName[MAX_JOYSTICKS];
|
||||
|
||||
/* The private structure used to keep track of a joystick */
|
||||
|
@ -148,7 +153,7 @@ SDL_SYS_JoystickInit(void)
|
|||
int i;
|
||||
int maxdevs;
|
||||
JOYINFOEX joyinfo;
|
||||
JOYCAPS joycaps;
|
||||
JOYCAPSA joycaps;
|
||||
MMRESULT result;
|
||||
|
||||
/* Reset the joystick ID & name mapping tables */
|
||||
|
@ -166,7 +171,7 @@ SDL_SYS_JoystickInit(void)
|
|||
joyinfo.dwFlags = JOY_RETURNALL;
|
||||
result = joyGetPosEx(i, &joyinfo);
|
||||
if (result == JOYERR_NOERROR) {
|
||||
result = joyGetDevCaps(i, &joycaps, sizeof(joycaps));
|
||||
result = joyGetDevCapsA(i, &joycaps, sizeof(joycaps));
|
||||
if (result == JOYERR_NOERROR) {
|
||||
SYS_JoystickID[SDL_SYS_numjoysticks] = i;
|
||||
SYS_Joystick[SDL_SYS_numjoysticks] = joycaps;
|
||||
|
@ -384,11 +389,9 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->hwdata != NULL) {
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
@ -397,10 +400,8 @@ SDL_SYS_JoystickQuit(void)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_JOYSTICKS; i++) {
|
||||
if (SYS_JoystickName[i] != NULL) {
|
||||
SDL_free(SYS_JoystickName[i]);
|
||||
SYS_JoystickName[i] = NULL;
|
||||
}
|
||||
SDL_free(SYS_JoystickName[i]);
|
||||
SYS_JoystickName[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue