From a154eb553610ae5067a84353fb783f160c79084c Mon Sep 17 00:00:00 2001 From: Lysann Schlegel Date: Sat, 10 Nov 2012 17:17:37 +0100 Subject: [PATCH] move find implementation for mac to different file; refactor a bit --- src/CMakeLists.txt | 8 +- src/os_mac.m | 185 ++-------------------------------- src/os_mac/os_mac.h | 66 ++++++++++++ src/os_mac/os_mac_find.m | 212 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+), 179 deletions(-) create mode 100644 src/os_mac/os_mac.h create mode 100644 src/os_mac/os_mac_find.m diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0231444..7906b76 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,10 +30,14 @@ if(WIN32) list(APPEND SOURCES os_win.c) set(CMAKE_DEBUG_POSTFIX _debug) elseif(APPLE) - list(APPEND SOURCES os_mac.m) + set(MAC_SOURCES + os_mac.m + os_mac/os_mac.h + os_mac/os_mac_find.m) + list(APPEND SOURCES ${MAC_SOURCES}) # make sure we use the gcc for Objective-C files as well so that the # sysroot and deployment target arguments are correctly passed to the compiler - SET_SOURCE_FILES_PROPERTIES(os_mac.m PROPERTIES LANGUAGE C) + SET_SOURCE_FILES_PROPERTIES(${MAC_SOURCES} PROPERTIES LANGUAGE C) else() list(APPEND SOURCES os_nix.c) endif() diff --git a/src/os_mac.m b/src/os_mac.m index d4afdd8..355f125 100644 --- a/src/os_mac.m +++ b/src/os_mac.m @@ -33,6 +33,8 @@ #ifdef __APPLE__ +#import "os_mac/os_mac.h" + #import "io.h" #import "events.h" #import "os.h" @@ -46,181 +48,8 @@ #import -#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 -#define WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE 1 -#else -#define WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE 0 -#endif - - -#pragma mark - -#pragma mark wiiuse_os_find - -@interface WiiuseDeviceInquiry : NSObject { - wiimote** wiimotes; - NSUInteger maxDevices; - int timeout; - - BOOL _running; - NSUInteger _foundDevices; - BOOL _inquiryComplete; -} - -- (id) initWithMemory:(wiimote**)wiimotes maxDevices:(int)maxDevices timeout:(int)timeout; -- (int) run; - -@end - -@implementation WiiuseDeviceInquiry - -- (id) initWithMemory:(wiimote**)wiimotes_ maxDevices:(int)maxDevices_ timeout:(int)timeout_ { - self = [super init]; - if(self) { - wiimotes = wiimotes_; - maxDevices = maxDevices_; - timeout = timeout_; - - _running = NO; - } - return self; -} - -// creates and starts inquiry. the returned object is in the current autorelease pool. -- (IOBluetoothDeviceInquiry*) start { - - // reset state variables - _foundDevices = 0; - _inquiryComplete = NO; - - // create inquiry - IOBluetoothDeviceInquiry* inquiry = [IOBluetoothDeviceInquiry inquiryWithDelegate: self]; - - // refine search & set timeout - [inquiry setSearchCriteria:kBluetoothServiceClassMajorAny - majorDeviceClass:WM_DEV_MAJOR_CLASS - minorDeviceClass:WM_DEV_MINOR_CLASS]; - [inquiry setUpdateNewDeviceNames: NO]; - if(timeout > 0) - [inquiry setInquiryLength:timeout]; - - // start inquiry - IOReturn status = [inquiry start]; - if (status != kIOReturnSuccess) { - WIIUSE_ERROR("Unable to start bluetooth device inquiry."); - if(![inquiry stop]) { - WIIUSE_ERROR("Unable to stop bluetooth device inquiry."); - } else { - WIIUSE_DEBUG("Bluetooth device inquiry stopped."); - } - return nil; - } - - return inquiry; -} - -- (void) wait { - // wait for the inquiry to complete - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - while(!_inquiryComplete && - [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) { - // no-op - } -} - -- (NSUInteger) collectResultsOf: (IOBluetoothDeviceInquiry*) inquiry { - // read found device information - NSArray* devices = [inquiry foundDevices]; - for(NSUInteger i = 0; i < [devices count]; i++) { - IOBluetoothDevice* device = [devices objectAtIndex:i]; -#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE - IOBluetoothDeviceRef deviceRef = (IOBluetoothDeviceRef)device; -#else - IOBluetoothDeviceRef deviceRef = [device getDeviceRef]; -#endif - - // save the device in the wiimote structure - wiimotes[i]->device = deviceRef; - [device retain]; // must retain it for later access through its ref - - // mark as found - WIIMOTE_ENABLE_STATE(wiimotes[i], WIIMOTE_STATE_DEV_FOUND); - NSString* address = IOBluetoothNSStringFromDeviceAddress([device getAddress]); - const char* address_str = [address cStringUsingEncoding:NSMacOSRomanStringEncoding]; - WIIUSE_INFO("Found Wiimote (%s) [id %i]", address_str, wiimotes[i]->unid); - } - - return [devices count]; -} - -- (int) run { - int result = -1; - - if(maxDevices == 0) { - result = 0; - } else if(!_running) { - _running = YES; - - if (![IOBluetoothHostController defaultController]) { - WIIUSE_ERROR("Unable to find any bluetooth receiver on your host."); - } else { - IOBluetoothDeviceInquiry* inquiry = [self start]; - if(inquiry) { - [self wait]; - result = [self collectResultsOf: inquiry]; - WIIUSE_INFO("Found %i Wiimote device(s).", result); - } - } - - _running = NO; - } else { // if(_running) - WIIUSE_ERROR("Device inquiry already running - won't start it again."); - } - - return result; -} - -- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) inquiry device:(IOBluetoothDevice *) device { - - WIIUSE_DEBUG("Found a wiimote"); - - _foundDevices++; - if(_foundDevices >= maxDevices) { - // reached maximum number of devices - if(![inquiry stop]) - WIIUSE_ERROR("Unable to stop bluetooth device inquiry."); - _inquiryComplete = YES; - } -} - -- (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry*) inquiry error:(IOReturn) error aborted:(BOOL) aborted -{ - WIIUSE_DEBUG("Inquiry complete, error=%i, aborted=%s", error, aborted ? "YES" : "NO"); - - // mark completion - _inquiryComplete = YES; - - // print error message if we stop due to an error - if ((error != kIOReturnSuccess) && !aborted) { - WIIUSE_ERROR("Bluetooth device inquiry not completed due to unexpected errors. Try increasing the timeout."); - } -} - -@end - -int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { - int result; - - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - WiiuseDeviceInquiry* inquiry = [[WiiuseDeviceInquiry alloc] initWithMemory:wm maxDevices:max_wiimotes timeout:timeout]; - result = [inquiry run]; - [inquiry release]; - - [pool drain]; - return result; -} - #pragma mark - +#pragma mark connect, disconnect int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) { return 0; @@ -231,6 +60,7 @@ void wiiuse_os_disconnect(struct wiimote_t* wm) { } #pragma mark - +#pragma mark poll, read, write int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { int i; @@ -253,14 +83,15 @@ int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len) { return 0; } -#pragma mark - +#pragma mark platform fields void wiiuse_init_platform_fields(struct wiimote_t* wm) { - + wm->device = NULL; } void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { - + [WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(wm->device) release]; + wm->device = NULL; } #endif // __APPLE__ diff --git a/src/os_mac/os_mac.h b/src/os_mac/os_mac.h new file mode 100644 index 0000000..abe875c --- /dev/null +++ b/src/os_mac/os_mac.h @@ -0,0 +1,66 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles device I/O for Mac OS X. + */ + +#ifdef __APPLE__ + + +#import + + +#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 +#define WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE 1 +#else +#define WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE 0 +#endif + + +// WIIUSE_IOBluetoothDevice_to_IOBluetoothDeviceRef +#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE +#define WIIUSE_IOBluetoothDevice_to_IOBluetoothDeviceRef(device) \ + ((IOBluetoothDeviceRef) (device)) +#else +#define WIIUSE_IOBluetoothDevice_to_IOBluetoothDeviceRef(device) \ + [(device) getDeviceRef] +#endif + +// WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice +#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE +#define WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(ref) \ + ((IOBluetoothDevice*) (ref)) +#else +#define WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(ref) \ + [IOBluetoothDevice withDeviceRef: (ref)] +#endif + + +#endif // __APPLE__ diff --git a/src/os_mac/os_mac_find.m b/src/os_mac/os_mac_find.m new file mode 100644 index 0000000..200fb64 --- /dev/null +++ b/src/os_mac/os_mac_find.m @@ -0,0 +1,212 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles device I/O for Mac OS X. + */ + +#ifdef __APPLE__ + +#import "os_mac.h" + +#import "../io.h" +#import "../events.h" +#import "../os.h" + + +#define BLUETOOTH_VERSION_USE_CURRENT +#import +#import +#import +#import + + +#pragma mark - +#pragma mark find + +@interface WiiuseDeviceInquiry : NSObject { + wiimote** wiimotes; + NSUInteger maxDevices; + int timeout; + + BOOL _running; + NSUInteger _foundDevices; + BOOL _inquiryComplete; +} + +- (id) initWithMemory:(wiimote**)wiimotes maxDevices:(int)maxDevices timeout:(int)timeout; +- (int) run; + +@end + +@implementation WiiuseDeviceInquiry + +- (id) initWithMemory:(wiimote**)wiimotes_ maxDevices:(int)maxDevices_ timeout:(int)timeout_ { + self = [super init]; + if(self) { + wiimotes = wiimotes_; + maxDevices = maxDevices_; + timeout = timeout_; + + _running = NO; + } + return self; +} + +// creates and starts inquiry. the returned object is in the current autorelease pool. +- (IOBluetoothDeviceInquiry*) start { + + // reset state variables + _foundDevices = 0; + _inquiryComplete = NO; + + // create inquiry + IOBluetoothDeviceInquiry* inquiry = [IOBluetoothDeviceInquiry inquiryWithDelegate: self]; + + // refine search & set timeout + [inquiry setSearchCriteria:kBluetoothServiceClassMajorAny + majorDeviceClass:WM_DEV_MAJOR_CLASS + minorDeviceClass:WM_DEV_MINOR_CLASS]; + [inquiry setUpdateNewDeviceNames: NO]; + if(timeout > 0) + [inquiry setInquiryLength:timeout]; + + // start inquiry + IOReturn status = [inquiry start]; + if (status != kIOReturnSuccess) { + WIIUSE_ERROR("Unable to start bluetooth device inquiry."); + if(![inquiry stop]) { + WIIUSE_ERROR("Unable to stop bluetooth device inquiry."); + } else { + WIIUSE_DEBUG("Bluetooth device inquiry stopped."); + } + return nil; + } + + return inquiry; +} + +- (void) wait { + // wait for the inquiry to complete + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while(!_inquiryComplete && + [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) { + // no-op + } +} + +- (NSUInteger) collectResultsOf: (IOBluetoothDeviceInquiry*) inquiry { + // read found device information + NSArray* devices = [inquiry foundDevices]; + for(NSUInteger i = 0; i < [devices count]; i++) { + IOBluetoothDevice* device = [devices objectAtIndex:i]; + + // save the device in the wiimote structure + wiimotes[i]->device = WIIUSE_IOBluetoothDevice_to_IOBluetoothDeviceRef(device); + [device retain]; // must retain it for later access through its ref + + // mark as found + WIIMOTE_ENABLE_STATE(wiimotes[i], WIIMOTE_STATE_DEV_FOUND); + NSString* address = IOBluetoothNSStringFromDeviceAddress([device getAddress]); + const char* address_str = [address cStringUsingEncoding:NSMacOSRomanStringEncoding]; + WIIUSE_INFO("Found Wiimote (%s) [id %i]", address_str, wiimotes[i]->unid); + } + + return [devices count]; +} + +- (int) run { + int result = -1; + + if(maxDevices == 0) { + result = 0; + } else if(!_running) { + _running = YES; + + if (![IOBluetoothHostController defaultController]) { + WIIUSE_ERROR("Unable to find any bluetooth receiver on your host."); + } else { + IOBluetoothDeviceInquiry* inquiry = [self start]; + if(inquiry) { + [self wait]; + result = [self collectResultsOf: inquiry]; + WIIUSE_INFO("Found %i Wiimote device(s).", result); + } + } + + _running = NO; + } else { // if(_running) + WIIUSE_ERROR("Device inquiry already running - won't start it again."); + } + + return result; +} + +- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) inquiry device:(IOBluetoothDevice *) device { + + WIIUSE_DEBUG("Found a wiimote"); + + _foundDevices++; + if(_foundDevices >= maxDevices) { + // reached maximum number of devices + if(![inquiry stop]) + WIIUSE_ERROR("Unable to stop bluetooth device inquiry."); + _inquiryComplete = YES; + } +} + +- (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry*) inquiry error:(IOReturn) error aborted:(BOOL) aborted +{ + WIIUSE_DEBUG("Inquiry complete, error=%i, aborted=%s", error, aborted ? "YES" : "NO"); + + // mark completion + _inquiryComplete = YES; + + // print error message if we stop due to an error + if ((error != kIOReturnSuccess) && !aborted) { + WIIUSE_ERROR("Bluetooth device inquiry not completed due to unexpected errors. Try increasing the timeout."); + } +} + +@end + +int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { + int result; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + WiiuseDeviceInquiry* inquiry = [[WiiuseDeviceInquiry alloc] initWithMemory:wm maxDevices:max_wiimotes timeout:timeout]; + result = [inquiry run]; + [inquiry release]; + + [pool drain]; + return result; +} + +#endif // __APPLE__