IOKit从不同的USB鼠标(MAC)获得X和Y

时间:2019-01-01 21:30:57

标签: c++ c mouse mouselistener iokit

我写了一些代码来从我的USB鼠标中获取信息。 我将信息存储在列表中,并希望以某种方式更新x和y的值。我必须使用某种事件吗?还是可以只设置值?

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有经验并可以提供帮助吗? 预先感谢!

0 个答案:

没有答案