276 lines
12 KiB
C++
276 lines
12 KiB
C++
//! \~\file pihidevice.h
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english HID device
|
||
//! \~russian HID устройство
|
||
/*
|
||
PIP - Platform Independent Primitives
|
||
HID device
|
||
Ivan Pelipenko peri4ko@yandex.ru
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef PIHIDEVICE_H
|
||
#define PIHIDEVICE_H
|
||
|
||
#include "pithread.h"
|
||
|
||
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english Information about a discovered HID device.
|
||
//! \~russian Информация об обнаруженном HID-устройстве.
|
||
struct PIP_EXPORT PIHIDeviceInfo {
|
||
friend class PIHIDevice;
|
||
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english Common information for HID controls addressed by index.
|
||
//! \~russian Общая информация об HID-элементах управления, адресуемых по индексу.
|
||
struct PIP_EXPORT ValueInfoBase {
|
||
//! \~english Returns \b true when this control description is initialized.
|
||
//! \~russian Возвращает \b true, если описание элемента управления инициализировано.
|
||
bool isValid() const { return index >= 0; }
|
||
|
||
//! \~english Sequential index in the corresponding public vector.
|
||
//! \~russian Порядковый индекс в соответствующем публичном векторе.
|
||
int index = -1;
|
||
|
||
//! \~english Platform data index used in input reports.
|
||
//! \~russian Платформенный индекс данных, используемый во входных отчетах.
|
||
int data_index = -1;
|
||
};
|
||
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english Description of a HID axis.
|
||
//! \~russian Описание HID-оси.
|
||
struct PIP_EXPORT AxisInfo: public ValueInfoBase {
|
||
//! \~english Axis resolution in bits when the platform reports it.
|
||
//! \~russian Разрешение оси в битах, если платформа его сообщает.
|
||
int bits = 0;
|
||
|
||
//! \~english Minimal raw axis value.
|
||
//! \~russian Минимальное сырое значение оси.
|
||
int min = 0;
|
||
|
||
//! \~english Maximal raw axis value.
|
||
//! \~russian Максимальное сырое значение оси.
|
||
int max = 1;
|
||
|
||
//! \~english Marks relative axes such as wheels or deltas.
|
||
//! \~russian Отмечает относительные оси, например колесо или дельты.
|
||
bool is_relative = false;
|
||
};
|
||
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english Description of a HID button.
|
||
//! \~russian Описание HID-кнопки.
|
||
struct PIP_EXPORT ButtonInfo: public ValueInfoBase {
|
||
//! \~english Platform button code when it is available.
|
||
//! \~russian Платформенный код кнопки, если он доступен.
|
||
int code = 0;
|
||
};
|
||
|
||
//! \~english Device path that can be passed to \a PIHIDevice::open().
|
||
//! \~russian Путь к устройству, который можно передать в \a PIHIDevice::open().
|
||
PIString path;
|
||
|
||
//! \~english Manufacturer name.
|
||
//! \~russian Имя производителя.
|
||
PIString manufacturer;
|
||
|
||
//! \~english Product name.
|
||
//! \~russian Имя продукта.
|
||
PIString product;
|
||
|
||
//! \~english Device serial number when available.
|
||
//! \~russian Серийный номер устройства, если доступен.
|
||
PIString serial;
|
||
|
||
//! \~english Device version string.
|
||
//! \~russian Строка версии устройства.
|
||
PIString version;
|
||
|
||
//! \~english USB vendor identifier.
|
||
//! \~russian Идентификатор производителя USB.
|
||
PIString VID;
|
||
|
||
//! \~english USB product identifier.
|
||
//! \~russian Идентификатор продукта USB.
|
||
PIString PID;
|
||
|
||
//! \~english All discovered axes in report order.
|
||
//! \~russian Все обнаруженные оси в порядке отчетов.
|
||
PIVector<AxisInfo> axes;
|
||
|
||
//! \~english All discovered buttons.
|
||
//! \~russian Все обнаруженные кнопки.
|
||
PIVector<ButtonInfo> buttons;
|
||
|
||
//! \~english Returns \b true when this descriptor does not point to a device.
|
||
//! \~russian Возвращает \b true, если этот дескриптор не указывает на устройство.
|
||
bool isNull() const { return path.isEmpty(); }
|
||
|
||
//! \~english Returns \b true when this descriptor points to a device.
|
||
//! \~russian Возвращает \b true, если этот дескриптор указывает на устройство.
|
||
bool isNotNull() const { return !isNull(); }
|
||
|
||
//! \~english Checks whether product name or path contains \a str ignoring case.
|
||
//! \~russian Проверяет, содержит ли имя продукта или путь строку \a str без учета регистра.
|
||
bool match(const PIString & str) const;
|
||
|
||
//! \~english Returns total number of discovered axes.
|
||
//! \~russian Возвращает общее число обнаруженных осей.
|
||
int axesCount() const { return axes.size_s(); }
|
||
|
||
//! \~english Returns number of absolute axes.
|
||
//! \~russian Возвращает число абсолютных осей.
|
||
int axesAbsoluteCount() const;
|
||
|
||
//! \~english Returns number of relative axes.
|
||
//! \~russian Возвращает число относительных осей.
|
||
int axesRelativeCount() const;
|
||
|
||
//! \~english Returns total number of discovered buttons.
|
||
//! \~russian Возвращает общее число обнаруженных кнопок.
|
||
int buttonsCount() const { return buttons.size_s(); }
|
||
|
||
private:
|
||
void prepare();
|
||
PIMap<int, AxisInfo> axis_by_dataindex;
|
||
PIMap<int, ButtonInfo> button_by_dataindex;
|
||
int input_report_size = 0;
|
||
int output_report_size = 0;
|
||
int feature_report_size = 0;
|
||
};
|
||
|
||
//! \relatesalso PIHIDeviceInfo
|
||
//! \~english Prints short HID device information to \a PICout.
|
||
//! \~russian Выводит краткую информацию об HID-устройстве в \a PICout.
|
||
PIP_EXPORT PICout operator<<(PICout s, const PIHIDeviceInfo & v);
|
||
|
||
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english Provides access to HID (Human Interface Device) devices such as game controllers, joysticks, and other input devices.
|
||
//! \~russian Предоставляет доступ к HID (Human Interface Device) устройствам, таким как геймконтроллеры, джойстики и другие устройства
|
||
//! ввода.
|
||
class PIP_EXPORT PIHIDevice: public PIThread {
|
||
PIOBJECT_SUBCLASS(PIHIDevice, PIThread)
|
||
|
||
public:
|
||
//! \~english Stops polling and closes the device.
|
||
//! \~russian Останавливает опрос и закрывает устройство.
|
||
~PIHIDevice();
|
||
|
||
//! \~\ingroup System
|
||
//! \~\brief
|
||
//! \~english Input event produced by %PIHIDevice.
|
||
//! \~russian Событие ввода, создаваемое %PIHIDevice.
|
||
struct PIP_EXPORT Event {
|
||
//! \~english Kind of HID event.
|
||
//! \~russian Вид HID-события.
|
||
enum Type {
|
||
tNone /** \~english Empty event \~russian Пустое событие */,
|
||
tButton /** \~english Button state change \~russian Изменение состояния кнопки */,
|
||
tAxisMove /** \~english Axis value change or relative axis delta \~russian Изменение значения оси или дельта относительной оси
|
||
*/
|
||
,
|
||
};
|
||
|
||
//! \~english Event kind.
|
||
//! \~russian Вид события.
|
||
Type type = tNone;
|
||
|
||
//! \~english Axis description for axis events.
|
||
//! \~russian Описание оси для событий оси.
|
||
PIHIDeviceInfo::AxisInfo axis;
|
||
|
||
//! \~english Button description for button events.
|
||
//! \~russian Описание кнопки для событий кнопки.
|
||
PIHIDeviceInfo::ButtonInfo button;
|
||
|
||
//! \~english Normalized axis value, relative delta, or button state.
|
||
//! \~russian Нормализованное значение оси, относительная дельта или состояние кнопки.
|
||
float value = 0.;
|
||
};
|
||
|
||
//! \~english Returns \b true when the device handle is open.
|
||
//! \~russian Возвращает \b true, если дескриптор устройства открыт.
|
||
bool isOpened() const;
|
||
|
||
//! \~english Opens the device described by \a device and stores it as current.
|
||
//! \~russian Открывает устройство, описанное в \a device, и сохраняет его как текущее.
|
||
bool open(const PIHIDeviceInfo & device);
|
||
|
||
//! \~english Reopens the device stored by the last successful \a open().
|
||
//! \~russian Повторно открывает устройство, сохраненное последним успешным вызовом \a open().
|
||
bool open();
|
||
|
||
//! \~english Stops reading and releases the current device handle.
|
||
//! \~russian Останавливает чтение и освобождает дескриптор текущего устройства.
|
||
void close();
|
||
|
||
//! \~english Starts polling the opened device for input changes.
|
||
//! \~russian Запускает опрос открытого устройства на изменения ввода.
|
||
void start();
|
||
|
||
//! \~english Stops device polling and waits for the thread to finish.
|
||
//! \~russian Останавливает опрос устройства и ожидает завершения потока.
|
||
void stop();
|
||
|
||
//! \~english Sets dead zone for absolute axes in normalized range.
|
||
//! \~russian Устанавливает мертвую зону для абсолютных осей в нормализованном диапазоне.
|
||
void setDeadZone(float v) { dead_zone = v; }
|
||
|
||
//! \~english Returns current dead zone for absolute axes.
|
||
//! \~russian Возвращает текущую мертвую зону для абсолютных осей.
|
||
float deadZone() const { return dead_zone; }
|
||
|
||
//! \events
|
||
//! \{
|
||
|
||
//! \fn void event(PIHIDevice::Event e)
|
||
//! \brief
|
||
//! \~english Raised when a button changes state or an axis value changes.
|
||
//! \~russian Генерируется при изменении состояния кнопки или значения оси.
|
||
EVENT1(event, PIHIDevice::Event, e);
|
||
|
||
//! \}
|
||
|
||
//! \~english Enumerates available HID devices. When \a try_open is enabled, inaccessible devices are skipped.
|
||
//! \~russian Перечисляет доступные HID-устройства. Если включен \a try_open, недоступные устройства пропускаются.
|
||
static PIVector<PIHIDeviceInfo> allDevices(bool try_open = true);
|
||
|
||
//! \~english Returns the first device whose path or product matches \a name.
|
||
//! \~russian Возвращает первое устройство, у которого путь или имя продукта совпадает с \a name.
|
||
static PIHIDeviceInfo findDevice(const PIString & name);
|
||
|
||
private:
|
||
void run() override;
|
||
double procDeadZone(double in);
|
||
|
||
PRIVATE_DECLARATION(PIP_EXPORT)
|
||
PIHIDeviceInfo di;
|
||
PIMap<int, float> prev_axes, cur_axes;
|
||
PIMap<int, int> prev_buttons, cur_buttons;
|
||
float dead_zone = 0.f;
|
||
};
|
||
|
||
|
||
#endif
|