diff --git a/src/os_mac.m b/src/os_mac.m index 620c77c..2459d3f 100644 --- a/src/os_mac.m +++ b/src/os_mac.m @@ -47,7 +47,7 @@ #pragma mark - -#pragma mark connect +#pragma mark connect, disconnect /** * @brief Connect to a wiimote with a known address. @@ -64,7 +64,7 @@ static short wiiuse_os_connect_single(struct wiimote_t* wm) { if(!wm) { WIIUSE_ERROR("No Wiimote given."); return 0; - } else if(wm && (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_DEV_FOUND) || wm->device == NULL)) { + } else if(wm && (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_DEV_FOUND) || wm->objc_wm == NULL)) { WIIUSE_ERROR("Tried to connect Wiimote without an address."); return 0; } else if(WIIMOTE_IS_CONNECTED(wm)) { @@ -78,7 +78,7 @@ static short wiiuse_os_connect_single(struct wiimote_t* wm) { short result = 0; // connect - WiiuseWiimote* objc_wm = [[WiiuseWiimote alloc] initWithPtr: wm]; + WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm; if([objc_wm connect] == kIOReturnSuccess) { WIIUSE_INFO("Connected to Wiimote [id %i].", wm->unid); @@ -93,8 +93,6 @@ static short wiiuse_os_connect_single(struct wiimote_t* wm) { wiiuse_set_report_type(wm); result = 1; - } else { - [objc_wm release]; } [pool drain]; @@ -111,8 +109,8 @@ int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) { break; } - if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND) || !wm[i]->device) { - // If the device is not set, skip it + if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND) || !wm[i]->objc_wm) { + // If the device is not found, skip it continue; } @@ -123,56 +121,13 @@ int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) { return connected; } -#pragma mark disconnect - -#define WIIUSE_MAC_CLOSE_CHANNEL(wm, channel) \ - { \ - IOBluetoothL2CAPChannel* channel = WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel((wm)->channel##Channel); \ - if([channel closeChannel] != kIOReturnSuccess) \ - WIIUSE_ERROR("Unable to close " #channel " channel [id %i].", (wm)->unid); \ - [channel release]; \ - (wm)->channel##Channel = NULL; \ - } - -#define WIIUSE_MAC_CLOSE_DEVICE_CONNECTION(wm) \ - { \ - IOBluetoothDevice* device = WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice((wm)->device); \ - if([device closeConnection] != kIOReturnSuccess) \ - WIIUSE_ERROR("Unable to close the device connection [id %i].", (wm)->unid); \ - [device release]; \ - (wm)->device = NULL; \ - } - -#define WIIUSE_MAC_DISCONNECT(wm) \ - { \ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \ - WIIUSE_MAC_CLOSE_CHANNEL(wm, interrupt); \ - WIIUSE_MAC_CLOSE_CHANNEL(wm, control); \ - WIIUSE_MAC_CLOSE_DEVICE_CONNECTION(wm); \ - [pool drain]; \ - } - void wiiuse_os_disconnect(struct wiimote_t* wm) { - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + if (!wm || !WIIMOTE_IS_CONNECTED(wm) || !wm->objc_wm) return; - // disconnect NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - { \ - IOBluetoothL2CAPChannel* channel = WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel((wm)->interruptChannel); \ - if([channel closeChannel] != kIOReturnSuccess) \ - WIIUSE_ERROR("Unable to close " "interrupt" " channel [id %i].", (wm)->unid); \ - [channel release]; \ - (wm)->interruptChannel = NULL; \ - } - WIIUSE_MAC_CLOSE_CHANNEL(wm, control); - WIIUSE_MAC_CLOSE_DEVICE_CONNECTION(wm); + [((WiiuseWiimote*)wm->objc_wm) disconnect]; [pool drain]; - - // clean up C struct - wm->event = WIIUSE_NONE; - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); } #pragma mark - @@ -203,25 +158,20 @@ int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len) { #pragma mark platform fields void wiiuse_init_platform_fields(struct wiimote_t* wm) { - wm->device = NULL; wm->objc_wm = NULL; - wm->controlChannel = NULL; - wm->interruptChannel = NULL; } void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { - // disconnect & release device and channels - // Note: this should already have happened, because this function is called - // once the device is disconnected. This is just paranoia. - WIIUSE_MAC_DISCONNECT(wm); + if(!wm) return; + WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm; - // this is also done on disconnect, so it's even more paranoia. - wm->device = NULL; - wm->controlChannel = NULL; - wm->interruptChannel = NULL; + // disconnect + // Note: this should already have happened, because this function + // is called once the device is disconnected. This is just paranoia. + [objc_wm disconnect]; // release WiiuseWiimote object - [((WiiuseWiimote*) wm->objc_wm) release]; + [objc_wm release]; wm->objc_wm = NULL; } @@ -230,10 +180,13 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { @implementation WiiuseWiimote -- (id) initWithPtr: (wiimote*) wm_ { +- (id) initWithPtr: (wiimote*) wm_ device:(IOBluetoothDevice *)device_ { self = [super init]; if(self) { wm = wm_; + device = device_; + controlChannel = nil; + interruptChannel = nil; disconnectNotification = nil; } return self; @@ -242,6 +195,11 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { - (void) dealloc { wm = NULL; + [interruptChannel release]; + [controlChannel release]; + [device release]; + + [disconnectNotification unregister]; [disconnectNotification release]; disconnectNotification = nil; @@ -249,14 +207,12 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { } - (IOReturn) connect { - IOBluetoothDevice* device = WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(wm->device); if(!device) { WIIUSE_ERROR("Missing device."); return kIOReturnBadArgument; } // open channels - IOBluetoothL2CAPChannel* controlChannel = nil, *interruptChannel = nil; if ([device openL2CAPChannelSync:&controlChannel withPSM:WM_OUTPUT_CHANNEL delegate:self] != kIOReturnSuccess) { WIIUSE_ERROR("Unable to open L2CAP control channel [id %i].", wm->unid); [device closeConnection]; @@ -278,14 +234,33 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { return kIOReturnNotOpen; } - // retain channels, and save them to the C struct - [controlChannel retain]; [interruptChannel retain]; - wm->controlChannel = WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(controlChannel); - wm->interruptChannel = WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(interruptChannel); + // retain channels + [controlChannel retain]; + [interruptChannel retain]; return kIOReturnSuccess; } +- (void) disconnect { + // interrupt channel + if([interruptChannel closeChannel] != kIOReturnSuccess) + WIIUSE_ERROR("Unable to close interrupt channel [id %i].", wm ? wm->unid : -1); + [interruptChannel release]; + interruptChannel = nil; + + // control channel + if([controlChannel closeChannel] != kIOReturnSuccess) + WIIUSE_ERROR("Unable to close control channel [id %i].", wm ? wm->unid : -1); + [controlChannel release]; + controlChannel = nil; + + // device + if([device closeConnection] != kIOReturnSuccess) + WIIUSE_ERROR("Unable to close the device connection [id %i].", wm ? wm->unid : -1); + [device release]; + device = nil; +} + #pragma mark IOBluetoothL2CAPChannel delegates - (void) disconnected:(IOBluetoothUserNotification*) notification fromDevice:(IOBluetoothDevice*) device { diff --git a/src/os_mac/os_mac.h b/src/os_mac/os_mac.h index 667f4ce..41d0c63 100644 --- a/src/os_mac/os_mac.h +++ b/src/os_mac/os_mac.h @@ -42,57 +42,29 @@ #import "../wiiuse_internal.h" +#if 0 #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 - -// WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef -#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE -#define WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(channel) \ - ((IOBluetoothL2CAPChannelRef) (channel)) -#else -#define WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(channel) \ - [(channel) getL2CAPChannelRef] -#endif - -// WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel -#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE -#define WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel(ref) \ - ((IOBluetoothL2CAPChannel*) (ref)) -#else -#define WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel(ref) \ - [IOBluetoothL2CAPChannel withChanneleRef: (ref)] #endif @interface WiiuseWiimote : NSObject { wiimote* wm; // reference to the C wiimote struct + + IOBluetoothDevice* device; + IOBluetoothL2CAPChannel* controlChannel; + IOBluetoothL2CAPChannel* interruptChannel; + IOBluetoothUserNotification* disconnectNotification; } -- (id) initWithPtr: (wiimote*) wm; +- (id) initWithPtr: (wiimote*) wm device: (IOBluetoothDevice*) device; + - (IOReturn) connect; +- (void) disconnect; @end diff --git a/src/os_mac/os_mac_find.m b/src/os_mac/os_mac_find.m index 032d262..ac51dbc 100644 --- a/src/os_mac/os_mac_find.m +++ b/src/os_mac/os_mac_find.m @@ -130,7 +130,7 @@ IOBluetoothDevice* device = [devices objectAtIndex:i]; // save the device in the wiimote structure - wiimotes[i]->device = WIIUSE_IOBluetoothDevice_to_IOBluetoothDeviceRef(device); + wiimotes[i]->objc_wm = (void*) [[WiiuseWiimote alloc] initWithPtr:wiimotes[i] device: device]; [device retain]; // must retain it for later access through its ref // mark as found diff --git a/src/wiiuse.h b/src/wiiuse.h index f88e793..4676b27 100644 --- a/src/wiiuse.h +++ b/src/wiiuse.h @@ -723,10 +723,7 @@ typedef struct wiimote_t { #ifdef WIIUSE_MAC /** @name Mac OS X-specific members */ /** @{ */ - WCONST IOBluetoothDeviceRef device; /** Device reference */ WCONST void* objc_wm; /** WiiuseWiimote* as opaque pointer */ - WCONST IOBluetoothL2CAPChannelRef controlChannel; /** control channel reference */ - WCONST IOBluetoothL2CAPChannelRef interruptChannel; /** interrupt channel reference */ /** @} */ #endif