move sources to a sub-project folder v_0 v0.1
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 19 Aug 2019 17:27:19 +0200
branchv_0
changeset 8 465572518625
parent 7 148f8dd077e8
child 9 d0fc5f337ea2
move sources to a sub-project folder
.hgignore
CMakeLists.txt
cadMousePro-daemon/CMakeLists.txt
cadMousePro-daemon/nbproject/configurations.xml
cadMousePro-daemon/nbproject/project.xml
cadMousePro-daemon/src/CLI.h
cadMousePro-daemon/src/CLIConfiguration.h
cadMousePro-daemon/src/CLIException.h
cadMousePro-daemon/src/CLIParser.h
cadMousePro-daemon/src/CMakeLists.txt
cadMousePro-daemon/src/CadMouseConfig.h
cadMousePro-daemon/src/HID.h
cadMousePro-daemon/src/cadMousePro.cpp
nbproject/configurations.xml
nbproject/project.xml
src/CLI.h
src/CLIConfiguration.h
src/CLIException.h
src/CLIParser.h
src/CMakeLists.txt
src/CadMouseConfig.h
src/HID.h
src/cadMousePro.cpp
--- a/.hgignore	Mon Aug 19 17:21:02 2019 +0200
+++ b/.hgignore	Mon Aug 19 17:27:19 2019 +0200
@@ -7,7 +7,6 @@
 
 ^temp/
 
-^\.dep\.inc
-^dist/
-^build/
-^nbproject/private/
+^[^/]+/dist/
+^[^/]+/build/
+^[^/]+/nbproject/private/
--- a/CMakeLists.txt	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-project (cadMousePro)
-cmake_minimum_required(VERSION 2.8)
-add_subdirectory (src)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/CMakeLists.txt	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,3 @@
+project (cadMousePro-daemon)
+cmake_minimum_required(VERSION 2.8)
+add_subdirectory (src)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/nbproject/configurations.xml	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+
+Contributor(s):
+-->
+<configurationDescriptor version="100">
+  <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+    <df root="." name="0">
+      <df name="src">
+        <in>cadMousePro.cpp</in>
+      </df>
+    </df>
+    <logicalFolder name="ExternalFiles"
+                   displayName="Important Files"
+                   projectFiles="false"
+                   kind="IMPORTANT_FILES_FOLDER">
+      <itemPath>CMakeLists.txt</itemPath>
+      <itemPath>build/Debug/Makefile</itemPath>
+      <itemPath>build/Release/Makefile</itemPath>
+    </logicalFolder>
+  </logicalFolder>
+  <sourceFolderFilter>^(nbproject|build)$</sourceFolderFilter>
+  <sourceRootList>
+    <Elem>.</Elem>
+  </sourceRootList>
+  <projectmakefile>build/Debug/Makefile</projectmakefile>
+  <confs>
+    <conf name="Debug" type="0">
+      <toolsSet>
+        <compilerSet>default</compilerSet>
+        <dependencyChecking>false</dependencyChecking>
+        <rebuildPropChanged>false</rebuildPropChanged>
+      </toolsSet>
+      <flagsDictionary>
+        <element flagsID="0" commonFlags="-fsanitize=address"/>
+      </flagsDictionary>
+      <codeAssistance>
+      </codeAssistance>
+      <makefileType>
+        <makeTool>
+          <buildCommandWorkingDir>build/Debug</buildCommandWorkingDir>
+          <buildCommand>${MAKE} -f Makefile</buildCommand>
+          <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
+          <executablePath>build/Debug/src/welcome</executablePath>
+          <ccTool>
+            <incDir>
+              <pElem>/usr/include/hidapi</pElem>
+              <pElem>build/Debug/src</pElem>
+            </incDir>
+          </ccTool>
+        </makeTool>
+        <preBuild>
+          <preBuildCommandWorkingDir>build/Debug</preBuildCommandWorkingDir>
+          <preBuildCommand>${CMAKE} -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${IDE_CC} -DCMAKE_CXX_COMPILER=${IDE_CXX} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../..</preBuildCommand>
+          <preBuildFirst>true</preBuildFirst>
+        </preBuild>
+      </makefileType>
+      <item path="src/cadMousePro.cpp" ex="false" tool="1" flavor2="0">
+        <ccTool flags="0">
+        </ccTool>
+      </item>
+    </conf>
+    <conf name="Release" type="0">
+      <toolsSet>
+        <compilerSet>default</compilerSet>
+        <dependencyChecking>false</dependencyChecking>
+        <rebuildPropChanged>false</rebuildPropChanged>
+      </toolsSet>
+      <flagsDictionary>
+        <element flagsID="0" commonFlags="-O3"/>
+      </flagsDictionary>
+      <codeAssistance>
+      </codeAssistance>
+      <makefileType>
+        <makeTool>
+          <buildCommandWorkingDir>build/Release</buildCommandWorkingDir>
+          <buildCommand>${MAKE} -f Makefile</buildCommand>
+          <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
+          <executablePath>build/Release/src/welcome</executablePath>
+          <ccTool>
+            <incDir>
+              <pElem>build/Release/src</pElem>
+            </incDir>
+            <preprocessorList>
+              <Elem>NDEBUG</Elem>
+            </preprocessorList>
+          </ccTool>
+        </makeTool>
+        <preBuild>
+          <preBuildCommandWorkingDir>build/Release</preBuildCommandWorkingDir>
+          <preBuildCommand>${CMAKE} -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${IDE_CC} -DCMAKE_CXX_COMPILER=${IDE_CXX} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../..</preBuildCommand>
+          <preBuildFirst>true</preBuildFirst>
+        </preBuild>
+      </makefileType>
+      <item path="src/cadMousePro.cpp" ex="false" tool="1" flavor2="0">
+        <ccTool flags="0">
+        </ccTool>
+      </item>
+    </conf>
+  </confs>
+</configurationDescriptor>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/nbproject/project.xml	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+
+Contributor(s):
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.cnd.makeproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/make-project/1">
+            <name>cadMousePro-daemon</name>
+            <c-extensions/>
+            <cpp-extensions>cpp</cpp-extensions>
+            <header-extensions>h</header-extensions>
+            <sourceEncoding>UTF-8</sourceEncoding>
+            <sourceRootList>
+                <sourceRootElem>.</sourceRootElem>
+            </sourceRootList>
+            <make-dep-projects/>
+            <sourceRootList>
+                <sourceRootElem>.</sourceRootElem>
+            </sourceRootList>
+            <confList>
+                <confElem>
+                    <name>Debug</name>
+                    <type>0</type>
+                </confElem>
+                <confElem>
+                    <name>Release</name>
+                    <type>0</type>
+                </confElem>
+            </confList>
+            <formatting>
+                <project-formatting-style>false</project-formatting-style>
+            </formatting>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/CLI.h	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,80 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <locale.h>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <locale>
+#include <codecvt>
+#include <iostream>
+
+/**
+ * a common header-only library for CLI programs
+ */
+class CLI {
+public:
+
+	CLI(int argc, char* argv[]) {
+		setlocale(LC_ALL, "");
+
+		this->argc = &argc;
+		this->argv = &argv;
+
+		program = convertor.from_bytes(argv[0]);
+
+		for (int i = 1; i < argc; i++) {
+			args.insert(args.end(), convertor.from_bytes(argv[i]));
+		}
+
+	}
+
+	CLI(const CLI& orig) {
+	}
+
+	virtual ~CLI() {
+	}
+
+	const std::wstring programName() {
+		return (const std::wstring) program;
+	}
+
+	const std::vector<std::wstring> arguments() {
+		return (const std::vector<std::wstring>)args;
+	}
+
+	static const int EXIT_CODE_SUCCESS = 0;
+	static const int EXIT_CODE_UNEXPECTED_ERROR = 1;
+	static const int EXIT_CODE_BAD_CLI_ARGUMENTS = 6;
+
+	/**
+	 * std::cin and std::cout are "tied" by default i.e. reading from std::cin causes flush of the std::cout.
+	 * Call this to "untie" them and have less write() calls (better buffering).
+	 */
+	static void untieStdIO() {
+		std::cin.tie(nullptr);
+	}
+
+private:
+	int* argc;
+	char*** argv;
+	std::wstring program;
+	std::vector<std::wstring> args;
+	std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/CLIConfiguration.h	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,30 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "CadMouseConfig.h"
+
+class CLIConfiguration {
+public:
+
+
+	CadMouseConfig cadMouseConfig;
+
+	virtual ~CLIConfiguration() {
+	}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/CLIException.h	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,41 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <string>
+
+#include "CLI.h"
+
+class CLIException {
+private:
+	std::wstring message;
+	int exitCode = CLI::EXIT_CODE_UNEXPECTED_ERROR;
+public:
+
+	CLIException(std::wstring message, int exitCode) : message(message), exitCode(exitCode) {
+	}
+	
+	std::wstring getMessge() const {
+		return message;
+	}
+
+	int getExitCode() const {
+		return exitCode;
+	}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/CLIParser.h	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,80 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <vector>
+
+#include "CLI.h"
+#include "CLIConfiguration.h"
+#include "CLIException.h"
+
+class CLIParser {
+private:
+
+	std::wstring readNext(std::vector<std::wstring> arguments, int& i) {
+		if (i < arguments.size()) return arguments[i++];
+		else throw CLIException(L"Missing CLI argument" + (i > 0 ? (L" after " + arguments[i - 1]) : L""), CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
+	}
+
+	bool parseBoolean(std::wstring value) {
+		if (value == L"true") return true;
+		else if (value == L"false") return false;
+		else throw CLIException(L"Unable to parse boolean value „" + value + L"“ – expecting „true“ or „false“", CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
+	}
+
+	Frequency parseFrequency(std::wstring value) {
+		if (value == L"125") return Frequency::Hz_0125;
+		else if (value == L"250") return Frequency::Hz_0250;
+		else if (value == L"500") return Frequency::Hz_0500;
+		else if (value == L"1000") return Frequency::Hz_1000;
+		else throw CLIException(L"Unable to parse frequency value „" + value + L"“ – expecting „125“ or „250“ or „500“ or „1000“", CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
+	}
+
+public:
+
+	static const std::wstring OPTION_FREQUENCY;
+	static const std::wstring OPTION_SMART_SCROLLING;
+	static const std::wstring OPTION_LIFT_OFF_DETECTION;
+	static const std::wstring OPTION_KEEP_FILE;
+
+	CLIConfiguration parse(const std::vector<std::wstring>& arguments) {
+		CLIConfiguration c;
+
+		for (int i = 0; i < arguments.size();) {
+			std::wstring option = readNext(arguments, i);
+
+			if (option == OPTION_FREQUENCY) {
+				c.cadMouseConfig.setFrequency(parseFrequency(readNext(arguments, i)));
+			} else if (option == OPTION_SMART_SCROLLING) {
+				c.cadMouseConfig.setSmartScrolling(parseBoolean(readNext(arguments, i)));
+			} else if (option == OPTION_LIFT_OFF_DETECTION) {
+				c.cadMouseConfig.setLiftOffDetection(parseBoolean(readNext(arguments, i)));
+			} else throw CLIException(L"Unsupported CLI option: " + option, CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
+		}
+
+		return c;
+	}
+
+	virtual ~CLIParser() {
+	}
+};
+
+
+const std::wstring CLIParser::OPTION_FREQUENCY = L"--frequency";
+const std::wstring CLIParser::OPTION_SMART_SCROLLING = L"--smart-scrolling";
+const std::wstring CLIParser::OPTION_LIFT_OFF_DETECTION = L"--lift-off-detection";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/CMakeLists.txt	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,21 @@
+set(EXECUTABLE_FILE "cadMousePro")
+
+# USB libraries:
+INCLUDE(FindPkgConfig)
+pkg_check_modules (USB_LIBS hidapi-hidraw)
+include_directories(${USB_LIBS_INCLUDE_DIRS})
+link_directories(${USB_LIBS_LIBRARY_DIRS})
+
+# Add ASan AddressSanitizer
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
+set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
+
+# Executable output:
+add_executable(
+	${EXECUTABLE_FILE}
+	cadMousePro.cpp
+)
+
+# Link libraries:
+target_link_libraries(${EXECUTABLE_FILE} ${USB_LIBS_LIBRARIES})
+set_property(TARGET ${EXECUTABLE_FILE} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/CadMouseConfig.h	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,99 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <type_traits>
+
+#include "HID.h"
+
+enum class Frequency : uint8_t {
+	Hz_0125 = 8,
+	Hz_0250 = 4,
+	Hz_0500 = 2,
+	Hz_1000 = 1
+};
+
+using FrequencyType = std::underlying_type<Frequency>::type;
+
+class CadMouseConfig {
+private:
+	bool liftOffDetection = true;
+	bool smartScrolling = false;
+	Frequency frequency = Frequency::Hz_1000;
+public:
+
+	void setFrequency(Frequency frequency) {
+		this->frequency = frequency;
+	}
+
+	void setLiftOffDetection(bool liftOffDetection) {
+		this->liftOffDetection = liftOffDetection;
+	}
+
+	void setSmartScrolling(bool smartScrolling) {
+		this->smartScrolling = smartScrolling;
+	}
+
+	Packet serialize() {
+		Packet data;
+		data.reserve(32);
+
+		data.push_back(0x10); // report ID
+		data.push_back(0x00); // option
+
+		data.push_back(0x1c); // speed
+
+		data.push_back(liftOffDetection ? 0x00 : 0x1f);
+
+		if (smartScrolling) {
+			data.push_back(0x00);
+			data.push_back(0x00);
+			data.push_back(0x00);
+			data.push_back(0x01);
+		} else {
+			data.push_back(0x01);
+			data.push_back(0xff);
+			data.push_back(0x00);
+			data.push_back(0x00);
+		}
+
+		for (int i = 0; i < 8; i++) data.push_back(0x00); // constant padding or magic
+
+		// magic constants or unknown fields
+		data.push_back(0x00);
+		data.push_back(0x03);
+		data.push_back(0x00);
+		data.push_back(0x0a);
+		data.push_back(0x0b);
+		data.push_back(0x0c);
+		data.push_back(0x0c);
+		data.push_back(0x0e);
+		data.push_back(0x0d);
+		data.push_back(0x2f);
+		data.push_back(0x00);
+		data.push_back(0x1e);
+
+		data.push_back(0x00);
+		data.push_back(0x00);
+		data.push_back(0x00);
+		data.push_back(static_cast<FrequencyType> (frequency));
+
+		return data;
+	}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/HID.h	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,91 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <array>
+#include <vector>
+#include <memory>
+#include <unistd.h>
+#include <cassert>
+
+#include <hidapi/hidapi.h>
+
+using Packet = std::vector<uint8_t>;
+static_assert(sizeof (uint8_t) == sizeof (unsigned char)); // unsigned char is used in the HID API library
+
+class HIDException {
+private:
+	std::wstring message;
+public:
+
+	HIDException(std::wstring message) : message(message) {
+	}
+
+	virtual ~HIDException() {
+	}
+
+	const std::wstring getMessage() const {
+		return message;
+	}
+
+};
+
+class HIDDevice {
+private:
+	std::shared_ptr<hid_device> handle;
+
+public:
+
+	HIDDevice(unsigned short vendorId, unsigned short productId, const wchar_t *serialNumber) {
+		int initError = hid_init(); // TODO: move to HIDContext class?
+		if (initError) throw HIDException(L"Unable to init HID API.");
+		handle.reset(hid_open(vendorId, productId, serialNumber), hid_close);
+		if (handle == nullptr) throw HIDException(L"Unable to open HID device. Are you root? Is the device present?");
+	}
+
+	virtual ~HIDDevice() {
+		hid_exit(); // TODO: move to HIDContext class?
+	}
+
+	const std::wstring getManufacturerName() const {
+		std::array<wchar_t, 200 > buffer;
+		int error = hid_get_manufacturer_string(handle.get(), buffer.data(), buffer.size());
+		if (error) throw HIDException(L"Unable to get manufacturer name.");
+		return buffer.data();
+	}
+
+	const std::wstring getProductName() const {
+		std::array<wchar_t, 200 > buffer;
+		int error = hid_get_product_string(handle.get(), buffer.data(), buffer.size());
+		if (error) throw HIDException(L"Unable to get product name.");
+		return buffer.data();
+	}
+
+	const std::wstring getSerialNumber() const {
+		std::array<wchar_t, 200 > buffer;
+		int error = hid_get_serial_number_string(handle.get(), buffer.data(), buffer.size());
+		if (error) throw HIDException(L"Unable to get serial number.");
+		return buffer.data();
+	}
+
+	void sendFeatureReport(Packet data) {
+		int written = hid_send_feature_report(handle.get(), data.data(), data.size());
+		if (written < 0) throw HIDException(L"Unable to send feature report.");
+	}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cadMousePro-daemon/src/cadMousePro.cpp	Mon Aug 19 17:27:19 2019 +0200
@@ -0,0 +1,50 @@
+/**
+ * cadMousePro
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include "CadMouseConfig.h"
+#include "CLI.h"
+#include "CLIParser.h"
+#include "HID.h"
+
+int main(int argc, char** argv) {
+	try {
+		CLI cli(argc, argv);
+
+		std::wcout << L"cadMousePro" << std::endl;
+		HIDDevice mouse(0x256f, 0xc652, nullptr);
+		std::wcout << L"mouse opened" << std::endl;
+		std::wcout << L"manufacturer:  " << mouse.getManufacturerName() << std::endl;
+		std::wcout << L"product:       " << mouse.getProductName() << std::endl;
+		// std::wcout << L"serial number: " << mouse.getSerialNumber() << std::endl; // throws exception
+
+		CLIParser cliParser;
+		CLIConfiguration configuration = cliParser.parse(cli.arguments());
+
+		mouse.sendFeatureReport(configuration.cadMouseConfig.serialize());
+
+		return CLI::EXIT_CODE_SUCCESS;
+	} catch (const HIDException& e) {
+		std::wcout << L"HIDException: " << e.getMessage() << std::endl;
+		return CLI::EXIT_CODE_UNEXPECTED_ERROR;
+	} catch (const CLIException& e) {
+		std::wcout << L"CLIException: " << e.getMessge() << std::endl;
+		return e.getExitCode();
+	}
+
+}
--- a/nbproject/configurations.xml	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
-
-Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
-
-Oracle and Java are registered trademarks of Oracle and/or its affiliates.
-Other names may be trademarks of their respective owners.
-
-The contents of this file are subject to the terms of either the GNU
-General Public License Version 2 only ("GPL") or the Common
-Development and Distribution License("CDDL") (collectively, the
-"License"). You may not use this file except in compliance with the
-License. You can obtain a copy of the License at
-http://www.netbeans.org/cddl-gplv2.html
-or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
-specific language governing permissions and limitations under the
-License.  When distributing the software, include this License Header
-Notice in each file and include the License file at
-nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the GPL Version 2 section of the License file that
-accompanied this code. If applicable, add the following below the
-License Header, with the fields enclosed by brackets [] replaced by
-your own identifying information:
-"Portions Copyrighted [year] [name of copyright owner]"
-
-If you wish your version of this file to be governed by only the CDDL
-or only the GPL Version 2, indicate your decision by adding
-"[Contributor] elects to include this software in this distribution
-under the [CDDL or GPL Version 2] license." If you do not indicate a
-single choice of license, a recipient has the option to distribute
-your version of this file under either the CDDL, the GPL Version 2 or
-to extend the choice of license to its licensees as provided above.
-However, if you add GPL Version 2 code and therefore, elected the GPL
-Version 2 license, then the option applies only if the new code is
-made subject to such option by the copyright holder.
-
-Contributor(s):
--->
-<configurationDescriptor version="100">
-  <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
-    <df root="." name="0">
-      <df name="src">
-        <in>cadMousePro.cpp</in>
-      </df>
-    </df>
-    <logicalFolder name="ExternalFiles"
-                   displayName="Important Files"
-                   projectFiles="false"
-                   kind="IMPORTANT_FILES_FOLDER">
-      <itemPath>CMakeLists.txt</itemPath>
-      <itemPath>build/Debug/Makefile</itemPath>
-      <itemPath>build/Release/Makefile</itemPath>
-    </logicalFolder>
-  </logicalFolder>
-  <sourceFolderFilter>^(nbproject|build)$</sourceFolderFilter>
-  <sourceRootList>
-    <Elem>.</Elem>
-  </sourceRootList>
-  <projectmakefile>build/Debug/Makefile</projectmakefile>
-  <confs>
-    <conf name="Debug" type="0">
-      <toolsSet>
-        <compilerSet>default</compilerSet>
-        <dependencyChecking>false</dependencyChecking>
-        <rebuildPropChanged>false</rebuildPropChanged>
-      </toolsSet>
-      <flagsDictionary>
-        <element flagsID="0" commonFlags="-fsanitize=address"/>
-      </flagsDictionary>
-      <codeAssistance>
-      </codeAssistance>
-      <makefileType>
-        <makeTool>
-          <buildCommandWorkingDir>build/Debug</buildCommandWorkingDir>
-          <buildCommand>${MAKE} -f Makefile</buildCommand>
-          <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
-          <executablePath>build/Debug/src/welcome</executablePath>
-          <ccTool>
-            <incDir>
-              <pElem>/usr/include/hidapi</pElem>
-              <pElem>build/Debug/src</pElem>
-            </incDir>
-          </ccTool>
-        </makeTool>
-        <preBuild>
-          <preBuildCommandWorkingDir>build/Debug</preBuildCommandWorkingDir>
-          <preBuildCommand>${CMAKE} -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${IDE_CC} -DCMAKE_CXX_COMPILER=${IDE_CXX} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../..</preBuildCommand>
-          <preBuildFirst>true</preBuildFirst>
-        </preBuild>
-      </makefileType>
-      <item path="src/cadMousePro.cpp" ex="false" tool="1" flavor2="0">
-        <ccTool flags="0">
-        </ccTool>
-      </item>
-    </conf>
-    <conf name="Release" type="0">
-      <toolsSet>
-        <compilerSet>default</compilerSet>
-        <dependencyChecking>false</dependencyChecking>
-        <rebuildPropChanged>false</rebuildPropChanged>
-      </toolsSet>
-      <flagsDictionary>
-        <element flagsID="0" commonFlags="-O3"/>
-      </flagsDictionary>
-      <codeAssistance>
-      </codeAssistance>
-      <makefileType>
-        <makeTool>
-          <buildCommandWorkingDir>build/Release</buildCommandWorkingDir>
-          <buildCommand>${MAKE} -f Makefile</buildCommand>
-          <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
-          <executablePath>build/Release/src/welcome</executablePath>
-          <ccTool>
-            <incDir>
-              <pElem>build/Release/src</pElem>
-            </incDir>
-            <preprocessorList>
-              <Elem>NDEBUG</Elem>
-            </preprocessorList>
-          </ccTool>
-        </makeTool>
-        <preBuild>
-          <preBuildCommandWorkingDir>build/Release</preBuildCommandWorkingDir>
-          <preBuildCommand>${CMAKE} -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${IDE_CC} -DCMAKE_CXX_COMPILER=${IDE_CXX} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../..</preBuildCommand>
-          <preBuildFirst>true</preBuildFirst>
-        </preBuild>
-      </makefileType>
-      <item path="src/cadMousePro.cpp" ex="false" tool="1" flavor2="0">
-        <ccTool flags="0">
-        </ccTool>
-      </item>
-    </conf>
-  </confs>
-</configurationDescriptor>
--- a/nbproject/project.xml	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
-
-Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
-
-Oracle and Java are registered trademarks of Oracle and/or its affiliates.
-Other names may be trademarks of their respective owners.
-
-The contents of this file are subject to the terms of either the GNU
-General Public License Version 2 only ("GPL") or the Common
-Development and Distribution License("CDDL") (collectively, the
-"License"). You may not use this file except in compliance with the
-License. You can obtain a copy of the License at
-http://www.netbeans.org/cddl-gplv2.html
-or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
-specific language governing permissions and limitations under the
-License.  When distributing the software, include this License Header
-Notice in each file and include the License file at
-nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the GPL Version 2 section of the License file that
-accompanied this code. If applicable, add the following below the
-License Header, with the fields enclosed by brackets [] replaced by
-your own identifying information:
-"Portions Copyrighted [year] [name of copyright owner]"
-
-If you wish your version of this file to be governed by only the CDDL
-or only the GPL Version 2, indicate your decision by adding
-"[Contributor] elects to include this software in this distribution
-under the [CDDL or GPL Version 2] license." If you do not indicate a
-single choice of license, a recipient has the option to distribute
-your version of this file under either the CDDL, the GPL Version 2 or
-to extend the choice of license to its licensees as provided above.
-However, if you add GPL Version 2 code and therefore, elected the GPL
-Version 2 license, then the option applies only if the new code is
-made subject to such option by the copyright holder.
-
-Contributor(s):
--->
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.cnd.makeproject</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/make-project/1">
-            <name>cadMousePro</name>
-            <c-extensions/>
-            <cpp-extensions>cpp</cpp-extensions>
-            <header-extensions>h</header-extensions>
-            <sourceEncoding>UTF-8</sourceEncoding>
-            <sourceRootList>
-                <sourceRootElem>.</sourceRootElem>
-            </sourceRootList>
-            <make-dep-projects/>
-            <sourceRootList>
-                <sourceRootElem>.</sourceRootElem>
-            </sourceRootList>
-            <confList>
-                <confElem>
-                    <name>Debug</name>
-                    <type>0</type>
-                </confElem>
-                <confElem>
-                    <name>Release</name>
-                    <type>0</type>
-                </confElem>
-            </confList>
-            <formatting>
-                <project-formatting-style>false</project-formatting-style>
-            </formatting>
-        </data>
-    </configuration>
-</project>
--- a/src/CLI.h	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <locale.h>
-#include <string>
-#include <vector>
-#include <sstream>
-#include <locale>
-#include <codecvt>
-#include <iostream>
-
-/**
- * a common header-only library for CLI programs
- */
-class CLI {
-public:
-
-	CLI(int argc, char* argv[]) {
-		setlocale(LC_ALL, "");
-
-		this->argc = &argc;
-		this->argv = &argv;
-
-		program = convertor.from_bytes(argv[0]);
-
-		for (int i = 1; i < argc; i++) {
-			args.insert(args.end(), convertor.from_bytes(argv[i]));
-		}
-
-	}
-
-	CLI(const CLI& orig) {
-	}
-
-	virtual ~CLI() {
-	}
-
-	const std::wstring programName() {
-		return (const std::wstring) program;
-	}
-
-	const std::vector<std::wstring> arguments() {
-		return (const std::vector<std::wstring>)args;
-	}
-
-	static const int EXIT_CODE_SUCCESS = 0;
-	static const int EXIT_CODE_UNEXPECTED_ERROR = 1;
-	static const int EXIT_CODE_BAD_CLI_ARGUMENTS = 6;
-
-	/**
-	 * std::cin and std::cout are "tied" by default i.e. reading from std::cin causes flush of the std::cout.
-	 * Call this to "untie" them and have less write() calls (better buffering).
-	 */
-	static void untieStdIO() {
-		std::cin.tie(nullptr);
-	}
-
-private:
-	int* argc;
-	char*** argv;
-	std::wstring program;
-	std::vector<std::wstring> args;
-	std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
-};
--- a/src/CLIConfiguration.h	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include "CadMouseConfig.h"
-
-class CLIConfiguration {
-public:
-
-
-	CadMouseConfig cadMouseConfig;
-
-	virtual ~CLIConfiguration() {
-	}
-};
--- a/src/CLIException.h	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <string>
-
-#include "CLI.h"
-
-class CLIException {
-private:
-	std::wstring message;
-	int exitCode = CLI::EXIT_CODE_UNEXPECTED_ERROR;
-public:
-
-	CLIException(std::wstring message, int exitCode) : message(message), exitCode(exitCode) {
-	}
-	
-	std::wstring getMessge() const {
-		return message;
-	}
-
-	int getExitCode() const {
-		return exitCode;
-	}
-
-};
--- a/src/CLIParser.h	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <vector>
-
-#include "CLI.h"
-#include "CLIConfiguration.h"
-#include "CLIException.h"
-
-class CLIParser {
-private:
-
-	std::wstring readNext(std::vector<std::wstring> arguments, int& i) {
-		if (i < arguments.size()) return arguments[i++];
-		else throw CLIException(L"Missing CLI argument" + (i > 0 ? (L" after " + arguments[i - 1]) : L""), CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
-	}
-
-	bool parseBoolean(std::wstring value) {
-		if (value == L"true") return true;
-		else if (value == L"false") return false;
-		else throw CLIException(L"Unable to parse boolean value „" + value + L"“ – expecting „true“ or „false“", CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
-	}
-
-	Frequency parseFrequency(std::wstring value) {
-		if (value == L"125") return Frequency::Hz_0125;
-		else if (value == L"250") return Frequency::Hz_0250;
-		else if (value == L"500") return Frequency::Hz_0500;
-		else if (value == L"1000") return Frequency::Hz_1000;
-		else throw CLIException(L"Unable to parse frequency value „" + value + L"“ – expecting „125“ or „250“ or „500“ or „1000“", CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
-	}
-
-public:
-
-	static const std::wstring OPTION_FREQUENCY;
-	static const std::wstring OPTION_SMART_SCROLLING;
-	static const std::wstring OPTION_LIFT_OFF_DETECTION;
-	static const std::wstring OPTION_KEEP_FILE;
-
-	CLIConfiguration parse(const std::vector<std::wstring>& arguments) {
-		CLIConfiguration c;
-
-		for (int i = 0; i < arguments.size();) {
-			std::wstring option = readNext(arguments, i);
-
-			if (option == OPTION_FREQUENCY) {
-				c.cadMouseConfig.setFrequency(parseFrequency(readNext(arguments, i)));
-			} else if (option == OPTION_SMART_SCROLLING) {
-				c.cadMouseConfig.setSmartScrolling(parseBoolean(readNext(arguments, i)));
-			} else if (option == OPTION_LIFT_OFF_DETECTION) {
-				c.cadMouseConfig.setLiftOffDetection(parseBoolean(readNext(arguments, i)));
-			} else throw CLIException(L"Unsupported CLI option: " + option, CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
-		}
-
-		return c;
-	}
-
-	virtual ~CLIParser() {
-	}
-};
-
-
-const std::wstring CLIParser::OPTION_FREQUENCY = L"--frequency";
-const std::wstring CLIParser::OPTION_SMART_SCROLLING = L"--smart-scrolling";
-const std::wstring CLIParser::OPTION_LIFT_OFF_DETECTION = L"--lift-off-detection";
--- a/src/CMakeLists.txt	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-set(EXECUTABLE_FILE "cadMousePro")
-
-# USB libraries:
-INCLUDE(FindPkgConfig)
-pkg_check_modules (USB_LIBS hidapi-hidraw)
-include_directories(${USB_LIBS_INCLUDE_DIRS})
-link_directories(${USB_LIBS_LIBRARY_DIRS})
-
-# Add ASan AddressSanitizer
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
-set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
-
-# Executable output:
-add_executable(
-	${EXECUTABLE_FILE}
-	cadMousePro.cpp
-)
-
-# Link libraries:
-target_link_libraries(${EXECUTABLE_FILE} ${USB_LIBS_LIBRARIES})
-set_property(TARGET ${EXECUTABLE_FILE} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
--- a/src/CadMouseConfig.h	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <type_traits>
-
-#include "HID.h"
-
-enum class Frequency : uint8_t {
-	Hz_0125 = 8,
-	Hz_0250 = 4,
-	Hz_0500 = 2,
-	Hz_1000 = 1
-};
-
-using FrequencyType = std::underlying_type<Frequency>::type;
-
-class CadMouseConfig {
-private:
-	bool liftOffDetection = true;
-	bool smartScrolling = false;
-	Frequency frequency = Frequency::Hz_1000;
-public:
-
-	void setFrequency(Frequency frequency) {
-		this->frequency = frequency;
-	}
-
-	void setLiftOffDetection(bool liftOffDetection) {
-		this->liftOffDetection = liftOffDetection;
-	}
-
-	void setSmartScrolling(bool smartScrolling) {
-		this->smartScrolling = smartScrolling;
-	}
-
-	Packet serialize() {
-		Packet data;
-		data.reserve(32);
-
-		data.push_back(0x10); // report ID
-		data.push_back(0x00); // option
-
-		data.push_back(0x1c); // speed
-
-		data.push_back(liftOffDetection ? 0x00 : 0x1f);
-
-		if (smartScrolling) {
-			data.push_back(0x00);
-			data.push_back(0x00);
-			data.push_back(0x00);
-			data.push_back(0x01);
-		} else {
-			data.push_back(0x01);
-			data.push_back(0xff);
-			data.push_back(0x00);
-			data.push_back(0x00);
-		}
-
-		for (int i = 0; i < 8; i++) data.push_back(0x00); // constant padding or magic
-
-		// magic constants or unknown fields
-		data.push_back(0x00);
-		data.push_back(0x03);
-		data.push_back(0x00);
-		data.push_back(0x0a);
-		data.push_back(0x0b);
-		data.push_back(0x0c);
-		data.push_back(0x0c);
-		data.push_back(0x0e);
-		data.push_back(0x0d);
-		data.push_back(0x2f);
-		data.push_back(0x00);
-		data.push_back(0x1e);
-
-		data.push_back(0x00);
-		data.push_back(0x00);
-		data.push_back(0x00);
-		data.push_back(static_cast<FrequencyType> (frequency));
-
-		return data;
-	}
-
-};
--- a/src/HID.h	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <array>
-#include <vector>
-#include <memory>
-#include <unistd.h>
-#include <cassert>
-
-#include <hidapi/hidapi.h>
-
-using Packet = std::vector<uint8_t>;
-static_assert(sizeof (uint8_t) == sizeof (unsigned char)); // unsigned char is used in the HID API library
-
-class HIDException {
-private:
-	std::wstring message;
-public:
-
-	HIDException(std::wstring message) : message(message) {
-	}
-
-	virtual ~HIDException() {
-	}
-
-	const std::wstring getMessage() const {
-		return message;
-	}
-
-};
-
-class HIDDevice {
-private:
-	std::shared_ptr<hid_device> handle;
-
-public:
-
-	HIDDevice(unsigned short vendorId, unsigned short productId, const wchar_t *serialNumber) {
-		int initError = hid_init(); // TODO: move to HIDContext class?
-		if (initError) throw HIDException(L"Unable to init HID API.");
-		handle.reset(hid_open(vendorId, productId, serialNumber), hid_close);
-		if (handle == nullptr) throw HIDException(L"Unable to open HID device. Are you root? Is the device present?");
-	}
-
-	virtual ~HIDDevice() {
-		hid_exit(); // TODO: move to HIDContext class?
-	}
-
-	const std::wstring getManufacturerName() const {
-		std::array<wchar_t, 200 > buffer;
-		int error = hid_get_manufacturer_string(handle.get(), buffer.data(), buffer.size());
-		if (error) throw HIDException(L"Unable to get manufacturer name.");
-		return buffer.data();
-	}
-
-	const std::wstring getProductName() const {
-		std::array<wchar_t, 200 > buffer;
-		int error = hid_get_product_string(handle.get(), buffer.data(), buffer.size());
-		if (error) throw HIDException(L"Unable to get product name.");
-		return buffer.data();
-	}
-
-	const std::wstring getSerialNumber() const {
-		std::array<wchar_t, 200 > buffer;
-		int error = hid_get_serial_number_string(handle.get(), buffer.data(), buffer.size());
-		if (error) throw HIDException(L"Unable to get serial number.");
-		return buffer.data();
-	}
-
-	void sendFeatureReport(Packet data) {
-		int written = hid_send_feature_report(handle.get(), data.data(), data.size());
-		if (written < 0) throw HIDException(L"Unable to send feature report.");
-	}
-
-};
--- a/src/cadMousePro.cpp	Mon Aug 19 17:21:02 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/**
- * cadMousePro
- * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <iostream>
-
-#include "CadMouseConfig.h"
-#include "CLI.h"
-#include "CLIParser.h"
-#include "HID.h"
-
-int main(int argc, char** argv) {
-	try {
-		CLI cli(argc, argv);
-
-		std::wcout << L"cadMousePro" << std::endl;
-		HIDDevice mouse(0x256f, 0xc652, nullptr);
-		std::wcout << L"mouse opened" << std::endl;
-		std::wcout << L"manufacturer:  " << mouse.getManufacturerName() << std::endl;
-		std::wcout << L"product:       " << mouse.getProductName() << std::endl;
-		// std::wcout << L"serial number: " << mouse.getSerialNumber() << std::endl; // throws exception
-
-		CLIParser cliParser;
-		CLIConfiguration configuration = cliParser.parse(cli.arguments());
-
-		mouse.sendFeatureReport(configuration.cadMouseConfig.serialize());
-
-		return CLI::EXIT_CODE_SUCCESS;
-	} catch (const HIDException& e) {
-		std::wcout << L"HIDException: " << e.getMessage() << std::endl;
-		return CLI::EXIT_CODE_UNEXPECTED_ERROR;
-	} catch (const CLIException& e) {
-		std::wcout << L"CLIException: " << e.getMessge() << std::endl;
-		return e.getExitCode();
-	}
-
-}