src/cadMousePro.cpp
branchv_0
changeset 4 405aa9de65d2
parent 3 1197b42e8b2e
child 5 6799cec5c2f8
equal deleted inserted replaced
3:1197b42e8b2e 4:405aa9de65d2
     1 #include <iostream>
     1 #include <iostream>
     2 #include <array>
     2 #include <array>
     3 #include <vector>
     3 #include <vector>
       
     4 #include <memory>
       
     5 #include <unistd.h>
       
     6 #include <cassert>
       
     7 #include <type_traits>
     4 
     8 
     5 #include <hidapi/hidapi.h>
     9 #include <hidapi/hidapi.h>
     6 #include <memory>
    10 
       
    11 using Packet = std::vector<uint8_t>;
       
    12 static_assert(sizeof (uint8_t) == sizeof (unsigned char)); // unsigned char is used in the HID API library
     7 
    13 
     8 class HIDException {
    14 class HIDException {
     9 private:
    15 private:
    10 	std::wstring message;
    16 	std::wstring message;
    11 public:
    17 public:
    58 		int error = hid_get_serial_number_string(handle.get(), buffer.data(), buffer.size());
    64 		int error = hid_get_serial_number_string(handle.get(), buffer.data(), buffer.size());
    59 		if (error) throw HIDException(L"Unable to get serial number.");
    65 		if (error) throw HIDException(L"Unable to get serial number.");
    60 		return buffer.data();
    66 		return buffer.data();
    61 	}
    67 	}
    62 
    68 
    63 	void sendFeatureReport(std::vector<unsigned char> data) {
    69 	void sendFeatureReport(Packet data) {
    64 		int written = hid_send_feature_report(handle.get(), data.data(), data.size());
    70 		int written = hid_send_feature_report(handle.get(), data.data(), data.size());
    65 		if (written < 0) throw HIDException(L"Unable to send feature report.");
    71 		if (written < 0) throw HIDException(L"Unable to send feature report.");
       
    72 	}
       
    73 
       
    74 };
       
    75 
       
    76 enum class Frequency : uint8_t {
       
    77 	Hz_0125 = 8,
       
    78 	Hz_0250 = 4,
       
    79 	Hz_0500 = 2,
       
    80 	Hz_1000 = 1
       
    81 };
       
    82 
       
    83 using FrequencyType = std::underlying_type<Frequency>::type;
       
    84 
       
    85 class CadMouseConfig {
       
    86 private:
       
    87 	bool liftOffDetection = true;
       
    88 	bool smartScrolling = false;
       
    89 	Frequency frequency = Frequency::Hz_1000;
       
    90 public:
       
    91 
       
    92 	void setFrequency(Frequency frequency) {
       
    93 		this->frequency = frequency;
       
    94 	}
       
    95 
       
    96 	void setLiftOffDetection(bool liftOffDetection) {
       
    97 		this->liftOffDetection = liftOffDetection;
       
    98 	}
       
    99 
       
   100 	void setSmartScrolling(bool smartScrolling) {
       
   101 		this->smartScrolling = smartScrolling;
       
   102 	}
       
   103 
       
   104 	Packet serialize() {
       
   105 		Packet data;
       
   106 		data.reserve(32);
       
   107 
       
   108 		data.push_back(0x10); // report ID
       
   109 		data.push_back(0x00); // option
       
   110 
       
   111 		data.push_back(0x1c); // speed
       
   112 
       
   113 		data.push_back(liftOffDetection ? 0x00 : 0x1f);
       
   114 
       
   115 		if (smartScrolling) {
       
   116 			data.push_back(0x00);
       
   117 			data.push_back(0x00);
       
   118 			data.push_back(0x00);
       
   119 			data.push_back(0x01);
       
   120 		} else {
       
   121 			data.push_back(0x01);
       
   122 			data.push_back(0xff);
       
   123 			data.push_back(0x00);
       
   124 			data.push_back(0x00);
       
   125 		}
       
   126 
       
   127 		for (int i = 0; i < 8; i++) data.push_back(0x00); // constant padding or magic
       
   128 
       
   129 		// magic constants or unknown fields
       
   130 		data.push_back(0x00);
       
   131 		data.push_back(0x03);
       
   132 		data.push_back(0x00);
       
   133 		data.push_back(0x0a);
       
   134 		data.push_back(0x0b);
       
   135 		data.push_back(0x0c);
       
   136 		data.push_back(0x0c);
       
   137 		data.push_back(0x0e);
       
   138 		data.push_back(0x0d);
       
   139 		data.push_back(0x2f);
       
   140 		data.push_back(0x00);
       
   141 		data.push_back(0x1e);
       
   142 
       
   143 		data.push_back(0x00);
       
   144 		data.push_back(0x00);
       
   145 		data.push_back(0x00);
       
   146 		data.push_back(static_cast<FrequencyType> (frequency));
       
   147 
       
   148 		return data;
    66 	}
   149 	}
    67 
   150 
    68 };
   151 };
    69 
   152 
    70 int main(int argc, char** argv) {
   153 int main(int argc, char** argv) {
    75 		std::wcout << L"mouse opened" << std::endl;
   158 		std::wcout << L"mouse opened" << std::endl;
    76 		std::wcout << L"manufacturer:  " << mouse.getManufacturerName() << std::endl;
   159 		std::wcout << L"manufacturer:  " << mouse.getManufacturerName() << std::endl;
    77 		std::wcout << L"product:       " << mouse.getProductName() << std::endl;
   160 		std::wcout << L"product:       " << mouse.getProductName() << std::endl;
    78 		// std::wcout << L"serial number: " << mouse.getSerialNumber() << std::endl; // throws exception
   161 		// std::wcout << L"serial number: " << mouse.getSerialNumber() << std::endl; // throws exception
    79 
   162 
    80 		std::vector<unsigned char> enableFreeWheel{0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c, 0x0c, 0x0e, 0x0d, 0x2f, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01};
   163 		CadMouseConfig config;
    81 		std::vector<unsigned char> disableFreeWheel{0x10, 0x00, 0x1c, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c, 0x0c, 0x0e, 0x0d, 0x2f, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01};
       
    82 		// mouse.sendFeatureReport(enableFreeWheel);
       
    83 		mouse.sendFeatureReport(disableFreeWheel);
       
    84 
   164 
    85 		// TODO: enable acceleration
   165 		mouse.sendFeatureReport(config.serialize());
    86 		// TODO: enable lift-off detection
       
    87 		// TODO: sensof polling rate – frequency
       
    88 		// TODO: wheel scrolling size – lines, page
       
    89 
   166 
       
   167 		return 0;
    90 	} catch (const HIDException& e) {
   168 	} catch (const HIDException& e) {
    91 		std::wcout << L"HIDException: " << e.getMessage() << std::endl;
   169 		std::wcout << L"HIDException: " << e.getMessage() << std::endl;
    92 
   170 		return 1;
    93 	}
   171 	}
    94 }
   172 }