mirror of https://github.com/nirenjan/libx52.git
Add initial version of libx52io
parent
bcc90ac24e
commit
329274e6c9
|
@ -858,6 +858,7 @@ INPUT_ENCODING = UTF-8
|
|||
|
||||
FILE_PATTERNS = \
|
||||
libx52.h \
|
||||
libx52io.h \
|
||||
libx52util.h \
|
||||
x52_cli.c \
|
||||
*.dox
|
||||
|
|
|
@ -47,7 +47,10 @@ AC_SUBST([X52_INCLUDE], ["-I \$(top_srcdir)/lib/libx52"])
|
|||
# Check for hidapi. This uses a different pkg-config file on Linux vs other
|
||||
# hosts, so check accordingly
|
||||
AM_COND_IF([LINUX], [hidapi_backend=hidapi-hidraw], [hidapi_backend=hidapi])
|
||||
AX_PKG_CHECK_MODULES([HIDAPI], [${hidapi_backend}], [], [have_hidapi=yes], [have_hidapi=no])
|
||||
AX_PKG_CHECK_MODULES([HIDAPI], [${hidapi_backend}])
|
||||
AC_SUBST([HIDAPI_CFLAGS])
|
||||
AC_SUBST([HIDAPI_LDFLAGS])
|
||||
AC_SUBST([HIDAPI_LIBS])
|
||||
|
||||
# Check for pthreads
|
||||
ACX_PTHREAD
|
||||
|
@ -102,6 +105,7 @@ AC_CONFIG_FILES([ po/Makefile.in
|
|||
lib/libx52/libx52.pc
|
||||
lib/libusbx52/Makefile
|
||||
lib/libx52util/Makefile
|
||||
lib/libx52io/Makefile
|
||||
udev/Makefile
|
||||
utils/Makefile
|
||||
utils/cli/Makefile
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
|
||||
|
||||
SUBDIRS = libx52 libx52util libusbx52
|
||||
SUBDIRS = libx52 libx52util libusbx52 libx52io
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ See the documentation for the following files for a complete list of all
|
|||
functions.
|
||||
|
||||
- libx52.h
|
||||
- libx52io.h
|
||||
- libx52util.h
|
||||
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# Automake for libx52io
|
||||
#
|
||||
# Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
|
||||
|
||||
lib_LTLIBRARIES = libx52io.la
|
||||
|
||||
# X52 IO library
|
||||
# This library handles the HID parsing of the X52 USB reports
|
||||
# Libtool Version Info
|
||||
# See: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
libx52io_v_CUR=0
|
||||
libx52io_v_AGE=0
|
||||
libx52io_v_REV=0
|
||||
libx52io_la_SOURCES = io_core.c
|
||||
libx52io_la_CFLAGS = @HIDAPI_CFLAGS@ -DLOCALEDIR=\"$(localedir)\" -I $(top_srcdir) $(WARN_CFLAGS)
|
||||
libx52io_la_LDFLAGS = \
|
||||
-export-symbols-regex '^libx52io_' \
|
||||
-version-info $(libx52io_v_CUR):$(libx52io_v_REV):$(libx52io_v_AGE) @HIDAPI_LIBS@ \
|
||||
$(WARN_LDFLAGS)
|
||||
libx52io_la_LIBADD = @LTLIBINTL@
|
||||
|
||||
# Header files that need to be copied
|
||||
x52includedir = $(includedir)/x52pro
|
||||
x52include_HEADERS = libx52io.h
|
||||
|
||||
# pkg-config files
|
||||
# pkgconfig_DATA = libx52io.pc
|
||||
|
||||
# Extra files that need to be in the distribution
|
||||
EXTRA_DIST = libx52io.h io_common.h
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Saitek X52 IO driver - common definitions
|
||||
*
|
||||
* Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
|
||||
*/
|
||||
|
||||
#ifndef IO_COMMON_H
|
||||
#define IO_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libx52io.h"
|
||||
#include "hidapi.h"
|
||||
|
||||
// Function handler for parsing reports
|
||||
typedef int (*x52_parse_report)(unsigned char *data, int length);
|
||||
|
||||
struct libx52io_context {
|
||||
hid_device *handle;
|
||||
|
||||
int32_t axis_min[LIBX52IO_AXIS_MAX];
|
||||
int32_t axis_max[LIBX52IO_AXIS_MAX];
|
||||
|
||||
int16_t pid;
|
||||
x52_parse_report parser;
|
||||
};
|
||||
|
||||
void _x52io_set_axis_range(libx52io_context *ctx);
|
||||
void _x52io_set_report_parser(libx52io_context *ctx);
|
||||
|
||||
#endif // !defined IO_COMMON_H
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Saitek X52 IO driver
|
||||
*
|
||||
* Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "io_common.h"
|
||||
|
||||
int libx52io_init(libx52io_context **ctx)
|
||||
{
|
||||
libx52io_context *tmp;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return LIBX52IO_ERROR_INVALID;
|
||||
}
|
||||
|
||||
if (hid_init()) {
|
||||
return LIBX52IO_ERROR_INIT_FAILURE;
|
||||
}
|
||||
|
||||
// Allocate a context
|
||||
tmp = calloc(1, sizeof(*tmp));
|
||||
if (tmp == NULL) {
|
||||
return LIBX52IO_ERROR_INIT_FAILURE;
|
||||
}
|
||||
|
||||
*ctx = tmp;
|
||||
return LIBX52IO_SUCCESS;
|
||||
}
|
||||
|
||||
void libx52io_exit(libx52io_context *ctx)
|
||||
{
|
||||
// Close any open handles, free context
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
libx52io_close(ctx);
|
||||
hid_exit();
|
||||
}
|
||||
|
||||
int libx52io_close(libx52io_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return LIBX52IO_ERROR_INVALID;
|
||||
}
|
||||
|
||||
if (ctx->handle != NULL) {
|
||||
hid_close(ctx->handle);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
return LIBX52IO_SUCCESS;
|
||||
}
|
||||
|
||||
int libx52io_open(libx52io_context *ctx)
|
||||
{
|
||||
struct hid_device_info *devs, *cur_dev;
|
||||
int rc = LIBX52IO_SUCCESS;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return LIBX52IO_ERROR_INVALID;
|
||||
}
|
||||
|
||||
/* Close any already open handles */
|
||||
libx52io_close(ctx);
|
||||
|
||||
/* Enumerate all Saitek HID devices */
|
||||
devs = hid_enumerate(0x06a3, 0);
|
||||
cur_dev = devs;
|
||||
while (cur_dev) {
|
||||
switch (cur_dev->product_id) {
|
||||
case 0x0255:
|
||||
case 0x075c:
|
||||
case 0x0762:
|
||||
ctx->handle = hid_open_path(cur_dev->path);
|
||||
if (ctx->handle == NULL) {
|
||||
rc = LIBX52IO_ERROR_CONN;
|
||||
goto finally;
|
||||
}
|
||||
|
||||
ctx->pid = cur_dev->product_id;
|
||||
/* _x52io_set_axis_range(ctx); */
|
||||
/* _x52io_set_report_parser(ctx); */
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cur_dev = cur_dev->next;
|
||||
}
|
||||
|
||||
finally:
|
||||
hid_free_enumeration(devs);
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Saitek X52 IO driver
|
||||
*
|
||||
* Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libx52io.h
|
||||
* @brief Functions, structures and enumerations for the Saitek X52 IO driver
|
||||
* library.
|
||||
*
|
||||
* This file contains the type, enum and function prototypes for the Saitek X52
|
||||
* IO driver library. These functions allow an application to connect to a
|
||||
* supported X52/X52Pro joystick and read the state of the buttons and axes.
|
||||
*
|
||||
* @author Nirenjan Krishnan (nirenjan@nirenjan.org)
|
||||
*/
|
||||
#ifndef LIBX52IO_H
|
||||
#define LIBX52IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup libx52io IO Library APIs
|
||||
*
|
||||
* These functions allow an application to connect to a supported X52/X52Pro
|
||||
* joystick and read the state of the buttons and axes.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Opaque structure used by libx52io
|
||||
*/
|
||||
struct libx52io_context;
|
||||
|
||||
/**
|
||||
* @brief Device context structure used by libx52io
|
||||
*
|
||||
* All libx52io API functions require the application to pass in a pointer to
|
||||
* a valid device context structure. A pointer can be obtained by calling
|
||||
* \ref libx52io_init
|
||||
*/
|
||||
typedef struct libx52io_context libx52io_context;
|
||||
|
||||
/**
|
||||
* @brief libx52 IO error codes
|
||||
*
|
||||
* Error codes returned by libx52io
|
||||
*/
|
||||
typedef enum {
|
||||
/** No error, indicates success */
|
||||
LIBX52IO_SUCCESS,
|
||||
|
||||
/** Initialization failure */
|
||||
LIBX52IO_ERROR_INIT_FAILURE,
|
||||
|
||||
/** No compatible device found */
|
||||
LIBX52IO_ERROR_NO_DEVICE,
|
||||
|
||||
/** Invalid arguments for function */
|
||||
LIBX52IO_ERROR_INVALID,
|
||||
|
||||
/** Connection error */
|
||||
LIBX52IO_ERROR_CONN,
|
||||
|
||||
/** Read error from device */
|
||||
LIBX52IO_ERROR_IO,
|
||||
|
||||
/** Other (unknown) error */
|
||||
LIBX52_ERROR_UNKNOWN
|
||||
} libx52io_error_code;
|
||||
|
||||
/**
|
||||
* @brief X52 Axis definitions
|
||||
*/
|
||||
typedef enum {
|
||||
/** Stick X axis */
|
||||
LIBX52IO_AXIS_X,
|
||||
|
||||
/** Stick Y axis */
|
||||
LIBX52IO_AXIS_Y,
|
||||
|
||||
/** Stick twist axis */
|
||||
LIBX52IO_AXIS_RZ,
|
||||
|
||||
/** Throttle axis */
|
||||
LIBX52IO_AXIS_Z,
|
||||
|
||||
/** Throttle Rotary X */
|
||||
LIBX52IO_AXIS_RX,
|
||||
|
||||
/** Throttle Rotary Y */
|
||||
LIBX52IO_AXIS_RY,
|
||||
|
||||
/** Throttle Slider */
|
||||
LIBX52IO_AXIS_SLIDER,
|
||||
|
||||
/** Thumbstick X */
|
||||
LIBX52IO_AXIS_THUMBX,
|
||||
|
||||
/** Thumbstick Y */
|
||||
LIBX52IO_AXIS_THUMBY,
|
||||
|
||||
LIBX52IO_AXIS_MAX
|
||||
} libx52io_axis;
|
||||
|
||||
/**
|
||||
* @brief X52 Button definitions
|
||||
*/
|
||||
typedef enum {
|
||||
/** Primary trigger */
|
||||
LIBX52IO_BTN_TRIGGER,
|
||||
|
||||
/** Secondary trigger */
|
||||
LIBX52IO_BTN_TRIGGER_2,
|
||||
|
||||
/** Fire button */
|
||||
LIBX52IO_BTN_FIRE,
|
||||
|
||||
/** Pinky trigger */
|
||||
LIBX52IO_BTN_PINKY,
|
||||
|
||||
/** A button, on stick */
|
||||
LIBX52IO_BTN_A,
|
||||
|
||||
/** B button, on stick */
|
||||
LIBX52IO_BTN_B,
|
||||
|
||||
/** C button, on stick */
|
||||
LIBX52IO_BTN_C,
|
||||
|
||||
/** D button, on throttle */
|
||||
LIBX52IO_BTN_D,
|
||||
|
||||
/** E button, on throttle */
|
||||
LIBX52IO_BTN_E,
|
||||
|
||||
/** Toggle 1 up */
|
||||
LIBX52IO_BTN_T1_UP,
|
||||
|
||||
/** Toggle 1 down */
|
||||
LIBX52IO_BTN_T1_DN,
|
||||
|
||||
/** Toggle 2 up */
|
||||
LIBX52IO_BTN_T2_UP,
|
||||
|
||||
/** Toggle 2 down */
|
||||
LIBX52IO_BTN_T2_DN,
|
||||
|
||||
/** Toggle 3 up */
|
||||
LIBX52IO_BTN_T3_UP,
|
||||
|
||||
/** Toggle 3 down */
|
||||
LIBX52IO_BTN_T3_DN,
|
||||
|
||||
/** POV 1 Up, on stick */
|
||||
LIBX52IO_BTN_POV_1_N,
|
||||
|
||||
/** POV 1 Right, on stick */
|
||||
LIBX52IO_BTN_POV_1_E,
|
||||
|
||||
/** POV 1 Down, on stick */
|
||||
LIBX52IO_BTN_POV_1_S,
|
||||
|
||||
/** POV 1 Left, on stick */
|
||||
LIBX52IO_BTN_POV_1_W,
|
||||
|
||||
/** POV 2 Up, on throttle */
|
||||
LIBX52IO_BTN_POV_2_N,
|
||||
|
||||
/** POV 2 Right, on throttle */
|
||||
LIBX52IO_BTN_POV_2_E,
|
||||
|
||||
/** POV 2 Down, on throttle */
|
||||
LIBX52IO_BTN_POV_2_S,
|
||||
|
||||
/** POV 2 Left, on throttle */
|
||||
LIBX52IO_BTN_POV_2_W,
|
||||
|
||||
/** Clutch button, on throttle */
|
||||
LIBX52IO_BTN_CLUTCH,
|
||||
|
||||
/** Primary mouse button, next to thumbstick */
|
||||
LIBX52IO_BTN_MOUSE_PRIMARY,
|
||||
|
||||
/** Secondary mouse button, press scroll wheel on throttle */
|
||||
LIBX52IO_BTN_MOUSE_SECONDARY,
|
||||
|
||||
/** Scroll wheel up, on throttle */
|
||||
LIBX52IO_BTN_MOUSE_SCROLL_UP,
|
||||
|
||||
/** Scroll wheel down, on throttle */
|
||||
LIBX52IO_BTN_MOUSE_SCROLL_DN,
|
||||
|
||||
/** Function button */
|
||||
LIBX52IO_BTN_FUNCTION,
|
||||
|
||||
/** Start/Stop button */
|
||||
LIBX52IO_BTN_START_STOP,
|
||||
|
||||
/** Reset button */
|
||||
LIBX52IO_BTN_RESET,
|
||||
|
||||
/** Page Up button, X52 Pro only */
|
||||
LIBX52IO_BTN_PG_UP,
|
||||
|
||||
/** Page Down button, X52 Pro only */
|
||||
LIBX52IO_BTN_PG_DN,
|
||||
|
||||
/** Up button, X52 Pro only */
|
||||
LIBX52IO_BTN_UP,
|
||||
|
||||
/** Down button, X52 Pro only */
|
||||
LIBX52IO_BTN_DN,
|
||||
|
||||
/** Select button, X52 Pro only */
|
||||
LIBX52IO_BTN_SELECT,
|
||||
|
||||
LIBX52IO_BUTTON_MAX
|
||||
} libx52io_button;
|
||||
|
||||
/**
|
||||
* @brief X52 HID Report
|
||||
*
|
||||
* This structure holds a parsed HID report
|
||||
*/
|
||||
struct libx52io_report {
|
||||
/** Axis values */
|
||||
int32_t axis_value[LIBX52IO_AXIS_MAX];
|
||||
|
||||
/** Button values, true is pressed */
|
||||
bool button[LIBX52IO_BUTTON_MAX];
|
||||
|
||||
/** Current mode - 1, 2 or 3 */
|
||||
uint8_t mode;
|
||||
|
||||
/** Hat position 0-8 */
|
||||
uint8_t hat;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief X52 HID Report
|
||||
*
|
||||
* This structure holds a parsed HID report
|
||||
*/
|
||||
typedef struct libx52io_report libx52io_report;
|
||||
|
||||
/**
|
||||
* @brief Initialize the IO library
|
||||
*
|
||||
* This function initializes the libx52io library, sets up any internal data
|
||||
* structures to access the joystick, and returns a \ref libx52io_context
|
||||
* pointer in the output parameter. All calls to libx52io use the returned
|
||||
* pointer to control the device.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* int rc;
|
||||
* libx52io_context *ctx;
|
||||
* rc = libx52io_init(&ctx);
|
||||
* if (rc != LIBX52IO_SUCCESS) {
|
||||
* // Error handling omitted for brevity
|
||||
* }
|
||||
*
|
||||
* // Save ctx for use later
|
||||
* @endcode
|
||||
*
|
||||
* @param[out] ctx Pointer to a \ref libx52io_context *. This function will
|
||||
* allocate a device context and return the pointer to the context in this variable.
|
||||
*
|
||||
* @returns \c libx52io_error_code indicating status
|
||||
*/
|
||||
int libx52io_init(libx52io_context **ctx);
|
||||
|
||||
/**
|
||||
* @brief Exit the library and free up any resources used
|
||||
*
|
||||
* This function releases any resources allocated by \ref libx52io_init and
|
||||
* terminates the library. Using the freed device now is invalid and can
|
||||
* cause errors.
|
||||
*
|
||||
* @param[in] ctx Pointer to the device context
|
||||
* @returns None
|
||||
*/
|
||||
void libx52io_exit(libx52io_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief Open a connection to a supported joystick
|
||||
*
|
||||
* This function scans for and opens a connection to a supported X52/X52Pro
|
||||
* joystick. If no supported joystick is found, it will return \ref
|
||||
* LIBX52IO_ERROR_NO_DEVICE.
|
||||
*
|
||||
* @param[in] ctx Pointer to the device context
|
||||
*
|
||||
* @returns
|
||||
* - \ref LIBX52IO_SUCCESS on successful opening
|
||||
* - \ref LIBX52IO_ERROR_INVALID if the context pointer is not valid
|
||||
* - \ref LIBX52IO_ERROR_NO_DEVICE if no supported joystick is found
|
||||
* - \ref LIBX52IO_ERROR_CONN if the connection fails
|
||||
*/
|
||||
int libx52io_open(libx52io_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief Close an existing connection to a supported joystick
|
||||
*
|
||||
* This function closes any existing connection to a joystick. It is acceptable
|
||||
* to call this function if no connection exists.
|
||||
*
|
||||
* @param[in] ctx Pointer to the device context
|
||||
*
|
||||
* @returns
|
||||
* - \ref LIBX52IO_SUCCESS on closing, or if the connection is already closed.
|
||||
* - \ref LIBX52IO_ERROR_INVALID if the context pointer is not valid
|
||||
*/
|
||||
int libx52io_close(libx52io_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief Read and parse a HID report
|
||||
*
|
||||
* This function reads and parses a HID report from a connected joystick. This
|
||||
* function will block until some data is available from the joystick.
|
||||
*
|
||||
* @param[in] ctx Pointer to the device context
|
||||
* @param[out] report Pointer to save the decoded HID report
|
||||
*
|
||||
* @returns
|
||||
* - \ref LIBX52IO_SUCCESS on read and parse success
|
||||
* - \ref LIBX52IO_ERROR_INVALID if the context or report pointers are not valid
|
||||
* - \ref LIBX52IO_ERROR_NO_DEVICE if the device is disconnected
|
||||
*/
|
||||
int libx52io_read(libx52io_context *ctx, libx52io_report *report);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the range of an axis
|
||||
*
|
||||
* This saves the minimum and maximum values of the requested axis in the output
|
||||
* parameters. This will only be valid if the device is connected.
|
||||
*
|
||||
* @param[in] ctx Pointer to the device context
|
||||
* @param[in] axis Axis identifier - see \ref libx52io_axis
|
||||
* @param[out] min Pointer to save the axis minimum value
|
||||
* @param[out] max Pointer to save the axis maximum value
|
||||
*
|
||||
* @returns
|
||||
* - \ref LIBX52IO_SUCCESS on read and parse success
|
||||
* - \ref LIBX52IO_ERROR_INVALID if the context or output pointers are not
|
||||
* valid, or the requested axis is not a valid axis identifier
|
||||
* - \ref LIBX52IO_ERROR_NO_DEVICE if the device is disconnected
|
||||
*/
|
||||
int libx52io_get_axis_range(libx52io_context *ctx, libx52io_axis axis, int32_t *min, int32_t *max);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !defined LIBX52IO_H
|
Loading…
Reference in New Issue