Created
March 12, 2012 09:41
-
-
Save bfncs/2020943 to your computer and use it in GitHub Desktop.
Read Linux mouse(s) in node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Read Linux mouse(s) in node.js | |
* Author: Marc Loehe ([email protected]) | |
* | |
* Adapted from Tim Caswell's nice solution to read a linux joystick | |
* http://nodebits.org/linux-joystick | |
* https://github.com/nodebits/linux-joystick | |
*/ | |
var fs = require('fs'), | |
EventEmitter = require('events').EventEmitter; | |
/** | |
* Parse PS/2 mouse protocol | |
* According to http://www.computer-engineering.org/ps2mouse/ | |
*/ | |
function parse(mouse, buffer) { | |
var event = { | |
leftBtn: (buffer[0] & 1 ) > 0, // Bit 0 | |
rightBtn: (buffer[0] & 2 ) > 0, // Bit 1 | |
middleBtn: (buffer[0] & 4 ) > 0, // Bit 2 | |
xSign: (buffer[0] & 16 ) > 0, // Bit 4 | |
ySign: (buffer[0] & 32 ) > 0, // Bit 5 | |
xOverflow: (buffer[0] & 64 ) > 0, // Bit 6 | |
yOverflow: (buffer[0] & 128) > 0, // Bit 7 | |
xDelta: buffer.readInt8(1), // Byte 2 as signed int | |
yDelta: buffer.readInt8(2) // Byte 3 as signed int | |
}; | |
if (event.leftBtn || event.rightBtn || event.middleBtn) { | |
event.type = 'button'; | |
} else { | |
event.type = 'moved'; | |
} | |
return event; | |
} | |
function Mouse(mouseid) { | |
this.wrap('onOpen'); | |
this.wrap('onRead'); | |
this.dev = typeof(mouseid) === 'number' ? 'mouse' + mouseid : 'mice'; | |
this.buf = new Buffer(3); | |
fs.open('/dev/input/' + this.dev, 'r', this.onOpen); | |
} | |
Mouse.prototype = Object.create(EventEmitter.prototype, { | |
constructor: {value: Mouse} | |
}); | |
Mouse.prototype.wrap = function(name) { | |
var self = this; | |
var fn = this[name]; | |
this[name] = function (err) { | |
if (err) return self.emit('error', err); | |
return fn.apply(self, Array.prototype.slice.call(arguments, 1)); | |
}; | |
}; | |
Mouse.prototype.onOpen = function(fd) { | |
this.fd = fd; | |
this.startRead(); | |
}; | |
Mouse.prototype.startRead = function() { | |
fs.read(this.fd, this.buf, 0, 3, null, this.onRead); | |
}; | |
Mouse.prototype.onRead = function(bytesRead) { | |
var event = parse(this, this.buf); | |
event.dev = this.dev; | |
this.emit(event.type, event); | |
if (this.fd) this.startRead(); | |
}; | |
Mouse.prototype.close = function(callback) { | |
fs.close(this.fd, (function(){console.log(this);})); | |
this.fd = undefined; | |
} | |
/**************** | |
* Sample Usage * | |
****************/ | |
// read all mouse events from /dev/input/mice | |
var mouse = new Mouse(); | |
mouse.on('button', console.log); | |
mouse.on('moved', console.log); | |
// to read only a specific mouse by id (e.g. /dev/input/mouse0) use | |
// var mouse0 = newMouse(0); | |
// to close mouse | |
// mouse.close(); | |
// mouse = undefined; |
@marc thanks a lot! This was what I was searching for. It works perfectly with mice on Linux. The problem that I have is that I would like to use a motion detection sensor instead. This sensor shows up like a normal mouse in /dev/input. But I don't get any output. I would expect that it should send some mouse events, but to be honest I can't tell which, because I don't have any spec of this device. Do you have any idea what the reason could be? Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This no longer works as there is no
'/dev/input/mice'
on MacOS