mirror of https://github.com/nirenjan/libx52.git
Add connect/disconnect methods to libx52
Prior to this change, libx52_init needed a supported joystick to be plugged in, otherwise it would fail with LIBX52_ERROR_NO_DEVICE. This change modifies the behavior so that libx52_init would still succeed, but the application should call libx52_connect to make sure that the device handle is valid. libx52_init still tries to connect to the joystick, but absence is no longer treated as a failure. This change also modifies x52cli to check that the joystick is actually connected before calling the individual handlers. Because libx52_init no longer fails if the joystick is absent, we need to rely on the return code from libx52_connect.debian-packaging
parent
93f1091b95
commit
d9ae8d4b79
|
@ -6,11 +6,15 @@ The format is based upon [Keep a Changelog].
|
|||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Connect/Disconnect methods in libx52. These allow for dynamically connecting
|
||||
or disconnecting from a supported joystick without having to reinitialize the
|
||||
library.
|
||||
- Internationalization for the following:
|
||||
* libx52
|
||||
* x52test
|
||||
|
||||
### Changed
|
||||
- libx52_init no longer fails when a supported joystick is not connected.
|
||||
- x52test moves the LED tests to execute after all other tests. See
|
||||
[#19](https://github.com/nirenjan/x52pro-linux/issues/19).
|
||||
|
||||
|
|
|
@ -227,11 +227,10 @@ typedef enum {
|
|||
* structures to access the joystick, and returns a \ref libx52_device pointer.
|
||||
* All calls to libx52 use the returned pointer to control the device.
|
||||
*
|
||||
* If no joystick is found `libx52_init()` returns _NULL_.
|
||||
*
|
||||
* @par Limitations
|
||||
* This function does not support hotplugging. The joystick must be plugged in
|
||||
* before calling this function.
|
||||
* This function attempts to connect to the joystick upon initialization.
|
||||
* However, if no device is connected, then the library initialization does
|
||||
* not fail, but the application must call \ref libx52_connect prior to any
|
||||
* calls to \ref libx52_update
|
||||
*
|
||||
* @param[out] dev Pointer to a \ref libx52_device *. This function will
|
||||
* allocate a device context and return the pointer to that in this variable.
|
||||
|
@ -252,6 +251,33 @@ int libx52_init(libx52_device ** dev);
|
|||
*/
|
||||
void libx52_exit(libx52_device *dev);
|
||||
|
||||
/**
|
||||
* @brief Connect to the X52 device
|
||||
*
|
||||
* Attempt to connect to a supported X52/X52Pro joystick. If no supported
|
||||
* joysticks are found, it will return \ref LIBX52_ERROR_NO_DEVICE. If any
|
||||
* errors are encountered during device enumeration, it will return an
|
||||
* appropriate \ref libx52_error_code.
|
||||
*
|
||||
* @param[in] dev Pointer to the device
|
||||
*
|
||||
* @returns \ref libx52_error_code indicating status
|
||||
*/
|
||||
int libx52_connect(libx52_device *dev);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from the X52 device
|
||||
*
|
||||
* This function disconnects any active connections to supported joysticks.
|
||||
* Applications must reconnect to the joystick using \ref libx52_connect prior
|
||||
* to calling \ref libx52_update.
|
||||
*
|
||||
* @param[in] dev Pointer to the device
|
||||
*
|
||||
* @returns \ref libx52_error_code indicating status
|
||||
*/
|
||||
int libx52_disconnect(libx52_device *dev);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,6 +70,13 @@ int libx52_vendor_command(libx52_device *x52, uint16_t index, uint16_t value)
|
|||
int j;
|
||||
int rc = 0;
|
||||
|
||||
/* It is possible for the vendor command to be called when the joystick
|
||||
* is not connected. Check for this and return an appropriate error.
|
||||
*/
|
||||
if (!x52->hdl) {
|
||||
return LIBX52_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
/* Allow retry in case of failure */
|
||||
for (j = 0; j < 3; j++) {
|
||||
rc = libusb_control_transfer(x52->hdl,
|
||||
|
@ -226,6 +233,13 @@ int libx52_update(libx52_device *x52)
|
|||
uint16_t value;
|
||||
int rc = LIBX52_SUCCESS;
|
||||
|
||||
/* It is possible for the update command to be called when the joystick
|
||||
* is not connected. Check for this and return an appropriate error.
|
||||
*/
|
||||
if (!x52->hdl) {
|
||||
return LIBX52_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
/* Save the update mask */
|
||||
update_mask = x52->update_mask;
|
||||
/* Reset the device update mask to 0 */
|
||||
|
|
|
@ -43,7 +43,22 @@ static int libx52_device_is_x52pro(uint16_t idProduct)
|
|||
return (idProduct == X52_PROD_X52PRO);
|
||||
}
|
||||
|
||||
int libx52_init(libx52_device **dev)
|
||||
int libx52_disconnect(libx52_device *dev)
|
||||
{
|
||||
if (!dev) {
|
||||
return LIBX52_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (dev->hdl) {
|
||||
libusb_close(dev->hdl);
|
||||
dev->hdl = NULL;
|
||||
dev->flags = 0;
|
||||
}
|
||||
|
||||
return LIBX52_SUCCESS;
|
||||
}
|
||||
|
||||
int libx52_connect(libx52_device *dev)
|
||||
{
|
||||
int rc;
|
||||
ssize_t count;
|
||||
|
@ -52,6 +67,52 @@ int libx52_init(libx52_device **dev)
|
|||
libusb_device *device;
|
||||
libusb_device_handle *hdl;
|
||||
struct libusb_device_descriptor desc;
|
||||
|
||||
/* Make sure that we have a valid pointer */
|
||||
if (!dev) {
|
||||
return LIBX52_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Disconnect any existing handles. This will force libx52 to rescan the
|
||||
* device list and bind to the first supported joystick, if any. If the
|
||||
* joystick was unplugged between subsequent calls to this function, then
|
||||
* it will return a No device error. This also means that a new device
|
||||
* handle is cached in the device structure.
|
||||
*/
|
||||
(void)libx52_disconnect(dev);
|
||||
|
||||
count = libusb_get_device_list(dev->ctx, &list);
|
||||
for (i = 0; i < count; i++) {
|
||||
device = list[i];
|
||||
if (!libusb_get_device_descriptor(device, &desc)) {
|
||||
if (libx52_check_product(desc.idVendor, desc.idProduct)) {
|
||||
rc = libusb_open(device, &hdl);
|
||||
if (rc) {
|
||||
return libx52internal_translate_libusb_error(rc);
|
||||
}
|
||||
|
||||
dev->hdl = hdl;
|
||||
|
||||
if (libx52_device_is_x52pro(desc.idProduct)) {
|
||||
set_bit(&(dev->flags), X52_FLAG_IS_PRO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(list, 1);
|
||||
|
||||
/* Make sure we actually have an X52 device detected */
|
||||
if (!dev->hdl) {
|
||||
return LIBX52_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
return LIBX52_SUCCESS;
|
||||
}
|
||||
|
||||
int libx52_init(libx52_device **dev)
|
||||
{
|
||||
int rc;
|
||||
libx52_device *x52_dev;
|
||||
|
||||
/* Make sure that we have a valid return pointer */
|
||||
|
@ -67,9 +128,10 @@ int libx52_init(libx52_device **dev)
|
|||
|
||||
rc = libusb_init(&(x52_dev->ctx));
|
||||
if (rc) {
|
||||
rc = LIBX52_ERROR_INIT_FAILURE;
|
||||
goto err_recovery;
|
||||
free(x52_dev);
|
||||
return LIBX52_ERROR_INIT_FAILURE;
|
||||
}
|
||||
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000106)
|
||||
/*
|
||||
* Use the libusb_set_option flag instead of libusb_set_debug. This
|
||||
|
@ -81,33 +143,11 @@ int libx52_init(libx52_device **dev)
|
|||
libusb_set_debug(x52_dev->ctx, LIBUSB_LOG_LEVEL_WARNING);
|
||||
#endif
|
||||
|
||||
count = libusb_get_device_list(x52_dev->ctx, &list);
|
||||
for (i = 0; i < count; i++) {
|
||||
device = list[i];
|
||||
if (!libusb_get_device_descriptor(device, &desc)) {
|
||||
if (libx52_check_product(desc.idVendor, desc.idProduct)) {
|
||||
rc = libusb_open(device, &hdl);
|
||||
if (rc) {
|
||||
rc = libx52internal_translate_libusb_error(rc);
|
||||
goto err_recovery;
|
||||
}
|
||||
|
||||
x52_dev->hdl = hdl;
|
||||
|
||||
if (libx52_device_is_x52pro(desc.idProduct)) {
|
||||
set_bit(&(x52_dev->flags), X52_FLAG_IS_PRO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(list, 1);
|
||||
|
||||
/* Make sure we actually have an X52 device detected */
|
||||
if (!x52_dev->hdl) {
|
||||
rc = LIBX52_ERROR_NO_DEVICE;
|
||||
goto err_recovery;
|
||||
}
|
||||
/* Try to connect to any supported joystick. It's OK if there aren't
|
||||
* any available to connect to, subsequent calls to libx52_connect will
|
||||
* be used to open the device handle
|
||||
*/
|
||||
(void)libx52_connect(x52_dev);
|
||||
|
||||
*dev = x52_dev;
|
||||
|
||||
|
@ -115,15 +155,11 @@ int libx52_init(libx52_device **dev)
|
|||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
||||
return LIBX52_SUCCESS;
|
||||
|
||||
err_recovery:
|
||||
free(x52_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void libx52_exit(libx52_device *dev)
|
||||
{
|
||||
libusb_close(dev->hdl);
|
||||
libx52_disconnect(dev);
|
||||
libusb_exit(dev->ctx);
|
||||
|
||||
/* Clear the memory to prevent reuse */
|
||||
|
|
|
@ -374,11 +374,18 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* Lookup the X52 device */
|
||||
/* Initialize libx52 */
|
||||
rc = libx52_init(&x52);
|
||||
|
||||
if (rc != LIBX52_SUCCESS) {
|
||||
fprintf(stderr, "Error initializing X52 joystick: %s\n", libx52_strerror(rc));
|
||||
fprintf(stderr, "Error initializing X52 library: %s\n", libx52_strerror(rc));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Make sure we are connected to the joystick */
|
||||
rc = libx52_connect(x52);
|
||||
if (rc != LIBX52_SUCCESS) {
|
||||
fprintf(stderr, "Error connecting to joystick: %s\n", libx52_strerror(rc));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue