forked from node-hid/node-hid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nodehid.js
133 lines (116 loc) · 3.79 KB
/
nodehid.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
var os = require('os')
var EventEmitter = require("events").EventEmitter,
util = require("util");
var driverType = null;
function setDriverType(type) {
driverType = type;
}
// lazy load the C++ binding
var binding = null;
function loadBinding() {
if( !binding ) {
if( os.platform() === 'linux' ) {
// Linux defaults to hidraw
if( !driverType || driverType === 'hidraw' ) {
binding = require('bindings')('HID_hidraw.node');
} else {
binding = require('bindings')('HID.node');
}
}
else {
binding = require('bindings')('HID.node');
}
}
}
//This class is a wrapper for `binding.HID` class
function HID() {
//Inherit from EventEmitter
EventEmitter.call(this);
loadBinding();
/* We also want to inherit from `binding.HID`, but unfortunately,
it's not so easy for native Objects. For example, the
following won't work since `new` keyword isn't used:
`binding.HID.apply(this, arguments);`
So... we do this craziness instead...
*/
var thisPlusArgs = new Array(arguments.length + 1);
thisPlusArgs[0] = null;
for(var i = 0; i < arguments.length; i++)
thisPlusArgs[i + 1] = arguments[i];
this._raw = new (Function.prototype.bind.apply(binding.HID,
thisPlusArgs) )();
/* Now we have `this._raw` Object from which we need to
inherit. So, one solution is to simply copy all
prototype methods over to `this` and binding them to
`this._raw`
*/
for(var i in binding.HID.prototype)
this[i] = binding.HID.prototype[i].bind(this._raw);
/* We are now done inheriting from `binding.HID` and EventEmitter.
Now upon adding a new listener for "data" events, we start
polling the HID device using `read(...)`
See `resume()` for more details. */
this._paused = true;
var self = this;
self.on("newListener", function(eventName, listener) {
if(eventName == "data")
process.nextTick(self.resume.bind(self) );
});
}
//Inherit prototype methods
util.inherits(HID, EventEmitter);
//Don't inherit from `binding.HID`; that's done above already!
HID.prototype.close = function close() {
this._closing = true;
this.removeAllListeners();
this._raw.close();
this._closed = true;
};
//Pauses the reader, which stops "data" events from being emitted
HID.prototype.pause = function pause() {
this._paused = true;
};
HID.prototype.read = function read(callback) {
if (this._closed) {
throw new Error('Unable to read from a closed HID device');
} else {
return this._raw.read(callback);
}
};
HID.prototype.resume = function resume() {
var self = this;
if(self._paused && self.listeners("data").length > 0)
{
//Start polling & reading loop
self._paused = false;
self.read(function readFunc(err, data) {
if(err)
{
//Emit error and pause reading
self._paused = true;
if(!self._closing)
self.emit("error", err);
//else ignore any errors if I'm closing the device
}
else
{
//If there are no "data" listeners, we pause
if(self.listeners("data").length <= 0)
self._paused = true;
//Keep reading if we aren't paused
if(!self._paused)
self.read(readFunc);
//Now emit the event
self.emit("data", data);
}
});
}
};
function showdevices() {
loadBinding();
return binding.devices.apply(HID,arguments);
}
//Expose API
exports.HID = HID;
exports.devices = showdevices;
exports.setDriverType = setDriverType;