Skip to content

Instantly share code, notes, and snippets.

@kleinerm
Created January 30, 2012 14:38
Show Gist options
  • Save kleinerm/1704739 to your computer and use it in GitHub Desktop.
Save kleinerm/1704739 to your computer and use it in GitHub Desktop.
Do your own mouse driver as M-File via raw HID access. Version for "12-Bit mouse'
function [ dx, dy, sx, sy ] = RawMouse2(devIndex)
% Parse raw HID datastream from a mouse to implement
% raw mouse movement from HID reports.
%
% This is just an example! The data format is mouse
% dependent, this is for a DELL LaserMouse.
%
% Must be run "sudo" root unless proper udev rules
% are defined to allow non-root raw access to mouse
% on your system.
%
% Will (violently) detach the mouse from the GUI,
% making it unuseable for regular "mousing" until
% mouse is unplugged and replugged.
%
% Should work on Linux and probably OS/X. Will not
% work on Windows, as MS forbids low-level HID access to
% mouse and keyboard.
%
% You should disable mouse queries after use via
% PsychHID('ReceiveReportsStop', devIndex); and/or
% flush the buffer via a PsychHID('GiveMeReports', devIndex);
% This is not shown in this demo...
persistent sx;
persistent sy;
% devIndex must be found out by proper matching against
% output of dev = PsychHID('Devices').
if nargin < 1 || isempty(devIndex)
devIndex = 1;
end
if isempty(sx)
sx = 0;
sy = 0;
% Process at most 2 msecs per 'ReceiveReports' call, so we
% don't block script execution for too long.
options.secs = 0.002;
PsychHID('ReceiveReports', devIndex, options);
end
dx = 0;
dy = 0;
% Fetch a bunch of HID-Reports from the HID device into
% PsychHID internal buffer:
PsychHID('ReceiveReports', devIndex);
% Retrieve them from PsychHID buffer:
reps = PsychHID('GiveMeReports', devIndex);
% Parse them:
for i=1:numel(reps)
rep = reps(i).report;
if ~isempty(rep)
% DELL Lasermouse encodes x,y motion as two 12 bit numbers,
% packed into bytes 2, 3 and 4: Decode...
% Byte2[0:7] = 8 LSB of x, Byte 3[0:3] = 4 MSB of x:
ix = bitshift(bitand(int32(rep(3)), 1+2+4+8), 8) + int32(rep(2));
% Byte3[4:7] = 4 LSB of y, Byte 4[0:7] = 8 MSB of x:
iy = bitand(bitshift(int32(rep(3)), -4), 1+2+4+8) + bitshift(int32(rep(4)), 4);
% 12th bit (aka Bit 11) encodes sign: 1 (aka dx >= 2048) -> Negative dx:
dx = double(ix);
if dx >= 2048
dx = dx - 4096;
end
dy = double(iy);
if dy >= 2048
dy = dy - 4096;
end
% (dx, dy) is mouse delta. Accumulate for abs position:
sx = sx + dx;
sy = sy + dy;
end
end
return;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment