Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e294727ac5 | ||
|
|
f29d64c803 | ||
|
|
0385b0ce29 | ||
|
|
b526274cd7 | ||
|
|
88c16af4a9 | ||
|
|
05ac9a6832 | ||
|
|
04aa5236c2 | ||
|
|
ec98e4e1c6 | ||
|
|
bb9ece494c | ||
|
|
217e6776ac | ||
|
|
2286218980 | ||
|
|
3d9c83f9f4 | ||
|
|
14ed163238 | ||
|
|
c815de0718 | ||
|
|
6a46556d9e | ||
|
|
f8f820529f |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -6,11 +6,21 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1
|
|||||||
|
|
||||||
Every Agent version includes the most recent firmware version. See the [firmware changelog](https://github.com/UltimateHackingKeyboard/firmware/blob/master/CHANGELOG.md).
|
Every Agent version includes the most recent firmware version. See the [firmware changelog](https://github.com/UltimateHackingKeyboard/firmware/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## [1.2.1] - 2018-05-12
|
||||||
|
|
||||||
|
Firmware: 8.2.**2** [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.2)] | Device Protocol: 4.3.0| User Config: 4.0.**1** | Hardware Config: 1.0.0
|
||||||
|
|
||||||
|
- Match for the new USB usage page and usage number. This is critical for UHKs flashed with firmware >=8.2.2 to be recognized by Agent on OSX.
|
||||||
|
- Make the config serializer handle long media macro actions. `USERCONFIG:PATCH`
|
||||||
|
- Add note on the macro page explaining that the macro engine of the firmware is not ready yet.
|
||||||
|
- Add an example to the scancode tooltip to better explain users how to invoke non-US characters.
|
||||||
|
|
||||||
## [1.2.0] - 2018-04-20
|
## [1.2.0] - 2018-04-20
|
||||||
|
|
||||||
Firmware: 8.**2.0** [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.0)] | Device Protocol: 4.**3.0** | User Config: 4.0.0 | Hardware Config: 1.0.0
|
Firmware: 8.**2.0** [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.0)] | Device Protocol: 4.**3.0** | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||||
|
|
||||||
- Tweak the default mouse speed. This was necessary because the last firmware version adjusted speed multipliers. The mouse speed can be reset via the "Reset speeds to default" button of the "Mouse speed" page.
|
- Tweak the default mouse speed. This was necessary because the last firmware version adjusted speed multipliers. The mouse speed can be reset via the "Reset speeds to default" button of the "Mouse speed" page.
|
||||||
|
- Make the newly added switch-keymap.js script utilize the new UsbCommandId_SwitchKeymap, allowing for programmatic keymap switching. `DEVICEPROTOCOL:MINOR`
|
||||||
|
|
||||||
## [1.1.5] - 2018-04-10
|
## [1.1.5] - 2018-04-10
|
||||||
|
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -5,17 +5,8 @@
|
|||||||
|
|
||||||
Agent is the configuration application of the [Ultimate Hacking Keyboard](https://ultimatehackingkeyboard.com/).
|
Agent is the configuration application of the [Ultimate Hacking Keyboard](https://ultimatehackingkeyboard.com/).
|
||||||
|
|
||||||
[Give it a whirl!](http://ultimatehackingkeyboard.github.io/agent/)
|
* Try out the [web build of Agent](http://ultimatehackingkeyboard.github.io/agent/) in your browser. This is meant to be used for demonstration purposes.
|
||||||
|
* Download the [desktop build of Agent](https://github.com/UltimateHackingKeyboard/agent/releases) from our releases page. Use this if you have an actual UHK at hand, or else you won't get past the opening screen!
|
||||||
## Two builds to rule them all
|
|
||||||
|
|
||||||
It's worth mentioning that Agent has two builds.
|
|
||||||
|
|
||||||
The **electron build** is the desktop application which is meant to be used if you have an actual UHK at hand. It starts with an opening screen which detects your UHK. You cannot get past this screen without connecting a UHK via USB.
|
|
||||||
|
|
||||||
The **web build** is meant to be used for demonstration purposes, so people who don't yet own a UHK can get a feel of Agent and its capabilities in their browser. Eventually, WebUSB support will be added to the web build, making it able to communicate with the UHK. Given the sandboxed nature of browsers, the web build will always lack features that the electron build offers, so this won't make the electron build obsolete.
|
|
||||||
|
|
||||||
The two builds share code as much as possible.
|
|
||||||
|
|
||||||
## Building the electron application
|
## Building the electron application
|
||||||
|
|
||||||
|
|||||||
173
package-lock.json
generated
173
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "uhk-agent",
|
"name": "uhk-agent",
|
||||||
"version": "1.1.4",
|
"version": "1.2.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -916,6 +916,12 @@
|
|||||||
"integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
|
"integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"base64url": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"bcrypt-pbkdf": {
|
"bcrypt-pbkdf": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
||||||
@@ -1494,6 +1500,58 @@
|
|||||||
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
|
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"check-node-version": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/check-node-version/-/check-node-version-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-mJu4dADRf+NUeOyGgFTXaLtjyyffD3Eej2RA9IEk1CdHmoVurErLD++e/Ps6uKfsB273ky+0Z9NlOiuplxuNdw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chalk": "2.4.1",
|
||||||
|
"map-values": "1.0.1",
|
||||||
|
"minimist": "1.2.0",
|
||||||
|
"object-filter": "1.0.2",
|
||||||
|
"object.assign": "4.1.0",
|
||||||
|
"run-parallel": "1.1.9",
|
||||||
|
"semver": "5.4.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "3.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"supports-color": "5.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||||
|
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
|
||||||
@@ -5780,8 +5838,7 @@
|
|||||||
"jsbn": {
|
"jsbn": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"json-schema": {
|
"json-schema": {
|
||||||
"version": "0.2.3",
|
"version": "0.2.3",
|
||||||
@@ -6384,6 +6441,72 @@
|
|||||||
"assert-plus": "1.0.0"
|
"assert-plus": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gh-pages": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZpDkeOVmIrN5mz+sBWDz5zmTqcbNJzI/updCwEv/7rrSdpTNlj1B5GhBqG7f4Q8p5sJOdnBV0SIqxJrxtZQ9FA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"async": "2.6.0",
|
||||||
|
"base64url": "2.0.0",
|
||||||
|
"commander": "2.11.0",
|
||||||
|
"fs-extra": "4.0.3",
|
||||||
|
"globby": "6.1.0",
|
||||||
|
"graceful-fs": "4.1.11",
|
||||||
|
"rimraf": "2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"async": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lodash": "4.17.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "4.1.11",
|
||||||
|
"jsonfile": "4.0.0",
|
||||||
|
"universalify": "0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||||
|
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "1.0.0",
|
||||||
|
"inflight": "1.0.6",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"once": "1.4.0",
|
||||||
|
"path-is-absolute": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rimraf": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"glob": "7.1.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"git-raw-commits": {
|
"git-raw-commits": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.2.0.tgz",
|
||||||
@@ -6692,6 +6815,12 @@
|
|||||||
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
|
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"has-symbols": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"has-unicode": {
|
"has-unicode": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||||
@@ -8462,6 +8591,12 @@
|
|||||||
"integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
|
"integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"map-values": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/map-values/-/map-values-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-douOecAJvytk/ugG4ip7HEGQyZA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"map-visit": {
|
"map-visit": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
|
||||||
@@ -9197,6 +9332,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object-filter": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-filter/-/object-filter-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-rwt5f/6+r4pSxmN87b6IFs/sG8g=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"object-keys": {
|
"object-keys": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
|
||||||
@@ -9220,6 +9361,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object.assign": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"define-properties": "1.1.2",
|
||||||
|
"function-bind": "1.1.1",
|
||||||
|
"has-symbols": "1.0.0",
|
||||||
|
"object-keys": "1.0.11"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"object-keys": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
|
||||||
|
"integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"object.omit": {
|
"object.omit": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
|
||||||
@@ -10567,6 +10728,12 @@
|
|||||||
"is-promise": "2.1.0"
|
"is-promise": "2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"run-parallel": {
|
||||||
|
"version": "1.1.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
|
||||||
|
"integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"rx-lite": {
|
"rx-lite": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
|
||||||
|
|||||||
17
package.json
17
package.json
@@ -3,10 +3,10 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"author": "Ultimate Gadget Laboratories",
|
"author": "Ultimate Gadget Laboratories",
|
||||||
"main": "electron/dist/electron-main.js",
|
"main": "electron/dist/electron-main.js",
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"firmwareVersion": "8.2.0",
|
"firmwareVersion": "8.2.2",
|
||||||
"deviceProtocolVersion": "4.3.0",
|
"deviceProtocolVersion": "4.3.0",
|
||||||
"userConfigVersion": "4.0.0",
|
"userConfigVersion": "4.0.1",
|
||||||
"hardwareConfigVersion": "1.0.0",
|
"hardwareConfigVersion": "1.0.0",
|
||||||
"description": "Agent is the configuration application of the Ultimate Hacking Keyboard.",
|
"description": "Agent is the configuration application of the Ultimate Hacking Keyboard.",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -23,16 +23,17 @@
|
|||||||
"@types/electron-settings": "3.0.0",
|
"@types/electron-settings": "3.0.0",
|
||||||
"@types/fs-extra": "5.0.1",
|
"@types/fs-extra": "5.0.1",
|
||||||
"@types/jasmine": "2.6.0",
|
"@types/jasmine": "2.6.0",
|
||||||
"@types/jsonfile": "4.0.1",
|
|
||||||
"@types/jquery": "3.3.1",
|
"@types/jquery": "3.3.1",
|
||||||
|
"@types/jsonfile": "4.0.1",
|
||||||
"@types/node": "8.0.53",
|
"@types/node": "8.0.53",
|
||||||
"@types/node-hid": "0.5.2",
|
"@types/node-hid": "0.5.2",
|
||||||
"@types/request": "2.0.8",
|
"@types/request": "2.0.8",
|
||||||
"@types/usb": "1.1.3",
|
"@types/usb": "1.1.3",
|
||||||
"autoprefixer": "6.5.3",
|
"autoprefixer": "6.5.3",
|
||||||
"buffer": "5.0.6",
|
"buffer": "5.0.6",
|
||||||
"copyfiles": "^2.0.0",
|
"check-node-version": "^3.2.0",
|
||||||
"copy-webpack-plugin": "4.0.1",
|
"copy-webpack-plugin": "4.0.1",
|
||||||
|
"copyfiles": "^2.0.0",
|
||||||
"core-js": "2.4.1",
|
"core-js": "2.4.1",
|
||||||
"cross-env": "5.0.5",
|
"cross-env": "5.0.5",
|
||||||
"decompress": "4.2.0",
|
"decompress": "4.2.0",
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
"exports-loader": "0.6.3",
|
"exports-loader": "0.6.3",
|
||||||
"file-loader": "0.10.0",
|
"file-loader": "0.10.0",
|
||||||
"fs-extra": "5.0.0",
|
"fs-extra": "5.0.0",
|
||||||
|
"gh-pages": "1.1.0",
|
||||||
"jsonfile": "4.0.0",
|
"jsonfile": "4.0.0",
|
||||||
"lerna": "2.9.0",
|
"lerna": "2.9.0",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "0.5.1",
|
||||||
@@ -84,6 +86,7 @@
|
|||||||
"lint:ts:test-serializer": "tslint --project ./packages/test-serializer/tsconfig.json",
|
"lint:ts:test-serializer": "tslint --project ./packages/test-serializer/tsconfig.json",
|
||||||
"lint:ts:uhk-usb": "tslint --project ./packages/uhk-usb/tsconfig.json",
|
"lint:ts:uhk-usb": "tslint --project ./packages/uhk-usb/tsconfig.json",
|
||||||
"lint:style": "stylelint \"packages/uhk-agent/src/**/*.scss\" \"packages/uhk-web/src/**/*.scss\" --syntax scss",
|
"lint:style": "stylelint \"packages/uhk-agent/src/**/*.scss\" \"packages/uhk-web/src/**/*.scss\" --syntax scss",
|
||||||
|
"prebuild": "check-node-version --package",
|
||||||
"build": "run-s build:common build:usb build:web build:electron",
|
"build": "run-s build:common build:usb build:web build:electron",
|
||||||
"build:web": "lerna exec --scope uhk-web npm run build",
|
"build:web": "lerna exec --scope uhk-web npm run build",
|
||||||
"build:electron": "cross-env AOT_BUILD=true run-s -sn build:electron:renderer build:electron:main",
|
"build:electron": "cross-env AOT_BUILD=true run-s -sn build:electron:renderer build:electron:main",
|
||||||
@@ -99,7 +102,9 @@
|
|||||||
"pack": "node ./scripts/release.js",
|
"pack": "node ./scripts/release.js",
|
||||||
"sprites": "node ./scripts/generate-svg-sprites",
|
"sprites": "node ./scripts/generate-svg-sprites",
|
||||||
"release": "node ./scripts/release.js",
|
"release": "node ./scripts/release.js",
|
||||||
"clean": "lerna exec rimraf ./node_modules ./dist"
|
"clean": "lerna exec rimraf ./node_modules ./dist && rimraf ./node_modules ./dist",
|
||||||
|
"predeploy-gh-pages": "run-s build:web",
|
||||||
|
"deploy-gh-pages": "gh-pages -d packages/uhk-web/dist"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { assertEnum, assertUInt8 } from '../../assert';
|
import { assertEnum, assertUInt8, assertUInt16 } from '../../assert';
|
||||||
import { UhkBuffer } from '../../uhk-buffer';
|
import { UhkBuffer } from '../../uhk-buffer';
|
||||||
import { KeyModifiers } from '../key-modifiers';
|
import { KeyModifiers } from '../key-modifiers';
|
||||||
import { MacroAction, MacroActionId, MacroKeySubAction, macroActionType } from './macro-action';
|
import { MacroAction, MacroActionId, MacroKeySubAction, macroActionType } from './macro-action';
|
||||||
@@ -20,12 +20,24 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
@assertEnum(KeystrokeType)
|
@assertEnum(KeystrokeType)
|
||||||
type: KeystrokeType;
|
type: KeystrokeType;
|
||||||
|
|
||||||
@assertUInt8
|
|
||||||
scancode: number;
|
|
||||||
|
|
||||||
@assertUInt8
|
@assertUInt8
|
||||||
modifierMask: number;
|
modifierMask: number;
|
||||||
|
|
||||||
|
@assertUInt16
|
||||||
|
private _scancode: number;
|
||||||
|
|
||||||
|
set scancode(scancode: number) {
|
||||||
|
this._scancode = scancode;
|
||||||
|
if (this.type !== KeystrokeType.shortMedia && this.type !== KeystrokeType.longMedia) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.type = scancode < 256 ? KeystrokeType.shortMedia : KeystrokeType.longMedia;
|
||||||
|
}
|
||||||
|
|
||||||
|
get scancode() {
|
||||||
|
return this._scancode;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(other?: KeyMacroAction) {
|
constructor(other?: KeyMacroAction) {
|
||||||
super();
|
super();
|
||||||
if (!other) {
|
if (!other) {
|
||||||
@@ -33,7 +45,7 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
}
|
}
|
||||||
this.action = other.action;
|
this.action = other.action;
|
||||||
this.type = other.type;
|
this.type = other.type;
|
||||||
this.scancode = other.scancode;
|
this._scancode = other._scancode;
|
||||||
this.modifierMask = other.modifierMask;
|
this.modifierMask = other.modifierMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +57,7 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
} else {
|
} else {
|
||||||
this.type = KeystrokeType[jsObject.type];
|
this.type = KeystrokeType[jsObject.type];
|
||||||
}
|
}
|
||||||
this.scancode = jsObject.scancode;
|
this._scancode = jsObject.scancode;
|
||||||
this.modifierMask = jsObject.modifierMask;
|
this.modifierMask = jsObject.modifierMask;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -58,7 +70,7 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
this.type = keyMacroType & 0b11;
|
this.type = keyMacroType & 0b11;
|
||||||
keyMacroType >>= 2;
|
keyMacroType >>= 2;
|
||||||
if (keyMacroType & 0b10) {
|
if (keyMacroType & 0b10) {
|
||||||
this.scancode = buffer.readUInt8();
|
this._scancode = this.type === KeystrokeType.longMedia ? buffer.readUInt16() : buffer.readUInt8();
|
||||||
}
|
}
|
||||||
if (keyMacroType & 0b01) {
|
if (keyMacroType & 0b01) {
|
||||||
this.modifierMask = buffer.readUInt8();
|
this.modifierMask = buffer.readUInt8();
|
||||||
@@ -78,7 +90,7 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
} else {
|
} else {
|
||||||
jsObject.type = KeystrokeType[this.type];
|
jsObject.type = KeystrokeType[this.type];
|
||||||
}
|
}
|
||||||
jsObject.scancode = this.scancode;
|
jsObject.scancode = this._scancode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasModifiers()) {
|
if (this.hasModifiers()) {
|
||||||
@@ -98,7 +110,11 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
|
|
||||||
buffer.writeUInt8(keyMacroType);
|
buffer.writeUInt8(keyMacroType);
|
||||||
if (this.hasScancode()) {
|
if (this.hasScancode()) {
|
||||||
buffer.writeUInt8(this.scancode);
|
if (this.type === KeystrokeType.longMedia) {
|
||||||
|
buffer.writeUInt16(this.scancode);
|
||||||
|
} else {
|
||||||
|
buffer.writeUInt8(this.scancode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.hasModifiers()) {
|
if (this.hasModifiers()) {
|
||||||
buffer.writeUInt8(this.modifierMask);
|
buffer.writeUInt8(this.modifierMask);
|
||||||
@@ -106,7 +122,7 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return `<KeyMacroAction action="${this.action}" scancode="${this.scancode}" modifierMask="${this.modifierMask}">`;
|
return `<KeyMacroAction action="${this.action}" scancode="${this._scancode}" modifierMask="${this.modifierMask}">`;
|
||||||
}
|
}
|
||||||
|
|
||||||
isModifierActive(modifier: KeyModifiers): boolean {
|
isModifierActive(modifier: KeyModifiers): boolean {
|
||||||
@@ -114,7 +130,7 @@ export class KeyMacroAction extends MacroAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasScancode(): boolean {
|
hasScancode(): boolean {
|
||||||
return !!this.scancode;
|
return !!this._scancode;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasModifiers(): boolean {
|
hasModifiers(): boolean {
|
||||||
|
|||||||
12
packages/uhk-usb/package-lock.json
generated
12
packages/uhk-usb/package-lock.json
generated
@@ -1,11 +1,14 @@
|
|||||||
{
|
{
|
||||||
"requires": true,
|
"name": "uhk-usb",
|
||||||
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "8.0.28",
|
"version": "8.0.28",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz",
|
||||||
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ=="
|
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
@@ -144,6 +147,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||||
},
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz",
|
||||||
|
"integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg=="
|
||||||
|
},
|
||||||
"mimic-response": {
|
"mimic-response": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"@types/node": "8.0.28"
|
"@types/node": "8.0.28"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"lodash-es": "^4.17.10",
|
||||||
"node-hid": "0.5.7",
|
"node-hid": "0.5.7",
|
||||||
"uhk-common": "1.0.0"
|
"uhk-common": "1.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { cloneDeep, isEqual } from 'lodash-es';
|
||||||
import { Device, devices, HID } from 'node-hid';
|
import { Device, devices, HID } from 'node-hid';
|
||||||
import { CommandLineArgs, LogService } from 'uhk-common';
|
import { CommandLineArgs, LogService } from 'uhk-common';
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@ export class UhkHidDevice {
|
|||||||
* Internal variable that represent the USB UHK device
|
* Internal variable that represent the USB UHK device
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
private _prevDevices = {};
|
||||||
private _device: HID;
|
private _device: HID;
|
||||||
private _hasPermission = false;
|
private _hasPermission = false;
|
||||||
|
|
||||||
@@ -197,7 +199,7 @@ export class UhkHidDevice {
|
|||||||
|
|
||||||
async sendKbootCommandToModule(module: ModuleSlotToI2cAddress, command: KbootCommands, maxTry = 1): Promise<any> {
|
async sendKbootCommandToModule(module: ModuleSlotToI2cAddress, command: KbootCommands, maxTry = 1): Promise<any> {
|
||||||
let transfer;
|
let transfer;
|
||||||
const moduleName = kbootKommandName(module);
|
const moduleName = kbootCommandName(module);
|
||||||
this.logService.debug(`[UhkHidDevice] USB[T]: Send KbootCommand ${moduleName} ${KbootCommands[command].toString()}`);
|
this.logService.debug(`[UhkHidDevice] USB[T]: Send KbootCommand ${moduleName} ${KbootCommands[command].toString()}`);
|
||||||
if (command === KbootCommands.idle) {
|
if (command === KbootCommands.idle) {
|
||||||
transfer = new Buffer([UsbCommand.SendKbootCommandToModule, command]);
|
transfer = new Buffer([UsbCommand.SendKbootCommandToModule, command]);
|
||||||
@@ -233,12 +235,20 @@ export class UhkHidDevice {
|
|||||||
private connectToDevice(): HID {
|
private connectToDevice(): HID {
|
||||||
try {
|
try {
|
||||||
const devs = devices();
|
const devs = devices();
|
||||||
this.logService.debug('[UhkHidDevice] Available devices:', devs);
|
if (!isEqual(this._prevDevices, devs)) {
|
||||||
|
this.logService.debug('[UhkHidDevice] Available devices:', devs);
|
||||||
|
this._prevDevices = devs;
|
||||||
|
} else {
|
||||||
|
this.logService.debug('[UhkHidDevice] Available devices unchanged');
|
||||||
|
}
|
||||||
|
|
||||||
const dev = devs.find((x: Device) =>
|
const dev = devs.find((x: Device) =>
|
||||||
x.vendorId === Constants.VENDOR_ID &&
|
x.vendorId === Constants.VENDOR_ID &&
|
||||||
x.productId === Constants.PRODUCT_ID &&
|
x.productId === Constants.PRODUCT_ID &&
|
||||||
((x.usagePage === 128 && x.usage === 129) || x.interface === 0));
|
// hidapi can not read the interface number on Mac, so check the usage page and usage
|
||||||
|
((x.usagePage === 128 && x.usage === 129) || // Old firmware
|
||||||
|
(x.usagePage === (0xFF00 | 0x00) && x.usage === 0x01) || // New firmware
|
||||||
|
x.interface === 0));
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
this.logService.debug('[UhkHidDevice] UHK Device not found:');
|
this.logService.debug('[UhkHidDevice] UHK Device not found:');
|
||||||
@@ -256,7 +266,7 @@ export class UhkHidDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function kbootKommandName(module: ModuleSlotToI2cAddress): string {
|
function kbootCommandName(module: ModuleSlotToI2cAddress): string {
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case ModuleSlotToI2cAddress.leftHalf:
|
case ModuleSlotToI2cAddress.leftHalf:
|
||||||
return 'leftHalf';
|
return 'leftHalf';
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export class MacroKeyTabComponent extends MacroBaseComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getKeyMacroAction(): KeyMacroAction {
|
getKeyMacroAction(): KeyMacroAction {
|
||||||
const keyMacroAction = Object.assign(new KeyMacroAction(), this.keypressTab.toKeyAction());
|
const keyMacroAction = new KeyMacroAction(this.keypressTab.toKeyAction() as any);
|
||||||
keyMacroAction.action = this.getActionType(this.activeTab);
|
keyMacroAction.action = this.getActionType(this.activeTab);
|
||||||
return keyMacroAction;
|
return keyMacroAction;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<div class="row list-container">
|
<div class="row list-container">
|
||||||
<div class="col-xs-10 col-xs-offset-1 list-group">
|
<div class="col-xs-10 col-xs-offset-1 list-group">
|
||||||
|
<p><i>Please note that macro playback is not implemented yet. You can create macros, but they won't have any effect until firmware support is implemented. We're working on this.</i></p>
|
||||||
<div class="macro-actions-container" [dragula]="'macroActions'" [dragulaModel]="macro.macroActions">
|
<div class="macro-actions-container" [dragula]="'macroActions'" [dragulaModel]="macro.macroActions">
|
||||||
<macro-item *ngFor="let macroAction of macro.macroActions; let macroActionIndex = index"
|
<macro-item *ngFor="let macroAction of macro.macroActions; let macroActionIndex = index"
|
||||||
[macroAction]="macroAction"
|
[macroAction]="macroAction"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
></select2>
|
></select2>
|
||||||
<icon name="question-circle"
|
<icon name="question-circle"
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
title="Looking for a non-US character? Just pick the character of the desired key according to the US layout."
|
title="Looking for a non-US character? Just pick the character of the desired key according to the US layout. For example, on US keyboards next to Tab there is the Q key, but it's й on Russian keyboards, so in this case choose Q instead of й in Agent."
|
||||||
data-placement="bottom"></icon>
|
data-placement="bottom"></icon>
|
||||||
<capture-keystroke-button (capture)="onKeysCapture($event)" tabindex="0"></capture-keystroke-button>
|
<capture-keystroke-button (capture)="onKeysCapture($event)" tabindex="0"></capture-keystroke-button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
|||||||
const scTypePair = this.toScancodeTypePair(this.selectedScancodeOption);
|
const scTypePair = this.toScancodeTypePair(this.selectedScancodeOption);
|
||||||
keystrokeAction.scancode = scTypePair[0];
|
keystrokeAction.scancode = scTypePair[0];
|
||||||
if (scTypePair[1] === 'media') {
|
if (scTypePair[1] === 'media') {
|
||||||
keystrokeAction.type = KeystrokeType.shortMedia;
|
keystrokeAction.type = keystrokeAction.scancode > 255 ? KeystrokeType.longMedia : KeystrokeType.shortMedia;
|
||||||
} else {
|
} else {
|
||||||
keystrokeAction.type = KeystrokeType[scTypePair[1]];
|
keystrokeAction.type = KeystrokeType[scTypePair[1]];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<span [ngSwitch]="toggle">
|
<span [ngSwitch]="toggle">
|
||||||
<ng-template [ngSwitchCase]="true">layer by pressing this key.</ng-template>
|
<ng-template [ngSwitchCase]="true">layer by tapping this key.</ng-template>
|
||||||
<ng-template ngSwitchDefault>layer by holding this key.</ng-template>
|
<ng-template ngSwitchDefault>layer by holding this key.</ng-template>
|
||||||
</span>
|
</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<span> No macros are available to choose from. Create a macro first! </span>
|
<span> No macros are available to choose from. Create a macro first! </span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template [ngIf]="macroOptions.length > 0">
|
<ng-template [ngIf]="macroOptions.length > 0">
|
||||||
<p><i>Please note that macro playback is not implemented yet. You can bind macros, but they don't have any effect.</i></p>
|
<p><i>Please note that macro playback is not implemented yet. You can bind macros, but they won't have any effect until firmware support is implemented. We're working on this.</i></p>
|
||||||
<div class="macro-selector">
|
<div class="macro-selector">
|
||||||
<b> Play macro: </b>
|
<b> Play macro: </b>
|
||||||
<select2 [data]="macroOptions" [value]="macroOptions[selectedMacroIndex].id" (valueChanged)="onChange($event)" [width]="'100%'"></select2>
|
<select2 [data]="macroOptions" [value]="macroOptions[selectedMacroIndex].id" (valueChanged)="onChange($event)" [width]="'100%'"></select2>
|
||||||
|
|||||||
@@ -11,4 +11,24 @@ const firmwareMajorVersion = uhk.getUint16(response, 1);
|
|||||||
const firmwareMinorVersion = uhk.getUint16(response, 3);
|
const firmwareMinorVersion = uhk.getUint16(response, 3);
|
||||||
const firmwarePatchVersion = uhk.getUint16(response, 5);
|
const firmwarePatchVersion = uhk.getUint16(response, 5);
|
||||||
|
|
||||||
|
const deviceProtocolMajorVersion = uhk.getUint16(response, 7);
|
||||||
|
const deviceProtocolMinorVersion = uhk.getUint16(response, 9);
|
||||||
|
const deviceProtocolPatchVersion = uhk.getUint16(response, 11);
|
||||||
|
|
||||||
|
const moduleProtocolMajorVersion = uhk.getUint16(response, 13);
|
||||||
|
const moduleProtocolMinorVersion = uhk.getUint16(response, 15);
|
||||||
|
const moduleProtocolPatchVersion = uhk.getUint16(response, 17);
|
||||||
|
|
||||||
|
const userConfigMajorVersion = uhk.getUint16(response, 19);
|
||||||
|
const userConfigMinorVersion = uhk.getUint16(response, 21);
|
||||||
|
const userConfigPatchVersion = uhk.getUint16(response, 23);
|
||||||
|
|
||||||
|
const hardwareConfigMajorVersion = uhk.getUint16(response, 25);
|
||||||
|
const hardwareConfigMinorVersion = uhk.getUint16(response, 27);
|
||||||
|
const hardwareConfigPatchVersion = uhk.getUint16(response, 29);
|
||||||
|
|
||||||
console.log(`firmwareVersion: ${firmwareMajorVersion}.${firmwareMinorVersion}.${firmwarePatchVersion}`);
|
console.log(`firmwareVersion: ${firmwareMajorVersion}.${firmwareMinorVersion}.${firmwarePatchVersion}`);
|
||||||
|
console.log(`deviceProtocolVersion: ${deviceProtocolMajorVersion}.${deviceProtocolMinorVersion}.${deviceProtocolPatchVersion}`);
|
||||||
|
console.log(`moduleProtocolVersion: ${moduleProtocolMajorVersion}.${moduleProtocolMinorVersion}.${moduleProtocolPatchVersion}`);
|
||||||
|
console.log(`userConfigVersion: ${userConfigMajorVersion}.${userConfigMinorVersion}.${userConfigPatchVersion}`);
|
||||||
|
console.log(`hardwareConfigVersion: ${hardwareConfigMajorVersion}.${hardwareConfigMinorVersion}.${hardwareConfigPatchVersion}`);
|
||||||
|
|||||||
@@ -71,7 +71,10 @@ function writeDevice(device, data, options={}) {
|
|||||||
function getUhkDevice() {
|
function getUhkDevice() {
|
||||||
const foundDevice = HID.devices().find(device =>
|
const foundDevice = HID.devices().find(device =>
|
||||||
device.vendorId === 0x1d50 && device.productId === 0x6122 &&
|
device.vendorId === 0x1d50 && device.productId === 0x6122 &&
|
||||||
((device.usagePage === 128 && device.usage === 129) || device.interface === 0));
|
// hidapi can not read the interface number on Mac, so check the usage page and usage
|
||||||
|
((device.usagePage === 128 && device.usage === 129) || // Old firmware
|
||||||
|
(device.usagePage === (0xFF00 | 0x00) && device.usage === 0x01) || // New firmware
|
||||||
|
device.interface === 0));
|
||||||
|
|
||||||
if (!foundDevice) {
|
if (!foundDevice) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user