//! \~\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 . */ #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 axes; //! \~english All discovered buttons. //! \~russian Все обнаруженные кнопки. PIVector 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 axis_by_dataindex; PIMap 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 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 prev_axes, cur_axes; PIMap prev_buttons, cur_buttons; float dead_zone = 0.f; }; #endif