Save USB device strings when opening HID device

This change saves the manufacturer, product and serial number strings in
a multibyte format, so that it can be used by the clients of the library
to print details about the connected device. This also ensures that
those multibyte strings are freed when closing the device.
pull/26/head
nirenjan 2020-07-11 17:13:27 -07:00
parent 81cb7367f8
commit c8ad37b3f7
4 changed files with 100 additions and 5 deletions

View File

@ -13,7 +13,7 @@ lib_LTLIBRARIES = libx52io.la
libx52io_v_CUR=0
libx52io_v_AGE=0
libx52io_v_REV=0
libx52io_la_SOURCES = io_core.c io_axis.c io_parser.c io_strings.c
libx52io_la_SOURCES = io_core.c io_axis.c io_parser.c io_strings.c io_device.c
libx52io_la_CFLAGS = @HIDAPI_CFLAGS@ -DLOCALEDIR=\"$(localedir)\" -I $(top_srcdir) $(WARN_CFLAGS)
libx52io_la_LDFLAGS = \
-export-symbols-regex '^libx52io_' \

View File

@ -22,7 +22,14 @@ struct libx52io_context {
int32_t axis_min[LIBX52IO_AXIS_MAX];
int32_t axis_max[LIBX52IO_AXIS_MAX];
int16_t vid;
int16_t pid;
int16_t version;
char *manufacturer;
char *product;
char *serial_number;
x52_parse_report parser;
};
@ -31,4 +38,7 @@ void _x52io_set_report_parser(libx52io_context *ctx);
int _x52io_parse_report(libx52io_context *ctx, libx52io_report *report,
unsigned char *data, int length);
void _x52io_save_device_info(libx52io_context *ctx, struct hid_device_info *dev);
void _x52io_release_device_info(libx52io_context *ctx);
#endif // !defined IO_COMMON_H

View File

@ -61,7 +61,7 @@ int libx52io_close(libx52io_context *ctx)
if (ctx->handle != NULL) {
hid_close(ctx->handle);
}
memset(ctx, 0, sizeof(*ctx));
_x52io_release_device_info(ctx);
return LIBX52IO_SUCCESS;
}
@ -92,9 +92,7 @@ int libx52io_open(libx52io_context *ctx)
goto finally;
}
ctx->pid = cur_dev->product_id;
_x52io_set_axis_range(ctx);
_x52io_set_report_parser(ctx);
_x52io_save_device_info(ctx, cur_dev);
rc = LIBX52IO_SUCCESS;
goto finally;

View File

@ -0,0 +1,87 @@
/*
* Saitek X52 IO driver - device information
*
* Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org)
*
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "io_common.h"
static char * _save_string(wchar_t *wcs)
{
int n;
char *out_str = NULL;
if (wcs == NULL) {
return NULL;
}
/*
* Get the number of bytes needed to save the wide character string as
* a multibyte string
*/
n = wcstombs(NULL, wcs, 0);
if (n <= 0) {
/* Two possibilities here:
* n == -1; A wide character that couldn't be converted was found.
* n == 0; No wide characters were in the input string.
*
* In the latter case, we don't have anything to convert, while in
* the former case, we don't know how long the string is to convert.
*
* Return NULL in both cases.
*/
return NULL;
}
n++;
out_str = calloc(n, sizeof(*out_str));
if (out_str != NULL) {
wcstombs(out_str, wcs, n);
}
return out_str;
}
static void _free_string(char **str)
{
if (*str != NULL) {
free(*str);
*str = NULL;
}
}
void _x52io_save_device_info(libx52io_context *ctx, struct hid_device_info *dev)
{
ctx->vid = dev->vendor_id;
ctx->pid = dev->product_id;
ctx->version = dev->release_number;
ctx->manufacturer = _save_string(dev->manufacturer_string);
ctx->product = _save_string(dev->product_string);
ctx->serial_number = _save_string(dev->serial_number);
_x52io_set_axis_range(ctx);
_x52io_set_report_parser(ctx);
}
void _x52io_release_device_info(libx52io_context *ctx)
{
ctx->vid = 0;
ctx->pid = 0;
ctx->version = 0;
_free_string(&(ctx->manufacturer));
_free_string(&(ctx->product));
_free_string(&(ctx->serial_number));
memset(ctx->axis_min, 0, sizeof(ctx->axis_min));
memset(ctx->axis_max, 0, sizeof(ctx->axis_max));
ctx->parser = NULL;
ctx->handle = NULL;
}