This file is indexed.

/usr/share/psychtoolbox-3/PsychTests/GetCharTest.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.

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
function GetCharTest(startAt)
% GetCharTest([startAt])
%
% Test the Psychtoolbox function "GetChar".
%
% For platforms such as OS X where GetCharTest is divided into subtests,
% begin at subtest "startAt" if it is in the allowable range.  Otherwise
% ignore the argument and begin with the first subtest.    
%
% GetCharTest tests GetChar for likely failure modes. It also tests associated
% functions for character events, such as CharAvail, ListenChar and FlushEvents. 

% HISTORY
% 5/31/02 ds   Written by Dan Shima <daniel.shima@vanderbilt.edu>
% 6/1/02  dgp  Polished.
% 6/3/02  dgp  Added 4, above.
% 3/3/06  awi  Added OS X section.
% 6/15/06 awi  Added FlushEvents call after opening onscreen window.  
%               Erases panic keypresses made during l o n g time it takes to open the onscreen window.   
%              Added WaitSecs and FlushEvents to onscreen window test to block keypresses carried over 
%               from previous test.  
% 10/14/06 dhb  Removed OS 9 branch.
% 

% NOTES
%
% 3/4/06 - awi Turned off video synch testing in screen preferences during
% GetCharTest.  For purposes of testing GetChar, we are not concerned with
% video synching. Generaly, PsychTests should be orthogonal. So do not fail the
% GetChar test because we fail the synchtest.
%
% 3/9/06 - awi In section 5 of the test, a better way to break lines would
% be to set breaks at fixed pixel widths, not fixed character widths. We
% use proportially spaced fonts, so fixed-character-width lines give ragged
% line breaks.  

% We test for some common failings of previous implementations of
% GetChar.  The labeling of each testing step is somewhat
% inaccurate because
fprintf('\nGetCharTest tests the Psychtoolbox function "GetChar".\n\n');
query=1;
% Enable character key press listening. We use mode 2, which will
% suppress any output to Matlabs windows.
try
    ListenChar(2);
    FlushEvents('keyDown');
    while query
        fprintf('Proceed with the test [Y/N]? ');
        response=GetChar;
        fprintf([upper(response) '\n']);
        yesFlag=(strcmp(upper(response), 'Y'));
        noFlag=(strcmp(upper(response), 'N'));
        if ~(yesFlag || noFlag)
            fprintf('\nI did not understand your response.  Please press the "Y" or "N" key on your keyboard.\n');
        else
            query=0;
        end
    end
    if ~yesFlag
        fprintf('You chose not to run the test. Bye!\n');
    else
        fprintf('\n');
        fprintf('Proceeding with GetChar test...\n');
        % TEST 1 of 6: CharAvail
        if nargin==0 || (nargin==1 && startAt == 1)
            fprintf('\n');
            fprintf('GetChar test 1 of 7: CharAvail\n');
            fprintf('  CharAvail reports if a keyboard key has been pressed, but without removing keys from the GetChar queue.\n');
            fprintf('  We will test CharAvail by flushing all characters from the GetChar queue, looping until CharAvail reports\n');
            fprintf('  a keypress and then reading that keypress using GetChar.\n');
            fprintf('     Calling "FlushEvents(''keyDown'')" to remove queued keypresses...');
            FlushEvents('keyDown');
            fprintf(' Done.\n');
            fprintf('     Calling "CharAvail" within a loop.  Press a character key to continue...');
            gotChar=0;
            while ~gotChar
                gotChar=CharAvail;
            end
            fprintf(' Detected a character using CharAvail.\n');
            fprintf('     Reading the character with GetChar...');
            c=GetChar;
            fprintf(['You pressed: ' c '\n']);
        end
        % TEST 2 of 6: FlushEvents
        if nargin==0 || (nargin==1 && startAt <= 2)
            fprintf('\n');
            fprintf('GetChar test 2 of 7: FlushEvents\n');
            fprintf('  FlushEvents removes all characters from the GetChar queue.\n');
            fprintf('  We will test FlushEvents by gathering keypresses, flushing them, then checking to see if the queue is empty\n');
            fprintf('  by using CharAvail.\n');
            fprintf('     Calling "FlushEvents(''keyDown'')" to empty the queue before beginning...');
            FlushEvents('keyDown');
            fprintf(' Done.\n');
            fprintf('     Testing that the queue is empty by calling CharAvail... ');
            gotChar=CharAvail;
            if gotChar
                fprintf('\n');
                error('CharAvail detected a character after calling "FlushEvents".');
            else
                fprintf(' Passed.\n');
            end
            fprintf('     Gathering a keypress to occupy the queue:  Please type a character key on your keyboard... ');
            gotChar=0;
            while ~gotChar
                gotChar=CharAvail;
            end
            fprintf(' Done.\n');
            fprintf('     Flushing the keyboard character from the queue by calling "FlushEvents(''keyDown'')"... ');
            FlushEvents('keyDown');
            fprintf(' Done.\n');
            gotChar=CharAvail;
            fprintf('     Testing that the queue is empty by calling CharAvail... ');
            if gotChar
                fprintf('\n');
                error('CharAvail detected a character after calling "FlushEvents".');
            else
                fprintf(' Passed.\n');
            end
        end
        % TEST 3 of 6: ListenChar
        if nargin==0 || (nargin==1 && startAt <= 3)
            fprintf('\n');
            fprintf('GetChar test 3 of 7: ListenChar\n');
            fprintf('  ListenChar directs keyboard input to the GetChar queue.  We will test ListenChar by first.\n');
            fprintf('  directing keyboard input to the MATLAB command window, then redirecting it to the GetChar queue\n');
            fprintf('  using ListenChar, then checking for a character.\n');
            fprintf('     Calling "FlushEvents(''keyDown'')" to empty the queue before beginning...');
            FlushEvents('keyDown');
            fprintf(' Done.\n');
            % Enable keyboard dispatch to Matlab again:
            ListenChar(1);
            fprintf('     Directing keyboard input into the MATLAB Command Window by using the "input" command.\n');
            input('     Hit the <RETURN> key to continue.', 's');
            fprintf('     Directing keyboard input into the GetChar queue by calling "ListenChar"... ');
            ListenChar(2);
            fprintf(' Done.\n');
            fprintf('     Testing that GetChar receives keys.  Press any character key on your keyboard... ');
            FlushEvents('keyDown');
            c=GetChar;
            fprintf(['You pressed: ' c '\n']);
        end
        % TEST 4 of 6: Typing
        if nargin==0 || (nargin==1 && startAt <= 4)
            fprintf('\n');
            fprintf('GetChar test 4 of 7: Typing Test\n');
            fprintf('  Getchar should reliably return characters.  Type and display characters to check for errors.\n');
            fprintf('      Entering the GetChar loop, Use the "Q" key to quit...\n');
            fprintf('\n      ');
            q=0;
            lineAcc=0;
            while ~q
                c=GetChar;
                fprintf(c);
                lineAcc=lineAcc+1;
                if lineAcc == 80
                    fprintf('\n      ');
                    lineAcc=0;
                end
                q=streq('Q',upper(c));
            end
            fprintf('\n');
        end
        % TEST 5 of 6: Compatibility with Fullscreen Windows
        closeSecondWindow=0;
        if nargin==0 || (nargin==1 && startAt <= 5)
            fprintf('\n');
            fprintf('GetChar test 5 of 7: Interoperability with Fullscreen Windows\n');
            fprintf('  Test Using GetChar at the same time fullscreen windows are open.  We will open fullscreen.\n');
            fprintf('  Windows on all screens and then use GetChar to gather and display kepresses.\n');
            % Pause...
            WaitSecs(2);
            % ...Then block any inadvertant carry over from the previous test.  Too much fast typying on that and we can breeze
            % right through this test.
            FlushEvents('keyDown');
            fprintf('      Press any character key to continue.\n');
            GetChar;
            try
                skipTestFlagOld=Screen('Preference','SkipSyncTests');
                suppressAllWarningsFlagOld=Screen('Preference','SuppressAllWarnings');
                Screen('Preference','SkipSyncTests', 2);
                % Warning: Only use SuppressAllWarnings in tests independent of those warnings.
                Screen('Preference','SuppressAllWarnings', 1);
                screenNumbers= Screen('Screens');
                for i=1:length(screenNumbers)
                    screenWindow(i)= Screen('OpenWindow', screenNumbers(i));
                    Screen('FillRect', screenWindow(i), WhiteIndex(screenNumbers(i)));
                    Screen('Flip', screenWindow(i));
                    Screen('FillRect', screenWindow(i), WhiteIndex(screenNumbers(i)));
                end
                if length(screenNumbers) == 2 && closeSecondWindow
                    Screen('Close', screenWindow(2));
                end
                % Draw instructions to the screen.  We will do all our work
                % on Screen 0.  We have opened other onscreen windows only to
                % demonstrate that GetChar works then.
                if ~IsLinux
                    Screen('TextFont', screenWindow(1), 'Times');
                    Screen('TextSize', screenWindow(1), 40);
                end

                Screen('TextColor', screenWindow(1), [0 0 0]);
                Screen('DrawText', screenWindow(1), 'Hello! Welcome to the Fullscreen Window section of GetCharTest.', 100, 100);
                Screen('DrawText', screenWindow(1), 'Press any character key to continue.', 100, 150);
                Screen('Flip', screenWindow(1));
                x=GetChar;
                Screen('FillRect', screenWindow(1), WhiteIndex(screenNumbers(1)));
                Screen('DrawText', screenWindow(1), 'This is the typing test.', 100, 100);
                Screen('DrawText', screenWindow(1), 'Please type on your keyboard. Use the "Q" key to quit.', 100, 150);
                Screen('Flip', screenWindow(1));
                FlushEvents('keyDown');
                charBuffer='';
                stopLoop=0;
                lineBuffer={};
                totalChars=0;
                lineBufferIndex=0;
                startingYPosition=200;
                textHeight=0;
                textYPosition=startingYPosition;
                Screen('TextSize', screenWindow(1), 20);
                charsPerLine=100;
                totalLines=5;
                while ~stopLoop
                    % Get the character
                    c=GetChar;
                    totalChars=totalChars+1;
                    % test for doneness
                    if streq(upper(c), 'Q') || lineBufferIndex > totalLines
                        break;
                    end
                    % break lines
                    charBuffer=[charBuffer c];
                    if length(charBuffer) == charsPerLine
                        lineBufferIndex= lineBufferIndex+1;
                        lineBuffer{lineBufferIndex}= charBuffer;
                        charBuffer='';
                    end
                    % Draw the characters...
                    Screen('FillRect', screenWindow(1), WhiteIndex(screenNumbers(1)));
                    % First draw the instructions
                    %Screen('TextSize', screenWindow(1), 40);
                    Screen('DrawText', screenWindow(1), 'This is the typing test.', 100, 100);
                    Screen('DrawText', screenWindow(1), 'Please type on your keyboard. Use the "Q" key to quit.', 100, 150);
                    Screen('TextSize', screenWindow(1), 20);
                    % then display full lines...
                    textYPosition=startingYPosition;
                    for i=1:lineBufferIndex
                        Screen('DrawText', screenWindow(1), lineBuffer{i}, 100, textYPosition);
                        if  textHeight==0
                            textRect= Screen('TextBounds', screenWindow(1), lineBuffer{i});
                            textHeight= RectHeight(textRect);
                        end
                        textYPosition= floor(textYPosition + textHeight + 0.2 * textHeight);
                    end
                    % then display remainder lines.
                    if length(charBuffer) > 0;
                        %textYPosition= floor(startingYPosition + (i+1) * (textHeight + 0.2 * textHeight));
                        Screen('DrawText', screenWindow(1), charBuffer, 100, textYPosition);
                    end
                    Screen('Flip',  screenWindow(1));
                end
                % Draw the characters...
                Screen('FillRect', screenWindow(1), WhiteIndex(screenNumbers(1)));
                % First draw the instructions
                if ~IsLinux
                    Screen('TextSize', screenWindow(1), 40);
                end
                Screen('DrawText', screenWindow(1), 'End of Typing Test.', 100, 100);
                Screen('TextSize', screenWindow(1), 20);
                Screen('DrawText', screenWindow(1), 'Either you ended the test by typing Q, or you reached the limit of the test.', 100, startingYPosition);
                Screen('Flip', screenWindow(1));
                WaitSecs(4); % In rapid typing the preceeding message vanishes without a pause here.
                FlushEvents('keyDown');
                Screen('DrawText', screenWindow(1), 'Press any character key to continue.', 100, startingYPosition);
                Screen('Flip', screenWindow(1));
                GetChar;
                Screen('CloseAll');
            catch
                Screen('CloseAll');
                Screen('Preference','SkipSyncTests', skipTestFlagOld);
                Screen('Preference','SuppressAllWarnings', suppressAllWarningsFlagOld);
                error(lasterr);
            end
            Screen('Preference','SkipSyncTests', skipTestFlagOld);
            Screen('Preference','SuppressAllWarnings', suppressAllWarningsFlagOld);
            FlushEvents('keyDown');
        end
        % TEST 6 of 6: GetChar during WaitSecs
        if nargin==0 || (nargin==1 && startAt <= 6)
            fprintf('\n');
            fprintf('GetChar test 6 of 7: GetChar during WaitSecs\n');
            fprintf('  Test Using GetChar to gather keypresses during WaitSecs. Unlike KbCheck, GetChar should.\n');
            fprintf('  detect keypresses in the background during WaitSecs.\n');
            fprintf('\n');
            fprintf('  GetChar test is about to call WaitSecs. During execution of WaitSecs, you should type on\n');
            fprintf('  your keyboard.  Press any character key when you are read to begin the test.  \n');
            GetChar;
            fprintf('\n');
            fprintf('  You have ten seconds to type character keys on your keyboard during WaitSecs. Please begin\n');
            fprintf('  typing now!\n');
            FlushEvents('keyDown');
            ListenChar(2);
            WaitSecs(10);
            tChars=[];
            while CharAvail
                tChars=[tChars GetChar];
            end
            FlushEvents('keyDown');
            fprintf(['  You typed ' int2str(length(tChars)) ' characters during WaitSecs\n']);
            fprintf('  The characters which you typed are:\n');
            fprintf(['  ' tChars '\n\n\n']);
        end
        % TEST 7 of 7: Comparing GetChar timing with KbWait timing: Only
        % makes sense with Java-based GetChar, skip test in -nojvm mode.
        if (nargin==0 || (nargin==1 && startAt <= 7))
            fprintf('GetChar test 7 of 7: Comparison of keypress timing reported by KbWait and GetChar\n');
            fprintf('  Timing test: The test will wait five times for a keypress of you. Each time, waiting\n');
            fprintf('  is performed via KbWait. Then the typed character is retrieved via GetChar as well and\n');
            fprintf('  the time stamps reported by KbWait and GetChar are compared to each other. The difference\n');
            fprintf('  between both values will give you a feeling for how much the reported timing is off between\n');
            fprintf('  KbWait and GetChar.\n\n');
            for i=1:5
                fprintf('  Press a character key (a,b,c,d,e,...): ');
                while KbCheck; end;
                FlushEvents('keyDown');
                t1=KbWait;
                [ch, when]=GetChar;
                if isempty(when)
                    break;
                end
                tdelta = 1000 * (t1 - when.secs);
                fprintf('  Pressed %s. Time delta between KbWait and GetChar is %f milliseconds.\n', ch, tdelta);
            end

            fprintf('\n\n  Thanks for typing!\n\n');
        end

        fprintf('\n');
        fprintf('The GetCharTest has reached the end.  Thank you for testing.\n');
        fprintf('\n');
    end
catch
    % This empty catch block makes sure that the following
    % ListenChar(0) command is called in case of error, so Matlab isn't
    % left with a dead keyboard.
end

% Disable listening and flush queue, reenable keyboard dispatching
% to Matlabs windows.
ListenChar(0);

return;