Files
pip/libs/main/system/pihidevice.h
2026-03-12 14:46:57 +03:00

276 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \~\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