Я написал некоторый код для получения информации от моих USB-мышей.
Я храню информацию в списке и хотел бы обновить значения для х и у как-то. Должен ли я использовать какие-то события? Или я могу просто установить значения?
PS: я знаю, что этот код получает значения только один раз прямо сейчас, но получение информации об устройствах и, возможно, установление какого-либо прямого события с ним должно быть первым шагом, или нет?
//
// Created by Rudolf Chrispens on 30.05.18.
//
#ifndef CPP_MULTIMOUSE_USBPRIVATEDATASAMPLE_H
#define CPP_MULTIMOUSE_USBPRIVATEDATASAMPLE_H
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
#include <iostream>
#include <list>
class Device;
class Device {
private:
size_t device_id;
std::string device_name;
std::string device_path;
std::string service_path;
std::string class_name;
float x_previous = 0;
float y_previous = 0;
float x_current = 0;
float y_current = 0;
public:
Device( size_t _deviceID,
std::string _device_name,
std::string _device_path,
std::string _service_path,
std::string _class_name) {
//std::cout << "###### Create Device - 0.0/0.0" << std::endl;
this->device_id = _deviceID;
this->device_name = _device_name;
this->service_path = _service_path;
this->class_name = _class_name;
std::string device_path = _device_path;
}
Device(
size_t _deviceID,
std::string const& _device_name,
std::string const& _device_path,
std::string const& _service_path,
std::string const& _class_name,
float _xStart,
float _yStart) : Device(_deviceID,
_device_name,
_device_path,
_service_path,
_class_name){
//std::cout << "###### Create Device - " << _xStart << "/" << _yStart << std::endl;
this->x_previous = _xStart;
this->y_previous = _yStart;
this->x_current = _xStart;
this->y_current = _yStart;
}
~Device(){
//std::cout << "###### Destroyed Device" << std::endl;
}
const size_t getId () const{
return this->device_id;
};
const std::string getName() const{
return this->device_name;
};
const std::string getPath() const{
return this->device_path;
};
const std::string getService() const{
return this->service_path;
};
const std::string getClass() const{
return this->class_name;
};
const float getDeltaX() const{
return x_previous - x_current;
};
const float getDeltaY() const{
return y_previous - y_current;
};
};
class DevicesManager{
private:
std::list<Device> list = std::list<Device>();
public:
DevicesManager(){
//std::cout << "###### Created Empty DevicesManager List" << std::endl;
}
~DevicesManager(){
//std::cout << "###### Destroyed DevicesManager List" << std::endl;
}
void getDevicesArray() {
CFMutableDictionaryRef usb_dictionary;
io_iterator_t io_device_iterator;
kern_return_t assembler_kernel_return_value;
io_service_t device_id;
io_name_t device_name = "unkown device";
io_name_t location;
io_string_t service_path;
io_name_t className;
// set up a matching dictionary for the class
usb_dictionary = IOServiceMatching(kIOUSBDeviceClassName);
if (usb_dictionary == NULL) {
std::cerr << "failed to fetch USB dictionary" << std::endl;
return;
}
// now we have a dictionary, get an iterator.
assembler_kernel_return_value = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_dictionary, &io_device_iterator);
if (assembler_kernel_return_value != KERN_SUCCESS) {
std::cerr << "failed to get a kern_return" << std::endl;
return;
}
device_id = IOIteratorNext(io_device_iterator);
while (device_id) {
// set name
IORegistryEntryGetName(device_id, device_name);
// set service path
IORegistryEntryGetPath(device_id, kIOServicePlane, service_path);
// set path
IORegistryEntryGetPath(device_id, kIOUSBPlane, location);
//get more info:
IOObjectGetClass(device_id, className);
// https://github.com/yene/USB-Lock/blob/master/USB-Lock/USBDevices.m
// TODO set current X or establish some kind of event to keep X up to date?
// TODO set current Y or establish some kind of event to keep Y up to date?
// add device
//TODO use overloaded constructor with x and y
this->list.emplace_back(device_id, device_name, location, service_path, className); //TODO use overloaded constructor with x and y
// next id
device_id = IOIteratorNext(io_device_iterator);
}
// release the iterator
IOObjectRelease(io_device_iterator);
}
void printDeviceIDs(){
for (Device const& device : this->list) {
std::cout << "# id: " << device.getId() << std::endl;
std::cout << "| name: " << "\t" << device.getName() << std::endl;
std::cout << "| path: " << "\t" << device.getPath() << std::endl;
std::cout << "| service: " << "\t" << device.getService() << std::endl;
std::cout << "| class: " << "\t" << device.getClass() << std::endl;
std::cout << "| x: " << "\t" << device.getDeltaX() << std::endl;
std::cout << "| y: " << "\t" << device.getDeltaY() << std::endl;
std::cout << "#-----------------------------------------------#" << std::endl;
}
}
};
int main(int argc, const char *argv[])
{
DevicesManager devices;
devices.getDevicesArray();
devices.printDeviceIDs();
}
#endif //CPP_MULTIMOUSE_USBPRIVATEDATASAMPLE_H
Пример печати:
# id: 3331
| name: Corsair Gaming M65 Pro RGB Mouse
| path:
| service: IOService:/IOResources/AppleUSBHostResources/AppleUSBLegacyRoot/AppleUSBXHCI@14000000/Corsair Gaming M65 Pro RGB Mouse@14100000
| class: IOUSBDevice
| x: 0
| y: 0
#-----------------------------------------------#
Кто-то имеет опыт работы с IOKit и может помочь?
Заранее спасибо!
Задача ещё не решена.
Других решений пока нет …