- 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;