scide: implement selectionLength for openDocument
[supercollider.git] / lang / LangPrimSource / HID_Utilities / HID_Queue_Utilities.c
blobd4b59b3da12e01a68e704796699a063b48a8a90d
1 //
2 // File: HID_Queue_Utilities.c
3 //
4 // Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple")
5 // in consideration of your agreement to the following terms, and your use,
6 // installation, modification or redistribution of this Apple software
7 // constitutes acceptance of these terms. If you do not agree with these
8 // terms, please do not use, install, modify or redistribute this Apple
9 // software.
11 // In consideration of your agreement to abide by the following terms, and
12 // subject to these terms, Apple grants you a personal, non - exclusive
13 // license, under Apple's copyrights in this original Apple software ( the
14 // "Apple Software" ), to use, reproduce, modify and redistribute the Apple
15 // Software, with or without modifications, in source and / or binary forms;
16 // provided that if you redistribute the Apple Software in its entirety and
17 // without modifications, you must retain this notice and the following text
18 // and disclaimers in all such redistributions of the Apple Software. Neither
19 // the name, trademarks, service marks or logos of Apple Inc. may be used to
20 // endorse or promote products derived from the Apple Software without specific
21 // prior written permission from Apple. Except as expressly stated in this
22 // notice, no other rights or licenses, express or implied, are granted by
23 // Apple herein, including but not limited to any patent rights that may be
24 // infringed by your derivative works or by other works in which the Apple
25 // Software may be incorporated.
27 // The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
28 // WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
29 // WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
30 // PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION
31 // ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
33 // IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
34 // CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 // INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
37 // AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
38 // UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR
39 // OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 // Copyright © 2001-2009 Apple Inc. All Rights Reserved.
44 #include "HID_Utilities_External.h"
46 // ==================================
47 // private functions
49 // creates a queue for a device, creates and opens device interface if required
50 static IOReturn HIDCreateQueue( IOHIDDeviceRef inIOHIDDeviceRef )
52 IOReturn result = kIOReturnSuccess;
54 if ( inIOHIDDeviceRef ) {
55 assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
57 // do we already have a queue?
58 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
60 if ( tIOHIDQueueRef ) { // (yes)
61 assert( IOHIDQueueGetTypeID() == CFGetTypeID( tIOHIDQueueRef ) );
62 } else {
63 tIOHIDQueueRef = IOHIDQueueCreate( kCFAllocatorDefault, inIOHIDDeviceRef, kDeviceQueueSize, kIOHIDOptionsTypeNone );
65 if ( tIOHIDQueueRef ) { // did that work
66 HIDReportErrorNum( "Failed to create queue via create", result );
67 } else {
68 result = kIOReturnSuccess;
71 } else {
72 HIDReportErrorNum( "HID device ref does not exist for queue creation", result );
74 return result;
75 } /* HIDCreateQueue */
77 // ---------------------------------
78 // returns true if queue is empty false otherwise
79 // error if no device, empty if no queue
80 static unsigned char HIDIsDeviceQueueEmpty( IOHIDDeviceRef inIOHIDDeviceRef )
82 if ( inIOHIDDeviceRef ) { // need device and queue
83 assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
84 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
85 if ( tIOHIDQueueRef ) {
86 IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement( inIOHIDDeviceRef, kHIDElementTypeIO );
87 while ( tIOHIDElementRef ) {
88 if ( IOHIDQueueContainsElement( tIOHIDQueueRef, tIOHIDElementRef ) ) {
89 return false;
91 tIOHIDElementRef = HIDGetNextDeviceElement( tIOHIDElementRef, kHIDElementTypeIO );
93 } else {
94 HIDReportError( "NULL device passed to HIDIsDeviceQueueEmpty." );
96 } else {
97 HIDReportError( "NULL device passed to HIDIsDeviceQueueEmpty." );
99 return true;
100 } /* HIDIsDeviceQueueEmpty */
102 // ---------------------------------
104 // disposes and releases queue, sets queue to NULL,.
105 // Note: will have no effect if device or queue do not exist
106 static IOReturn HIDDisposeReleaseQueue( IOHIDDeviceRef inIOHIDDeviceRef )
108 IOReturn result = kIOReturnSuccess;
110 if ( inIOHIDDeviceRef ) {
111 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
112 if ( tIOHIDQueueRef ) {
113 // stop queue
114 IOHIDQueueStop( tIOHIDQueueRef );
116 // release the queue
117 CFRelease( tIOHIDQueueRef );
119 } else {
120 HIDReportError( "NULL device passed to HIDDisposeReleaseQueue." );
122 return result;
123 } /* HIDDisposeReleaseQueue */
125 // ==================================
126 // public functions
127 // ----------------------------------
129 // queues specific element, performing any device queue set up required
130 // queue is started and ready to return events on exit from this function
131 int HIDQueueElement( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef )
133 IOReturn result = kIOReturnSuccess;
135 if ( inIOHIDDeviceRef ) {
136 assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
137 if ( inIOHIDElementRef ) {
138 assert( IOHIDElementGetTypeID() == CFGetTypeID( inIOHIDElementRef ) );
139 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
140 if ( !tIOHIDQueueRef ) { // if no queue create queue
141 result = HIDCreateQueue( inIOHIDDeviceRef );
142 if ( kIOReturnSuccess == result ) {
143 tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
146 if ( tIOHIDQueueRef ) {
148 // stop queue
149 IOHIDQueueStop( tIOHIDQueueRef );
151 // queue element
152 if ( !IOHIDQueueContainsElement( tIOHIDQueueRef, inIOHIDElementRef ) ) {
153 IOHIDQueueAddElement( tIOHIDQueueRef, inIOHIDElementRef );
156 // restart queue
157 IOHIDQueueStart( tIOHIDQueueRef );
158 } else {
159 HIDReportError( "No queue for device passed to HIDQueueElement." );
160 if ( kIOReturnSuccess == result ) {
161 result = kIOReturnError;
164 } else {
165 HIDReportError( "NULL element passed to HIDQueueElement." );
166 result = kIOReturnBadArgument;
168 } else {
169 HIDReportError( "NULL device passed to HIDQueueElement." );
170 result = kIOReturnBadArgument;
172 return result;
173 } /* HIDQueueElement */
174 // ---------------------------------
176 // adds all elements to queue, performing any device queue set up required
177 // queue is started and ready to return events on exit from this function
178 int HIDQueueDevice( IOHIDDeviceRef inIOHIDDeviceRef )
180 IOReturn result = kIOReturnSuccess;
182 // error checking
183 if ( !inIOHIDDeviceRef ) {
184 HIDReportError( "Device does not exist, cannot queue device." );
185 return kIOReturnBadArgument;
188 if ( !inIOHIDDeviceRef ) { // must have interface
189 HIDReportError( "Device does not have hid device ref, cannot queue device." );
190 return kIOReturnError;
193 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
194 if ( !tIOHIDQueueRef ) { // if no queue create queue
195 result = HIDCreateQueue( inIOHIDDeviceRef );
196 if ( kIOReturnSuccess == result ) {
197 tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
201 if ( ( kIOReturnSuccess != result ) || ( !tIOHIDQueueRef ) ) {
202 printf("queue NOT created successfully\n");
204 HIDReportErrorNum( "Could not queue device due to problem creating queue.", result );
206 if ( kIOReturnSuccess != result ) {
207 return result;
208 } else {
209 return kIOReturnError;
213 // stop queue
214 IOHIDQueueStop( tIOHIDQueueRef );
216 // queue element
217 IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement( inIOHIDDeviceRef, kHIDElementTypeIO );
218 while ( tIOHIDElementRef ) {
219 if ( !IOHIDQueueContainsElement( tIOHIDQueueRef, tIOHIDElementRef ) ) {
220 IOHIDQueueAddElement( tIOHIDQueueRef, tIOHIDElementRef );
222 tIOHIDElementRef = HIDGetNextDeviceElement( tIOHIDElementRef, kHIDElementTypeIO );
225 // restart queue
226 IOHIDQueueStart( tIOHIDQueueRef );
228 return result;
229 } /* HIDQueueDevice */
231 // ---------------------------------
232 // removes element for queue, if last element in queue will release queue and closes device interface
233 int HIDDequeueElement( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef )
235 IOReturn result = kIOReturnSuccess;
237 if ( inIOHIDDeviceRef ) {
238 assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
239 if ( inIOHIDElementRef ) {
240 assert( IOHIDElementGetTypeID() == CFGetTypeID( inIOHIDElementRef ) );
241 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
242 if ( tIOHIDQueueRef ) {
243 // stop queue
244 IOHIDQueueStop( tIOHIDQueueRef );
246 // de-queue element
247 if ( IOHIDQueueContainsElement( tIOHIDQueueRef, inIOHIDElementRef ) ) {
248 IOHIDQueueRemoveElement( tIOHIDQueueRef, inIOHIDElementRef );
251 // release device queue and close interface if queue empty
252 if ( HIDIsDeviceQueueEmpty( inIOHIDDeviceRef ) ) {
253 result = HIDDisposeReleaseQueue( inIOHIDDeviceRef );
255 if ( kIOReturnSuccess != result ) {
256 HIDReportErrorNum( "Failed to dispose and release queue.", result );
258 } else { // not empty so restart queue
259 IOHIDQueueStart( tIOHIDQueueRef );
261 } else {
262 HIDReportError( "No queue for device passed to HIDDequeueElement." );
263 if ( kIOReturnSuccess == result ) {
264 result = kIOReturnError;
267 } else {
268 HIDReportError( "NULL element passed to HIDDequeueElement." );
269 result = kIOReturnBadArgument;
271 } else {
272 HIDReportError( "NULL device passed to HIDDequeueElement." );
273 result = kIOReturnBadArgument;
275 return result;
276 } /* HIDDequeueElement */
278 // ---------------------------------
279 // completely removes all elements from queue and releases queue and closes device interface
280 // does not release device interfaces, application must call ReleaseHIDDeviceList on exit
281 int HIDDequeueDevice( IOHIDDeviceRef inIOHIDDeviceRef )
284 IOReturn result = kIOReturnSuccess;
286 // error checking
287 if ( !inIOHIDDeviceRef ) {
288 HIDReportError( "Device does not exist, cannot queue device." );
289 return kIOReturnBadArgument;
292 if ( !inIOHIDDeviceRef ) { // must have interface
293 HIDReportError( "Device does not have hid device ref, cannot queue device." );
294 return kIOReturnError;
297 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
299 if ( tIOHIDQueueRef ) {
300 // iterate through elements and if queued, remove
301 IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement( inIOHIDDeviceRef, kHIDElementTypeIO );
302 while ( tIOHIDElementRef ) {
303 // de-queue element
304 if ( IOHIDQueueContainsElement( tIOHIDQueueRef, tIOHIDElementRef ) ) {
305 IOHIDQueueRemoveElement( tIOHIDQueueRef, tIOHIDElementRef );
307 tIOHIDElementRef = HIDGetNextDeviceElement( tIOHIDElementRef, kHIDElementTypeIO );
309 // ensure queue is disposed and released
310 result = HIDDisposeReleaseQueue( inIOHIDDeviceRef );
312 if ( kIOReturnSuccess != result ) {
313 HIDReportErrorNum( "Failed to dispose and release queue.", result );
315 } else {
316 HIDReportError( "No queue for device passed to HIDDequeueElement." );
317 if ( kIOReturnSuccess == result ) {
318 result = kIOReturnError;
321 return result;
322 } /* HIDDequeueDevice */
323 // ---------------------------------
325 // releases all device queues for quit or rebuild (must be called)
326 // does not release device interfaces, application must call ReleaseHIDDeviceList on exit
327 IOReturn HIDReleaseAllDeviceQueues( void )
329 IOReturn result = kIOReturnSuccess;
330 IOHIDDeviceRef tIOHIDDeviceRef = HIDGetFirstDevice();
331 while ( tIOHIDDeviceRef ) {
332 result = HIDDequeueDevice( tIOHIDDeviceRef );
334 if ( kIOReturnSuccess != result ) {
335 HIDReportErrorNum( "Could not dequeue device.", result );
337 tIOHIDDeviceRef = HIDGetNextDevice( tIOHIDDeviceRef );
339 return result;
340 } /* HIDReleaseAllDeviceQueues */
342 // ---------------------------------
343 // Get the next event in the queue for a device
344 // elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice
345 // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
346 // Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition
347 // Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility)
348 unsigned char HIDGetEvent( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef * pIOHIDValueRef )
350 if ( inIOHIDDeviceRef ) {
351 IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
352 if ( tIOHIDQueueRef ) {
353 printf("There is a queue!\n");
354 if ( pIOHIDValueRef ) {
355 *pIOHIDValueRef = IOHIDQueueCopyNextValueWithTimeout( tIOHIDQueueRef, 0.0 );
357 if ( *pIOHIDValueRef ) {
358 return true;
361 } else {
362 printf("There is not a queue!\n");
363 HIDReportError( "Could not get HID event, hid queue reference does not exist." );
365 } else {
366 HIDReportError( "Could not get HID event, device does not exist." );
368 return false; // did not get event
369 } /* HIDGetEvent */