Skip to content
This repository has been archived by the owner on Jun 19, 2021. It is now read-only.

Commit

Permalink
Add a hid_listen console (#48)
Browse files Browse the repository at this point in the history
Add hid_listen support
  • Loading branch information
skullydazed authored Jun 28, 2017
1 parent 3c152dd commit 3020054
Show file tree
Hide file tree
Showing 17 changed files with 214 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ node_modules
.DS_Store
*.swp
dist
*.log
package-lock.json
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Releases

[Check out the releases](https://github.com/jackhumbert/qmk_firmware_flasher/releases/) (darwin is OSX)
[Check out the releases](https://github.com/jackhumbert/qmk_flasher/releases/) (darwin is OSX)

# Contributions

Expand Down
2 changes: 1 addition & 1 deletion dist-common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ if [ -d "$output_dir" -o -d "dist" ]; then
fi

if ! [ -d dfu -a -d src ]; then
echo '*** This must be run from the top-level qmk_firmware_flasher directory!'
echo '*** This must be run from the top-level qmk_flasher directory!'
exit 1
fi

Expand Down
2 changes: 1 addition & 1 deletion dist-darwin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ arch=x64
if [ -f ./dist-common.sh ]; then
. ./dist-common.sh
else
echo '*** This must be run from the top-level qmk_firmware_flasher directory!'
echo '*** This must be run from the top-level qmk_flasher directory!'
exit 1
fi

Expand Down
4 changes: 2 additions & 2 deletions dist-win32.bat
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@echo off

:: This script will create a packaged version of the app in firmware_flasher in your home folder.
:: After executing this script, use NSIS to create an installer from the firmware_flasher.win32.nsi file located there.
:: This script will create a packaged version of the app in qmk_flasher in your home folder.
:: After executing this script, use NSIS to create an installer from the qmk_flasher.win32.nsi file located there.
:: You may need to run npm install electron-packager --global once before this will work correctly.

set PLATFORM=win32
Expand Down
2 changes: 1 addition & 1 deletion dist-win32.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ arch=ia32
if [ -f ./dist-common.sh ]; then
. ./dist-common.sh
else
echo '*** This must be run from the top-level qmk_firmware_flasher directory!'
echo '*** This must be run from the top-level qmk_flasher directory!'
exit 1
fi

Expand Down
8 changes: 0 additions & 8 deletions dist.sh

This file was deleted.

23 changes: 12 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
{
"name": "qmk-firmware-flasher",
"name": "qmk-flasher",
"productName": "QMK Flasher",
"version": "0.5.2",
"description": "GUI app to load firmware onto atmega32u4 chips.",
"description": "GUI app to load firmware onto QMK Keyboards.",
"main": "src/main.js",
"scripts": {
"start": "electron .",
"postinstall": "install-app-deps",
"postinstall": "install-app-deps; electron-rebuild --force",
"pack": "build",
"dist": "build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/qmk/qmk_firmware_flasher.git"
"url": "git+https://github.com/qmk/qmk_flasher.git"
},
"keywords": [
"dfu-programmer",
"dfu",
"keyboard",
"mechanical keyboard",
"qmk",
"qmk-firmware-flasher",
"qmk-flasher"
],
"author": "Jack Humbert",
"license": "MIT",
"bugs": {
"url": "https://github.com/qmk/qmk_firmware_flasher/issues"
"url": "https://github.com/qmk/qmk_flasher/issues"
},
"homepage": "https://github.com/qmk/qmk_firmware_flasher",
"homepage": "https://github.com/qmk/qmk_flasher",
"dependencies": {
"bootbox": "~4.4",
"bootstrap": "~3.3",
"chokidar": "~1.7",
"electron-debug": "~1.1",
"electron-settings": "~3.1.1",
"electron-settings": "~3.1",
"jquery": "~2.2",
"node-hid": "~0.5",
"usb": "~1.2"
},
"devDependencies": {
"devtron": "^1.4.0",
"electron": "^1.6.10",
"electron-builder": "^18.3.5"
"electron-builder": "^18.3.5",
"electron-rebuild": "^1.0.2"
},
"build": {
"appId": "com.github.qmk-firmware-flasher",
"appId": "com.github.qmk-flasher",
"fileAssociation": [
{
"ext": "hex",
Expand All @@ -58,7 +59,7 @@
"target": "zip"
},
"win": {
"iconUrl": "https://github.com/qmk/qmk_firmware_flasher/blob/master/build/windows.ico?raw=true"
"iconUrl": "https://github.com/qmk/qmk_flasher/blob/master/build/windows.ico?raw=true"
}
}
}
6 changes: 3 additions & 3 deletions qmk_flasher.win32.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
!define VERSIONBUILD 2
# These will be displayed by the "Click here for support information" link in "Add/Remove Programs"
# It is possible to use "mailto:" links in here to open the email client
!define HELPURL "https://github.com/qmk/qmk_firmware_flasher/issues" # "Support Information" link
!define UPDATEURL "https://github.com/qmk/qmk_firmware_flasher/releases" # "Product Updates" link
!define ABOUTURL "https://github.com/qmk/qmk_firmware_flasher" # "Publisher" link
!define HELPURL "https://github.com/qmk/qmk_flasher/issues" # "Support Information" link
!define UPDATEURL "https://github.com/qmk/qmk_flasher/releases" # "Product Updates" link
!define ABOUTURL "https://github.com/qmk/qmk_flasher" # "Publisher" link

# This is the size (in kB) of all the files copied into "Program Files"
#!define INSTALLSIZE 7233
Expand Down
101 changes: 101 additions & 0 deletions src/ConsoleWindow/console.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/* This file says HID device, which is redundant, a lot. You'll get over it.
*/

window.$ = window.jQuery = require('jquery');
const bootstrap = require('bootstrap');

const {ipcRenderer} = require('electron');
const remote = require('electron').remote;
const BrowserWindow = remote.BrowserWindow;
const HID = require('node-hid');

/* HTML Entities
*/
let $status = $('#status');
let $keyboardChooserLabel = $('#keyboard-chooser-label');
let $keyboardList = $('#keyboard-list');

/* State variables
*/
let currentHidDevice;

/* Helpful functions
*/
function clearConsole() {
$status.text('');
}

function writeConsole(text) {
/* Write a line to the console window. Should only be used to write
* log output.
*/
$status.append(text);
$status.scrollTop(1E10); // Scroll a lot so we don't have to calculate.
}

function process_usb_packet(data_array) {
/* Process a USB message.
*/
let message = '';
for (let char of data_array) {
message += String.fromCharCode(char);
}
writeConsole(message);
}

function handleError(error) {
/* Called when there's an error from the HID device
*/
console.log('HID error:', error);
writeConsole('\n<b>Connection to keyboard closed:</b> ' + error);
currentHidDevice.close();
currentHidDevice = null;
$keyboardChooserLabel.html('Choose Keyboard');
}

function selectKeyboard(manufacturer, product, path) {
console.log('selectKeyboard: ', manufacturer, product, path);
clearConsole();
currentHidDevice = new HID.HID(path);
currentHidDevice.on("data", process_usb_packet);
currentHidDevice.on("error", handleError);
$keyboardChooserLabel.html('<b>Manufacturer:</b> ' + manufacturer + ', <b>Keyboard:</b> ' + product);
writeConsole('<b>Connected to ' + manufacturer + ' ' + product + ': ' + path + '</b>\n');
}

function populateKeyboardDropdown() {
/* Empty the keyboard list and repopulate it.
*/
let keys = [];
let keyboards = {}
let devices = HID.devices();
console.log('devices:', devices);

for (let device of devices) {
if (device.usage == 116) { // Look for USB devices with hid_listen usage
console.log('device:', device)
keys.push(device.path);
keyboards[device.path] = device;
}
}

keys.sort();
$keyboardList.empty();
for (let key of keys) {
keyboard = keyboards[key];
let select_opts = "'" + keyboard.manufacturer + "', '" + keyboard.product + "', '" + keyboard.path + "'";
let dropdown_entry = keyboard.manufacturer + '(0x' + keyboard.vendorId.toString(16).toUpperCase() + '): ' + keyboard.product + '(0x' + keyboard.productId.toString(16).toUpperCase() + ')';

$keyboardList.append('<li><a href="#" onclick="selectKeyboard(' + select_opts + ');">' + dropdown_entry + '</a></li>');
}

window.setTimeout(populateKeyboardDropdown, 3000);
}

$(document).ready(function() {
/* main()
*/
$("<link/>", {rel: "stylesheet", type: "text/css", href: "../MainWindow/themes/" + ipcRenderer.sendSync('get-setting-theme') + ".css"}).appendTo("head");

populateKeyboardDropdown();
});
20 changes: 20 additions & 0 deletions src/ConsoleWindow/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>hid_listen</title>
<link href="../../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div id="keyboard-chooser-div" class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="keyboard-chooser" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span class="caret"></span> <span id="keyboard-chooser-label">Choose Keyboard</span>
</button>
<ul class="dropdown-menu" aria-labelledby="keyboard-chooser" id="keyboard-list">
<li><a href="#">No Keyboards Detected</a></li>
</ul>
</div>
<span id="status"></span>
<script src="console.js"></script>
</body>
</html>
35 changes: 35 additions & 0 deletions src/ConsoleWindow/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#status {
font-family: monospace;
font-size: 12px;
position: absolute;
left: 14px;
right: 14px;
top: 50px;
bottom: 14px;
border-radius: 2px;
overflow-x: scroll;
overflow-y: scroll;
white-space: pre-wrap;
padding: 7px;
-webkit-app-region: no-drag;
}

#status, #status b {
-webkit-user-select: text;
}

#keyboard-chooser {
width: 100%;
text-align: left;
}

#keyboard-chooser-div {
position: absolute;
top: 10px;
left: 14px;
right: 14px;
height: 24px;
border-radius: 6px;
margin: 0;
padding: 0;
}
13 changes: 7 additions & 6 deletions src/GearMenuWindow/index.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<link href="../../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
<link href="../../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="dropdown">
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" id="about-item">About...</a></li>
<li><a class="dropdown-item" href="#" id="options-item">Options...</a></li>
</ul>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" id="about">About</a></li>
<li><a class="dropdown-item" href="#" id="console">hid_listen</a></li>
<li><a class="dropdown-item" href="#" id="options">Options</a></li>
</ul>
</div>
<script src="menu-handler.js"></script>
</body>
Expand Down
31 changes: 25 additions & 6 deletions src/GearMenuWindow/menu-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,36 @@ const BrowserWindow = remote.BrowserWindow;
const mainWindow = BrowserWindow.fromId(remote.getGlobal('mainWinId'));
const win = remote.getCurrentWindow();

const aboutMenuItem = $('#about-item');
const optionsMenuItem = $('#options-item');
const $aboutMenu = $('#about');
const $consoleMenu = $('#console');
const $optionsMenu = $('#options');

aboutMenuItem.bind('click', () => {
$aboutMenu.bind('click', () => {
mainWindow.webContents.executeJavaScript("openAboutDialog()");
aboutMenuItem.blur();
$aboutMenu.blur();
win.hide();
});

optionsMenuItem.bind('click', () => {
$consoleMenu.bind('click', () => {
$consoleMenu.blur();
consoleWin = new BrowserWindow({
show: false,
frame: true,
resizable: true,
maximizable: true,
fullscreen: false,
fullscreenable: false,
title: 'hid_listen',
});
consoleWin.loadURL('file://' + __dirname + '/../ConsoleWindow/index.html');
consoleWin.setMenu(null);
consoleWin.once('ready-to-show', () => { consoleWin.show(); });
consoleWin.on('closed', function() { consoleWin = null; });
win.hide();
});

$optionsMenu.bind('click', () => {
mainWindow.webContents.executeJavaScript("openOptions()");
optionsMenuItem.blur();
$optionsMenu.blur();
win.hide();
});
2 changes: 1 addition & 1 deletion src/MainWindow/simple.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ html, body {

#load-file {
position: absolute;
top: 10px;
top: 14px;
right: 14px;
width: 100px;
height: 24px;
Expand Down
2 changes: 1 addition & 1 deletion src/MainWindow/themes/platform.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ html, body, .modal-content {
font: icon;
}

.dropdown-menu {
.menu {
font: menu;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ app.on('ready', function() {

menuWin = new BrowserWindow({
width: 120,
height: 64,
height: 85,
frame: false,
x: mainWin.getPosition()[0] + menuWinXOffset,
y: mainWin.getPosition()[1] + menuWinYOffset,
Expand Down

0 comments on commit 3020054

Please sign in to comment.