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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
function [strInputName, x, y] = bvlWaitForInput(scal,fSeconds, fBufferWindow)
% [strInputName, x, y] = bvlWaitForInput(fSeconds [, fBufferWindow])
%
% Wait for a key press or mouse input, then return the input name and mouse position.
% strInputName is a string identifier of the key. (Defined in KbName)
% x, y are the pixel coordinates of the mouse
%
% Returns after fSeconds, if no key is pressed.
% If fSeconds is not specified, returns after 1.0 seconds
%
% fBufferWindow allows you to specify the time buffer (window) between
% key/mouse events that will be accepted. This way we don't register the
% key-down and key-up of the same key as two events. Nor do we register
% one key press as multiple events. If this parameter is not passed in,
% the default is 0.250 (250 milliseconds). Reduce this if you need
% constant feedback, for instance, in tracing out a rectangle when
% selecting points in the calibration, I use 0.010 seconds.
%
% Some example strInputNames:
% LeftArrow
% RightArrow
% UpArrow
% DownArrow
% ESCAPE
% LeftMouse
% MiddleMouse
% RightMouse
%
% 2007-05-15 - cburns - update to fix bugs in events not being handled.
% 2007-05-10 - cburns - Rewrote for include mouse input and update
% for Psychtoolbox 3.x install.
%
% 2006-01-31 - cburns - Bankslab, UC Berkeley
%
global gTimeOfPrevKeyEvent
% bv180108 Try to find out what the current display window is. If there are
% more than 1 active windows, this method won;t work and we have to proceed
% without information about the presentation window (indicated by an empty
% variable windowlist)
if isempty(gTimeOfPrevKeyEvent)
% initialize the global timestamp otherwise we'll never enter the
% event-handling blocks below and set a new timestamp
gTimeOfPrevKeyEvent = GetSecs;
end
if (nargin < 2)
fSeconds = 1.0;
windowlist=0;
else
windowlist = scal.windowPtr;
end
if (nargin < 3)
fBufferWindow = 0.250;
end
% initialize return variables
strInputName = '';
x = 0;
y = 0;
fCurrTime = GetSecs;
fEndTime = fCurrTime + fSeconds;
while (fCurrTime < fEndTime)
% Check state for entire keyboard
% iKeyCode is an array of size 256
[iKeyIsDown, fSecs, iKeyboardCodes] = KbCheck(-1);
% Handle keyboard input
if iKeyIsDown
% We want to allow people to hold down keys for repeated behavior
% but we need to dampen the speed of the input. So grab the events
% as they come in but only process them ever 250ms.
% A hacked way of flushing the event queue.
% This is a timed version of the "while KbCheck; end" used in the
% KbDemo.m in the PTB.
if fSecs - gTimeOfPrevKeyEvent > fBufferWindow
iKeyIndex = find(iKeyboardCodes);
% For Debugging:
%KbName(iKeyIndex)
% Get the keyboard name from PTB.
strInputName = KbName(iKeyIndex);
% BUGGY: On the same WindowsXP development machine, using Matlab
% 7.0.1 and PTB 3.0.8, I received both the Windows keynames and the
% OSX keynames.... I don't know why. Map them to one here so we
% can count on the same from the calling function.
if strcmp(strInputName, 'left')
strInputName = 'LeftArrow';
elseif strcmp(strInputName, 'right')
strInputName = 'RightArrow';
elseif strcmp(strInputName, 'up')
strInputName = 'UpArrow';
elseif strcmp(strInputName, 'down')
strInputName = 'DownArrow';
elseif strcmp(strInputName, 'esc')
strInputName = 'ESCAPE';
end
% event handled break out of loop
gTimeOfPrevKeyEvent = fSecs;
break;
end
end
% No keyboard input, Check mouse state.
% bv180108 If there is information about
% the presentation window, then we will retrieve the mouse position
% relative to that window.
if isempty(windowlist),
[xMouse, yMouse, buttons] = GetMouse;
else
[xMouse, yMouse, buttons] = GetMouse(windowlist);
end
x = xMouse;
y = yMouse;
% Handle mouse input
if buttons(1) || buttons(2) || buttons(3)
% Just as for the keyboard input, only accept new input every
% 250ms. This allows someone to hold down the mouse button and
% cycle through items at a reasonable pace
if fSecs - gTimeOfPrevKeyEvent > fBufferWindow
if IsWin || IsLinux
if buttons(1)
strInputName = 'LeftMouse';
elseif buttons(2)
strInputName = 'MiddleMouse';
elseif buttons(3)
strInputName = 'RightMouse';
end
end
if IsOSX
if buttons(1)
strInputName = 'LeftMouse';
elseif buttons(3)
strInputName = 'MiddleMouse';
elseif buttons(2)
strInputName = 'RightMouse';
end
end
% event handled break out of loop
gTimeOfPrevKeyEvent = fSecs;
break;
end
end
% No need to check more then every 5 millisecond
WaitSecs('YieldSecs', 0.005);
fCurrTime = GetSecs;
end
|