function [secs, keyCode, deltaSecs] = KbWait(deviceNumber, forWhat, untilTime) % [secs, keyCode, deltaSecs] = KbWait([deviceNumber][, forWhat=0][, untilTime=inf]) % % Waits until any key is down and optionally returns the time in seconds % and the keyCode vector of keyboard states, just as KbCheck would do. Also % allows to wait for release of all keys or for single keystrokes, see % below. % % If the optional parameter 'untilTime' is provided, KbWait will only wait % until that time and then return regardless if anything happened on the % keyboard or not. % % CAUTION: KbWait periodically checks the keyboard. After each failed check % (ie. no change in keyboard state) it will wait for 5 msecs before the % next check. This is done to reduce the load on your system, and it is % important to do so. However if you want to measure reaction times this is % clearly not what you want, as it adds up to 5 msecs extra uncertainty to % all measurements! % % If you have trouble with KbWait always returning immediately, this could % be due to "stuck keys". See "help DisableKeysForKbCheck" on how to work % around this problem. See also "help RestrictKeysForKbCheck". % % GetChar and CharAvail are character oriented (and slow), whereas KbCheck % and KbWait are keypress oriented (and fast). % % Using KbWait from the MATLAB command line: When you type "KbWait" at the % prompt and hit the enter/return key to execute that command, then KbWait % will detect the enter/return key press and return immediately. If you % want to test KbWait from the command line, then try this: % % WaitSecs(0.2);KbWait % % KbWait can also wait for releasing of keys instead of pressing of keys % if you set the optional 2nd argument 'forWhat' to 1. % % If you want to wait for a single keystroke, set the 'forWhat' value to 2. % KbWait will then first wait until all keys are released, then for the % first keypress, then it will return. The above example could be realized % via: % % KbWait([], 2); % % If you would set 'forWhat' to 3 then it would wait for releasing the key % after pressing it againg, ie. waitForAllKeysReleased -> waitForKeypress % -> waitForAllKeysReleased -> Return [secs, keyCode] of the key press. % % % OSX and Linux: _______________________________________________________________ % % KbWait uses the PsychHID function, a general purpose function for % reading from the Human Interface Device (HID) class of USB devices. % % KbWait tests a keyboard device by default, which is chosen by an operating % system dependent heuristic and usually makes a reasonable choice. For better % control over the keyboard input device, you can pass in a 'deviceNumber' to % test a different keyboard if multiple keyboards are connected to your machine. % See the "help KbCheck" for KbCheck for the meaning of the 'deviceNumber'. % ______________________________________________________________________________ % % See also: KbCheck, KbStrokeWait, KbPressWait, KbReleaseWait, GetChar, CharAvail, KbDemo. % 3/6/97 dhb Wrote it. % 8/2/97 dgp Explain difference between key and character. See KbCheck. % 9/06/03 awi ****** OS X-specific fork from the OS 9 version ******* % Added OS X conditional. % 7/12/04 awi Cosmetic. OS 9 Section. Uses IsOSX. % 4/11/05 awi Added to help note about testing kbWait from command line. % 11/29/05 mk Fixed really stupid bug: deviceNumber wasn't queried! % 02/22/06 mk Modified for Linux: Currently a hack. % 10/24/06 mk Replaced by a generic implementation that just uses KbCheck % in a while loop. This way we directly benefit from KbChecks % improvements. % 3/15/07 kas Added in option to poll all keyboard devices by passing % deviceNumber == -1 % % 3/03/08 mk Added option 'forWhat' to optionally wait for key release % or isolated keystrokes, and optional return argument 'keyCode' % to return keyCode vector, just as KbCheck does. % % 12/27/09 mk Remove all the redundant code for 'deviceNumber' specific % behaviour. This is already covered by code in KbCheck! % This also fixes a bug reported in forum message 10468 % where KbReleaseWait(-1) didn't wait for all keys on all % keyboards to be released. % 12/18/09 rpw Added documentation about keypad devices on OS/X. % 06/06/15 mk Fix treatment of empty forWhat argument. Suggested by Taylor Hanayik. % Time (in seconds) to wait between "failed" checks, in order to not % overload the system in realtime mode. 5 msecs seems to be an ok value... yieldInterval = 0.005; if nargin < 1 deviceNumber = []; end if nargin < 2 || isempty(forWhat) forWhat = 0; end if nargin < 3 || isempty(untilTime) untilTime = inf; end % Wait for keystroke? if (forWhat == 2) || (forWhat == 3) % Wait for keystroke, ie., first make sure all keys are released, then % wait for a keypress: % Wait for key release. we know we have deviceNumber valid here: KbWait(deviceNumber, 1, untilTime); if forWhat == 2 % Now just go on with forWhat = 0, ie., wait for keypress: forWhat = 0; else % Wait for keypress: [secs, keyCode, deltaSecs] = KbWait(deviceNumber, 0, untilTime); % Wait for key release. we know we have deviceNumber valid here: KbWait(deviceNumber, 1, untilTime); return; end end secs = -inf; while secs < untilTime [isDown, secs, keyCode, deltaSecs] = KbCheck(deviceNumber); if (isDown == ~forWhat) || (secs >= untilTime) return; end % A tribute to Windows: A useless call to GetMouse to trigger % Screen()'s Windows application event queue processing to avoid % white-death due to hitting the "Application not responding" timeout: if IsWin GetMouse; end % Wait for yieldInterval to prevent system overload. secs = WaitSecs('YieldSecs', yieldInterval); end