2 File: HID_Queue_Utilities.c
4 Contains: Implementation of the HID queue functions for the HID utilites.
8 Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
10 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
11 ("Apple") in consideration of your agreement to the following terms, and your
12 use, installation, modification or redistribution of this Apple software
13 constitutes acceptance of these terms. If you do not agree with these terms,
14 please do not use, install, modify or redistribute this Apple software.
16 In consideration of your agreement to abide by the following terms, and subject
17 to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
18 copyrights in this original Apple software (the "Apple Software"), to use,
19 reproduce, modify and redistribute the Apple Software, with or without
20 modifications, in source and/or binary forms; provided that if you redistribute
21 the Apple Software in its entirety and without modifications, you must retain
22 this notice and the following text and disclaimers in all such redistributions of
23 the Apple Software. Neither the name, trademarks, service marks or logos of
24 Apple Computer, Inc. may be used to endorse or promote products derived from the
25 Apple Software without specific prior written permission from Apple. Except as
26 expressly stated in this notice, no other rights or licenses, express or implied,
27 are granted by Apple herein, including but not limited to any patent rights that
28 may be infringed by your derivative works or by other works in which the Apple
29 Software may be incorporated.
31 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
32 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
33 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
35 COMBINATION WITH YOUR PRODUCTS.
37 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
38 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
39 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
41 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
42 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
43 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 //#include <IOKit/hid/IOHIDDevice.h>
48 #include "HID_Utilities_Internal.h"
49 #include "HID_Utilities_External.h"
51 // ==================================
52 // compiler directives
53 // ==================================
54 #define USE_ASYNC_EVENTS TRUE
55 #define REPORT_ERRORS FALSE
56 // ==================================
58 #define HIDREPORTERRORNUM(s,n) HIDReportErrorNum(s,n)
59 #define HIDREPORTERROR(s) HIDReportError(s)
61 #define HIDREPORTERRORNUM(s,n) do {} while (false)
62 #define HIDREPORTERROR(s) do {} while (false)
64 // ==================================
66 // ==================================
68 // creates a queue for a device
70 static IOReturn
hid_CreateQueue (pRecDevice pDevice
)
72 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
74 if (HIDIsValidDevice(pDevice
))
76 if (NULL
== pDevice
->queue
) // do we already have a queue
78 if (NULL
!= pDevice
->interface
)
80 pDevice
->queue
= (void *) (*(IOHIDDeviceInterface
**) pDevice
->interface
)->allocQueue (pDevice
->interface
); // alloc queue
83 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->create (pDevice
->queue
, 0, kDeviceQueueSize
); // create actual queue
84 if (kIOReturnSuccess
!= result
)
85 HIDREPORTERRORNUM ("hid_CreateQueue - Failed to create queue via create", result
);
89 HIDREPORTERROR ("hid_CreateQueue - Failed to alloc IOHIDQueueInterface ** via allocQueue");
90 result
= kIOReturnError
; // synthesis error
94 HIDREPORTERRORNUM ("hid_CreateQueue - Device inteface does not exist for queue creation", result
);
98 HIDREPORTERRORNUM ("hid_CreateQueue - Invalid Device", result
);
102 // ---------------------------------
103 // returns true if queue is empty false otherwise
104 // error if no device, empty if no queue
106 static unsigned char hid_IsDeviceQueueEmpty (pRecDevice pDevice
)
108 if (HIDIsValidDevice(pDevice
)) // need valid device
110 if (pDevice
->queue
) // and queue
112 pRecElement pElement
= HIDGetFirstDeviceElement (pDevice
, kHIDElementTypeIO
);
115 if ((*(IOHIDQueueInterface
**) pDevice
->queue
)->hasElement (pDevice
->queue
, pElement
->cookie
))
117 pElement
= HIDGetNextDeviceElement (pElement
, kHIDElementTypeIO
);
121 HIDREPORTERROR ("hid_IsDeviceQueueEmpty - no queue.");
124 HIDREPORTERROR ("hid_IsDeviceQueueEmpty - Invalid device.");
128 // ---------------------------------
129 // disposes and releases queue, sets queue to NULL,.
130 // Note: will have no effect if device or queue do not exist
132 static IOReturn
hid_DisposeReleaseQueue (pRecDevice pDevice
)
134 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
136 if (HIDIsValidDevice(pDevice
)) // need valid device
138 if (pDevice
->queue
) // and queue
141 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->stop (pDevice
->queue
);
142 if (kIOReturnSuccess
!= result
)
143 HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to stop queue.", result
);
145 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->dispose (pDevice
->queue
);
146 if (kIOReturnSuccess
!= result
)
147 HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to dipose queue.", result
);
149 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->Release (pDevice
->queue
);
150 if (kIOReturnSuccess
!= result
)
151 HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to release queue.", result
);
153 pDevice
->queue
= NULL
;
156 HIDREPORTERROR ("hid_DisposeReleaseQueue - no queue.");
159 HIDREPORTERROR ("hid_DisposeReleaseQueue - Invalid device.");
163 // ==================================
166 // ---------------------------------
167 // queues specific element, performing any device queue set up required
168 // queue is started and ready to return events on exit from this function
170 unsigned long HIDQueueElement (pRecDevice pDevice
, pRecElement pElement
)
172 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
174 if (HIDIsValidElement(pDevice
,pElement
))
176 if (NULL
== pDevice
->interface
) // must have interface
178 HIDREPORTERROR ("HIDQueueElement - Device does not have interface.");
179 return kIOReturnError
;
181 if (NULL
== pDevice
->queue
) // if no queue create queue
182 result
= hid_CreateQueue (pDevice
);
183 if ((kIOReturnSuccess
!= result
) || (NULL
== pDevice
->queue
))
185 HIDREPORTERRORNUM ("HIDQueueElement - problem creating queue.", result
);
186 if (kIOReturnSuccess
!= result
)
189 return kIOReturnError
;
193 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->stop (pDevice
->queue
);
194 if (kIOReturnSuccess
!= result
)
195 HIDREPORTERROR ("HIDQueueElement - Failed to stop queue.");
198 if (!(*(IOHIDQueueInterface
**) pDevice
->queue
)->hasElement (pDevice
->queue
, pElement
->cookie
))
200 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->addElement (pDevice
->queue
, pElement
->cookie
, 0);
201 if (kIOReturnSuccess
!= result
)
202 HIDREPORTERROR ("HIDQueueElement - Failed to add Element to queue.");
206 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->start (pDevice
->queue
);
207 if (kIOReturnSuccess
!= result
)
208 HIDREPORTERROR ("HIDQueueElement - Failed to start queue.");
212 HIDREPORTERROR ("HIDQueueElement - Invalid Device and/or element.");
213 return kIOReturnBadArgument
;
219 // ---------------------------------
220 // adds all elements to queue, performing any device queue set up required
221 // queue is started and ready to return events on exit from this function
223 unsigned long HIDQueueDevice (pRecDevice pDevice
)
225 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
226 pRecElement pElement
;
228 if (HIDIsValidDevice(pDevice
))
233 HIDREPORTERROR ("HIDQueueDevice - Device does not exist.");
234 return kIOReturnBadArgument
;
236 if (NULL
== pDevice
->interface
) // must have interface
238 HIDREPORTERROR ("HIDQueueDevice - Device does not have interface.");
239 return kIOReturnError
;
241 if (NULL
== pDevice
->queue
) // if no queue create queue
242 result
= hid_CreateQueue (pDevice
);
243 if ((kIOReturnSuccess
!= result
) || (NULL
== pDevice
->queue
))
245 HIDREPORTERRORNUM ("HIDQueueDevice - problem creating queue.", result
);
246 if (kIOReturnSuccess
!= result
)
249 return kIOReturnError
;
253 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->stop (pDevice
->queue
);
254 if (kIOReturnSuccess
!= result
)
255 HIDREPORTERRORNUM ("HIDQueueDevice - Failed to stop queue.", result
);
258 //¥ pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO);
259 pElement
= HIDGetFirstDeviceElement (pDevice
, kHIDElementTypeInput
| kHIDElementTypeFeature
);
263 if (!(*(IOHIDQueueInterface
**) pDevice
->queue
)->hasElement (pDevice
->queue
, pElement
->cookie
))
265 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->addElement (pDevice
->queue
, pElement
->cookie
, 0);
266 if (kIOReturnSuccess
!= result
)
267 HIDREPORTERRORNUM ("HIDQueueDevice - Failed to add element to queue.", result
);
269 //¥ pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
270 pElement
= HIDGetNextDeviceElement (pElement
, kHIDElementTypeInput
| kHIDElementTypeFeature
);
274 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->start (pDevice
->queue
);
275 if (kIOReturnSuccess
!= result
)
276 HIDREPORTERRORNUM ("HIDQueueDevice - Failed to start queue.", result
);
280 HIDREPORTERROR ("HIDQueueDevice - Invalid device.");
285 // ---------------------------------
286 // removes element for queue, if last element in queue will release queue and closes device interface
288 unsigned long HIDDequeueElement (pRecDevice pDevice
, pRecElement pElement
)
290 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
292 if (HIDIsValidElement(pDevice
,pElement
))
294 if (!pDevice
|| !pElement
)
295 result
= kIOReturnBadArgument
;
298 if ((pDevice
->interface
) && (pDevice
->queue
))
301 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->stop (pDevice
->queue
);
302 if (kIOReturnSuccess
!= result
)
303 HIDREPORTERRORNUM ("HIDDequeueElement - Failed to stop queue.", result
);
305 if ((*(IOHIDQueueInterface
**) pDevice
->queue
)->hasElement (pDevice
->queue
, pElement
->cookie
)) // if has element then remove
307 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->removeElement (pDevice
->queue
, pElement
->cookie
);
308 if (kIOReturnSuccess
!= result
)
309 HIDREPORTERRORNUM ("HIDDequeueElement - Failed to add element to queue", result
);
312 if (hid_IsDeviceQueueEmpty (pDevice
)) // release device queue and close interface if queue empty
314 result
= hid_DisposeReleaseQueue (pDevice
);
315 if (kIOReturnSuccess
!= result
)
316 HIDREPORTERRORNUM ("HIDDequeueElement - Failed to dispose and release queue.", result
);
318 else // not empty so restart queue
320 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->start (pDevice
->queue
);
321 if (kIOReturnSuccess
!= result
)
322 HIDREPORTERRORNUM ("HIDDequeueElement - Failed to start queue.", result
);
327 HIDREPORTERROR ("HIDDequeueElement - No device inteface or queue.");
328 return kIOReturnError
;
333 HIDREPORTERROR ("HIDDequeueElement - Invalid device.");
338 // ---------------------------------
339 // completely removes all elements from queue and releases queue and closes device interface
340 // does not release device interfaces, application must call HIDReleaseDeviceList on exit
342 unsigned long HIDDequeueDevice (pRecDevice pDevice
)
344 IOReturn result
= kIOReturnSuccess
;
346 if (HIDIsValidDevice(pDevice
))
348 if ((pDevice
->interface
) && (pDevice
->queue
))
350 // iterate through elements and if queued, remove
351 pRecElement pElement
= HIDGetFirstDeviceElement (pDevice
, kHIDElementTypeIO
);
354 if ((*(IOHIDQueueInterface
**) pDevice
->queue
)->hasElement (pDevice
->queue
, pElement
->cookie
))
356 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->removeElement (pDevice
->queue
, pElement
->cookie
);
357 if (kIOReturnSuccess
!= result
)
358 HIDREPORTERRORNUM ("HIDDequeueDevice - Failed to remove element from queue.", result
);
360 pElement
= HIDGetNextDeviceElement (pElement
, kHIDElementTypeIO
);
363 // ensure queue is disposed and released
364 // interface will be closed and released on call to HIDReleaseDeviceList
365 result
= hid_DisposeReleaseQueue (pDevice
);
366 if (kIOReturnSuccess
!= result
)
367 HIDREPORTERRORNUM ("removeElement - Failed to dispose and release queue.", result
);
369 else if (NULL
!= pDevice
->queueRunLoopSource
)
371 if (CFRunLoopContainsSource(CFRunLoopGetCurrent(), pDevice
->queueRunLoopSource
, kCFRunLoopDefaultMode
))
372 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pDevice
->queueRunLoopSource
, kCFRunLoopDefaultMode
);
373 CFRelease(pDevice
->queueRunLoopSource
);
374 pDevice
->queueRunLoopSource
= NULL
;
376 #endif USE_ASYNC_EVENTS
380 HIDREPORTERROR ("HIDDequeueDevice - Invalid device.");
381 result
= kIOReturnBadArgument
;
386 // ---------------------------------
387 // releases all device queues for quit or rebuild (must be called)
388 // does not release device interfaces, application must call HIDReleaseDeviceList on exit
390 unsigned long HIDReleaseAllDeviceQueues (void)
392 IOReturn result
= kIOReturnBadArgument
;
393 pRecDevice pDevice
= HIDGetFirstDevice ();
397 result
= HIDDequeueDevice (pDevice
);
398 if (kIOReturnSuccess
!= result
)
399 HIDREPORTERRORNUM ("HIDReleaseAllDeviceQueues - Could not dequeue device.", result
);
400 pDevice
= HIDGetNextDevice (pDevice
);
405 // ---------------------------------
406 // Closes and releases interface to device, should be done prior to exting application
407 // Note: will have no affect if device or interface do not exist
408 // application will "own" the device if interface is not closed
409 // (device may have to be plug and re-plugged in different location to get it working again without a restart)
411 unsigned long HIDCloseReleaseInterface (pRecDevice pDevice
)
413 IOReturn result
= kIOReturnSuccess
;
415 if (HIDIsValidDevice(pDevice
) && (NULL
!= pDevice
->interface
))
417 // close the interface
418 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->close (pDevice
->interface
);
419 if (kIOReturnNotOpen
== result
)
421 // do nothing as device was not opened, thus can't be closed
423 else if (kIOReturnSuccess
!= result
)
424 HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to close IOHIDDeviceInterface.", result
);
425 //release the interface
426 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->Release (pDevice
->interface
);
427 if (kIOReturnSuccess
!= result
)
428 HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to release interface.", result
);
429 pDevice
->interface
= NULL
;
434 // ---------------------------------
435 // Get the next event in the queue for a device
436 // elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice
437 // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
438 // Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition
439 // Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility)
441 unsigned char HIDGetEvent (pRecDevice pDevice
, void * pHIDEvent
)
443 IOReturn result
= kIOReturnBadArgument
;
444 AbsoluteTime zeroTime
= {0,0};
446 if (HIDIsValidDevice(pDevice
))
450 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->getNextEvent (pDevice
->queue
, (IOHIDEventStruct
*)pHIDEvent
, zeroTime
, 0);
451 if (kIOReturnUnderrun
== result
)
452 return false; // no events in queue not an error per say
453 else if (kIOReturnSuccess
!= result
) // actual error versus just an empty queue
454 HIDREPORTERRORNUM ("HIDGetEvent - Could not get HID event via getNextEvent.", result
);
459 HIDREPORTERROR ("HIDGetEvent - queue does not exist.");
462 HIDREPORTERROR ("HIDGetEvent - invalid device.");
464 return false; // did not get event
467 // ---------------------------------
468 // returns current value for element, polling element
469 // will return 0 on error conditions which should be accounted for by application
471 long HIDGetElementValue (pRecDevice pDevice
, pRecElement pElement
)
473 IOReturn result
= kIOReturnBadArgument
;
474 IOHIDEventStruct hidEvent
;
477 hidEvent
.longValueSize
= 0;
478 hidEvent
.longValue
= nil
;
480 if (HIDIsValidElement(pDevice
, pElement
))
482 if (NULL
!= pDevice
->interface
)
484 // ++ NOTE: If the element type is feature then use queryElementValue instead of getElementValue
485 if (kIOHIDElementTypeFeature
== pElement
->type
)
487 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->queryElementValue (pDevice
->interface
, pElement
->cookie
, &hidEvent
,0,NULL
,NULL
,NULL
);
488 if (kIOReturnUnsupported
== result
) // unless it's unsuported.
489 goto try_getElementValue
;
490 else if (kIOReturnSuccess
!= result
)
491 HIDREPORTERRORNUM ("HIDGetElementValue - Could not get HID element value via queryElementValue.", result
);
493 else if (pElement
->type
<= kIOHIDElementTypeInput_ScanCodes
)
496 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->getElementValue (pDevice
->interface
, pElement
->cookie
, &hidEvent
);
497 if (kIOReturnSuccess
!= result
)
498 HIDREPORTERRORNUM ("HIDGetElementValue - Could not get HID element value via getElementValue.", result
);
500 // on 10.0.x this returns the incorrect result for negative ranges, so fix it!!!
501 // this is not required on Mac OS X 10.1+
502 if ((pElement
->min
< 0) && (hidEvent
.value
> pElement
->max
)) // assume range problem
503 hidEvent
.value
= hidEvent
.value
+ pElement
->min
- pElement
->max
- 1;
506 HIDREPORTERROR ("HIDGetElementValue - no interface for device.");
509 HIDREPORTERROR ("HIDGetElementValue - invalid device and/or element.");
511 // record min and max for auto scale and auto ...
512 if (hidEvent
.value
< pElement
->calMin
)
513 pElement
->calMin
= hidEvent
.value
;
514 if (hidEvent
.value
> pElement
->calMax
)
515 pElement
->calMax
= hidEvent
.value
;
518 return hidEvent
.value
;
521 // ---------------------------------
522 // Set an elements value
523 // NOTE: This should only be used when a single element of a report needs to be sent.
524 // If multiple elements are to be send then transactions should be used.
526 long HIDSetElementValue (pRecDevice pDevice
, pRecElement pElement
,void* pIOHIDEvent
)
528 IOHIDEventStruct
* pMyIOHIDEvent
= (IOHIDEventStruct
*) pIOHIDEvent
;
529 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
531 if (HIDIsValidElement(pDevice
, pElement
))
533 if (NULL
!= pDevice
->interface
)
535 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->setElementValue (pDevice
->interface
, pElement
->cookie
, pMyIOHIDEvent
, -1, nil
, nil
, nil
);
536 if (kIOReturnSuccess
!= result
)
537 HIDREPORTERRORNUM ("HIDSetElementValue - Could not set HID element value via setElementValue.", result
);
540 HIDREPORTERROR ("HIDSetElementValue - no interface for device.");
543 HIDREPORTERROR ("HIDSetElementValue - invalid device and/or element.");
548 // ---------------------------------
549 // Set a callback to be called when a queue goes from empty to non-empty
550 long HIDSetQueueCallback (pRecDevice pDevice
, IOHIDCallbackFunction callback
)
552 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
554 if (HIDIsValidDevice(pDevice
))
557 // if we don't have a queue runloop sourceÉ
558 if (NULL
== pDevice
->queueRunLoopSource
)
561 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->createAsyncEventSource((void *) pDevice
->queue
,
562 (CFRunLoopSourceRef
*) &pDevice
->queueRunLoopSource
);
563 if (kIOReturnSuccess
!= result
)
564 HIDREPORTERRORNUM ("HIDSetQueueCallback - Failed to createAsyncEventSource error: ", result
);
566 // if we have one nowÉ
567 if (NULL
!= pDevice
->queueRunLoopSource
)
569 // and it's not already attached to our runloopÉ
570 if (!CFRunLoopContainsSource(CFRunLoopGetCurrent(), pDevice
->queueRunLoopSource
, kCFRunLoopDefaultMode
))
571 // then attach it now.
572 CFRunLoopAddSource(CFRunLoopGetCurrent(), pDevice
->queueRunLoopSource
, kCFRunLoopDefaultMode
);
575 // now install our callback
576 result
= (*(IOHIDQueueInterface
**) pDevice
->queue
)->setEventCallout(pDevice
->queue
, callback
, pDevice
, pDevice
);
577 if (kIOReturnSuccess
!= result
)
578 HIDREPORTERRORNUM ("HIDSetQueueCallback - Could not set HID queue callback via setEventCallout.", result
);
579 #endif USE_ASYNC_EVENTS
582 HIDREPORTERROR ("HIDSetQueueCallback - invalid device and/or element.");
587 // ---------------------------------
588 // Get a report from a device
589 long HIDGetReport (pRecDevice pDevice
,const IOHIDReportType reportType
, const UInt32 reportID
, void* reportBuffer
, UInt32
* reportBufferSize
)
591 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
593 if (HIDIsValidDevice(pDevice
))
595 if (NULL
!= pDevice
->interface
)
597 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->getReport (pDevice
->interface
, reportType
, reportID
, reportBuffer
, reportBufferSize
, -1, nil
, nil
, nil
);
598 if (kIOReturnSuccess
!= result
)
599 HIDREPORTERRORNUM ("HIDGetReport - Could not getReport, error: ", result
);
602 HIDREPORTERROR ("HIDGetReport - no interface for device.");
605 HIDREPORTERROR ("HIDGetReport - invalid device.");
610 // ---------------------------------
611 // Send a report to a device
612 long HIDSetReport (pRecDevice pDevice
,const IOHIDReportType reportType
, const UInt32 reportID
, void* reportBuffer
, const UInt32 reportBufferSize
)
614 IOReturn result
= kIOReturnError
; // assume failure (pessimist!)
616 if (HIDIsValidDevice(pDevice
))
618 if (NULL
!= pDevice
->interface
)
620 result
= (*(IOHIDDeviceInterface
**) pDevice
->interface
)->setReport (pDevice
->interface
, reportType
, reportID
, reportBuffer
, reportBufferSize
, -1, nil
, nil
, nil
);
621 if (kIOReturnSuccess
!= result
)
622 HIDREPORTERRORNUM ("HIDGetReport - Could not setReport; error: ", result
);
625 HIDREPORTERROR ("HIDGetReport - no interface for device.");
628 HIDREPORTERROR ("HIDGetReport - invalid device.");