File: KbQueueCreate.m

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (216 lines) | stat: -rw-r--r-- 10,262 bytes parent folder | download
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
function KbQueueCreate(deviceNumber, keyList, numValuators, numSlots, flags, win)
% KbQueueCreate([deviceNumber][, keyList][, numValuators=0][, numSlots=10000][, flags=0][, windowHandle=0])
%
% The routines KbQueueCreate, KbQueueStart, KbQueueStop, KbQueueCheck
%  KbQueueWait, KbQueueFlush and KbQueueRelease provide replacements for
%  KbCheck and KbWait, providing the following advantages:
%
%     1) Brief key presses that would be missed by KbCheck or KbWait
%        are reliably detected
%     2) The times of key presses are recorded more accurately
%     3) The times of key releases are also recorded
%
% Limitations:
%
%     1) If a key is pressed multiple times before KbQueueCheck is called,
%        only the times of the first and last presses and releases of that
%        key can be recovered (this has no effect on other keys)
%     2) If many keys are pressed very quickly in succession on OSX, it is
%        at least theoretically possible for the queue to fill more quickly
%        than it can be emptied, losing key events temporarily while filled
%        to capacity. The queue holds up to thirty events, and events are
%        constantly being removed from the queue and processed, so this is
%        unlikely to be a problem in actual use.
%
%  The deviceNumber of a HID input device can be specified as 'deviceNumber'.
%  Allowable devices are "keyboard like" devices, e.g., Keyboards, Keypads,
%  Mouse, Joystick, Gamepad, Touchpad, etc. - Stuff that has buttons or keys
%  to press. This way a mouse or joysticks buttons can be used as response
%  devices, ignoring mouse movements etc. If deviceNumber is not specified, the first 
%  device is the default (like KbCheck). If KbQueueCreate has not been called 
%  first, the other routines will generate an error message. Likewise, if 
%  KbQueueRelease has been called more recently than KbQueueCreate, the other 
%  routines will generate error messages.
%
% It is acceptable to call KbQueueCreate at any time (e.g., to switch to a new
%  device or to change the list of queued keys) without calling KbQueueRelease.
%
%  KbQueueCreate([deviceNumber][, keyList][, numValuators=0][, numSlots=10000][, flags=0][, windowHandle=0])
%      Creates the queue for the specified (or default) device number
%      If the device number is less than zero, the default device is used.
%
%      'keyList' is an optional 256-length vector of doubles (not logicals)
%      with each element corresponding to a particular key (use KbName
%      to map between keys and their positions). If the double value
%      corresponding to a particular key is zero, events for that key
%      are not added to the queue and will not be reported.
%
%      'numValuators' is an optional maximum number of additional values to report.
%      It defaults to zero. For values greater than zero, if the selected type
%      of input device supports this, and if the operating system supports this,
%      additional info will be recorded. For pointing devices like mice, the mouse
%      position may be reported, for joysticks the state of their various axis, etc.
%      For mouse/joystick/pointing device position reporting numValuators must be
%      at least 2. On touch devices, a value of 2 treats them like a mouse, a value
%      >= 4 treats them as touchscreen. However, for touch devices there are separate
%      functions like TouchQueueCreate, TouchEventGet etc. for convenient handling.
%      See "help KbEventGet" for how to retrieve potential additionally recorded
%      information.
%
%      'numSlots' defines how many events the event buffer can store. If a script
%      does not periodically remove events via KbEventGet() or KbEventFlush(), the
%      buffer will fill up, and once 'numSlots' elements are stored, it will stop
%      recording new events. 10000 elements capacity is the default, which may be
%      too little if you use 'numValuators' > 0 to store dynamic (motion) data like
%      mouse movements or touchscreen input, which can be generated at rates of
%      multiple hundred events per second of data collection.
%
%      'flags' defines special modes of operation for the queue. These are OS
%      specific, see "PsychHID KbQueueCreate?" for an up to date list of supported
%      flags. In general, you don't need these.
%
%      'windowHandle' defines the optional onscreen window handle of an associated
%      onscreen window. By default, input is taken for all windows and screens.
%      This argument is silently ignored on systems other than Linux/X11 at the moment.
%
%      No events are delivered to the queue until KbQueueStart or 
%      KbQueueWait is called.
%      KbQueueCreate can be called again at any time. The function can also
%      treat other HID devices with buttons or keys as if they are
%      keyboards. E.g., it can also record button state of a mouse, a
%      joystick or a gamepad.
%
%  KbQueueStart([deviceNumber])
%      Starts delivering keyboard events from the specified device to the 
%      queue.
%
%  KbQueueStop([deviceNumber])
%      Stops delivery of new keyboard events from the specified device to 
%      the queue.
%      Data regarding events already queued is not cleared and can be 
%      recovered by KbQueueCheck
%
% [pressed, firstPress, firstRelease, lastPress, lastRelease]=
%   KbQueueCheck([deviceNumber])
%      Obtains data about keypresses on the specified device since the 
%      most recent call to this routine, KbQueueStart, KbQueueWait
%      Clears all scored events, but unscored events that are still being
%      processed may remain in the queue
%
%      pressed: a boolean indicating whether a key has been pressed
%
%      firstPress: an array indicating the time that each key was first
%        pressed since the most recent call to KbQueueCheck or KbQueueStart
%
%      firstRelease: an array indicating the time that each key was first
%        released since the most recent call to KbQueueCheck or KbQueueStart
%
%      lastPress: an array indicating the most recent time that each key was
%        pressed since the most recent call to KbQueueCheck or KbQueueStart
%
%      lastRelease: an array indicating the most recent time that each key
%         was released since the most recent call to KbQueueCheck or 
%         KbQueueStart
%
%     For firstPress, firstRelease, lastPress and lastRelease, a time value
%       of zero indicates that no event for the corresponding key was
%       detected since the most recent call to KbQueueCheck or KbQueueStart
%
%     To identify specific keys, use KbName (e.g., KbName(firstPress)) to
%       generate a list of the keys for which the events occurred
%
%     For compatibility with KbCheck, any key codes stored in
%     ptb_kbcheck_disabledKeys (see "help DisableKeysForKbCheck"), will
%     not cause pressed to return as true and will be zeroed out in the
%     returned arrays. However, a better alternative is to specify a
%     keyList argument to KbQueueCreate. 
%
% secs=KbQueueWait([deviceNumber])
%      Waits for any key to be pressed and returns the time of the press.
%
%      KbQueueFlush should be called immediately prior to this function
%      (unless the queue has just been created and started) to clear any 
%      prior events.
%
%      Note that this command will not respond to any keys that were 
%      inactivated by using the keyList argument to KbQueueCreate.
%
%      Since KbQueueWait is implemented as a looping call to
%      KbQueueCheck, it will not respond to any key codes stored in
%      the global variable ptb_kbcheck_disabledKeys
%      (see "help DisableKeysForKbCheck")
%
% KbQueueFlush([deviceNumber])
%      Removes all unprocessed events from the queue and zeros out any
%      already scored events.
%
% KbQueueRelease([deviceNumber])
%      Releases queue-associated resources; once called, KbQueueCreate
%      must be invoked before using any of the other routines
%
%      This routine is called automatically at clean-up (e.g., when 
%      'clear mex' is invoked and can be omitted expense of keeping 
%      memory allocated and an additional thread running unnecessarily
%
% Note that any keyboard typing used to invoke KbQueue commands will be
% recorded. This would include the release of the carriage return used
% to execute KbQueueStart and the keys pressed and released to invoke 
% KbQueueCheck
% _________________________________________________________________________
%
% See also: KbQueueCreate, KbQueueStart, KbQueueStop, KbQueueCheck,
%           KbQueueWait, KbQueueFlush, KbQueueRelease

% 8/19/07    rpw  Wrote it.
% 8/23/07    rpw  Modifications to add KbQueueFlush

persistent macosxrecent;

if nargin < 1
  deviceNumber = [];
end

% Try to reserve keyboard queue for 'deviceNumber' for our exclusive use:
if ~KbQueueReserve(1, 2, deviceNumber)
  if isempty(deviceNumber)
      deviceNumber = NaN;
  end
  error('Keyboard queue for device %i already in use by GetChar() et al. Use of GetChar/CharAvail/FlushEvents and keyboard queues is mutually exclusive!', deviceNumber);
end

if isempty(macosxrecent)
  macosxrecent = IsOSX;
  LoadPsychHID;
end

if nargin >= 6
  if ~isempty(win)
    % Onscreen window handle given. Validate and map to windowing system handle:
    if Screen('WindowKind', win) == 1 
      % Onscreen window handle of open onscreen window: Map to winsys handle:
      winfo = Screen('GetWindowInfo', win);
      win = winfo.SysWindowHandle;
    elseif ismember(win, Screen('Screens'))
      % screenid given: Pass in as X-Screen id + 1:
      win = uint64(win + 1);
    end
  end
end

if nargin == 6
  PsychHID('KbQueueCreate', deviceNumber, keyList, numValuators, numSlots, flags, win);
elseif nargin == 5
  PsychHID('KbQueueCreate', deviceNumber, keyList, numValuators, numSlots, flags);
elseif nargin == 4
  PsychHID('KbQueueCreate', deviceNumber, keyList, numValuators, numSlots);
elseif nargin == 3
  PsychHID('KbQueueCreate', deviceNumber, keyList, numValuators);
elseif nargin == 2
  PsychHID('KbQueueCreate', deviceNumber, keyList);
elseif nargin == 1
  PsychHID('KbQueueCreate', deviceNumber);
elseif nargin == 0
  PsychHID('KbQueueCreate');
elseif nargin > 4
  error('Too many arguments supplied to KbQueueCreate'); 
end