This file is indexed.

/usr/share/psychtoolbox-3/PsychDocumentation/KbQueue.html is in psychtoolbox-3-common 3.0.9+svn2579.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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>KbQueueCheck and KbQueueWait</title>
</head>
<body>
	<h3>Using KbQueueCheck, KbQueueWait and KbTriggerWait</h3>
	<h4>When to use these functions</h4>
	<p>
		The Psychophysics Toolbox includes the functions KbCheck, KbWait, 
		CharAvail and GetChar for responding to keyboard events. These easily
		used functions provide sufficient functionality for many types of task
		design. The functions KbQueueCheck, KbQueueWait and KbTriggerWait
		provide more complex alternatives that may be advantageous under 
		selected circumstances requiring any of the following:
	</p>
	<ul>
		<li>Detection of key presses that are too brief to be reliably
		detected even by the most tightly written KbCheck loop</li>
		
		<li>Detection of keyboard events that take place while other code is
		actively executing</li>
		
		<li>Detection of keyboard events with maximal timing accuracy</li>
		
		<li>Accurate measurement of the duration of keypresses</li>
		
		<li>Detection of only certain keys while ignoring all other keys</li>
	</ul>
	<h4>Overview</h4>
	<p>
		The Psychophysics Toolbox function KbCheck looks to see which keys are
		depressed each time that it is called. In effect, KbCheck answers the
		question "Which keys are pressed right now?". By asking this question
		repetitively in a tight Mablab code loop, it is possible to get a 
		reasonably accurate estimate of the time at which a key was pressed.
		However, if a keypress is very brief, it can take place in between
		successive calls to KbCheck and can potentially be lost. For example,
		the Fiber Optic Response Pad (FORP) manufactured by Current Designs for
		use with functional magnetic resonance imaging (fMRI) transduces a 
		trigger signal from the MRI scanner into an apparent keypress that lasts 
		only 8 msec; such signals are often missed even with the fastest 
		processors. 
	</p>
	<p>
		In contrast to KbCheck, the function GetChar answers the question "What
		characters have been input to allow this function to return?" where it 
		is possible that the relevant characters were input (and released) even
		before GetChar was invoked thanks to an internal queueing mechanism
		(note that a call to KbCheck might therefore miss characters 
		identifiable by a call to GetChar). However, GetChar requires Matlab's 
		Java and is not recommended for situations requiring precision timing 
		because it is slow and because the timebase used by Java can differ 
		substantially from the timebase used by GetSecs (the documentation for 
		GetChar indicates that discrepancies can be tens or even hundreds of 
		miiliseconds).
	</p>
	<p>
		Like GetChar, KbQueueCheck makes use of an internal queue to record
		events asynchronously, but, like KbCheck, it is fast, does not require
		Java, and uses the same timebase as GetSecs, making it suitable for
		high precision timing. Indeed, since the timestamps of keyboard events
		are assigned directly by the operating system, their accuracy does not
		require the KbQueueCheck be called in a tight loop like KbCheck.
	</p>
	<p>
		To use KbQueueCheck, it is first necessary to set up the internal 
		queue. This is accomplished by a call to KbQueueCreate. Only one 
		keyboard device can be used at any given time with this internal queue, 
		so when multiple keyboards are present, the desired keyboard should be 
		specified explicitly. If it is not, the first device is the default 
		(like KbCheck). It is also possible to restrict the keys that are 
		recorded in the queue to some specific set of keys of interest when the 
		queue is created. Once it has been created, a queue can be reused 
		multiple times so long as the keyboard of interest and keys of interest 
		remain unchanged. To change to a different keyboard of interest or set 
		of keys of interest, simply call KbQueueCreate again with the new
		specification. It is not necessary to call KbQueueRelease before a 
		second call to KbQueueCreate, but KbQueueRelease (or 'clear mex') should 
		be called once the queue is no longer needed to release queue-associated 
		resources.
	</p>
	<p>
		Since creation of a queue involves some computational overhead, delivery
		of keyboard events to the queue is not started automatically. This
		allows the queue to be created in advance during a phase that is not
		time critical and then subsequently efficiently started in a phase that
		is potentially time critical. Delivery of events to the queue is started
		by a call to KbQueueStart. Delivery can subsequently be stopped (without
		losing any queued events that have not yet been retrieved) by a call to
		KbQueueStop. 
	</p>
	<p>
		Events can be retrieved by calling KbQueueCheck, which will report about
		new events since the most recent call to KbQueueStart, KbQueueCheck,
		KbQueueFlush or KbQueueWait. Although a call to KbQueueStart should 
		suffice to flush a queue that is not actively receiving events, 
		KbQueueFlush should be used preferentially to flush events from an 
		actively running queue.
	</p>
	<p>
		Analogously to KbWait, the function KbQueueWait can be used to pause
		execution until a keypress has taken place (and unlike KbWait, will 
		respond to very brief events). Like KbWait, KbQueueWait does not 
		directly identify the specific key that was pressed, and it should be 
		kept in mind that the keypress will already have been removed from
		the queue when KbQueueWait returns and its identity therefore cannot be 
		recovered by an immediate call to KbQueueCheck. If the identity of the 
		pressed key is needed, KbQueueCheck should be called directly in a 
		tight loop instead of using KbQueueWait. If only one key is of interest,
		another option is to specify only that key when creating the queue with
		KbQueueCreate.
	</p>
	<p>
		In the specific setting where it is important to recognize a brief
		trigger event consisting of a signal that a specific key has been
		pressed (e.g., in the setting of fMRI where the trigger from the
		scanner may only be present for 8 msec), it is possible to unify the
		functionality of KbQueueCreate, KbQueueStart, KbQueueWait and
		KbQueueRelease into a single command, KbTriggerWait. The trigger key and
		optionally the device number of the keyboard must be specified, and no
		queue created by KbQueueCreate should exist when this convenience 
		function is called. Note that a call to KbTriggerWait involves more 
		short term overhead than a call to KbWait since the a queue must be
		automatically created (and automaticaly destroyed) each time it is 
		called.
	</p>
	
	<h4>Sample Code</h4>
		To detect all keypresses from the default device and when they occurred relative to some start time:<br>
		<pre>
	KbQueueCreate;
	% Perform some other initializations, etc
	startTime=GetSecs;
	KbQueueStart;
	% Do some other computations, display things on screen, play sounds, etc
	[ pressed, firstPress]=KbQueueCheck; % Collect keyboard events since KbQueueStart was invoked
	if pressed
		pressedCodes=find(firstPress);
		for i=1:size(pressedCodes,2)
			fprintf('The %s key was pressed at time %.3f seconds\n', KbName(pressedCodes(i)), firstPress(pressedCodes(i))-startTime);
		end
	else
		fprintf("No key presses were detected\n");
	end
	% Do additional computations, possibly including more calls to KbQueueCheck, etc
	KbQueueRelease;
		</pre>
		
	<hr>
		To detect keypresses involving only the 'r', 'g', 'b' and 'y' keys on the default device:<br>
		<pre>
	keysOfInterest=zeros(1,256);
	keysOfInterest(KbName({'r', 'g', 'b', 'y'}))=1;
	KbQueueCreate(-1, keysOfInterest);
	% Perform some other initializations
	KbQueueStart;
	% Perform some other tasks while key events are being recorded
	[ pressed, firstPress]=KbQueueCheck; % Collect keyboard events since KbQueueStart was invoked
	if pressed
		if firstPress(KbName('r'))
			% Handle press of 'r' key
		end
		if firstPress(KbName('g'))
			% Handle press of 'g' key
		end
		if firstPress(KbName('b'))
			% Handle press of 'b' key
		end
		if firstPress(KbName('y'))
			% Handle press of 'y' key
		end
	end
	% Do additional computations
	KbQueueRelease;
		</pre>
		
	<hr>
		To detect a 't' trigger from an fMRI scanner using a Fiber Optic Response Pad and then process events from the 'r', 'g', 'b' and 'y' keys:<br>
		<pre>
	psychtoolbox_forp_id=-1;
	
	% List of vendor IDs for valid FORP devices:
	vendorIDs = [1240 6171];
    
	Devices = PsychHID('Devices');
	% Loop through all KEYBOARD devices with the vendorID of FORP's vendor:
	for i=1:size(Devices,2)
		if (strcmp(Devices(i).usageName,'Keyboard')|strcmp(Devices(i).usageName,'Keypad')) & ismember(Devices(i).vendorID, vendorIDs)
			psychtoolbox_forp_id=i;
			break;
		end
	end
	
	if psychtoolbox_forp_id==-1;
		error('No FORP-Device detected on your system');
	end
	keysOfInterest=zeros(1,256);
	keysOfInterest(KbName('t'))=1;
	KbQueueCreate(psychtoolbox_forp_id, keysOfInterest);	% First queue
	% Perform other initializations
	KbQueueStart;
	KbQueueWait; % Wait until the 't' key signal is sent
	keysOfInterest=zeros(1,256);
	keysOfInterest(KbName({'r', 'g', 'b', 'y'}))=1;
	KbQueueCreate(psychtoolbox_forp_id, keysOfInterest);	% New queue
	% Perform some other initializations
	KbQueueStart;
	% Perform some other tasks while key events are being recorded
	[ pressed, firstPress]=KbQueueCheck;	% Collect keyboard events since KbQueueStart was invoked
	if pressed
		if firstPress(KbName('r'))
			% Handle press of 'r' key
		end
		if firstPress(KbName('g'))
			% Handle press of 'g' key
		end
		if firstPress(KbName('b'))
			% Handle press of 'b' key
		end
		if firstPress(KbName('y'))
			% Handle press of 'y' key
		end
	end
	% Do additional computations
	KbQueueRelease;
		</pre>
	<hr>
		To detect a 't' trigger from an fMRI scanner via a Fiber Optic Response Pad without creating a persistent queue:
		<pre>
	psychtoolbox_forp_id=-1;
	
	% List of vendor IDs for valid FORP devices:
	vendorIDs = [1240 6171];
    
	Devices = PsychHID('Devices');
	% Loop through all KEYBOARD devices with the vendorID of FORP's vendor:
	for i=1:size(Devices,2)
		if (strcmp(Devices(i).usageName,'Keyboard')|strcmp(Devices(i).usageName,'Keypad')) & ismember(Devices(i).vendorID, vendorIDs)
			psychtoolbox_forp_id=i;
			break;
		end
	end
	
	if psychtoolbox_forp_id==-1;
		error('No FORP-Device detected on your system');
	end
	% Note that KbTriggerWait will not respond to interrupts reliably--
	% if no trigger is generated, you may have to kill Matlab to break out
	% of the call to KbTriggerWait
	KbTriggerWait(KbName('t'), psychtoolbox_forp_id);
	% Trigger has been detected, proceed with other tasks
		</pre>

</body>
</html>