/usr/share/psychtoolbox-3/PsychBasic/GetChar.m is in psychtoolbox-3-common 3.0.11.20140816.dfsg1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | function [ch, when] = GetChar(getExtendedData, getRawCode)
% [ch, when] = GetChar([getExtendedData], [getRawCode])
%
% Wait for a typed character and return it. If a character was typed
% before calling GetChar then GetChar will return that character immediatly.
% Characters flushed by FlushEvents are all ignored by GetChar. Characters
% are returned in the first return argument "ch".
%
% Please read the 'help ListenChar' carefully to understand various
% limitations and caveats of this function, and to learn about - often
% better - alternatives.
%
% CAUTION: Do not rely on the keypress timestamps returned by GetChar
% without fully reading and understanding this help text. Run your own
% timing tests on GetChar and KbCheck to verify that the timing is good
% enough and avoid GetChar for timed keypresses if possible at all. Use
% KbWait and KbCheck instead.
%
% The main purpose of GetChar is to reliably collect keyboard input in the
% background while your experiment script is occupied with performing other
% operations, e.g., Matlab computations, sound output or visual stimulus
% drawing. After an initial call to ListenChar, the operating system will
% record all keyboard input into an internal queue. GetChar removes
% characters from that queue, one character per invocation of GetChar. You
% can empty that queue any time by calling FlushEvents('keyDown').
%
% If you want to check the current state of the keyboard, e.g., for
% triggering immediate actions in response to a key press, waiting for a
% subjects response, synchronizing to keytriggers (e.g., fMRI machines) or
% if you require high timing precision then use KbCheck instead of GetChar.
%
% GetChar should work on all platforms, but its specific functionality,
% beyond simply returning typed characters, will vary depending on OS type
% and version, if you use Matlab or Octave, and if you use Matlab with or
% without Java based GUI active. For portability it is therefore best to
% ignore all info returned beyond the character code.
%
% "when" is a struct. It (used to) return the time of the keypress, the "adb"
% address of the input device, and the state of all the modifier keys
% (shift, control, command, option, alphaLock) and the mouse button.
% "when.secs" is an estimate, of what GetSecs would have been. Since it's
% derived sometime from a timebase different from the timebase of GetSecs,
% times returned by GetSecs are not directly comparable to when.secs.
%
% By setting getExtendedData to 0, all extended timing/modifier information
% will not be collected and "when" will be returned empty. This speeds up
% calls to this function. If ommitted or set to 1, the "when" data
% structure is filled. getRawCode set to 1 will set "ch" to be the integer
% ACII code of the available character. If ommitted or set to 0, "ch" will
% be in char format. When running under Linux in "matlab -nojvm" mode or on
% Octave, "when" will be returned empty. When running on any other
% operating system under Octave or in "matlab -nojvm" mode, or on Windows
% Vista and later versions of the Windows OS, when will only contain a
% valid timestamp, but all other fields will be meaningless.
%
% GetChar and CharAvail are character-oriented (and slow), whereas KbCheck
% and KbWait are keypress-oriented (and fast). If only a meta key (like
% <option> or <shift>) was hit, KbCheck will return true, because a key was
% pressed, but CharAvail will return false, because no character was
% generated. See KbCheck.
%
% CharAvail and GetChar use the system event queue to retrieve the character
% generated, not the raw key press(es) per se. If the user presses "a",
% GetChar returns 'a', but if the user presses option-e followed by "a",
% this selects an accented a, "?", which is treated by GetChar as a single
% character, even though it took the user three keypresses (counting the
% option key) to produce it.
%
% There can be some delay between when the key is pressed and when CharAvail
% or GetChar detects it, due to internal processing overhead in Matlabs Java
% implementation. GetChar internally collects timestamps in the timebase
% used by Matlabs Java implementation, whereas other Psychtoolbox timing functions
% (GetSecs, Screen('Flip'), KbCheck, KbWait, ...) use time reported by some
% high precision system timer. The "when.secs" time reported by GetChar is
% converted from Java timebase to Psychtoolboxs timebase. Due to conversion
% errors mostly out of our control, the reported values can be off by
% multiple dozen or even hundreds of milliseconds from what KbWait, KbCheck
% or GetSecs would report. Example: A high-end Pentium-4 3.2 Ghz system
% running Windows-XP has been measured to be off by 40 to 70 milliseconds.
%
% Some Java implementations are also known to have problems/bugs in
% timestamping keyboard presses properly and each Matlab version on each
% operating system is bundled with a different Java version, so some Matlab
% versions may be reliable with respect to GetChars timing, whereas others
% are not.
%
% ---> If precise timing of the keypress is important, use KbCheck or
% KbWait or KbQueueXXX functions or KbEventGet for consistent results!
%
% OS X / Windows-XP / Linux with Matlab and Java enabled: _________________
%
% JAVA PATH: The GetChar implementation for Matlab is based on Java.
% Therefore, the Psychtoolbox subfolder PsychJava must be added to Matlabs
% static classpath. Normally this is done by the Psychtoolbox installer by
% editing the Matlab file "classpath.txt" (enter which('classpath.txt') to
% find the location of that file). If the installer fails to edit the file
% properly, you'll need to perform that step manually by following the
% instructions of the installer. See 'help PsychJavaTrouble' for more infos
% on this.
%
% KEYSTROKES IN THE BACKGROUND: To detect keypresses made before the
% GetChar call, you must have called "ListenChar" earlier. ListenChar
% redirects keystrokes to the GetChar queue. Calling ListenChar at the
% beginning of your script should cause GetChar to behave identically
% to OS 9 GetChar with respect to background keystroke collection.
%
% KEYSTROKES IN MATLAB WINDOW: By default, all keystrokes are also sent to
% Matlabs window, generating some ugly clutter. You can suppress this by
% calling ListenChar(2), so your Matlab console stays nice and clean. Don't
% forget to call ListenChar(1) or ListenChar(0) though before the end of
% your script. If Matlab returns to its command prompt without reenabling
% keyboard input via ListenChar(0) or ListenChar(1), Matlab will be left
% with a dead keyboard until you press the CTRL+C key combo. This silencing
% of clutter does currently not work in matlab -nojvm mode, or if you use
% GNU/Octave instead of Matlab.
%
% OTHER "when" RETURN ARGUMENT FIELDS: Owing to differences in what
% accessory information the underlying operating systems provides about
% keystrokes, "when' return argument fields differs between operating systems.
% GetChar sets fields for which it returns no value to the value 'Nan'.
%
% See also: ListenChar, CharAvail, FlushEvents, TestGetChar, KbCheck,
% KbWait
% 5/7/96 dgp Wrote this help file.
% 1/22/97 dhb Added comment and pointer to TIMER routines.
% 3/6/97 dhb References to KbWait, KbCheck.
% 7/23/97 dgp It's a character not a keypress.
% 8/2/97 dgp Explain difference between key and character. See KbCheck.
% 2/7/98 dgp Streamlined. Eliminated call to GetKey, since it's now GetChar.mex.
% 3/24/98 dgp Explain backgrounding and meta keys. Don't mention obsolete GetKey and KbHit.
% 3/15/99 xmz Put in some comment for Windows version.
% 3/19/99 dgp Update explanation of backgrounding.
% 3/28/99 dgp Show how to turn off backgrounding.
% 8/19/00 dgp Cosmetic.
% 4/23/02 dgp Fixed GetChar.mex to always quit on command-period.
% 4/27/02 dgp Added optional second return argument.
% 6/1/02 dgp Mention Tick0Secs.
% 9/21/02 dgp Added address field to "when", using C code donated by Tom Busey.
% 7/12/04 awi ****** OS X-specific fork from the OS 9 version *******
% Expanded on explantion in the first paragraph about when
% GetChar waits, when it returns immediatly, what
% it ignores. Retains OS 9-specific comments.
% 1/27/04 awi Issue an error when calling GetChar and suggest KbWait.
% 1/19/05 awi Implemented GetChar on OS X. Added AssertMex for OS 9 and OS X conditional block.
% 7/20/05 awi Wrote OS X documentation section.
% 2/2/06 awi Tested to see if this works when the MATLAB text editing
% window is minimized. It does not.
% 2/22/06 awi Commented out Cocoa wrapper and wrote Java wrapper.
% 3/28/06 awi Detect buffer overflow.
% Handle new double value from .getChar(), was char type.
% Changed "char" return value to "ch" to avoid name conflict with
% built-in MATLAB function "char"
% 6/15/06 awi Added a second return argument.
% Updated built-in help for the Java implementation.
% 6/15/06 awi Added break on CTRL-C
% Added TO DO section and item to detect genuine KeyDown
% events.
% 6/20/06 awi Use AddPsychJavaPath instead of AssertGetCharJava.
% 8/16/06 cgb Now using the new GetChar system which taps straight into
% the java keypress dispatcher.
% 9/18/06 mk GetChar now works on all Matlabs (OS-X, Windows) in JVM
% mode. In -nojvm mode on Windows, it falls back to the old
% Windows DLL ...
%
% 05/31/09 mk Add support for Octave and Matlab in noJVM mode.
% 10/22/12 mk Remove support for legacy Matlab R11 GetCharNoJVM.dll.
% 10/22/12 mk Add support for KbQueue-Based implementation.
% NOTES:
%
% The second return argument from OS 9 PTB looks like this:
% ticks: 5760808
% secs: 1.4681e+05
% address: 2
% mouseButton: 0
% alphaLock: 0
% commandKey: 0
% controlKey: 0
% optionKey: 0
% shiftKey: 0
%
global OSX_JAVA_GETCHAR;
% If no command line argument was passed we'll assume that the user only
% wants to get character data and timing/modifier data.
if nargin == 0
getExtendedData = 1;
getRawCode = 0;
elseif nargin == 1
getRawCode = 0;
end
% Is this Matlab? Is the JVM running? Isn't this Windows Vista or later?
if psychusejava('desktop') && ~IsWinVista
% Java virtual machine and AWT and Desktop are running. Use our Java based
% GetChar.
% Make sure that the GetCharJava class is loaded and registered with
% the java focus manager.
if isempty(OSX_JAVA_GETCHAR)
try
OSX_JAVA_GETCHAR = AssignGetCharJava;
catch %#ok<*CTCH>
error('Could not load Java class GetCharJava! Read ''help PsychJavaTrouble'' for help.');
end
OSX_JAVA_GETCHAR.register;
end
% Make sure the Matlab window has keyboard focus:
if exist('commandwindow') %#ok<EXIST>
% Call builtin implementation:
commandwindow;
end
% Loop until we receive character input.
keepChecking = 1;
while keepChecking
% Check to see if a character is available, and stop looking if
% we've found one.
charValue = OSX_JAVA_GETCHAR.getChar;
keepChecking = charValue == 0;
if keepChecking
drawnow;
end
end
% Throw an error if we've exceeded the buffer size.
if charValue == -1
% Reenable keystroke dispatching to Matlab to leave us with a
% functional Matlab console.
OSX_JAVA_GETCHAR.setRedispatchFlag(0);
error('GetChar buffer overflow. Use "FlushEvents" to clear error');
end
% Get the typed character.
if getRawCode
ch = charValue;
else
ch = char(charValue);
end
% Only fill up the 'when' data stucture if extended data was requested.
if getExtendedData
when.address=nan;
when.mouseButton=nan;
when.alphaLock=nan;
modifiers = OSX_JAVA_GETCHAR.getModifiers;
when.commandKey = modifiers(1);
when.controlKey = modifiers(2);
when.optionKey = modifiers(3);
when.shiftKey = modifiers(4);
rawEventTimeMs = OSX_JAVA_GETCHAR.getEventTime; % result is in units of ms.
when.ticks = nan;
when.secs = JavaTimeToGetSecs(rawEventTimeMs, -1);
else
when = [];
end
return;
end
% Running either on Octave, or on Matlab in No JVM mode or on MS-Vista+:
% If we are on Linux and the keyboard queue is already in use by usercode,
% we can fall back to 'GetMouseHelper' low-level terminal tty magic. The
% only downside is that typed characters will spill into the console, ie.,
% ListenChar(2) suppression is unsupported:
if IsLinux && KbQueueReserve(3, 2, [])
% Loop until we receive character input.
keepChecking = 1;
while keepChecking
% Check to see if a character is available, and stop looking if
% we've found one.
% KeyboardHelper with command code 15 delivers
% id of currently pending characters on stdin:
charValue = PsychHID('KeyboardHelper', -15);
keepChecking = charValue == 0;
if keepChecking
drawnow;
if exist('fflush') %#ok<EXIST>
builtin('fflush', 1);
end
end
end
% Throw an error if we've exceeded the buffer size.
if charValue == -1
% Reenable keystroke display to leave us with a
% functional console.
PsychHID('KeyboardHelper', -11);
error('GetChar buffer overflow. Use "FlushEvents" to clear error');
end
% No extended data in this mode:
when = [];
else
% Use keyboard queue:
% Only need to reserve/create/start queue if we don't have it
% already:
if ~KbQueueReserve(3, 1, [])
% LoadPsychHID is needed on MS-Windows. It no-ops if called redundantly:
LoadPsychHID;
% Try to reserve default keyboard queue for our exclusive use:
if ~KbQueueReserve(1, 1, [])
% Ok, we have to abort here. While the same issue is only worth
% a warning for CharAvail and FlushEvents, it is game over for
% GetChar, as we must not touch a user managed kbqueue, and we
% can't provide any sensible behaviour if we can't do that:
error('Keyboard queue for default keyboard device already in use by KbQueue/KbEvent functions et al. Use of ListenChar/GetChar etc. and keyboard queues is mutually exclusive!');
end
% Got it. Allocate and start it:
PsychHID('KbQueueCreate');
PsychHID('KbQueueStart');
if (IsOSX(1) || (IsOctave && IsGUI))
% Enable keystroke redirection via kbyqueue and pty to bypass
% blockade of onscreen windows:
PsychHID('KeyboardHelper', -14);
end
end
% Queue is running: Poll it for new events we're interested in:
% Loop until we receive character input.
keepChecking = 1;
while keepChecking
% Check to see if a character is available, and stop looking if
% we've found one.
event = PsychHID('KbQueueGetEvent', [], 0.1);
if ~isempty(event) && event.Pressed && (event.CookedKey > 0)
charValue = event.CookedKey;
keepChecking = 0;
else
charValue = 0;
keepChecking = 1;
end
if keepChecking
drawnow;
if exist('fflush') %#ok<EXIST>
builtin('fflush', 1);
end
end
end
% Only fill up the 'when' data stucture if extended data was requested.
if getExtendedData
when.address=nan;
when.mouseButton=nan;
when.alphaLock=nan;
modifiers = [nan, nan, nan, nan];
when.commandKey = modifiers(1);
when.controlKey = modifiers(2);
when.optionKey = modifiers(3);
when.shiftKey = modifiers(4);
when.ticks = nan;
when.secs = event.Time;
else
when = [];
end
end
% Get the typed character.
if getRawCode
ch = charValue;
else
ch = char(charValue);
end
return;
|