HIDLibElement.m   [plain text]

/*
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 2017 Apple Computer, Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#import <Foundation/Foundation.h>
#import <mach/mach_time.h>
#import "HIDLibElement.h"
#import <IOKit/hid/IOHIDLibPrivate.h>

@implementation HIDLibElement

@synthesize elementRef = _element;
@synthesize valueRef = _value;
@synthesize psKey = _psKey;
@synthesize elementStruct = _elementStruct;
@synthesize defaultValueRef = _defaultValue;
@synthesize isConstant = _isConstant;
@synthesize isUpdated = _isUpdated;

- (nullable instancetype)initWithElementRef:(nonnull IOHIDElementRef)elementRef
{
self = [super init];

if (!self) {
return self;
}

CFRetain(elementRef);
_element = elementRef;

return self;
}

- (nullable instancetype)initWithElementStruct:(IOHIDElementStruct *)elementStruct
parent:(IOHIDElementRef)parent
index:(uint32_t)index
{
self = [super init];

if (!self) {
return self;
}

CFDataRef dummyData = CFDataCreateMutable(kCFAllocatorDefault, 1);

bcopy(elementStruct, &_elementStruct, sizeof(IOHIDElementStruct));

_element = _IOHIDElementCreateWithParentAndData(kCFAllocatorDefault,
parent,
dummyData,
&_elementStruct,
index);

CFRelease(dummyData);

if (!_element) {
return nil;
}

return self;
}

- (void)dealloc
{
if (_value) {
CFRelease(_value);
}

if (_defaultValue) {
CFRelease(_defaultValue);
}

if (_element) {
CFRelease(_element);
}
}

- (NSString *)description
{
return [NSString stringWithFormat:@"element: %p type: %d uP: 0x%02x u: 0x%02x cookie: %d val: %ld",
_element, self.type, self.usagePage, self.usage, self.elementCookie, (long)self.integerValue];
}

- (BOOL)isEqualToHIDLibElement:(HIDLibElement *)element {
if (!element) {
return NO;
}

if (self->_element != element->_element) {
return NO;
}

return YES;
}

- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}

if (![object isKindOfClass:[HIDLibElement class]]) {
return NO;
}

return [self isEqualToHIDLibElement:(HIDLibElement *)object];
}

- (IOHIDElementRef)elementRef
{
return _element;
}

- (void)setElementRef:(IOHIDElementRef)elementRef
{
if (_element) {
CFRelease(_element);
}

_element = elementRef;
}

- (IOHIDValueRef)valueRef
{
return _value;
}

-(void)setValueRef:(IOHIDValueRef)valueRef
{

// what if valueRef == _value,
// in that case underline value is already
// released

if (_value == valueRef) {
return;
}

if (_value) {
CFRelease(_value);
_value = NULL;
}

if (valueRef) {
_value = _IOHIDValueCreateWithValue(kCFAllocatorDefault,
valueRef,
_element);
}
}

- (IOHIDValueRef)defaultValueRef
{
return _defaultValue;
}

-(void)setDefaultValueRef:(IOHIDValueRef)defaultValueRef
{
if (_defaultValue == defaultValueRef) {
return;
}

if (_defaultValue) {
CFRelease(_defaultValue);
}

if (defaultValueRef) {
CFRetain(defaultValueRef);
}

_defaultValue = defaultValueRef;
}

- (NSInteger)integerValue
{
return self.valueRef ? IOHIDValueGetIntegerValue(self.valueRef) : 0;
}

- (void)setIntegerValue:(NSInteger)integerValue
{
IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(
kCFAllocatorDefault,
_element,
mach_absolute_time(),
integerValue);
self.valueRef = value;
CFRelease(value);
}

- (nullable NSData *)dataValue
{
return self.valueRef ? [NSData dataWithBytes:(void *)IOHIDValueGetBytePtr(self.valueRef)
length:IOHIDValueGetLength(self.valueRef)] : nil;
}

- (void)setDataValue:(NSData *)dataValue
{
IOHIDValueRef value = IOHIDValueCreateWithBytes(
kCFAllocatorDefault,
_element,
0,
[dataValue bytes],
[dataValue length]);
self.valueRef = value;
CFRelease(value);
}

- (uint64_t)timestamp
{
return self.valueRef ? IOHIDValueGetTimeStamp(self.valueRef) : 0;
}

- (NSInteger)length
{
return _IOHIDElementGetLength(_element);
}

- (uint32_t)elementCookie
{
return (uint32_t)IOHIDElementGetCookie(_element);
}

- (uint32_t)collectionCookie
{
return _elementStruct.parentCookie;
}

- (IOHIDElementType)type
{
return IOHIDElementGetType(_element);
}

- (uint32_t)usage
{
return IOHIDElementGetUsage(_element);
}

- (uint32_t)usagePage
{
return IOHIDElementGetUsagePage(_element);
}

- (uint32_t)unit
{
return IOHIDElementGetUnit(_element);
}

- (uint8_t)unitExponent
{
return IOHIDElementGetUnitExponent(_element);
}

- (uint8_t)reportID
{
return IOHIDElementGetReportID(_element);
}

- (uint32_t)usageMin
{
return _elementStruct.usageMin;
}

- (uint32_t)usageMax
{
return _elementStruct.usageMax;
}

- (IOHIDElementCollectionType)collectionType
{
return IOHIDElementGetCollectionType(_element);
}

@end