Repository: electric-monk/360Controller Branch: master Commit: 649b9712d2a2 Files: 96 Total size: 639.3 KB Directory structure: gitextract_62qdvxky/ ├── 360Controller/ │ ├── 360Controller.xcodeproj/ │ │ └── project.pbxproj │ ├── ChatPad.cpp │ ├── ChatPad.h │ ├── ControlStruct.h │ ├── Controller.cpp │ ├── Controller.h │ ├── English.lproj/ │ │ └── InfoPlist.strings │ ├── Info copy.plist │ ├── Info.plist │ ├── _60Controller.cpp │ ├── _60Controller.h │ ├── chatpadhid.h │ ├── chatpadkeys.cpp │ ├── chatpadkeys.h │ ├── version.plist │ └── xbox360hid.h ├── 360Daemon/ │ ├── 360Daemon.1 │ ├── 360Daemon.m │ ├── 360Daemon.xcodeproj/ │ │ └── project.pbxproj │ ├── 360Daemon_Prefix.pch │ ├── Alert.tif │ ├── ControlPrefs.h │ ├── ControlPrefs.m │ ├── FoundationTool.pbproj/ │ │ └── project.pbxproj │ └── com.mice.360Daemon.plist ├── DriverTool/ │ ├── DriverTool.1 │ ├── DriverTool.m │ ├── DriverTool.xcodeproj/ │ │ └── project.pbxproj │ └── DriverTool_Prefix.pch ├── Feedback360/ │ ├── English.lproj/ │ │ └── InfoPlist.strings │ ├── Feedback360.xcodeproj/ │ │ ├── colin.mode1 │ │ └── project.pbxproj │ ├── Info.plist │ ├── devlink.c │ ├── devlink.h │ ├── emulator.c │ ├── emulator.h │ ├── main.c │ ├── main.h │ └── version.plist ├── Install360Controller/ │ ├── Install360Controller.pkgproj │ ├── Scripts/ │ │ ├── finish.sh │ │ └── upgrade.sh │ └── Text/ │ └── Welcome.rtf ├── Licence.txt ├── Pref360Control/ │ ├── DeviceItem.h │ ├── DeviceItem.m │ ├── DeviceLister.h │ ├── DeviceLister.m │ ├── English.lproj/ │ │ ├── InfoPlist.strings │ │ └── Pref360ControlPref.nib/ │ │ ├── designable.nib │ │ └── keyedobjects.nib │ ├── Info.plist │ ├── MyAnalogStick.h │ ├── MyAnalogStick.m │ ├── MyCentreButtons.h │ ├── MyCentreButtons.m │ ├── MyDigitalStick.h │ ├── MyDigitalStick.m │ ├── MyMainButtons.h │ ├── MyMainButtons.m │ ├── MyShoulderButton.h │ ├── MyShoulderButton.m │ ├── Pref360Control.xcodeproj/ │ │ └── project.pbxproj │ ├── Pref360ControlPref.h │ ├── Pref360ControlPref.m │ ├── Pref360Control_Prefix.pch │ ├── batt0.tif │ ├── batt1.tif │ ├── batt2.tif │ ├── batt3.tif │ ├── battNone.tif │ ├── pref360controlpref.tiff │ └── version.plist ├── Readme.rtf ├── Wireless360Controller/ │ ├── English.lproj/ │ │ └── InfoPlist.strings │ ├── IOKitDriver.pbproj/ │ │ └── project.pbxproj │ ├── Info.plist │ ├── Wireless360Controller.cpp │ ├── Wireless360Controller.h │ ├── Wireless360Controller.xcodeproj/ │ │ └── project.pbxproj │ └── version.plist ├── WirelessGamingReceiver/ │ ├── English.lproj/ │ │ └── InfoPlist.strings │ ├── IOKitDriver.pbproj/ │ │ └── project.pbxproj │ ├── Info.plist │ ├── WirelessDevice.cpp │ ├── WirelessDevice.h │ ├── WirelessGamingReceiver.cpp │ ├── WirelessGamingReceiver.h │ ├── WirelessGamingReceiver.xcodeproj/ │ │ ├── colin.mode1 │ │ └── project.pbxproj │ ├── WirelessHIDDevice.cpp │ ├── WirelessHIDDevice.h │ ├── devices.h │ └── version.plist └── build ================================================ FILE CONTENTS ================================================ ================================================ FILE: 360Controller/360Controller.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 32D94FC60562CBF700B6AF17 /* _60Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A224C3EFF42367911CA2CB7 /* _60Controller.h */; }; 32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 32D94FCA0562CBF700B6AF17 /* _60Controller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A224C3FFF42367911CA2CB7 /* _60Controller.cpp */; settings = {ATTRIBUTES = (); }; }; 3B36DCC410B7816F00FFD769 /* Controller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B36DCC210B7816F00FFD769 /* Controller.cpp */; }; 3B36DCC510B7816F00FFD769 /* Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B36DCC310B7816F00FFD769 /* Controller.h */; }; 3B36DCCB10B7817E00FFD769 /* ChatPad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B36DCC610B7817E00FFD769 /* ChatPad.cpp */; }; 3B36DCCC10B7817E00FFD769 /* ChatPad.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B36DCC710B7817E00FFD769 /* ChatPad.h */; }; 3B36DCCD10B7817E00FFD769 /* chatpadhid.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B36DCC810B7817E00FFD769 /* chatpadhid.h */; }; 3B36DCCE10B7817E00FFD769 /* chatpadkeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B36DCC910B7817E00FFD769 /* chatpadkeys.cpp */; }; 3B36DCCF10B7817E00FFD769 /* chatpadkeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B36DCCA10B7817E00FFD769 /* chatpadkeys.h */; }; 3BB5E09C09641F8200F83598 /* xbox360hid.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BB5E09B09641F8200F83598 /* xbox360hid.h */; }; 3BCE45CA09638EBC00B69EDF /* ControlStruct.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BCE45C909638EBC00B69EDF /* ControlStruct.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1A224C3EFF42367911CA2CB7 /* _60Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _60Controller.h; sourceTree = ""; }; 1A224C3FFF42367911CA2CB7 /* _60Controller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = _60Controller.cpp; sourceTree = ""; }; 32D94FCF0562CBF700B6AF17 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32D94FD00562CBF700B6AF17 /* 360Controller.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = 360Controller.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 3B0F1276097B395B00127827 /* Feedback360.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Feedback360.bundle; path = ../Feedback360/build/Deployment/Feedback360.bundle; sourceTree = SOURCE_ROOT; }; 3B36DCC210B7816F00FFD769 /* Controller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Controller.cpp; sourceTree = ""; }; 3B36DCC310B7816F00FFD769 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; 3B36DCC610B7817E00FFD769 /* ChatPad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChatPad.cpp; sourceTree = ""; }; 3B36DCC710B7817E00FFD769 /* ChatPad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatPad.h; sourceTree = ""; }; 3B36DCC810B7817E00FFD769 /* chatpadhid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chatpadhid.h; sourceTree = ""; }; 3B36DCC910B7817E00FFD769 /* chatpadkeys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chatpadkeys.cpp; sourceTree = ""; }; 3B36DCCA10B7817E00FFD769 /* chatpadkeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chatpadkeys.h; sourceTree = ""; }; 3BB5E09B09641F8200F83598 /* xbox360hid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = xbox360hid.h; sourceTree = ""; }; 3BCE45C909638EBC00B69EDF /* ControlStruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlStruct.h; sourceTree = ""; }; 8DA8362C06AD9B9200E5AC22 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 32D94FCB0562CBF700B6AF17 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* 360Controller */ = { isa = PBXGroup; children = ( 247142CAFF3F8F9811CA285C /* Source */, 089C167CFE841241C02AAC07 /* Resources */, 19C28FB6FE9D52B211CA2CBB /* Products */, ); name = 360Controller; sourceTree = ""; }; 089C167CFE841241C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 3B2EF52A0965A0AE007BFB7B /* Kernel Driver */, ); name = Resources; sourceTree = ""; }; 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( 32D94FD00562CBF700B6AF17 /* 360Controller.kext */, ); name = Products; sourceTree = ""; }; 247142CAFF3F8F9811CA285C /* Source */ = { isa = PBXGroup; children = ( 3B2EF19A0965A03E007BFB7B /* Kernel Driver */, ); name = Source; sourceTree = ""; }; 3B2EF19A0965A03E007BFB7B /* Kernel Driver */ = { isa = PBXGroup; children = ( 3B36DCC010B7815000FFD769 /* Controller */, 3B36DCC110B7815700FFD769 /* ChatPad */, 3BCE45C909638EBC00B69EDF /* ControlStruct.h */, 1A224C3EFF42367911CA2CB7 /* _60Controller.h */, 1A224C3FFF42367911CA2CB7 /* _60Controller.cpp */, ); name = "Kernel Driver"; sourceTree = ""; }; 3B2EF52A0965A0AE007BFB7B /* Kernel Driver */ = { isa = PBXGroup; children = ( 3B0F1276097B395B00127827 /* Feedback360.bundle */, 8DA8362C06AD9B9200E5AC22 /* Kernel.framework */, 32D94FCF0562CBF700B6AF17 /* Info.plist */, 089C167DFE841241C02AAC07 /* InfoPlist.strings */, ); name = "Kernel Driver"; sourceTree = ""; }; 3B36DCC010B7815000FFD769 /* Controller */ = { isa = PBXGroup; children = ( 3B36DCC210B7816F00FFD769 /* Controller.cpp */, 3B36DCC310B7816F00FFD769 /* Controller.h */, 3BB5E09B09641F8200F83598 /* xbox360hid.h */, ); name = Controller; sourceTree = ""; }; 3B36DCC110B7815700FFD769 /* ChatPad */ = { isa = PBXGroup; children = ( 3B36DCC610B7817E00FFD769 /* ChatPad.cpp */, 3B36DCC710B7817E00FFD769 /* ChatPad.h */, 3B36DCC910B7817E00FFD769 /* chatpadkeys.cpp */, 3B36DCCA10B7817E00FFD769 /* chatpadkeys.h */, 3B36DCC810B7817E00FFD769 /* chatpadhid.h */, ); name = ChatPad; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 32D94FC50562CBF700B6AF17 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 32D94FC60562CBF700B6AF17 /* _60Controller.h in Headers */, 3BCE45CA09638EBC00B69EDF /* ControlStruct.h in Headers */, 3BB5E09C09641F8200F83598 /* xbox360hid.h in Headers */, 3B36DCC510B7816F00FFD769 /* Controller.h in Headers */, 3B36DCCC10B7817E00FFD769 /* ChatPad.h in Headers */, 3B36DCCD10B7817E00FFD769 /* chatpadhid.h in Headers */, 3B36DCCF10B7817E00FFD769 /* chatpadkeys.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 32D94FC30562CBF700B6AF17 /* 360Controller */ = { isa = PBXNativeTarget; buildConfigurationList = 3BBDC682097938A90023AAD8 /* Build configuration list for PBXNativeTarget "360Controller" */; buildPhases = ( 32D94FC50562CBF700B6AF17 /* Headers */, 32D94FC70562CBF700B6AF17 /* Resources */, 32D94FC90562CBF700B6AF17 /* Sources */, 32D94FCB0562CBF700B6AF17 /* Frameworks */, 32D94FCC0562CBF700B6AF17 /* Rez */, 3B0F12A1097B3A3A00127827 /* ShellScript */, ); buildRules = ( ); dependencies = ( ); name = 360Controller; productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; productName = 360Controller; productReference = 32D94FD00562CBF700B6AF17 /* 360Controller.kext */; productType = "com.apple.product-type.kernel-extension.iokit"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 3BBDC686097938A90023AAD8 /* Build configuration list for PBXProject "360Controller" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 089C166AFE841209C02AAC07 /* 360Controller */; projectDirPath = ""; projectRoot = ""; targets = ( 32D94FC30562CBF700B6AF17 /* 360Controller */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 32D94FC70562CBF700B6AF17 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 32D94FCC0562CBF700B6AF17 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3B0F12A1097B3A3A00127827 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "cd \"$TARGET_BUILD_DIR/$TARGET_NAME.kext/Contents\"\nmkdir PlugIns > /dev/null 2>&1\nrm -R PlugIns/Feedback360.plugin > /dev/null 2>&1\necho \"$SRCROOT/../Feedback360/build/Deployment/Feedback360.bundle\"\ncp -R \"$SRCROOT/../Feedback360/build/Deployment/Feedback360.bundle\" PlugIns/Feedback360.plugin\n# Renaming extension from bundle to a plugin? Could be naughty."; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 32D94FC90562CBF700B6AF17 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 32D94FCA0562CBF700B6AF17 /* _60Controller.cpp in Sources */, 3B36DCC410B7816F00FFD769 /* Controller.cpp in Sources */, 3B36DCCB10B7817E00FFD769 /* ChatPad.cpp in Sources */, 3B36DCCE10B7817E00FFD769 /* chatpadkeys.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C167EFE841241C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 3BBDC683097938A90023AAD8 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = com.mice.driver.Xbox360Controller; MODULE_VERSION = 1.0.0d11; PREBINDING = NO; PRODUCT_NAME = 360Controller; SDKROOT = ""; WRAPPER_EXTENSION = kext; ZERO_LINK = YES; }; name = Development; }; 3BBDC684097938A90023AAD8 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, x86_64, ); COPY_PHASE_STRIP = YES; CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; LD_GENERATE_MAP_FILE = NO; MODULE_NAME = com.mice.driver.Xbox360Controller; MODULE_VERSION = 1.0.0d11; PREBINDING = NO; PRODUCT_NAME = 360Controller; WRAPPER_EXTENSION = kext; ZERO_LINK = NO; }; name = Deployment; }; 3BBDC685097938A90023AAD8 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = com.mice.driver.Xbox360Controller; MODULE_VERSION = 1.0.0d11; PREBINDING = NO; PRODUCT_NAME = 360Controller; WRAPPER_EXTENSION = kext; }; name = Default; }; 3BBDC687097938A90023AAD8 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Development; }; 3BBDC688097938A90023AAD8 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_VERSION = ""; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; "SDKROOT[arch=x86_64]" = ""; }; name = Deployment; }; 3BBDC689097938A90023AAD8 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 3BBDC682097938A90023AAD8 /* Build configuration list for PBXNativeTarget "360Controller" */ = { isa = XCConfigurationList; buildConfigurations = ( 3BBDC683097938A90023AAD8 /* Development */, 3BBDC684097938A90023AAD8 /* Deployment */, 3BBDC685097938A90023AAD8 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 3BBDC686097938A90023AAD8 /* Build configuration list for PBXProject "360Controller" */ = { isa = XCConfigurationList; buildConfigurations = ( 3BBDC687097938A90023AAD8 /* Development */, 3BBDC688097938A90023AAD8 /* Deployment */, 3BBDC689097938A90023AAD8 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } ================================================ FILE: 360Controller/ChatPad.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro ChatPad.cpp - Implementation of the ChatPad Accessory driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "ChatPad.h" namespace HID_ChatPad { #include "chatpadhid.h" } #include "chatpadkeys.h" #include "_60Controller.h" OSDefineMetaClassAndStructors(ChatPadKeyboardClass, IOHIDDevice) IOReturn ChatPadKeyboardClass::newReportDescriptor(IOMemoryDescriptor **descriptor) const { IOBufferMemoryDescriptor *buffer; buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, sizeof(HID_ChatPad::ReportDescriptor)); if (buffer == NULL) return kIOReturnNoResources; buffer->writeBytes(0, HID_ChatPad::ReportDescriptor, sizeof(HID_ChatPad::ReportDescriptor)); *descriptor = buffer; return kIOReturnSuccess; } IOReturn ChatPadKeyboardClass::setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { // Maybe add LED support later? return kIOReturnUnsupported; } IOReturn ChatPadKeyboardClass::getReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { return kIOReturnUnsupported; } IOReturn ChatPadKeyboardClass::handleReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { IOBufferMemoryDescriptor *realReport = OSDynamicCast(IOBufferMemoryDescriptor, report); if (realReport != NULL) { unsigned char *data = (unsigned char*)realReport->getBytesNoCopy(); if (data[0] == 0x00) { for (int i = 2; i < 5; i++) { data[i] = ChatPad2USB(data[i]); } } } return IOHIDDevice::handleReport(report, reportType, options); } OSNumber* ChatPadKeyboardClass::newPrimaryUsageNumber() const { return OSNumber::withNumber(HID_ChatPad::ReportDescriptor[3], 8); } OSNumber* ChatPadKeyboardClass::newPrimaryUsagePageNumber() const { return OSNumber::withNumber(HID_ChatPad::ReportDescriptor[1], 8); } OSString* ChatPadKeyboardClass::newProductString() const { return OSString::withCString("ChatPad"); } OSString* ChatPadKeyboardClass::newTransportString() const { return OSString::withCString("Serial"); } OSNumber* ChatPadKeyboardClass::newVendorIDNumber() const { // Same as USB return OSNumber::withNumber(100, 32); } OSNumber* ChatPadKeyboardClass::newProductIDNumber() const { // Same as USB, plus one return OSNumber::withNumber(100, 32); } static IOHIDDevice* GetParent(const IOService *current) { Xbox360Peripheral *owner; owner = OSDynamicCast(Xbox360Peripheral, current->getProvider()); if (owner == NULL) return NULL; return owner->getController(0); } bool ChatPadKeyboardClass::start(IOService *provider) { if (!IOHIDDevice::start(provider)) return false; return OSDynamicCast(Xbox360Peripheral, provider) != NULL; } OSString* ChatPadKeyboardClass::newManufacturerString() const { IOHIDDevice *device = GetParent(this); if (device == NULL) return NULL; return device->newManufacturerString(); } OSString* ChatPadKeyboardClass::newSerialNumberString() const { IOHIDDevice *device = GetParent(this); if (device == NULL) return NULL; return device->newSerialNumberString(); } OSNumber* ChatPadKeyboardClass::newLocationIDNumber() const { IOHIDDevice *device = GetParent(this); if (device == NULL) return NULL; OSNumber *number = device->newLocationIDNumber(); if (number == NULL) return NULL; UInt32 value = number->unsigned32BitValue(); number->release(); return OSNumber::withNumber(value + 1, 32); } ================================================ FILE: 360Controller/ChatPad.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro ChatPad.h - Driver class for the ChatPad accessory This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include class ChatPadKeyboardClass : public IOHIDDevice { OSDeclareDefaultStructors(ChatPadKeyboardClass) private: public: virtual bool start(IOService *provider); // IOHidDevice methods virtual IOReturn newReportDescriptor(IOMemoryDescriptor **descriptor) const; virtual IOReturn setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options=0); virtual IOReturn getReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options); virtual IOReturn handleReport(IOMemoryDescriptor *report, IOHIDReportType reportType = kIOHIDReportTypeInput, IOOptionBits options = 0); virtual OSString* newManufacturerString() const; virtual OSNumber* newPrimaryUsageNumber() const; virtual OSNumber* newPrimaryUsagePageNumber() const; virtual OSNumber* newProductIDNumber() const; virtual OSString* newProductString() const; virtual OSString* newSerialNumberString() const; virtual OSString* newTransportString() const; virtual OSNumber* newVendorIDNumber() const; virtual OSNumber* newLocationIDNumber() const; }; ================================================ FILE: 360Controller/ControlStruct.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro ControlStruct.h - Structures used by the device This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CONTROLSTRUCT_H__ #define __CONTROLSTRUCT_H__ typedef UInt8 XBox360_Byte; typedef UInt16 XBox360_Short; typedef SInt16 XBox360_SShort; #define Xbox360_Prepare(x,t) {memset(&x,0,sizeof(x));x.header.command=t;x.header.size=sizeof(x);} #define PACKED __attribute__((__packed__)) // Common structure format typedef struct { XBox360_Byte command; XBox360_Byte size; } PACKED XBOX360_PACKET; // Analog stick format typedef struct { XBox360_SShort x,y; } PACKED XBOX360_HAT; // Structure describing the report had back from the controller typedef struct { XBOX360_PACKET header; XBox360_Short buttons; XBox360_Byte trigL,trigR; XBOX360_HAT left,right; XBox360_Byte reserved[6]; } PACKED XBOX360_IN_REPORT; // Structure describing the command to change LED status typedef struct { XBOX360_PACKET header; XBox360_Byte pattern; } PACKED XBOX360_OUT_LED; // Structure describing the command to change rumble motor status typedef struct { XBOX360_PACKET header; XBox360_Byte reserved1; XBox360_Byte big,little; XBox360_Byte reserved[3]; } PACKED XBOX360_OUT_RUMBLE; // Enumeration of command types enum { // In inReport = 0, // Out outRumble = 0, outLed = 1 }; // Button bits enum { btnHatRight = 0x8000, btnHatLeft = 0x4000, btnBack = 0x2000, btnStart = 0x1000, btnDigiRight = 0x0800, btnDigiLeft = 0x0400, btnDigiDown = 0x0200, btnDigiUp = 0x0100, btnY = 0x0080, btnX = 0x0040, btnB = 0x0020, btnA = 0x0010, btnReserved1 = 0x0008, // Unused? btnXbox = 0x0004, btnShoulderRight = 0x0002, btnShoulderLeft = 0x0001 }; // LED values enum { ledOff = 0x00, ledBlinkingAll = 0x01, ledFlashOn1 = 0x02, ledFlashOn2 = 0x03, ledFlashOn3 = 0x04, ledFlashOn4 = 0x05, ledOn1 = 0x06, ledOn2 = 0x07, ledOn3 = 0x08, ledOn4 = 0x09, ledRotating = 0x0a, ledBlinking = 0x0b, // Blinking of previously enabled LED (e.g. from 0x01-0x09) ledBlinkingSlow = 0x0c, // As above ldAlternating = 0x0d // 1+4, 2+3, then back to previous after a short time }; #endif // __CONTROLSTRUCT_H__ ================================================ FILE: 360Controller/Controller.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Controller.cpp - driver class for the 360 controller This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "Controller.h" #include "ControlStruct.h" namespace HID_360 { #include "xbox360hid.h" } #include "_60Controller.h" OSDefineMetaClassAndStructors(Xbox360ControllerClass, IOHIDDevice) static Xbox360Peripheral* GetOwner(IOService *us) { IOService *prov; prov = us->getProvider(); if (prov == NULL) return NULL; return OSDynamicCast(Xbox360Peripheral, prov); } static IOUSBDevice* GetOwnerProvider(const IOService *us) { IOService *prov, *provprov; prov = us->getProvider(); if (prov == NULL) return NULL; provprov = prov->getProvider(); if (provprov == NULL) return NULL; return OSDynamicCast(IOUSBDevice, provprov); } bool Xbox360ControllerClass::start(IOService *provider) { if (OSDynamicCast(Xbox360Peripheral, provider) == NULL) return false; return IOHIDDevice::start(provider); } IOReturn Xbox360ControllerClass::setProperties(OSObject *properties) { Xbox360Peripheral *owner = GetOwner(this); if (owner == NULL) return kIOReturnUnsupported; return owner->setProperties(properties); } // Returns the HID descriptor for this device IOReturn Xbox360ControllerClass::newReportDescriptor(IOMemoryDescriptor **descriptor) const { IOBufferMemoryDescriptor *buffer; buffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,sizeof(HID_360::ReportDescriptor)); if(buffer==NULL) return kIOReturnNoResources; buffer->writeBytes(0,HID_360::ReportDescriptor,sizeof(HID_360::ReportDescriptor)); *descriptor=buffer; return kIOReturnSuccess; } // Handles a message from the userspace IOHIDDeviceInterface122::setReport function IOReturn Xbox360ControllerClass::setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options) { char data[2]; report->readBytes(0,data,2); switch(data[0]) { case 0x00: // Set force feedback if((data[1]!=report->getLength())||(data[1]!=0x04)) return kIOReturnUnsupported; { XBOX360_OUT_RUMBLE rumble; Xbox360_Prepare(rumble,outRumble); report->readBytes(2,data,2); rumble.big=data[0]; rumble.little=data[1]; GetOwner(this)->QueueWrite(&rumble,sizeof(rumble)); // IOLog("Set rumble: big(%d) little(%d)\n", rumble.big, rumble.little); } return kIOReturnSuccess; case 0x01: // Set LEDs if((data[1]!=report->getLength())||(data[1]!=0x03)) return kIOReturnUnsupported; { XBOX360_OUT_LED led; report->readBytes(2,data,1); Xbox360_Prepare(led,outLed); led.pattern=data[0]; GetOwner(this)->QueueWrite(&led,sizeof(led)); // IOLog("Set LED: %d\n", led.pattern); } return kIOReturnSuccess; default: IOLog("Unknown escape %d\n", data[0]); return kIOReturnUnsupported; } } // Get report IOReturn Xbox360ControllerClass::getReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options) { // Doesn't do anything yet ;) return kIOReturnUnsupported; } // Returns the string for the specified index from the USB device's string list, with an optional default OSString* Xbox360ControllerClass::getDeviceString(UInt8 index,const char *def) const { IOReturn err; char buf[1024]; const char *string; err = GetOwnerProvider(this)->GetStringDescriptor(index,buf,sizeof(buf)); if(err==kIOReturnSuccess) string=buf; else { if(def==NULL) string="Unknown"; else string=def; } return OSString::withCString(string); } OSString* Xbox360ControllerClass::newManufacturerString() const { return getDeviceString(GetOwnerProvider(this)->GetManufacturerStringIndex()); } OSNumber* Xbox360ControllerClass::newPrimaryUsageNumber() const { return OSNumber::withNumber(HID_360::ReportDescriptor[3], 8); } OSNumber* Xbox360ControllerClass::newPrimaryUsagePageNumber() const { return OSNumber::withNumber(HID_360::ReportDescriptor[1], 8); } OSNumber* Xbox360ControllerClass::newProductIDNumber() const { return OSNumber::withNumber(GetOwnerProvider(this)->GetProductID(),16); } OSString* Xbox360ControllerClass::newProductString() const { return getDeviceString(GetOwnerProvider(this)->GetProductStringIndex()); } OSString* Xbox360ControllerClass::newSerialNumberString() const { return getDeviceString(GetOwnerProvider(this)->GetSerialNumberStringIndex()); } OSString* Xbox360ControllerClass::newTransportString() const { return OSString::withCString("USB"); } OSNumber* Xbox360ControllerClass::newVendorIDNumber() const { return OSNumber::withNumber(GetOwnerProvider(this)->GetVendorID(),16); } OSNumber* Xbox360ControllerClass::newLocationIDNumber() const { IOUSBDevice *device; OSNumber *number; UInt32 location; device = GetOwnerProvider(this); if (device) { if ((number = OSDynamicCast(OSNumber, device->getProperty("locationID")))) { location = number->unsigned32BitValue(); } else { // Make up an address if ((number = OSDynamicCast(OSNumber, device->getProperty("USB Address")))) location |= number->unsigned8BitValue() << 24; if ((number = OSDynamicCast(OSNumber, device->getProperty("idProduct")))) location |= number->unsigned8BitValue() << 16; } } return (location != 0) ? OSNumber::withNumber(location, 32) : 0; } ================================================ FILE: 360Controller/Controller.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Controller.h - Driver class for the 360 controller This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include class Xbox360ControllerClass : public IOHIDDevice { OSDeclareDefaultStructors(Xbox360ControllerClass) private: OSString* getDeviceString(UInt8 index,const char *def=NULL) const; public: virtual bool start(IOService *provider); virtual IOReturn setProperties(OSObject *properties); virtual IOReturn newReportDescriptor(IOMemoryDescriptor **descriptor) const; virtual IOReturn setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options=0); virtual IOReturn getReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options); virtual OSString* newManufacturerString() const; virtual OSNumber* newPrimaryUsageNumber() const; virtual OSNumber* newPrimaryUsagePageNumber() const; virtual OSNumber* newProductIDNumber() const; virtual OSString* newProductString() const; virtual OSString* newSerialNumberString() const; virtual OSString* newTransportString() const; virtual OSNumber* newVendorIDNumber() const; virtual OSNumber* newLocationIDNumber() const; }; ================================================ FILE: 360Controller/English.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ CFBundleName = "360Controller"; NSHumanReadableCopyright = "© Colin Munro, 2005-11"; ================================================ FILE: 360Controller/Info copy.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable 360Controller CFBundleIconFile CFBundleIdentifier com.mice.driver.Xbox360Controller CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType KEXT CFBundleSignature ???? CFBundleVersion 1.0.0d1 IOKitPersonalities Controller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360ControllerClass IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 654 idVendor 1118 OSBundleLibraries com.apple.iokit.IOHIDFamily 1.2 com.apple.iokit.IOUSBFamily 1.8 com.apple.kernel.libkern 6.9.9 com.apple.kernel.mach 6.9.9 ================================================ FILE: 360Controller/Info.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.mice.driver.Xbox360Controller CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType KEXT CFBundleSignature ???? CFBundleVersion 1.0.0d12 IOKitPersonalities AfterglowGamepadforXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 275 idVendor 3695 AfterglowGamepadforXbox360Z CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 531 idVendor 3695 AfterglowGamepadforXbox360ZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63744 idVendor 7085 AviatorforXbox360PC CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 52009 idVendor 1848 BatarangwiredcontrollerXBOX CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 16144 idVendor 5604 BigbenControllerBB7201 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 1537 idVendor 5227 ChatPadKeyboardEvents CFBundleIdentifier com.apple.iokit.IOHIDFamily IOClass IOHIDEventDriver IOProviderClass IOHIDInterface VendorID 100 Controller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 62465 idVendor 1848 ControllerZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 62721 idVendor 3695 ControllerZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63489 idVendor 5168 ControllerZZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 654 idVendor 7085 ControllerZZZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 64001 idVendor 7085 DDRUniverse2Mat CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 4 idVendor 4779 Ferrari458Racingwheel CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 23296 idVendor 9414 GH4Guitar CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18228 idVendor 5168 GamepadF310 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 49693 idVendor 1133 GamepadforXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 769 idVendor 3695 GamepadforXbox360Z CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 1025 idVendor 3695 GamepadforXbox360ZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 770 idVendor 4779 GamepadforXbox360ZZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63746 idVendor 7085 GamestopXbox360Controller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63745 idVendor 7085 GuitarHeroforPCMAC CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18252 idVendor 5168 HORIPADEX2TURBO CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 62721 idVendor 7085 HarmonixDrumKitforXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 3 idVendor 7085 HarmonixGuitarforXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 2 idVendor 7085 HoriCoDOA4FightStick CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 10 idVendor 3853 HoriFightingStickEx2 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 13 idVendor 3853 HoriRealArcadeProEx CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 22 idVendor 3853 HoriRealArcadeProVXSA CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 21761 idVendor 9414 HoriSOULCALIBURVStick CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 21766 idVendor 9414 JoytechNeoSe CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61485 idVendor 7085 JoytechNeoSeTake2 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 48879 idVendor 5678 LogitechChillStream CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 49730 idVendor 1133 LogitechF510 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 49694 idVendor 1133 MadCatz360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 64769 idVendor 7085 MadCatzBeatPad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18240 idVendor 1848 MadCatzCallofDutyGamePad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61477 idVendor 7085 MadCatzFPSProGamePad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61479 idVendor 7085 MadCatzGhostReconFSGamePad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61473 idVendor 7085 MadCatzMicroConGamePadPro CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18230 idVendor 1848 MadCatzMicroConGamePadProZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61494 idVendor 7085 MadCatzPortableDrumKit CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 39025 idVendor 1848 MadCatzStreetFighterIVFightPad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18216 idVendor 1848 MadCatzStreetFighterIVFightStickSE CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18200 idVendor 1848 MadCatzXbox360Controller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18198 idVendor 1848 MadCatzXbox360ControllerZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18214 idVendor 1848 MadCatzXbox360ControllerZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 48879 idVendor 1848 MadCatzXbox360ControllerZZZ CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61462 idVendor 7085 MadCatzXboxcontrollerMW2 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 46886 idVendor 1848 MicrosoftXbox360Controller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 654 idVendor 1118 PDPAFTERGLOWAX1 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 769 idVendor 4779 PDPDancePad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 261 idVendor 3695 PelicanTSZ360Pad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 513 idVendor 3695 PowerAMiniProElite CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 16128 idVendor 5604 PowerAMiniProEliteGlow CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 21248 idVendor 9414 REALARCADEPROEX CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 62724 idVendor 7085 REALARCADEProVX CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 62722 idVendor 7085 RazerOnza CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 64768 idVendor 5769 RazerOnzaTournamentEdition CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 64769 idVendor 5769 RedOctaneGuitarHeroXplorer CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18248 idVendor 5168 RockCandyGamepadforXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 287 idVendor 3695 RockRevolutionforXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 6 idVendor 4779 SaitekCyborgRumblePadPCXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 51970 idVendor 1848 SaitekP3200RumblePadPCXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 51971 idVendor 1848 StreetFighterIVFightPad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 61480 idVendor 7085 StreetFighterIVFightStickTE CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 18232 idVendor 1848 SuperSFIVFightStickTES CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63288 idVendor 1848 TronXbox360controller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63747 idVendor 7085 USBGamepad CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 21760 idVendor 7085 XB360MortalKombatFightStick CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 63750 idVendor 7085 XboxAirflowiredcontroller CFBundleIdentifier com.mice.driver.Xbox360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Xbox360Peripheral IOKitDebug 65535 IOProviderClass IOUSBDevice idProduct 16138 idVendor 5604 NSHumanReadableCopyright Copyright © 2013 MICE Software. All rights reserved. OSBundleLibraries com.apple.iokit.IOHIDFamily 1.2 com.apple.iokit.IOUSBFamily 1.8 com.apple.kpi.iokit 8.0.0 com.apple.kpi.libkern 8.0.0 com.apple.kpi.mach 8.0.0 ================================================ FILE: 360Controller/_60Controller.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Bug fixes contributed by Cody "codeman38" Boisclair _60Controller.cpp - main source of the driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "_60Controller.h" #include "ControlStruct.h" #include "ChatPad.h" #include "Controller.h" #define kDriverSettingKey "DeviceData" #define kIOSerialDeviceType "Serial360Device" OSDefineMetaClassAndStructors(Xbox360Peripheral, IOService) #define super IOService class LockRequired { private: IOLock *_lock; public: LockRequired(IOLock *lock) { _lock = lock; IOLockLock(_lock); } ~LockRequired() { IOLockUnlock(_lock); } }; // Find the maximum packet size of this pipe static UInt32 GetMaxPacketSize(IOUSBPipe *pipe) { const IOUSBEndpointDescriptor *ed; ed=pipe->GetEndpointDescriptor(); if(ed==NULL) return 0; else return ed->wMaxPacketSize; } void Xbox360Peripheral::SendSpecial(UInt16 value) { IOUSBDevRequest controlReq; controlReq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBInterface); controlReq.bRequest = 0x00; controlReq.wValue = value; controlReq.wIndex = 0x0002; controlReq.wLength = 0; controlReq.pData = NULL; if (device->DeviceRequest(&controlReq, 100, 100, NULL) != kIOReturnSuccess) IOLog("Failed to send special message %.4x\n", value); } void Xbox360Peripheral::SendInit(UInt16 value, UInt16 index) { IOUSBDevRequest controlReq; controlReq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice); controlReq.bRequest = 0xa9; controlReq.wValue = value; controlReq.wIndex = index; controlReq.wLength = 0; controlReq.pData = NULL; device->DeviceRequest(&controlReq, 100, 100, NULL); // Will fail - but device should still act on it } bool Xbox360Peripheral::SendSwitch(bool sendOut) { IOUSBDevRequest controlReq; controlReq.bmRequestType = USBmakebmRequestType(sendOut ? kUSBOut : kUSBIn, kUSBVendor, kUSBDevice); controlReq.bRequest = 0xa1; controlReq.wValue = 0x0000; controlReq.wIndex = 0xe416; controlReq.wLength = sizeof(chatpadInit); controlReq.pData = chatpadInit; if (device->DeviceRequest(&controlReq, 100, 100, NULL) == kIOReturnSuccess) return true; IOLog("start - failed to %s chatpad setting\n", sendOut ? "write" : "read"); return false; } void Xbox360Peripheral::SendToggle(void) { SendSpecial(serialToggle ? 0x1F : 0x1E); serialToggle = !serialToggle; } void Xbox360Peripheral::ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender) { Xbox360Peripheral *controller; controller = OSDynamicCast(Xbox360Peripheral, owner); controller->ChatPadTimerAction(sender); } void Xbox360Peripheral::ChatPadTimerAction(IOTimerEventSource *sender) { int nextTime, serialGot; serialGot = 0; nextTime = 1000; switch (serialTimerState) { case tsToggle: SendToggle(); if (serialActive) { if (!serialHeard) { serialActive = false; serialGot = 2; } } else { if (serialHeard) { serialTimerState = tsReset1; serialResetCount = 0; nextTime = 40; } } break; case tsMiniToggle: SendToggle(); if (serialHeard) { serialTimerState = tsSet1; nextTime = 40; } else { serialResetCount++; if (serialResetCount > 3) { serialTimerState = tsToggle; } else { serialTimerState = tsReset1; nextTime = 40; } } break; case tsReset1: SendSpecial(0x1B); serialTimerState = tsReset2; nextTime = 35; break; case tsReset2: SendSpecial(0x1B); serialTimerState = tsMiniToggle; nextTime = 150; break; case tsSet1: SendSpecial(0x18); serialTimerState = tsSet2; nextTime = 10; break; case tsSet2: SendSpecial(0x10); serialTimerState = tsSet3; nextTime = 10; break; case tsSet3: SendSpecial(0x03); serialTimerState = tsToggle; nextTime = 940; serialActive = true; serialGot = 1; break; } sender->setTimeoutMS(nextTime); // Todo: Make it take into account function execution time? serialHeard = false; // Make it happen after the timer's set, for minimum impact switch (serialGot) { case 1: SerialConnect(); break; case 2: SerialDisconnect(); break; default: break; } } // Read the settings from the registry void Xbox360Peripheral::readSettings(void) { OSDictionary *dataDictionary; OSBoolean *value; OSNumber *number; dataDictionary=OSDynamicCast(OSDictionary,getProperty(kDriverSettingKey)); if(dataDictionary==NULL) return; value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertLeftX")); if(value!=NULL) invertLeftX=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertLeftY")); if(value!=NULL) invertLeftY=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertRightX")); if(value!=NULL) invertRightX=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertRightY")); if(value!=NULL) invertRightY=value->getValue(); number=OSDynamicCast(OSNumber,dataDictionary->getObject("DeadzoneLeft")); if(number!=NULL) deadzoneLeft=number->unsigned32BitValue(); number=OSDynamicCast(OSNumber,dataDictionary->getObject("DeadzoneRight")); if(number!=NULL) deadzoneRight=number->unsigned32BitValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("RelativeLeft")); if(value!=NULL) relativeLeft=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("RelativeRight")); if(value!=NULL) relativeRight=value->getValue(); /* IOLog("Xbox360Peripheral preferences loaded:\n invertLeft X: %s, Y: %s\n invertRight X: %s, Y:%s\n deadzone Left: %d, Right: %d\n\n", invertLeftX?"True":"False",invertLeftY?"True":"False", invertRightX?"True":"False",invertRightY?"True":"False", deadzoneLeft,deadzoneRight); */ } // Initialise the extension bool Xbox360Peripheral::init(OSDictionary *propTable) { bool res=super::init(propTable); mainLock = IOLockAlloc(); device=NULL; interface=NULL; inPipe=NULL; outPipe=NULL; inBuffer=NULL; padHandler = NULL; serialIn = NULL; serialInPipe = NULL; serialInBuffer = NULL; serialTimer = NULL; serialHandler = NULL; // Default settings invertLeftX=invertLeftY=FALSE; invertRightX=invertRightY=FALSE; deadzoneLeft=deadzoneRight=0; relativeLeft=relativeRight=FALSE; // Done return res; } // Free the extension void Xbox360Peripheral::free(void) { IOLockFree(mainLock); super::free(); } bool Xbox360Peripheral::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest intf; IOUSBFindEndpointRequest pipe; XBOX360_OUT_LED led; IOWorkLoop *workloop = NULL; if (!super::start(provider)) return false; // Get device device=OSDynamicCast(IOUSBDevice,provider); if(device==NULL) { IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if(device->GetNumConfigurations()<1) { device=NULL; IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd=device->GetFullConfigurationDescriptor(0); if(cd==NULL) { device=NULL; IOLog("start - couldn't get configuration descriptor\n"); goto fail; } // Open if(!device->open(this)) { device=NULL; IOLog("start - unable to open device\n"); goto fail; } if(device->SetConfiguration(this,cd->bConfigurationValue,true)!=kIOReturnSuccess) { IOLog("start - unable to set configuration\n"); goto fail; } // Get release { UInt16 release = device->GetDeviceRelease(); switch (release) { default: IOLog("Unknown device release %.4x", release); // fall through case 0x0110: chatpadInit[0] = 0x01; chatpadInit[1] = 0x02; break; case 0x0114: chatpadInit[0] = 0x09; chatpadInit[1] = 0x00; break; } } // Find correct interface intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=93; intf.bInterfaceProtocol=1; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { IOLog("start - unable to find the interface\n"); goto fail; } interface->open(this); // Find pipes pipe.direction=kUSBIn; pipe.interval=0; pipe.type=kUSBInterrupt; pipe.maxPacketSize=0; inPipe=interface->FindNextPipe(NULL,&pipe); if(inPipe==NULL) { IOLog("start - unable to find in pipe\n"); goto fail; } inPipe->retain(); pipe.direction=kUSBOut; outPipe=interface->FindNextPipe(NULL,&pipe); if(outPipe==NULL) { IOLog("start - unable to find out pipe\n"); goto fail; } outPipe->retain(); // Get a buffer inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe)); if(inBuffer==NULL) { IOLog("start - failed to allocate input buffer\n"); goto fail; } // Find chatpad interface intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass = 93; intf.bInterfaceProtocol = 2; intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; serialIn = device->FindNextInterface(NULL, &intf); if (serialIn == NULL) { IOLog("start - unable to find chatpad interface\n"); goto nochat; } serialIn->open(this); // Find chatpad pipe pipe.direction = kUSBIn; pipe.interval = 0; pipe.type = kUSBInterrupt; pipe.maxPacketSize = 0; serialInPipe = serialIn->FindNextPipe(NULL, &pipe); if (serialInPipe == NULL) { IOLog("start - unable to find chatpad in pipe\n"); goto fail; } serialInPipe->retain(); // Get a buffer for the chatpad serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe)); if (serialInBuffer == NULL) { IOLog("start - failed to allocate input buffer for chatpad\n"); goto fail; } // Create timer for chatpad serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { IOLog("start - failed to create timer for chatpad\n"); goto fail; } workloop = getWorkLoop(); if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) { IOLog("start - failed to connect timer for chatpad\n"); goto fail; } // Configure ChatPad // Send 'configuration' SendInit(0xa30c, 0x4423); SendInit(0x2344, 0x7f03); SendInit(0x5839, 0x6832); // Set 'switch' if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) goto fail; // Begin toggle serialHeard = false; serialActive = false; serialToggle = false; serialResetCount = 0; serialTimerState = tsToggle; serialTimer->setTimeoutMS(1000); // Begin reading if (!QueueSerialRead()) goto fail; nochat: if (!QueueRead()) goto fail; // Disable LED Xbox360_Prepare(led,outLed); led.pattern=ledOff; QueueWrite(&led,sizeof(led)); // Done PadConnect(); registerService(); return true; fail: ReleaseAll(); return false; } // Set up an asynchronous read bool Xbox360Peripheral::QueueRead(void) { IOUSBCompletion complete; IOReturn err; if ((inPipe == NULL) || (inBuffer == NULL)) return false; complete.target=this; complete.action=ReadCompleteInternal; complete.parameter=inBuffer; err=inPipe->Read(inBuffer,0,0,inBuffer->getLength(),&complete); if(err==kIOReturnSuccess) return true; else { IOLog("read - failed to start (0x%.8x)\n",err); return false; } } bool Xbox360Peripheral::QueueSerialRead(void) { IOUSBCompletion complete; IOReturn err; if ((serialInPipe == NULL) || (serialInBuffer == NULL)) return false; complete.target = this; complete.action = SerialReadCompleteInternal; complete.parameter = serialInBuffer; err = serialInPipe->Read(serialInBuffer, 0, 0, serialInBuffer->getLength(), &complete); if (err == kIOReturnSuccess) { return true; } else { IOLog("read - failed to start for chatpad (0x%.8x)\n",err); return false; } } // Set up an asynchronous write bool Xbox360Peripheral::QueueWrite(const void *bytes,UInt32 length) { IOBufferMemoryDescriptor *outBuffer; IOUSBCompletion complete; IOReturn err; outBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,length); if(outBuffer==NULL) { IOLog("send - unable to allocate buffer\n"); return false; } outBuffer->writeBytes(0,bytes,length); complete.target=this; complete.action=WriteCompleteInternal; complete.parameter=outBuffer; err=outPipe->Write(outBuffer,0,0,length,&complete); if(err==kIOReturnSuccess) return true; else { IOLog("send - failed to start (0x%.8x)\n",err); return false; } } void Xbox360Peripheral::stop(IOService *provider) { ReleaseAll(); super::stop(provider); } // Releases all the objects used void Xbox360Peripheral::ReleaseAll(void) { LockRequired locker(mainLock); SerialDisconnect(); PadDisconnect(); if (serialTimer != NULL) { serialTimer->cancelTimeout(); getWorkLoop()->removeEventSource(serialTimer); serialTimer->release(); serialTimer = NULL; } if (serialInPipe != NULL) { serialInPipe->Abort(); serialInPipe->release(); serialInPipe = NULL; } if (serialInBuffer != NULL) { serialInBuffer->release(); serialInBuffer = NULL; } if (serialIn != NULL) { serialIn->close(this); serialIn = NULL; } if(outPipe!=NULL) { outPipe->Abort(); outPipe->release(); outPipe=NULL; } if(inPipe!=NULL) { inPipe->Abort(); inPipe->release(); inPipe=NULL; } if(inBuffer!=NULL) { inBuffer->release(); inBuffer=NULL; } if(interface!=NULL) { interface->close(this); interface=NULL; } if(device!=NULL) { device->close(this); device=NULL; } } // Handle message sent to the driver IOReturn Xbox360Peripheral::message(UInt32 type,IOService *provider,void *argument) { switch(type) { case kIOMessageServiceIsTerminated: case kIOMessageServiceIsRequestingClose: if(device->isOpen(this)) ReleaseAll(); return kIOReturnSuccess; default: return super::message(type,provider,argument); } } // This returns the abs() value of a short, swapping it if necessary static inline XBox360_SShort getAbsolute(XBox360_SShort value) { XBox360_SShort reverse; #ifdef __LITTLE_ENDIAN__ reverse=value; #elif __BIG_ENDIAN__ reverse=((value&0xFF00)>>8)|((value&0x00FF)<<8); #else #error Unknown CPU byte order #endif return (reverse<0)?~reverse:reverse; } // Adjusts the report for any settings speciified by the user void Xbox360Peripheral::fiddleReport(IOBufferMemoryDescriptor *buffer) { XBOX360_IN_REPORT *report=(XBOX360_IN_REPORT*)buffer->getBytesNoCopy(); if(invertLeftX) report->left.x=~report->left.x; if(!invertLeftY) report->left.y=~report->left.y; if(invertRightX) report->right.x=~report->right.x; if(!invertRightY) report->right.y=~report->right.y; if(deadzoneLeft!=0) { if(relativeLeft) { if((getAbsolute(report->left.x)left.y)left.x=0; report->left.y=0; } } else { if(getAbsolute(report->left.x)left.x=0; if(getAbsolute(report->left.y)left.y=0; } } if(deadzoneRight!=0) { if(relativeRight) { if((getAbsolute(report->right.x)right.y)right.x=0; report->right.y=0; } } else { if(getAbsolute(report->right.x)right.x=0; if(getAbsolute(report->right.y)right.y=0; } } } // This forwards a completed read notification to a member function void Xbox360Peripheral::ReadCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining) { if(target!=NULL) ((Xbox360Peripheral*)target)->ReadComplete(parameter,status,bufferSizeRemaining); } void Xbox360Peripheral::SerialReadCompleteInternal(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { if (target != NULL) ((Xbox360Peripheral*)target)->SerialReadComplete(parameter, status, bufferSizeRemaining); } // This forwards a completed write notification to a member function void Xbox360Peripheral::WriteCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining) { if(target!=NULL) ((Xbox360Peripheral*)target)->WriteComplete(parameter,status,bufferSizeRemaining); } // This handles a completed asynchronous read void Xbox360Peripheral::ReadComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining) { if (padHandler != NULL) // avoid deadlock with release { LockRequired locker(mainLock); IOReturn err; bool reread=!isInactive(); switch(status) { case kIOReturnOverrun: IOLog("read - kIOReturnOverrun, clearing stall\n"); if (inPipe != NULL) inPipe->ClearStall(); // Fall through case kIOReturnSuccess: if (inBuffer != NULL) { const XBOX360_IN_REPORT *report=(const XBOX360_IN_REPORT*)inBuffer->getBytesNoCopy(); if((report->header.command==inReport)&&(report->header.size==sizeof(XBOX360_IN_REPORT))) { fiddleReport(inBuffer); err = padHandler->handleReport(inBuffer, kIOHIDReportTypeInput); if(err!=kIOReturnSuccess) { IOLog("read - failed to handle report: 0x%.8x\n",err); } } } break; case kIOReturnNotResponding: IOLog("read - kIOReturnNotResponding\n"); reread=false; break; default: reread=false; break; } if(reread) QueueRead(); } } void Xbox360Peripheral::SerialReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { if (padHandler != NULL) // avoid deadlock with release { LockRequired locker(mainLock); bool reread = !isInactive(); switch (status) { case kIOReturnOverrun: IOLog("read (serial) - kIOReturnOverrun, clearing stall\n"); if (serialInPipe != NULL) serialInPipe->ClearStall(); // Fall through case kIOReturnSuccess: serialHeard = true; if (serialInBuffer != NULL) SerialMessage(serialInBuffer, serialInBuffer->getCapacity() - bufferSizeRemaining); break; case kIOReturnNotResponding: IOLog("read (serial) - kIOReturnNotResponding\n"); reread = false; break; default: reread = false; break; } if (reread) QueueSerialRead(); } } // Handle a completed asynchronous write void Xbox360Peripheral::WriteComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining) { IOMemoryDescriptor *memory=(IOMemoryDescriptor*)parameter; if(status!=kIOReturnSuccess) { IOLog("write - Error writing: 0x%.8x\n",status); } memory->release(); } // Called by the userspace IORegistryEntrySetCFProperties function IOReturn Xbox360Peripheral::setProperties(OSObject *properties) { OSDictionary *dictionary; dictionary=OSDynamicCast(OSDictionary,properties); if(dictionary!=NULL) { setProperty(kDriverSettingKey,dictionary); readSettings(); return kIOReturnSuccess; } else return kIOReturnBadArgument; } IOHIDDevice* Xbox360Peripheral::getController(int index) { switch (index) { case 0: return padHandler; case 1: return serialHandler; default: return NULL; } } // Main controller support void Xbox360Peripheral::PadConnect(void) { PadDisconnect(); padHandler = new Xbox360ControllerClass; if (padHandler != NULL) { const OSString *keys[] = { OSString::withCString(kIOSerialDeviceType), OSString::withCString("IOCFPlugInTypes"), OSString::withCString("IOKitDebug"), }; const OSObject *objects[] = { OSNumber::withNumber((unsigned long long)1, 32), getProperty("IOCFPlugInTypes"), OSNumber::withNumber((unsigned long long)65535, 32), }; OSDictionary *dictionary = OSDictionary::withObjects(objects, keys, sizeof(keys) / sizeof(keys[0]), 0); if (padHandler->init(dictionary)) { padHandler->attach(this); padHandler->start(this); } else { padHandler->release(); padHandler = NULL; } } } void Xbox360Peripheral::PadDisconnect(void) { if (padHandler != NULL) { padHandler->terminate(kIOServiceRequired | kIOServiceSynchronous); padHandler->release(); padHandler = NULL; } } // Serial peripheral support void Xbox360Peripheral::SerialConnect(void) { SerialDisconnect(); serialHandler = new ChatPadKeyboardClass; if (serialHandler != NULL) { const OSString *keys[] = { OSString::withCString(kIOSerialDeviceType), }; const OSObject *objects[] = { OSNumber::withNumber((unsigned long long)0, 32), }; OSDictionary *dictionary = OSDictionary::withObjects(objects, keys, sizeof(keys) / sizeof(keys[0]), 0); if (serialHandler->init(dictionary)) { serialHandler->attach(this); serialHandler->start(this); } else { serialHandler->release(); serialHandler = NULL; } } } void Xbox360Peripheral::SerialDisconnect(void) { if (serialHandler != NULL) { // Hope it's okay to terminate twice... serialHandler->terminate(kIOServiceRequired | kIOServiceSynchronous); serialHandler->release(); serialHandler = NULL; } } void Xbox360Peripheral::SerialMessage(IOBufferMemoryDescriptor *data, size_t length) { if (serialHandler != NULL) { char *buffer = (char*)data->getBytesNoCopy(); if ((length == 5) && (buffer[0] == 0x00)) serialHandler->handleReport(data, kIOHIDReportTypeInput); } } ================================================ FILE: 360Controller/_60Controller.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro _60Controller.h - declaration of the driver main class This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XBOX360CONTROLLER_H__ #define __XBOX360CONTROLLER_H__ #include #include #include class Xbox360ControllerClass; class ChatPadKeyboardClass; class Xbox360Peripheral : public IOService { OSDeclareDefaultStructors(Xbox360Peripheral) private: void ReleaseAll(void); bool QueueRead(void); bool QueueSerialRead(void); static void SerialReadCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); static void ReadCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); static void WriteCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); void SerialReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); void fiddleReport(IOBufferMemoryDescriptor *buffer); void readSettings(void); static void ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender); void ChatPadTimerAction(IOTimerEventSource *sender); void SendToggle(void); void SendSpecial(UInt16 value); void SendInit(UInt16 value, UInt16 index); bool SendSwitch(bool sendOut); void PadConnect(void); void PadDisconnect(void); void SerialConnect(void); void SerialDisconnect(void); void SerialMessage(IOBufferMemoryDescriptor *data, size_t length); protected: typedef enum { tsToggle, tsReset1, tsReset2, tsMiniToggle, tsSet1, tsSet2, tsSet3, } TIMER_STATE; IOUSBDevice *device; IOLock *mainLock; // Joypad IOUSBInterface *interface; IOUSBPipe *inPipe,*outPipe; IOBufferMemoryDescriptor *inBuffer; // Keyboard IOUSBInterface *serialIn; IOUSBPipe *serialInPipe; IOBufferMemoryDescriptor *serialInBuffer; IOTimerEventSource *serialTimer; bool serialToggle, serialHeard, serialActive; int serialResetCount; TIMER_STATE serialTimerState; ChatPadKeyboardClass *serialHandler; Xbox360ControllerClass *padHandler; UInt8 chatpadInit[2]; // Settings bool invertLeftX,invertLeftY; bool invertRightX,invertRightY; short deadzoneLeft,deadzoneRight; bool relativeLeft,relativeRight; public: // this is from the IORegistryEntry - no provider yet virtual bool init(OSDictionary *propTable); virtual void free(void); bool start(IOService *provider); void stop(IOService *provider); // IOKit methods. These methods are defines in virtual IOReturn setProperties(OSObject *properties); virtual IOReturn message(UInt32 type, IOService *provider, void *argument); // Hooks virtual void ReadComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining); virtual void WriteComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining); bool QueueWrite(const void *bytes,UInt32 length); IOHIDDevice* getController(int index); }; #endif /* __XBOX360CONTROLLER_H__ */ ================================================ FILE: 360Controller/chatpadhid.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro chatpadhid.h - a HID descriptor for the Microsoft ChatPad accessory This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // F:\Documents and Settings\Desktop\hid\ChatPad_Keyboard.h char ReportDescriptor[58] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x25, 0x00, // LOGICAL_MAXIMUM (0) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x09, 0xe1, // USAGE (Keyboard LeftShift) 0x09, 0xe0, // USAGE (Keyboard LeftControl) 0x09, 0xe2, // USAGE (Keyboard LeftAlt) 0x09, 0xe3, // USAGE (Keyboard Left GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x03, // REPORT_COUNT (3) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x26, 0xe7, 0x00, // LOGICAL_MAXIMUM (231) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0 // END_COLLECTION }; ================================================ FILE: 360Controller/chatpadkeys.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro chatpadkeys.cpp - Converts a chatpad scancode to a USB key value This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "chatpadkeys.h" #define ROW_SIZE 8 typedef struct MAP_DATA { unsigned char row[ROW_SIZE]; } MAP_DATA; static const MAP_DATA columns[] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E}, {0x00, 0x18, 0x1C, 0x17, 0x15, 0x08, 0x1A, 0x14}, {0x00, 0x0D, 0x0B, 0x0A, 0x09, 0x07, 0x16, 0x04}, {0x00, 0x11, 0x05, 0x19, 0x06, 0x1B, 0x1D, 0x00}, {0x00, 0x4F, 0x10, 0x37, 0x2C, 0x50, 0x00, 0x00}, {0x00, 0x00, 0x36, 0x28, 0x13, 0x27, 0x26, 0x25}, {0x00, 0x2A, 0x0F, 0x00, 0x00, 0x12, 0x0C, 0x0E}, }; unsigned char ChatPad2USB(unsigned char input) { unsigned char row, column; row = input & 0x0F; if (row >= ROW_SIZE) return 0x00; column = (input & 0xF0) >> 4; if (column >= (sizeof(columns) / sizeof(columns[0]))) return 0x00; return columns[column].row[row]; } ================================================ FILE: 360Controller/chatpadkeys.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro chatpadkeys.h - public functions of the ChatPad key handling This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ unsigned char ChatPad2USB(unsigned char input); ================================================ FILE: 360Controller/version.plist ================================================ BuildVersion 12 CFBundleVersion 1.0 ProductBuildVersion 7K571 ProjectName DevToolsWizardTemplates SourceVersion 3870000 ================================================ FILE: 360Controller/xbox360hid.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro xbox360hid.h - HID descriptor for the driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * This descriptor was generated using the USB HID definition tool available * from the USB people's website. It's not quite the same as the HID descriptor * on the free60.org site as I created this file before I knew about it and * just kept working with this one anyway :) */ char ReportDescriptor[196] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x05, // USAGE (Game Pad) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x3a, // USAGE (Counted Buffer) 0xa1, 0x02, // COLLECTION (Logical) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x02, // REPORT_COUNT (2) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x3f, // USAGE (Reserved) 0x09, 0x3b, // USAGE (Byte Count) 0x81, 0x01, // INPUT (Cnst,Ary,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x45, 0x01, // PHYSICAL_MAXIMUM (1) 0x95, 0x04, // REPORT_COUNT (4) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x0c, // USAGE_MINIMUM (Button 12) 0x29, 0x0f, // USAGE_MAXIMUM (Button 15) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x45, 0x01, // PHYSICAL_MAXIMUM (1) 0x95, 0x04, // REPORT_COUNT (4) 0x05, 0x09, // USAGE_PAGE (Button) 0x09, 0x09, // USAGE (Button 9) 0x09, 0x0a, // USAGE (Button 10) 0x09, 0x07, // USAGE (Button 7) 0x09, 0x08, // USAGE (Button 8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x45, 0x01, // PHYSICAL_MAXIMUM (1) 0x95, 0x03, // REPORT_COUNT (3) 0x05, 0x09, // USAGE_PAGE (Button) 0x09, 0x05, // USAGE (Button 5) 0x09, 0x06, // USAGE (Button 6) 0x09, 0x0b, // USAGE (Button 11) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x01, // INPUT (Cnst,Ary,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x45, 0x01, // PHYSICAL_MAXIMUM (1) 0x95, 0x04, // REPORT_COUNT (4) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x04, // USAGE_MAXIMUM (Button 4) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255) 0x95, 0x02, // REPORT_COUNT (2) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x32, // USAGE (Z) 0x09, 0x35, // USAGE (Rz) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 0x10, // REPORT_SIZE (16) 0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768) 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767) 0x36, 0x00, 0x80, // PHYSICAL_MINIMUM (-32768) 0x46, 0xff, 0x7f, // PHYSICAL_MAXIMUM (32767) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x95, 0x02, // REPORT_COUNT (2) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x95, 0x02, // REPORT_COUNT (2) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x33, // USAGE (Rx) 0x09, 0x34, // USAGE (Ry) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; ================================================ FILE: 360Daemon/360Daemon.1 ================================================ .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. .\"See Also: .\"man mdoc.samples for a complete listing of options .\"man mdoc for the short list of editing options .\"/usr/share/misc/mdoc.template .Dd 7/8/07 \" DATE .Dt 360Daemon 1 \" Program name and manual section number .Os Darwin .Sh NAME \" Section Header - required - don't modify .Nm 360Daemon, .\" The following lines are read in generating the apropos(man -k) database. Use only key .\" words here as the database is built based on the words here and in the .ND line. .Nm Other_name_for_same_program(), .Nm Yet another name for the same program. .\" Use .Nm macro to designate other names for the documented program. .Nd This line parsed for whatis database. .Sh SYNOPSIS \" Section Header - required - don't modify .Nm .Op Fl abcd \" [-abcd] .Op Fl a Ar path \" [-a path] .Op Ar file \" [file] .Op Ar \" [file ...] .Ar arg0 \" Underlined argument - use .Ar anywhere to underline arg2 ... \" Arguments .Sh DESCRIPTION \" Section Header - required - don't modify Use the .Nm macro to refer to your program throughout the man page like such: .Nm Underlining is accomplished with the .Ar macro like this: .Ar underlined text . .Pp \" Inserts a space A list of items with descriptions: .Bl -tag -width -indent \" Begins a tagged list .It item a \" Each item preceded by .It macro Description of item a .It item b Description of item b .El \" Ends the list .Pp A list of flags and their descriptions: .Bl -tag -width -indent \" Differs from above in tag removed .It Fl a \"-a flag as a list item Description of -a flag .It Fl b Description of -b flag .El \" Ends the list .Pp .\" .Sh ENVIRONMENT \" May not be needed .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 .\" .It Ev ENV_VAR_1 .\" Description of ENV_VAR_1 .\" .It Ev ENV_VAR_2 .\" Description of ENV_VAR_2 .\" .El .Sh FILES \" File used or created by the topic of the man page .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact .It Pa /usr/share/file_name FILE_1 description .It Pa /Users/joeuser/Library/really_long_file_name FILE_2 description .El \" Ends the list .\" .Sh DIAGNOSTICS \" May not be needed .\" .Bl -diag .\" .It Diagnostic Tag .\" Diagnostic informtion here. .\" .It Diagnostic Tag .\" Diagnostic informtion here. .\" .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. .\" Please do not reference files that do not exist without filing a bug report .Xr a 1 , .Xr b 1 , .Xr c 1 , .Xr a 2 , .Xr b 2 , .Xr a 3 , .Xr b 3 .\" .Sh BUGS \" Document known, unremedied bugs .\" .Sh HISTORY \" Document history if command behaves in a unique manner ================================================ FILE: 360Daemon/360Daemon.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro 360Daemon.m - main functionality of the support daemon This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import #import #import #import #import #include #import #include "ControlPrefs.h" #define CHECK_SHOWAGAIN @"Do not show this message again" #define INSTALL_PATH @"/Library/Application Support/MICE/360Daemon" #define RESOURCE_PATH INSTALL_PATH @"/Resources" mach_port_t masterPort; IONotificationPortRef notifyPort; CFRunLoopSourceRef notifySource; io_iterator_t onIteratorWired; io_iterator_t onIteratorWireless; io_iterator_t onIteratorOther; io_iterator_t offIteratorWired; io_iterator_t offIteratorWireless; BOOL foundWirelessReceiver; NSString *leds[4]; CFUserNotificationRef activeAlert = nil; CFRunLoopSourceRef activeAlertSource; int activeAlertIndex; enum { kaPlugNCharge = 0, }; NSString *alertStrings[] = { @"You have attached a Microsoft Play & Charge cable for your XBox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!", }; static void releaseAlert(void) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), activeAlertSource, kCFRunLoopCommonModes); CFRelease(activeAlertSource); CFRelease(activeAlert); activeAlertSource = nil; activeAlert = nil; } static void callbackAlert(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; if (responseFlags & CFUserNotificationCheckBoxChecked(0)) SetAlertDisabled(activeAlertIndex); releaseAlert(); [pool release]; } static void ShowAlert(int index) { SInt32 error; NSArray *checkBoxes = [NSArray arrayWithObjects:CHECK_SHOWAGAIN, nil]; NSArray *dictKeys = [NSArray arrayWithObjects: (NSString*)kCFUserNotificationAlertHeaderKey, (NSString*)kCFUserNotificationAlertMessageKey, (NSString*)kCFUserNotificationCheckBoxTitlesKey, (NSString*)kCFUserNotificationIconURLKey, nil]; NSArray *dictValues = [NSArray arrayWithObjects: @"XBox 360 Controller Driver", alertStrings[index], checkBoxes, [NSURL fileURLWithPath:RESOURCE_PATH @"/Alert.tif"], nil]; NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:dictValues forKeys:dictKeys]; if (AlertDisabled(index)) return; if (activeAlert != nil) { CFUserNotificationCancel(activeAlert); releaseAlert(); } activeAlertIndex = index; activeAlert = CFUserNotificationCreate(kCFAllocatorDefault, 0, kCFUserNotificationPlainAlertLevel, &error, (CFDictionaryRef)dictionary); activeAlertSource = CFUserNotificationCreateRunLoopSource(kCFAllocatorDefault, activeAlert, callbackAlert, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), activeAlertSource, kCFRunLoopCommonModes); } static void ConfigureDevice(io_service_t object) { IOCFPlugInInterface **iodev; IOUSBDeviceInterface **dev; IOReturn err; SInt32 score; if ((!IOCreatePlugInInterfaceForService(object, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score))&&iodev) { err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&dev); (*iodev)->Release(iodev); if ((!err) && dev) { if ((*dev)->USBDeviceOpen(dev) == 0) { IOUSBConfigurationDescriptorPtr confDesc; if ((*dev)->GetConfigurationDescriptorPtr(dev, 0, &confDesc) == 0) { (*dev)->SetConfiguration(dev, confDesc->bConfigurationValue); // Open interface? Hopefully not necessary } (*dev)->USBDeviceClose(dev); } (*dev)->Release(dev); } } } // Supported device - connecting - set settings? static void callbackConnected(void *param,io_iterator_t iterator) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; io_service_t object = 0; while ((object = IOIteratorNext(iterator)) != 0) { /* CFStringRef bob = IOObjectCopyClass(object); NSLog(@"Found %p: %@", object, bob); CFRelease(bob); */ if (IOObjectConformsTo(object, "WirelessHIDDevice") || IOObjectConformsTo(object, "Xbox360ControllerClass")) { FFDeviceObjectReference forceFeedback; NSString *serialNumber; serialNumber = GetSerialNumber(object); // Supported device - load settings ConfigController(object, GetController(serialNumber)); // Set LEDs forceFeedback = 0; if (FFCreateDevice(object, &forceFeedback) != FF_OK) forceFeedback = 0; if (forceFeedback != 0) { FFEFFESCAPE escape; unsigned char c; int i; c = 0x0a; if (serialNumber != nil) { for (i = 0; i < 4; i++) { if ((leds[i] == nil) || ([leds[i] caseInsensitiveCompare:serialNumber] == NSOrderedSame)) { c = 0x06 + i; if (leds[i] == nil) leds[i] = [serialNumber retain]; // NSLog(@"Added controller with LED %i", i); break; } } } escape.dwSize = sizeof(escape); escape.dwCommand = 0x02; escape.cbInBuffer = sizeof(c); escape.lpvInBuffer = &c; escape.cbOutBuffer = 0; escape.lpvOutBuffer = NULL; FFDeviceEscape(forceFeedback, &escape); FFReleaseDevice(forceFeedback); } } else { CFTypeRef vendorID = IORegistryEntrySearchCFProperty(object,kIOServicePlane,CFSTR("idVendor"),kCFAllocatorDefault,kIORegistryIterateRecursively | kIORegistryIterateParents); CFTypeRef productID = IORegistryEntrySearchCFProperty(object,kIOServicePlane,CFSTR("idProduct"),kCFAllocatorDefault,kIORegistryIterateRecursively | kIORegistryIterateParents); if ((vendorID != NULL) && (productID != NULL)) { UInt32 idVendor = [((NSNumber*)vendorID) unsignedIntValue]; UInt32 idProduct = [((NSNumber*)productID) unsignedIntValue]; if (idVendor == 0x045e) { // Microsoft switch (idProduct) { case 0x028f: // Plug'n'charge cable if (!foundWirelessReceiver) ShowAlert(kaPlugNCharge); ConfigureDevice(object); break; case 0x0719: // Microsoft Wireless Gaming Receiver case 0x0291: // Third party Wireless Gaming Receiver foundWirelessReceiver = TRUE; break; } } } if (vendorID != NULL) CFRelease(vendorID); if (productID != NULL) CFRelease(productID); } IOObjectRelease(object); } [pool release]; } // Supported device - disconnecting static void callbackDisconnected(void *param, io_iterator_t iterator) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; io_service_t object = 0; NSString *serial; int i; while ((object = IOIteratorNext(iterator)) != 0) { /* CFStringRef bob = IOObjectCopyClass(object); NSLog(@"Lost %p: %@", object, bob); CFRelease(bob); */ serial = GetSerialNumber(object); if (serial != nil) { for (i = 0; i < 4; i++) { if (leds[i] == nil) continue; if ([leds[i] caseInsensitiveCompare:serial] == NSOrderedSame) { [leds[i] release]; leds[i] = nil; // NSLog(@"Removed controller with LED %i", i); } } } IOObjectRelease(object); } [pool release]; } // Entry point int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; foundWirelessReceiver = FALSE; memset(leds, 0, sizeof(leds)); // Get master port, for accessing I/O Kit IOMasterPort(MACH_PORT_NULL,&masterPort); // Set up notification of USB device addition/removal notifyPort=IONotificationPortCreate(masterPort); notifySource=IONotificationPortGetRunLoopSource(notifyPort); CFRunLoopAddSource(CFRunLoopGetCurrent(),notifySource,kCFRunLoopCommonModes); // Start listening // USB devices IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, IOServiceMatching(kIOUSBDeviceClassName), callbackConnected, NULL, &onIteratorOther); callbackConnected(NULL, onIteratorOther); // Wired 360 devices IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, IOServiceMatching("Xbox360ControllerClass"), callbackConnected, NULL, &onIteratorWired); callbackConnected(NULL, onIteratorWired); IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, IOServiceMatching("Xbox360ControllerClass"), callbackDisconnected, NULL, &offIteratorWired); callbackDisconnected(NULL, offIteratorWired); // Wireless 360 devices IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, IOServiceMatching("WirelessHIDDevice"), callbackConnected, NULL, &onIteratorWireless); callbackConnected(NULL, onIteratorWireless); IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, IOServiceMatching("WirelessHIDDevice"), callbackDisconnected, NULL, &offIteratorWireless); callbackDisconnected(NULL, offIteratorWireless); // Run loop CFRunLoopRun(); // Stop listening IOObjectRelease(onIteratorOther); IOObjectRelease(onIteratorWired); IOObjectRelease(offIteratorWired); IOObjectRelease(onIteratorWireless); IOObjectRelease(offIteratorWireless); CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifySource, kCFRunLoopCommonModes); CFRunLoopSourceInvalidate(notifySource); IONotificationPortDestroy(notifyPort); // End [pool release]; return 0; } ================================================ FILE: 360Daemon/360Daemon.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 3B7905000CE3F6A400ACB699 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B7904FF0CE3F6A400ACB699 /* ForceFeedback.framework */; }; 3B7A8E2C0CE14E38005BB45B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B7A8E2B0CE14E38005BB45B /* IOKit.framework */; }; 3B8698090CE2903100283CEC /* ControlPrefs.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B8698080CE2903100283CEC /* ControlPrefs.m */; }; 8DD76F9A0486AA7600D96B5E /* 360Daemon.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* 360Daemon.m */; settings = {ATTRIBUTES = (); }; }; 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; 8DD76F9F0486AA7600D96B5E /* 360Daemon.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* 360Daemon.1 */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( 8DD76F9F0486AA7600D96B5E /* 360Daemon.1 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 08FB7796FE84155DC02AAC07 /* 360Daemon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = 360Daemon.m; sourceTree = ""; }; 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 32A70AAB03705E1F00C91783 /* 360Daemon_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 360Daemon_Prefix.pch; sourceTree = ""; }; 3B7904D50CE3F13700ACB699 /* Alert.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Alert.tif; sourceTree = ""; }; 3B7904FF0CE3F6A400ACB699 /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = /System/Library/Frameworks/ForceFeedback.framework; sourceTree = ""; }; 3B7A8E2B0CE14E38005BB45B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 3B8698070CE2903100283CEC /* ControlPrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlPrefs.h; sourceTree = ""; }; 3B8698080CE2903100283CEC /* ControlPrefs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ControlPrefs.m; sourceTree = ""; }; 3BBB7EED16C387C600BC7827 /* com.mice.360Daemon.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.mice.360Daemon.plist; sourceTree = ""; }; 8DD76FA10486AA7600D96B5E /* 360Daemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = 360Daemon; sourceTree = BUILT_PRODUCTS_DIR; }; C6859EA3029092ED04C91782 /* 360Daemon.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = 360Daemon.1; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */, 3B7A8E2C0CE14E38005BB45B /* IOKit.framework in Frameworks */, 3B7905000CE3F6A400ACB699 /* ForceFeedback.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 08FB7794FE84155DC02AAC07 /* 360Daemon */ = { isa = PBXGroup; children = ( 08FB7795FE84155DC02AAC07 /* Source */, C6859EA2029092E104C91782 /* Documentation */, 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, ); name = 360Daemon; sourceTree = ""; }; 08FB7795FE84155DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( 3B7904D50CE3F13700ACB699 /* Alert.tif */, 3B8698070CE2903100283CEC /* ControlPrefs.h */, 3B8698080CE2903100283CEC /* ControlPrefs.m */, 32A70AAB03705E1F00C91783 /* 360Daemon_Prefix.pch */, 08FB7796FE84155DC02AAC07 /* 360Daemon.m */, 3BBB7EED16C387C600BC7827 /* com.mice.360Daemon.plist */, ); name = Source; sourceTree = ""; }; 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 3B7904FF0CE3F6A400ACB699 /* ForceFeedback.framework */, 3B7A8E2B0CE14E38005BB45B /* IOKit.framework */, 08FB779EFE84155DC02AAC07 /* Foundation.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 1AB674ADFE9D54B511CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8DD76FA10486AA7600D96B5E /* 360Daemon */, ); name = Products; sourceTree = ""; }; C6859EA2029092E104C91782 /* Documentation */ = { isa = PBXGroup; children = ( C6859EA3029092ED04C91782 /* 360Daemon.1 */, ); name = Documentation; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 8DD76F960486AA7600D96B5E /* 360Daemon */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "360Daemon" */; buildPhases = ( 8DD76F990486AA7600D96B5E /* Sources */, 8DD76F9B0486AA7600D96B5E /* Frameworks */, 8DD76F9E0486AA7600D96B5E /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); name = 360Daemon; productInstallPath = "$(HOME)/bin"; productName = 360Daemon; productReference = 8DD76FA10486AA7600D96B5E /* 360Daemon */; productType = "com.apple.product-type.tool"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "360Daemon" */; compatibilityVersion = "Xcode 2.4"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 08FB7794FE84155DC02AAC07 /* 360Daemon */; projectDirPath = ""; projectRoot = ""; targets = ( 8DD76F960486AA7600D96B5E /* 360Daemon */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ 8DD76F990486AA7600D96B5E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8DD76F9A0486AA7600D96B5E /* 360Daemon.m in Sources */, 3B8698090CE2903100283CEC /* ControlPrefs.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB927508733DD40010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = 360Daemon_Prefix.pch; INSTALL_PATH = "$(HOME)/bin"; PRODUCT_NAME = 360Daemon; SDKROOT = ""; ZERO_LINK = YES; }; name = Debug; }; 1DEB927608733DD40010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = 360Daemon_Prefix.pch; INSTALL_PATH = "$(HOME)/bin"; PRODUCT_NAME = 360Daemon; }; name = Release; }; 1DEB927908733DD40010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; PREBINDING = NO; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Debug; }; 1DEB927A08733DD40010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; PREBINDING = NO; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "360Daemon" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB927508733DD40010E9CD /* Debug */, 1DEB927608733DD40010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "360Daemon" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB927908733DD40010E9CD /* Debug */, 1DEB927A08733DD40010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; } ================================================ FILE: 360Daemon/360Daemon_Prefix.pch ================================================ // // Prefix header for all source files of the '360Daemon' target in the '360Daemon' project. // #ifdef __OBJC__ #import #endif ================================================ FILE: 360Daemon/ControlPrefs.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro ControlPrefs.h - interface to the preferences functionality This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import #define DOM_DAEMON CFSTR("com.mice.driver.Xbox360Controller.daemon") #define DOM_CONTROLLERS CFSTR("com.mice.driver.Xbox360Controller.devices") #define D_SHOWONCE @"ShowAlert" #define D_KNOWNDEV @"KnownDevices" // Daemon's own settings void SetAlertDisabled(int index); BOOL AlertDisabled(int index); // Controller settings void SetController(NSString *serial, NSDictionary *data); NSDictionary* GetController(NSString *serial); // Configuration settings void SetKnownDevices(NSDictionary *devices); NSDictionary* GetKnownDevices(void); // Utility functions NSString* GetSerialNumber(io_service_t device); void ConfigController(io_service_t device, NSDictionary *config); ================================================ FILE: 360Daemon/ControlPrefs.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro ControlPrefs.m - code to read and write shared preferences This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import "ControlPrefs.h" void SetAlertDisabled(int index) { NSString *prop; NSNumber *value; prop = [NSString stringWithFormat:@"%@%i", D_SHOWONCE, index]; value = [NSNumber numberWithBool:TRUE]; CFPreferencesSetValue((CFStringRef)prop, value, DOM_DAEMON, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); CFPreferencesSynchronize((CFStringRef)DOM_DAEMON, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); } BOOL AlertDisabled(int index) { NSString *prop; BOOL result; CFPropertyListRef value; result = FALSE; prop = [NSString stringWithFormat:@"%@%i", D_SHOWONCE, index]; value = CFPreferencesCopyValue((CFStringRef)prop, DOM_DAEMON, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); if (value != NULL) { result = [((NSNumber*)value) boolValue]; CFRelease(value); } return result; } void SetController(NSString *serial, NSDictionary *data) { CFPreferencesSetValue((CFStringRef)serial, data, DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); } NSDictionary* GetController(NSString *serial) { CFPropertyListRef value; CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); value = CFPreferencesCopyValue((CFStringRef)serial, DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); return [((NSDictionary*)value) autorelease]; } NSString* GetSerialNumber(io_service_t device) { CFTypeRef value; value = IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR("USB Serial Number"), kCFAllocatorDefault, kIORegistryIterateRecursively); if (value == NULL) value = IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR("SerialNumber"), kCFAllocatorDefault, kIORegistryIterateRecursively); return [((NSString*)value) autorelease]; } void ConfigController(io_service_t device, NSDictionary *config) { IORegistryEntrySetCFProperties(device, config); } void SetKnownDevices(NSDictionary *devices) { // Setting the dictionary should work? NSData *data = [NSKeyedArchiver archivedDataWithRootObject:devices]; CFPreferencesSetValue((CFStringRef)D_KNOWNDEV, data, DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); } NSDictionary* GetKnownDevices(void) { CFPropertyListRef value; NSData *data; CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); value = CFPreferencesCopyValue((CFStringRef)D_KNOWNDEV, DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); data = [(NSData*)value autorelease]; if (data == nil) return nil; return [NSKeyedUnarchiver unarchiveObjectWithData:data]; } ================================================ FILE: 360Daemon/FoundationTool.pbproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 39; objects = { 014CEA4F0018CE4811CA2923 = { buildRules = ( ); buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; ZERO_LINK = YES; }; isa = PBXBuildStyle; name = Development; }; 014CEA500018CE4811CA2923 = { buildRules = ( ); buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; ZERO_LINK = NO; }; isa = PBXBuildStyle; name = Deployment; }; //010 //011 //012 //013 //014 //080 //081 //082 //083 //084 08FB7793FE84155DC02AAC07 = { buildSettings = { }; buildStyles = ( 014CEA4F0018CE4811CA2923, 014CEA500018CE4811CA2923, ); hasScannedForEncodings = 1; isa = PBXProject; mainGroup = 08FB7794FE84155DC02AAC07; projectDirPath = ""; targets = ( 8DD76F960486AA7600D96B5E, ); }; 08FB7794FE84155DC02AAC07 = { children = ( 08FB7795FE84155DC02AAC07, C6859EA2029092E104C91782, 08FB779DFE84155DC02AAC07, 1AB674ADFE9D54B511CA2CBB, ); isa = PBXGroup; name = "«PROJECTNAME»"; refType = 4; sourceTree = ""; }; 08FB7795FE84155DC02AAC07 = { children = ( 32A70AAB03705E1F00C91783, 08FB7796FE84155DC02AAC07, ); isa = PBXGroup; name = Source; refType = 4; sourceTree = ""; }; 08FB7796FE84155DC02AAC07 = { fileEncoding = 4; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "«PROJECTNAME».m"; refType = 4; sourceTree = ""; }; 08FB779DFE84155DC02AAC07 = { children = ( 08FB779EFE84155DC02AAC07, ); isa = PBXGroup; name = "External Frameworks and Libraries"; refType = 4; sourceTree = ""; }; 08FB779EFE84155DC02AAC07 = { fallbackIsa = PBXFileReference; isa = PBXFrameworkReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; refType = 0; sourceTree = ""; }; //080 //081 //082 //083 //084 //1A0 //1A1 //1A2 //1A3 //1A4 1AB674ADFE9D54B511CA2CBB = { children = ( 8DD76FA10486AA7600D96B5E, ); isa = PBXGroup; name = Products; refType = 4; sourceTree = ""; }; //1A0 //1A1 //1A2 //1A3 //1A4 //320 //321 //322 //323 //324 32A70AAB03705E1F00C91783 = { fileEncoding = 4; isa = PBXFileReference; lastKnownFileType = file; path = "«PROJECTNAME»_Prefix.pch"; refType = 4; sourceTree = ""; }; //320 //321 //322 //323 //324 //8D0 //8D1 //8D2 //8D3 //8D4 8DD76F960486AA7600D96B5E = { buildPhases = ( 8DD76F990486AA7600D96B5E, 8DD76F9B0486AA7600D96B5E, 8DD76F9E0486AA7600D96B5E, ); buildRules = ( ); buildSettings = { GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "«PROJECTNAME»_Prefix.pch"; INSTALL_PATH = "$(HOME)/bin"; PRODUCT_NAME = "«PROJECTNAME»"; }; dependencies = ( ); isa = PBXNativeTarget; name = "«PROJECTNAME»"; productInstallPath = "$(HOME)/bin"; productName = "«PROJECTNAME»"; productReference = 8DD76FA10486AA7600D96B5E; productType = "com.apple.product-type.tool"; }; 8DD76F990486AA7600D96B5E = { buildActionMask = 2147483647; files = ( 8DD76F9A0486AA7600D96B5E, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 8DD76F9A0486AA7600D96B5E = { fileRef = 08FB7796FE84155DC02AAC07; isa = PBXBuildFile; settings = { ATTRIBUTES = ( ); }; }; 8DD76F9B0486AA7600D96B5E = { buildActionMask = 2147483647; files = ( 8DD76F9C0486AA7600D96B5E, ); isa = PBXFrameworksBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 8DD76F9C0486AA7600D96B5E = { fileRef = 08FB779EFE84155DC02AAC07; isa = PBXBuildFile; settings = { }; }; 8DD76F9E0486AA7600D96B5E = { buildActionMask = 8; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( 8DD76F9F0486AA7600D96B5E, ); isa = PBXCopyFilesBuildPhase; runOnlyForDeploymentPostprocessing = 1; }; 8DD76F9F0486AA7600D96B5E = { fileRef = C6859EA3029092ED04C91782; isa = PBXBuildFile; settings = { }; }; 8DD76FA10486AA7600D96B5E = { explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; isa = PBXFileReference; path = "«PROJECTNAME»"; refType = 3; sourceTree = BUILT_PRODUCTS_DIR; }; //8D0 //8D1 //8D2 //8D3 //8D4 //C60 //C61 //C62 //C63 //C64 C6859EA2029092E104C91782 = { children = ( C6859EA3029092ED04C91782, ); isa = PBXGroup; name = Documentation; refType = 4; sourceTree = ""; }; C6859EA3029092ED04C91782 = { isa = PBXFileReference; lastKnownFileType = file; path = "«PROJECTNAME».1"; refType = 4; sourceTree = ""; }; }; rootObject = 08FB7793FE84155DC02AAC07; } ================================================ FILE: 360Daemon/com.mice.360Daemon.plist ================================================ RunAtLoad ProgramArguments /Library/Application Support/MICE/360Daemon/360Daemon KeepAlive Label com.mice.360Daemon ================================================ FILE: DriverTool/DriverTool.1 ================================================ .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. .\"See Also: .\"man mdoc.samples for a complete listing of options .\"man mdoc for the short list of editing options .\"/usr/share/misc/mdoc.template .Dd 8/05/2011 \" DATE .Dt DriverTool 1 \" Program name and manual section number .Os Darwin .Sh NAME \" Section Header - required - don't modify .Nm DriverTool, .\" The following lines are read in generating the apropos(man -k) database. Use only key .\" words here as the database is built based on the words here and in the .ND line. .Nm Other_name_for_same_program(), .Nm Yet another name for the same program. .\" Use .Nm macro to designate other names for the documented program. .Nd This line parsed for whatis database. .Sh SYNOPSIS \" Section Header - required - don't modify .Nm .Op Fl abcd \" [-abcd] .Op Fl a Ar path \" [-a path] .Op Ar file \" [file] .Op Ar \" [file ...] .Ar arg0 \" Underlined argument - use .Ar anywhere to underline arg2 ... \" Arguments .Sh DESCRIPTION \" Section Header - required - don't modify Use the .Nm macro to refer to your program throughout the man page like such: .Nm Underlining is accomplished with the .Ar macro like this: .Ar underlined text . .Pp \" Inserts a space A list of items with descriptions: .Bl -tag -width -indent \" Begins a tagged list .It item a \" Each item preceded by .It macro Description of item a .It item b Description of item b .El \" Ends the list .Pp A list of flags and their descriptions: .Bl -tag -width -indent \" Differs from above in tag removed .It Fl a \"-a flag as a list item Description of -a flag .It Fl b Description of -b flag .El \" Ends the list .Pp .\" .Sh ENVIRONMENT \" May not be needed .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 .\" .It Ev ENV_VAR_1 .\" Description of ENV_VAR_1 .\" .It Ev ENV_VAR_2 .\" Description of ENV_VAR_2 .\" .El .Sh FILES \" File used or created by the topic of the man page .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact .It Pa /usr/share/file_name FILE_1 description .It Pa /Users/joeuser/Library/really_long_file_name FILE_2 description .El \" Ends the list .\" .Sh DIAGNOSTICS \" May not be needed .\" .Bl -diag .\" .It Diagnostic Tag .\" Diagnostic informtion here. .\" .It Diagnostic Tag .\" Diagnostic informtion here. .\" .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. .\" Please do not reference files that do not exist without filing a bug report .Xr a 1 , .Xr b 1 , .Xr c 1 , .Xr a 2 , .Xr b 2 , .Xr a 3 , .Xr b 3 .\" .Sh BUGS \" Document known, unremedied bugs .\" .Sh HISTORY \" Document history if command behaves in a unique manner ================================================ FILE: DriverTool/DriverTool.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro DriverTool.m - implementation of driver info tweaking tool This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import #define DRIVER_NAME @"360Controller.kext" static NSDictionary *infoPlistAttributes = nil; static NSString* GetDriverDirectory(void) { NSArray *data = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, YES); return [[data objectAtIndex:0] stringByAppendingPathComponent:@"Extensions"]; } static NSString* GetDriverConfigPath(NSString *driver) { NSString *root = GetDriverDirectory(); NSString *driverPath = [root stringByAppendingPathComponent:driver]; NSString *contents = [driverPath stringByAppendingPathComponent:@"Contents"]; return [contents stringByAppendingPathComponent:@"Info.plist"]; } static id ReadDriverConfig(NSString *driver) { NSString *filename; NSError *error = nil; NSData *data; NSDictionary *config; filename = GetDriverConfigPath(driver); infoPlistAttributes = [[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:&error] retain]; if (infoPlistAttributes == nil) { NSLog(@"Warning: Failed to read attributes of '%@': %@", filename, error); } data = [NSData dataWithContentsOfFile:filename]; config = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:0 format:NULL errorDescription:NULL]; return config; } static void WriteDriverConfig(NSString *driver, id config) { NSString *filename; NSString *errorString; NSData *data; filename = GetDriverConfigPath(driver); errorString = nil; data = [NSPropertyListSerialization dataFromPropertyList:config format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString]; if (data == nil) NSLog(@"Error writing config for driver: %@", errorString); [errorString release]; if (![data writeToFile:filename atomically:NO]) NSLog(@"Failed to write file!"); if (infoPlistAttributes != nil) { NSError *error = nil; if (![[NSFileManager defaultManager] setAttributes:infoPlistAttributes ofItemAtPath:filename error:&error]) { NSLog(@"Error setting attributes on '%@': %@", filename, error); } } } static void ScrubDevices(NSMutableDictionary *devices) { NSMutableArray *deviceKeys; deviceKeys = [NSMutableArray arrayWithCapacity:10]; for (NSString *key in [devices allKeys]) { NSDictionary *device = [devices objectForKey:key]; if ([(NSString*)[device objectForKey:@"IOClass"] compare:@"Xbox360Peripheral"] == NSOrderedSame) [deviceKeys addObject:key]; } [devices removeObjectsForKeys:deviceKeys]; } static id MakeMutableCopy(id object) { return [(id)CFPropertyListCreateDeepCopy( kCFAllocatorDefault, (CFTypeRef)object, kCFPropertyListMutableContainers) autorelease]; } static void AddDevice(NSMutableDictionary *personalities, NSString *name, int vendor, int product) { NSMutableDictionary *controller; controller = [NSMutableDictionary dictionaryWithCapacity:10]; // Standard [controller setObject:@"com.mice.driver.Xbox360Controller" forKey:@"CFBundleIdentifier"]; [controller setObject:[NSDictionary dictionaryWithObject:@"360Controller.kext/Contents/PlugIns/Feedback360.plugin" forKey:@"F4545CE5-BF5B-11D6-A4BB-0003933E3E3E"] forKey:@"IOCFPlugInTypes"]; [controller setObject:@"Xbox360Peripheral" forKey:@"IOClass"]; [controller setObject:@"IOUSBDevice" forKey:@"IOProviderClass"]; [controller setObject:[NSNumber numberWithInt:65535] forKey:@"IOKitDebug"]; // Device-specific [controller setObject:[NSNumber numberWithInt:vendor] forKey:@"idVendor"]; [controller setObject:[NSNumber numberWithInt:product] forKey:@"idProduct"]; // Add it to the tree [personalities setObject:controller forKey:name]; } static void AddDevices(NSMutableDictionary *personalities, int argc, const char *argv[]) { int i, count; count = (argc - 2) / 3; for (i = 0; i < count; i++) { NSString *name = [NSString stringWithCString:argv[(i * 3) + 2] encoding:NSUTF8StringEncoding]; int vendor = atoi(argv[(i * 3) + 3]); int product = atoi(argv[(i * 3) + 4]); AddDevice(personalities, name, vendor, product); } } int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSDictionary *config = ReadDriverConfig(DRIVER_NAME); if (argc == 1) { // Print out current types NSDictionary *types; NSArray *keys; types = [config objectForKey:@"IOKitPersonalities"]; keys = [types allKeys]; for (NSString *key in keys) { NSDictionary *device = [types objectForKey:key]; if ([(NSString*)[device objectForKey:@"IOClass"] compare:@"Xbox360Peripheral"] != NSOrderedSame) continue; fprintf(stdout, "%s,%i,%i\n", [key UTF8String], [[device objectForKey:@"idVendor"] intValue], [[device objectForKey:@"idProduct"] intValue]); } } else if ((argc > 1) && (strcmp(argv[1], "edit") == 0) && (((argc - 2) % 3) == 0)) { NSMutableDictionary *saving; NSMutableDictionary *devices; saving = MakeMutableCopy(config); devices = [saving objectForKey:@"IOKitPersonalities"]; ScrubDevices(devices); AddDevices(devices, argc, argv); WriteDriverConfig(DRIVER_NAME, saving); system("/usr/bin/touch /System/Library/Extensions"); } else NSLog(@"Invalid number of parameters (%i)", argc); [pool drain]; return 0; } ================================================ FILE: DriverTool/DriverTool.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 8DD76F9A0486AA7600D96B5E /* DriverTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* DriverTool.m */; settings = {ATTRIBUTES = (); }; }; 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; 8DD76F9F0486AA7600D96B5E /* DriverTool.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* DriverTool.1 */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( 8DD76F9F0486AA7600D96B5E /* DriverTool.1 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 08FB7796FE84155DC02AAC07 /* DriverTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DriverTool.m; sourceTree = ""; }; 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 32A70AAB03705E1F00C91783 /* DriverTool_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DriverTool_Prefix.pch; sourceTree = ""; }; 8DD76FA10486AA7600D96B5E /* DriverTool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = DriverTool; sourceTree = BUILT_PRODUCTS_DIR; }; C6859EA3029092ED04C91782 /* DriverTool.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = DriverTool.1; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 08FB7794FE84155DC02AAC07 /* DriverTool */ = { isa = PBXGroup; children = ( 08FB7795FE84155DC02AAC07 /* Source */, C6859EA2029092E104C91782 /* Documentation */, 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, ); name = DriverTool; sourceTree = ""; }; 08FB7795FE84155DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( 32A70AAB03705E1F00C91783 /* DriverTool_Prefix.pch */, 08FB7796FE84155DC02AAC07 /* DriverTool.m */, ); name = Source; sourceTree = ""; }; 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 08FB779EFE84155DC02AAC07 /* Foundation.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 1AB674ADFE9D54B511CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8DD76FA10486AA7600D96B5E /* DriverTool */, ); name = Products; sourceTree = ""; }; C6859EA2029092E104C91782 /* Documentation */ = { isa = PBXGroup; children = ( C6859EA3029092ED04C91782 /* DriverTool.1 */, ); name = Documentation; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 8DD76F960486AA7600D96B5E /* DriverTool */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "DriverTool" */; buildPhases = ( 8DD76F990486AA7600D96B5E /* Sources */, 8DD76F9B0486AA7600D96B5E /* Frameworks */, 8DD76F9E0486AA7600D96B5E /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); name = DriverTool; productInstallPath = "$(HOME)/bin"; productName = DriverTool; productReference = 8DD76FA10486AA7600D96B5E /* DriverTool */; productType = "com.apple.product-type.tool"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "DriverTool" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 08FB7794FE84155DC02AAC07 /* DriverTool */; projectDirPath = ""; projectRoot = ""; targets = ( 8DD76F960486AA7600D96B5E /* DriverTool */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ 8DD76F990486AA7600D96B5E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8DD76F9A0486AA7600D96B5E /* DriverTool.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB927508733DD40010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = DriverTool_Prefix.pch; INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = DriverTool; }; name = Debug; }; 1DEB927608733DD40010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = DriverTool_Prefix.pch; INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = DriverTool; SDKROOT = ""; }; name = Release; }; 1DEB927908733DD40010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Debug; }; 1DEB927A08733DD40010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; PREBINDING = NO; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "DriverTool" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB927508733DD40010E9CD /* Debug */, 1DEB927608733DD40010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "DriverTool" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB927908733DD40010E9CD /* Debug */, 1DEB927A08733DD40010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; } ================================================ FILE: DriverTool/DriverTool_Prefix.pch ================================================ // // Prefix header for all source files of the 'DriverTool' target in the 'DriverTool' project. // #ifdef __OBJC__ #import #endif ================================================ FILE: Feedback360/English.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ CFBundleName = "Feedback360"; NSHumanReadableCopyright = "© Colin Munro, 2005-2011"; ================================================ FILE: Feedback360/Feedback360.xcodeproj/colin.mode1 ================================================ ActivePerspectiveName Project AllowedModules BundleLoadPath MaxInstances n Module PBXSmartGroupTreeModule Name Groups and Files Outline View BundleLoadPath MaxInstances n Module PBXNavigatorGroup Name Editor BundleLoadPath MaxInstances n Module XCTaskListModule Name Task List BundleLoadPath MaxInstances n Module XCDetailModule Name File and Smart Group Detail Viewer BundleLoadPath MaxInstances 1 Module PBXBuildResultsModule Name Detailed Build Results Viewer BundleLoadPath MaxInstances 1 Module PBXProjectFindModule Name Project Batch Find Tool BundleLoadPath MaxInstances n Module PBXRunSessionModule Name Run Log BundleLoadPath MaxInstances n Module PBXBookmarksModule Name Bookmarks Tool BundleLoadPath MaxInstances n Module PBXClassBrowserModule Name Class Browser BundleLoadPath MaxInstances n Module PBXCVSModule Name Source Code Control Tool BundleLoadPath MaxInstances n Module PBXDebugBreakpointsModule Name Debug Breakpoints Tool BundleLoadPath MaxInstances n Module XCDockableInspector Name Inspector BundleLoadPath MaxInstances n Module PBXOpenQuicklyModule Name Open Quickly Tool BundleLoadPath MaxInstances 1 Module PBXDebugSessionModule Name Debugger BundleLoadPath MaxInstances 1 Module PBXDebugCLIModule Name Debug Console Description DefaultDescriptionKey DockingSystemVisible Extension mode1 FavBarConfig PBXProjectModuleGUID 3B2EF59109661AF5007BFB7B XCBarModuleItemNames XCBarModuleItems FirstTimeWindowDisplayed Identifier com.apple.perspectives.project.mode1 MajorVersion 31 MinorVersion 1 Name Default Notifications OpenEditors PerspectiveWidths -1 -1 Perspectives ChosenToolbarItems active-target-popup active-buildstyle-popup action NSToolbarFlexibleSpaceItem buildOrClean build-and-runOrDebug com.apple.ide.PBXToolbarStopButton get-info toggle-editor NSToolbarFlexibleSpaceItem com.apple.pbx.toolbar.searchfield ControllerClassBaseName IconName WindowOfProjectWithEditor Identifier perspective.project IsVertical Layout BecomeActive ContentConfiguration PBXBottomSmartGroupGIDs 1C37FBAC04509CD000000102 1C37FAAC04509CD000000102 1C08E77C0454961000C914BD 1C37FABC05509CD000000102 1C37FABC05539CD112110102 E2644B35053B69B200211256 1C37FABC04509CD000100104 1CC0EA4004350EF90044410B 1CC0EA4004350EF90041110B PBXProjectModuleGUID 1CE0B1FE06471DED0097A5F4 PBXProjectModuleLabel Files PBXProjectStructureProvided yes PBXSmartGroupTreeModuleColumnData PBXSmartGroupTreeModuleColumnWidthsKey 186 PBXSmartGroupTreeModuleColumnsKey_v4 MainColumn PBXSmartGroupTreeModuleOutlineStateKey_v7 PBXSmartGroupTreeModuleOutlineStateExpansionKey 089C166AFE841209C02AAC07 08FB77AFFE84173DC02AAC07 089C167CFE841241C02AAC07 3B2EF5470965B8E3007BFB7B 089C1671FE841209C02AAC07 3B2EF54B0965C358007BFB7B 0AA1909FFE8422F4C02AAC07 19C28FB6FE9D52B211CA2CBB 1C37FABC05509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey {{0, 0}, {186, 338}} PBXTopSmartGroupGIDs XCIncludePerspectivesSwitch XCSharingToken com.apple.Xcode.GFSharingToken GeometryConfiguration Frame {{0, 0}, {203, 356}} GroupTreeTableConfiguration MainColumn 186 RubberWindowFrame 308 400 690 397 0 0 1280 1002 Module PBXSmartGroupTreeModule Proportion 203pt Dock ContentConfiguration PBXProjectModuleGUID 1CE0B20306471E060097A5F4 PBXProjectModuleLabel MyNewFile14.java PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 1CE0B20406471E060097A5F4 PBXProjectModuleLabel MyNewFile14.java SplitCount 1 StatusBarVisibility GeometryConfiguration Frame {{0, 0}, {482, 0}} RubberWindowFrame 308 400 690 397 0 0 1280 1002 Module PBXNavigatorGroup Proportion 0pt ContentConfiguration PBXProjectModuleGUID 1CE0B20506471E060097A5F4 PBXProjectModuleLabel Detail GeometryConfiguration Frame {{0, 5}, {482, 351}} RubberWindowFrame 308 400 690 397 0 0 1280 1002 Module XCDetailModule Proportion 351pt Proportion 482pt Name Project ServiceClasses XCModuleDock PBXSmartGroupTreeModule XCModuleDock PBXNavigatorGroup XCDetailModule TableOfContents 3BCC40840BDA915400B1619B 1CE0B1FE06471DED0097A5F4 3BCC40850BDA915400B1619B 1CE0B20306471E060097A5F4 1CE0B20506471E060097A5F4 ToolbarConfiguration xcode.toolbar.config.default ControllerClassBaseName IconName WindowOfProject Identifier perspective.morph IsVertical 0 Layout BecomeActive 1 ContentConfiguration PBXBottomSmartGroupGIDs 1C37FBAC04509CD000000102 1C37FAAC04509CD000000102 1C08E77C0454961000C914BD 1C37FABC05509CD000000102 1C37FABC05539CD112110102 E2644B35053B69B200211256 1C37FABC04509CD000100104 1CC0EA4004350EF90044410B 1CC0EA4004350EF90041110B PBXProjectModuleGUID 11E0B1FE06471DED0097A5F4 PBXProjectModuleLabel Files PBXProjectStructureProvided yes PBXSmartGroupTreeModuleColumnData PBXSmartGroupTreeModuleColumnWidthsKey 186 PBXSmartGroupTreeModuleColumnsKey_v4 MainColumn PBXSmartGroupTreeModuleOutlineStateKey_v7 PBXSmartGroupTreeModuleOutlineStateExpansionKey 29B97314FDCFA39411CA2CEA 1C37FABC05509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey {{0, 0}, {186, 337}} PBXTopSmartGroupGIDs XCIncludePerspectivesSwitch 1 XCSharingToken com.apple.Xcode.GFSharingToken GeometryConfiguration Frame {{0, 0}, {203, 355}} GroupTreeTableConfiguration MainColumn 186 RubberWindowFrame 373 269 690 397 0 0 1440 878 Module PBXSmartGroupTreeModule Proportion 100% Name Morph PreferredWidth 300 ServiceClasses XCModuleDock PBXSmartGroupTreeModule TableOfContents 11E0B1FE06471DED0097A5F4 ToolbarConfiguration xcode.toolbar.config.default.short PerspectivesBarVisible ShelfIsVisible SourceDescription file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' StatusbarIsVisible TimeStamp 0.0 ToolbarDisplayMode 1 ToolbarIsVisible ToolbarSizeMode 1 Type Perspectives UpdateMessage The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? WindowJustification 5 WindowOrderList 3B2EF5820965C4A5007BFB7B /Users/colin/Projects2/OSX/360 Controller/Feedback360/Feedback360.xcodeproj WindowString 308 400 690 397 0 0 1280 1002 WindowTools FirstTimeWindowDisplayed Identifier windowTool.build IsVertical Layout Dock ContentConfiguration PBXProjectModuleGUID 1CD0528F0623707200166675 PBXProjectModuleLabel StatusBarVisibility GeometryConfiguration Frame {{0, 0}, {500, 218}} RubberWindowFrame 691 470 500 500 0 0 1280 1002 Module PBXNavigatorGroup Proportion 218pt ContentConfiguration PBXBuildLogShowsTranscriptDefaultKey {{0, 5}, {500, 231}} PBXProjectModuleGUID XCMainBuildResultsModuleGUID PBXProjectModuleLabel Build XCBuildResultsTrigger_Collapse 1021 XCBuildResultsTrigger_Open 1011 GeometryConfiguration Frame {{0, 223}, {500, 236}} RubberWindowFrame 691 470 500 500 0 0 1280 1002 Module PBXBuildResultsModule Proportion 236pt Proportion 459pt Name Build Results ServiceClasses PBXBuildResultsModule StatusbarIsVisible TableOfContents 3B2EF5820965C4A5007BFB7B 3BCC40880BDA916800B1619B 1CD0528F0623707200166675 XCMainBuildResultsModuleGUID ToolbarConfiguration xcode.toolbar.config.build WindowString 691 470 500 500 0 0 1280 1002 WindowToolGUID 3B2EF5820965C4A5007BFB7B WindowToolIsVisible Identifier windowTool.debugger Layout Dock ContentConfiguration Debugger HorizontalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {317, 164}} {{317, 0}, {377, 164}} VerticalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {694, 164}} {{0, 164}, {694, 216}} LauncherConfigVersion 8 PBXProjectModuleGUID 1C162984064C10D400B95A72 PBXProjectModuleLabel Debug - GLUTExamples (Underwater) GeometryConfiguration DebugConsoleDrawerSize {100, 120} DebugConsoleVisible None DebugConsoleWindowFrame {{200, 200}, {500, 300}} DebugSTDIOWindowFrame {{200, 200}, {500, 300}} Frame {{0, 0}, {694, 380}} RubberWindowFrame 321 238 694 422 0 0 1440 878 Module PBXDebugSessionModule Proportion 100% Proportion 100% Name Debugger ServiceClasses PBXDebugSessionModule StatusbarIsVisible 1 TableOfContents 1CD10A99069EF8BA00B06720 1C0AD2AB069F1E9B00FABCE6 1C162984064C10D400B95A72 1C0AD2AC069F1E9B00FABCE6 ToolbarConfiguration xcode.toolbar.config.debug WindowString 321 238 694 422 0 0 1440 878 WindowToolGUID 1CD10A99069EF8BA00B06720 WindowToolIsVisible 0 FirstTimeWindowDisplayed Identifier windowTool.find IsVertical Layout Dock Dock ContentConfiguration PBXProjectModuleGUID 1CDD528C0622207200134675 PBXProjectModuleLabel IOHIDLib.h StatusBarVisibility GeometryConfiguration Frame {{0, 0}, {781, 212}} RubberWindowFrame 31 477 781 470 0 0 1280 1002 Module PBXNavigatorGroup Proportion 781pt Proportion 212pt BecomeActive ContentConfiguration PBXProjectModuleGUID 1CD0528E0623707200166675 PBXProjectModuleLabel Project Find GeometryConfiguration Frame {{0, 217}, {781, 212}} RubberWindowFrame 31 477 781 470 0 0 1280 1002 Module PBXProjectFindModule Proportion 212pt Proportion 429pt Name Project Find ServiceClasses PBXProjectFindModule StatusbarIsVisible TableOfContents 1C530D57069F1CE1000CFCEE 3BCF4DD2097DA7030049C083 3BCF4DD3097DA7030049C083 1CDD528C0622207200134675 1CD0528E0623707200166675 WindowString 31 477 781 470 0 0 1280 1002 WindowToolGUID 1C530D57069F1CE1000CFCEE WindowToolIsVisible Identifier MENUSEPARATOR Identifier windowTool.debuggerConsole Layout Dock BecomeActive 1 ContentConfiguration PBXProjectModuleGUID 1C78EAAC065D492600B07095 PBXProjectModuleLabel Debugger Console GeometryConfiguration Frame {{0, 0}, {440, 358}} RubberWindowFrame 650 41 440 400 0 0 1280 1002 Module PBXDebugCLIModule Proportion 358pt Proportion 358pt Name Debugger Console ServiceClasses PBXDebugCLIModule StatusbarIsVisible 1 TableOfContents 1C78EAAD065D492600B07095 1C78EAAE065D492600B07095 1C78EAAC065D492600B07095 WindowString 650 41 440 400 0 0 1280 1002 Identifier windowTool.run Layout Dock ContentConfiguration LauncherConfigVersion 3 PBXProjectModuleGUID 1CD0528B0623707200166675 PBXProjectModuleLabel Run Runner HorizontalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {493, 167}} {{0, 176}, {493, 267}} VerticalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {405, 443}} {{414, 0}, {514, 443}} GeometryConfiguration Frame {{0, 0}, {460, 159}} RubberWindowFrame 316 696 459 200 0 0 1280 1002 Module PBXRunSessionModule Proportion 159pt Proportion 159pt Name Run Log ServiceClasses PBXRunSessionModule StatusbarIsVisible 1 TableOfContents 1C0AD2B3069F1EA900FABCE6 1C0AD2B4069F1EA900FABCE6 1CD0528B0623707200166675 1C0AD2B5069F1EA900FABCE6 ToolbarConfiguration xcode.toolbar.config.run WindowString 316 696 459 200 0 0 1280 1002 WindowToolGUID 1C0AD2B3069F1EA900FABCE6 WindowToolIsVisible 0 Identifier windowTool.scm Layout Dock ContentConfiguration PBXProjectModuleGUID 1C78EAB2065D492600B07095 PBXProjectModuleLabel <No Editor> PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 1C78EAB3065D492600B07095 SplitCount 1 StatusBarVisibility 1 GeometryConfiguration Frame {{0, 0}, {452, 0}} RubberWindowFrame 743 379 452 308 0 0 1280 1002 Module PBXNavigatorGroup Proportion 0pt BecomeActive 1 ContentConfiguration PBXProjectModuleGUID 1CD052920623707200166675 PBXProjectModuleLabel SCM GeometryConfiguration ConsoleFrame {{0, 259}, {452, 0}} Frame {{0, 7}, {452, 259}} RubberWindowFrame 743 379 452 308 0 0 1280 1002 TableConfiguration Status 30 FileName 199 Path 197.09500122070312 TableFrame {{0, 0}, {452, 250}} Module PBXCVSModule Proportion 262pt Proportion 266pt Name SCM ServiceClasses PBXCVSModule StatusbarIsVisible 1 TableOfContents 1C78EAB4065D492600B07095 1C78EAB5065D492600B07095 1C78EAB2065D492600B07095 1CD052920623707200166675 ToolbarConfiguration xcode.toolbar.config.scm WindowString 743 379 452 308 0 0 1280 1002 Identifier windowTool.breakpoints IsVertical Layout Dock BecomeActive ContentConfiguration PBXBottomSmartGroupGIDs 1C77FABC04509CD000000102 PBXProjectModuleGUID 1CE0B1FE06471DED0097A5F4 PBXProjectModuleLabel Files PBXProjectStructureProvided no PBXSmartGroupTreeModuleColumnData PBXSmartGroupTreeModuleColumnWidthsKey 168 PBXSmartGroupTreeModuleColumnsKey_v4 MainColumn PBXSmartGroupTreeModuleOutlineStateKey_v7 PBXSmartGroupTreeModuleOutlineStateExpansionKey 1C77FABC04509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey {{0, 0}, {168, 350}} PBXTopSmartGroupGIDs XCIncludePerspectivesSwitch GeometryConfiguration Frame {{0, 0}, {185, 368}} GroupTreeTableConfiguration MainColumn 168 RubberWindowFrame 315 424 744 409 0 0 1440 878 Module PBXSmartGroupTreeModule Proportion 185pt ContentConfiguration PBXProjectModuleGUID 1CA1AED706398EBD00589147 PBXProjectModuleLabel Detail GeometryConfiguration Frame {{190, 0}, {554, 368}} RubberWindowFrame 315 424 744 409 0 0 1440 878 Module XCDetailModule Proportion 554pt Proportion 368pt MajorVersion 2 MinorVersion 0 Name Breakpoints ServiceClasses PBXSmartGroupTreeModule XCDetailModule StatusbarIsVisible TableOfContents 1CDDB66807F98D9800BB5817 1CDDB66907F98D9800BB5817 1CE0B1FE06471DED0097A5F4 1CA1AED706398EBD00589147 ToolbarConfiguration xcode.toolbar.config.breakpoints WindowString 315 424 744 409 0 0 1440 878 WindowToolGUID 1CDDB66807F98D9800BB5817 WindowToolIsVisible Identifier windowTool.debugAnimator Layout Dock Module PBXNavigatorGroup Proportion 100% Proportion 100% Name Debug Visualizer ServiceClasses PBXNavigatorGroup StatusbarIsVisible ToolbarConfiguration xcode.toolbar.config.debugAnimator WindowString 100 100 700 500 0 0 1280 1002 Identifier windowTool.bookmarks Layout Dock Module PBXBookmarksModule Proportion 100% Proportion 100% Name Bookmarks ServiceClasses PBXBookmarksModule StatusbarIsVisible 0 WindowString 538 42 401 187 0 0 1280 1002 Identifier windowTool.classBrowser Layout Dock BecomeActive 1 ContentConfiguration OptionsSetName Hierarchy, all classes PBXProjectModuleGUID 1CA6456E063B45B4001379D8 PBXProjectModuleLabel Class Browser - NSObject GeometryConfiguration ClassesFrame {{0, 0}, {374, 96}} ClassesTreeTableConfiguration PBXClassNameColumnIdentifier 208 PBXClassBookColumnIdentifier 22 Frame {{0, 0}, {630, 331}} MembersFrame {{0, 105}, {374, 395}} MembersTreeTableConfiguration PBXMemberTypeIconColumnIdentifier 22 PBXMemberNameColumnIdentifier 216 PBXMemberTypeColumnIdentifier 97 PBXMemberBookColumnIdentifier 22 PBXModuleWindowStatusBarHidden2 1 RubberWindowFrame 385 179 630 352 0 0 1440 878 Module PBXClassBrowserModule Proportion 332pt Proportion 332pt Name Class Browser ServiceClasses PBXClassBrowserModule StatusbarIsVisible 0 TableOfContents 1C0AD2AF069F1E9B00FABCE6 1C0AD2B0069F1E9B00FABCE6 1CA6456E063B45B4001379D8 ToolbarConfiguration xcode.toolbar.config.classbrowser WindowString 385 179 630 352 0 0 1440 878 WindowToolGUID 1C0AD2AF069F1E9B00FABCE6 WindowToolIsVisible 0 ================================================ FILE: Feedback360/Feedback360.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 3B2EF54C0965C358007BFB7B /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B2EF54B0965C358007BFB7B /* ForceFeedback.framework */; }; 3BBA037D09697D80008A46C9 /* emulator.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BBA037C09697D80008A46C9 /* emulator.c */; }; 3BBA03D0096A22F5008A46C9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BBA03CF096A22F5008A46C9 /* IOKit.framework */; }; 3BBA03E3096A29B5008A46C9 /* devlink.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BBA03E2096A29B5008A46C9 /* devlink.c */; }; 8D576312048677EA00EA77CD /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB77B6FE84183AC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; }; 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; }; 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 08FB77B6FE84183AC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 3B2EF5440965B3C7007BFB7B /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = ""; }; 3B2EF54B0965C358007BFB7B /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = /System/Library/Frameworks/ForceFeedback.framework; sourceTree = ""; }; 3BBA037B09697D80008A46C9 /* emulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emulator.h; sourceTree = ""; }; 3BBA037C09697D80008A46C9 /* emulator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = emulator.c; sourceTree = ""; }; 3BBA03CF096A22F5008A46C9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 3BBA03E1096A29B5008A46C9 /* devlink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = devlink.h; sourceTree = ""; }; 3BBA03E2096A29B5008A46C9 /* devlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = devlink.c; sourceTree = ""; }; 8D576316048677EA00EA77CD /* Feedback360.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Feedback360.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8D576313048677EA00EA77CD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */, 3B2EF54C0965C358007BFB7B /* ForceFeedback.framework in Frameworks */, 3BBA03D0096A22F5008A46C9 /* IOKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* Feedback360 */ = { isa = PBXGroup; children = ( 08FB77AFFE84173DC02AAC07 /* Source */, 089C167CFE841241C02AAC07 /* Resources */, 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 19C28FB6FE9D52B211CA2CBB /* Products */, ); name = Feedback360; sourceTree = ""; }; 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 3BBA03CF096A22F5008A46C9 /* IOKit.framework */, 3B2EF54B0965C358007BFB7B /* ForceFeedback.framework */, 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 089C167CFE841241C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 3B2EF5470965B8E3007BFB7B /* New Group */, ); name = Resources; sourceTree = ""; }; 08FB77AFFE84173DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( 3B2EF5440965B3C7007BFB7B /* main.h */, 08FB77B6FE84183AC02AAC07 /* main.c */, 3BBA037B09697D80008A46C9 /* emulator.h */, 3BBA037C09697D80008A46C9 /* emulator.c */, 3BBA03E1096A29B5008A46C9 /* devlink.h */, 3BBA03E2096A29B5008A46C9 /* devlink.c */, ); name = Source; sourceTree = ""; }; 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8D576316048677EA00EA77CD /* Feedback360.bundle */, ); name = Products; sourceTree = ""; }; 3B2EF5470965B8E3007BFB7B /* New Group */ = { isa = PBXGroup; children = ( 8D576317048677EA00EA77CD /* Info.plist */, 8D5B49A704867FD3000E48DA /* InfoPlist.strings */, ); name = "New Group"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 8D57630D048677EA00EA77CD /* Feedback360 */ = { isa = PBXNativeTarget; buildConfigurationList = 3BBDC69309793BF60023AAD8 /* Build configuration list for PBXNativeTarget "Feedback360" */; buildPhases = ( 8D57630F048677EA00EA77CD /* Resources */, 8D576311048677EA00EA77CD /* Sources */, 8D576313048677EA00EA77CD /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = Feedback360; productInstallPath = "$(HOME)/Library/Bundles"; productName = Feedback360; productReference = 8D576316048677EA00EA77CD /* Feedback360.bundle */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 3BBDC69709793BF60023AAD8 /* Build configuration list for PBXProject "Feedback360" */; compatibilityVersion = "Xcode 2.4"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 089C166AFE841209C02AAC07 /* Feedback360 */; projectDirPath = ""; projectRoot = ""; targets = ( 8D57630D048677EA00EA77CD /* Feedback360 */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 8D57630F048677EA00EA77CD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8D576311048677EA00EA77CD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D576312048677EA00EA77CD /* main.c in Sources */, 3BBA037D09697D80008A46C9 /* emulator.c in Sources */, 3BBA03E3096A29B5008A46C9 /* devlink.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C167EFE841241C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 3BBDC69409793BF60023AAD8 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; PRODUCT_NAME = Feedback360; WRAPPER_EXTENSION = bundle; ZERO_LINK = YES; }; name = Development; }; 3BBDC69509793BF60023AAD8 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; PRODUCT_NAME = Feedback360; WRAPPER_EXTENSION = bundle; ZERO_LINK = NO; }; name = Deployment; }; 3BBDC69609793BF60023AAD8 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { GCC_GENERATE_DEBUGGING_SYMBOLS = NO; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; PRODUCT_NAME = Feedback360; WRAPPER_EXTENSION = bundle; }; name = Default; }; 3BBDC69809793BF60023AAD8 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Development; }; 3BBDC69909793BF60023AAD8 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Deployment; }; 3BBDC69A09793BF60023AAD8 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 3BBDC69309793BF60023AAD8 /* Build configuration list for PBXNativeTarget "Feedback360" */ = { isa = XCConfigurationList; buildConfigurations = ( 3BBDC69409793BF60023AAD8 /* Development */, 3BBDC69509793BF60023AAD8 /* Deployment */, 3BBDC69609793BF60023AAD8 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 3BBDC69709793BF60023AAD8 /* Build configuration list for PBXProject "Feedback360" */ = { isa = XCConfigurationList; buildConfigurations = ( 3BBDC69809793BF60023AAD8 /* Development */, 3BBDC69909793BF60023AAD8 /* Deployment */, 3BBDC69A09793BF60023AAD8 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } ================================================ FILE: Feedback360/Info.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.mice.Xbox360ControllerForceFeedback CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BNDL CFBundleSignature ???? CFBundleVersion 1.0 CFPlugInDynamicRegistration NO CFPlugInFactories B8ED278F-EC8A-4E8E-B4CF-13E2A9D68E83 Control360Factory CFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E B8ED278F-EC8A-4E8E-B4CF-13E2A9D68E83 CFBundleName ${PRODUCT_NAME} NSHumanReadableCopyright Copyright © 2013 MICE Software. All rights reserved. ================================================ FILE: Feedback360/devlink.c ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro devlink.c - code to speak to the driver itself This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "devlink.h" // Initialise the link bool Device_Initialise(DeviceLink *link,io_object_t device) { IOCFPlugInInterface **plugInInterface; SInt32 score; IOReturn ret; plugInInterface=NULL; score=0; ret=IOCreatePlugInInterfaceForService(device,kIOHIDDeviceUserClientTypeID,kIOCFPlugInInterfaceID,&plugInInterface,&score); if(ret!=kIOReturnSuccess) return FALSE; ret=(*plugInInterface)->QueryInterface(plugInInterface,CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID121),(LPVOID)&link->interface); (*plugInInterface)->Release(plugInInterface); if(ret!=kIOReturnSuccess) return FALSE; (*link->interface)->open(link->interface,0); return TRUE; } // Finish the link void Device_Finalise(DeviceLink *link) { (*link->interface)->close(link->interface); (*link->interface)->Release(link->interface); link->interface=NULL; } // Send a report via the link bool Device_Send(DeviceLink *link,void *data,int length) { if(link->interface==NULL) return FALSE; else { IOReturn res=(*link->interface)->setReport(link->interface,kIOHIDReportTypeOutput,0,data,length,10000,NULL,NULL,NULL); if (res != kIOReturnSuccess) fprintf(stderr, "Device_Send failed: 0x%.8x\n", res); return res==kIOReturnSuccess; } } ================================================ FILE: Feedback360/devlink.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro devlink.h - Interface to the device link This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include typedef struct { IOHIDDeviceInterface121 **interface; } DeviceLink; bool Device_Initialise(DeviceLink *link,io_object_t device); void Device_Finalise(DeviceLink *link); bool Device_Send(DeviceLink *link,void *data,int length); ================================================ FILE: Feedback360/emulator.c ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro emulator.c - simulate a force feedback device This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "emulator.h" /* * This code could do with being improved. For example, the two motors could * allow for a "left" and "right" rumble in a car game. * * For debugging, you may use fprintf(stderr,...). The output will appear on * the console of whatever game is using the Apple Force Feedback Framework. */ #define LoopGranularity 500 // Microseconds #define LoopTimerDelay (LoopGranularity*0.000001f) // In seconds static void Emulate_Timer(CFRunLoopTimerRef timer,void *context); // Initialise the emulation of a force feedback device void Emulate_Initialise(ForceEmulator *emulator,int effectCount,void (*SetForce)(void*,unsigned char,unsigned char),void *context) { int i; CFRunLoopTimerContext callbackData; // Set callback emulator->SetForce=SetForce; emulator->context=context; // Create effects memory emulator->effects=(ForceEffect*)malloc(sizeof(ForceEffect)*effectCount); emulator->effectCount=effectCount; // Defaults emulator->enable=TRUE; emulator->pause=FALSE; emulator->gain=4; emulator->maxGain=4; emulator->activeEffect=-1; // Reset for(i=0;ieffects[i].inUse=FALSE; // Launch timer callbackData.version=0; callbackData.info=emulator; callbackData.retain=NULL; callbackData.release=NULL; callbackData.copyDescription=NULL; emulator->timer=CFRunLoopTimerCreate(NULL,LoopTimerDelay,LoopTimerDelay,0,0,Emulate_Timer,&callbackData); CFRunLoopAddTimer(CFRunLoopGetCurrent(),emulator->timer,kCFRunLoopCommonModes); } // Close down the force feedback stuff void Emulate_Finalise(ForceEmulator *emulator) { CFRunLoopTimerInvalidate(emulator->timer); CFRelease(emulator->timer); free(emulator->effects); emulator->SetForce(emulator->context,0,0); } // Call the callback, if output is enabled void Emulate_Callback(ForceEmulator *emulator,unsigned char large,unsigned char small) { emulator->oldLarge=large; emulator->oldSmall=small; if(emulator->enable) emulator->SetForce(emulator->context,large,small); } // Create an effect - for the FF API int Emulate_CreateEffect(ForceEmulator *emulator,const ForceParams *params) { int i; for(i=0;ieffectCount;i++) { if(!emulator->effects[i].inUse) { emulator->effects[i].inUse=TRUE; if(!Emulate_ChangeEffect(emulator,i+1,params)) { emulator->effects[i].inUse=FALSE; return 0; } return i+1; } } return 0; } // Change an effect - for the FF API bool Emulate_ChangeEffect(ForceEmulator *emulator,int index,const ForceParams *params) { ForceEffect *effect=emulator->effects+index-1; effect->gain=params->gain; effect->maxLevel=params->maxLevel; effect->startCount=params->startDelay/LoopGranularity; effect->attackLevel=params->attackLevel; effect->attackCount=params->attackTime/LoopGranularity; effect->sustainLevel=params->sustainLevel; effect->sustainCount=params->sustainTime/LoopGranularity; effect->fadeLevel=params->fadeLevel; effect->fadeCount=params->fadeTime/LoopGranularity; return TRUE; } // Destroy an effect - for the FF API void Emulate_DestroyEffect(ForceEmulator *emulator,int index) { emulator->effects[index-1].inUse=FALSE; if(emulator->activeEffect==(index-1)) emulator->activeEffect=-1; } // Returns true if the effect index is in use bool Emulate_IsValidEffect(ForceEmulator *emulator,int index) { if((index<1)||(index>emulator->effectCount)) return FALSE; return emulator->effects[index-1].inUse; } // Returns true if the effect index is playing bool Emulate_IsPlaying(ForceEmulator *emulator,int index) { return emulator->activeEffect==(index-1); } // Returns true if the device has no effects bool Emulate_IsEmpty(ForceEmulator *emulator) { int i; for(i=0;ieffectCount;i++) if(emulator->effects[i].inUse) return FALSE; return TRUE; } // Resets the device void Emulate_Reset(ForceEmulator *emulator) { int i; for(i=0;ieffectCount;i++) emulator->effects[i].inUse=FALSE; Emulate_Callback(emulator,0,0); } // Starts an effect for the specified number of loops void Emulate_Start(ForceEmulator *emulator,int index,int iterations) { ForceEffect *effect; // fprintf(stderr,"Emulate_Start(%p,%i,%i)\n",emulator,index,iterations); effect=emulator->effects+index-1; effect->countStart=effect->startCount; effect->countAttack=effect->attackCount; effect->countSustain=effect->sustainCount; effect->countFade=effect->fadeCount; effect->countLoop=iterations; emulator->activeEffect=index-1; } // Stops an effect void Emulate_Stop(ForceEmulator *emulator,int index) { // fprintf(stderr,"Emulate_Stop(%p,%i)\n",emulator,index); if((index-1)==emulator->activeEffect) { emulator->activeEffect=-1; Emulate_Callback(emulator,0,0); } } // Returns true if no effects are running bool Emulate_IsStopped(ForceEmulator *emulator) { return emulator->activeEffect==-1; } // Returns the number of used effects UInt32 Emulate_Effects_Used(ForceEmulator *emulator) { int i,j; for(i=j=0;ieffectCount;i++) if(emulator->effects[i].inUse) j++; return j; } // Returns the number of possible effects UInt32 Emulate_Effects_Total(ForceEmulator *emulator) { return emulator->effectCount; } // Enables or disables the force feedback void Emulate_SetEnable(ForceEmulator *emulator,bool enable) { bool old=emulator->enable; // Stop motors in case they were running if(old&&(!enable)) Emulate_Callback(emulator,0,0); emulator->enable=enable; // Resume motors at last computed value, as we'll have // been computing new values for them even if disabled if((!old)&&enable) Emulate_Callback(emulator,emulator->oldLarge,emulator->oldSmall); } // Returns true if enabled bool Emulate_IsEnabled(ForceEmulator *emulator) { return emulator->enable; } // Pauses the device void Emulate_SetPaused(ForceEmulator *emulator,bool enable) { bool old=emulator->pause; // Stop motors in case they were running if((!old)&&enable) Emulate_Callback(emulator,0,0); emulator->pause=enable; // Resume motors at last computed value, as we'll be // resuming feedback effects where we left off. if(old&&(!enable)) Emulate_Callback(emulator,emulator->oldLarge,emulator->oldSmall); } // Returns true if paused bool Emulate_IsPaused(ForceEmulator *emulator) { return emulator->pause; } // Sets the gain for the device void Emulate_SetGain(ForceEmulator *emulator,int gain,int gainMax) { if((emulator->gain<=0)||(emulator->maxGain<=0)) return; emulator->gain=gain; emulator->maxGain=gainMax; while(emulator->maxGain<4) { emulator->gain*=2; emulator->maxGain*=2; } } // Utility - scales a value static inline int Emulate_Scale(int from,int to,int max,int val) { int upper=max-1; return from+(((to-from)*(upper-val))/upper); } // Utility - computes the values for the large and small motors from the effect static void Emulate_Force(ForceEmulator *emulator,int force,int maxGain) { int adjusted; int bling; int small,large; // fprintf(stderr,"Emulate_Force(%p,%i)\n",emulator,force); adjusted=(force*emulator->gain)/emulator->maxGain; bling=maxGain/4; if(adjustedactiveEffect; if((i==-1)||emulator->pause) return; effect=emulator->effects+emulator->activeEffect; // Process each counter on the effect, to see what's happening if(effect->countStart>0) { // In the start (pre-effect) stage level=effect->attackLevel; effect->countStart--; } else { if(effect->countAttack>0) { // In the attack stage level=Emulate_Scale(effect->attackLevel,effect->sustainLevel,effect->attackCount,effect->countAttack); effect->countAttack--; } else { if(effect->countSustain>0) { // In the sustain stage level=effect->sustainLevel; effect->countSustain--; } else { if(effect->countFade>0) { // In the fade stage level=Emulate_Scale(effect->sustainLevel,effect->fadeLevel,effect->fadeCount,effect->countFade); effect->countFade--; } else { // Work out if we need to do it again effect->countLoop--; if(effect->countLoop>0) { // Prepare for next loop level=effect->attackLevel; effect->countStart=effect->startCount; effect->countAttack=effect->attackCount; effect->countSustain=effect->sustainCount; effect->countFade=effect->fadeCount; } else { // Effect finished level=0; emulator->activeEffect=-1; } } } } } // Actually calculate what to do for the effect Emulate_Force(emulator,(level*effect->gain)/effect->maxLevel,effect->maxLevel); } ================================================ FILE: Feedback360/emulator.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro emulator.h - Interface to fake FF API effects using rumble motors This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include typedef enum { fsStop, fsPlay, } ForceState; typedef struct { bool inUse; ForceState state; // Information int gain; int maxLevel; int startCount; int attackLevel; int attackCount; int sustainLevel; int sustainCount; int fadeLevel; int fadeCount; // Runtime int countStart; int countAttack; int countSustain; int countFade; int countLoop; } ForceEffect; typedef struct { // Settings int gain; // 0-maxLevel int maxLevel; int startDelay; // Microseconds // Envelope for effect int attackLevel; // 0-maxLevel int attackTime; // Microseconds int sustainLevel; // 0-maxLevel int sustainTime; // Microseconds int fadeLevel; // 0-maxLevel int fadeTime; // Microseconds } ForceParams; typedef struct { // Callback void (*SetForce)(void *context,unsigned char large,unsigned char small); void *context; // Options int gain,maxGain; bool enable,pause; // Effect entries ForceEffect *effects; int effectCount; // Runtime CFRunLoopTimerRef timer; unsigned char oldLarge,oldSmall; int activeEffect; } ForceEmulator; // Constructor/destructor void Emulate_Initialise(ForceEmulator *emulator,int effectCount,void (*SetForce)(void*,unsigned char,unsigned char),void *context); void Emulate_Finalise(ForceEmulator *emulator); // Options void Emulate_SetGain(ForceEmulator *emulator,int gain,int gainMax); void Emulate_SetEnable(ForceEmulator *emulator,bool enable); bool Emulate_IsEnabled(ForceEmulator *emulator); void Emulate_SetPaused(ForceEmulator *emulator,bool enable); bool Emulate_IsPaused(ForceEmulator *emulator); // Using effects int Emulate_CreateEffect(ForceEmulator *emulator,const ForceParams *params); bool Emulate_ChangeEffect(ForceEmulator *emulator,int index,const ForceParams *params); void Emulate_DestroyEffect(ForceEmulator *emulator,int index); bool Emulate_IsValidEffect(ForceEmulator *emulator,int index); bool Emulate_IsPlaying(ForceEmulator *emulator,int index); bool Emulate_IsEmpty(ForceEmulator *emulator); void Emulate_Reset(ForceEmulator *emulator); void Emulate_Start(ForceEmulator *emulator,int index,int iterations); void Emulate_Stop(ForceEmulator *emulator,int index); bool Emulate_IsStopped(ForceEmulator *emulator); UInt32 Emulate_Effects_Used(ForceEmulator *emulator); UInt32 Emulate_Effects_Total(ForceEmulator *emulator); // Callbacks void Emulate_Callback(ForceEmulator *emulator,unsigned char large,unsigned char small); ================================================ FILE: Feedback360/main.c ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro main.c - Main code for the FF plugin This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "main.h" static void dealloc360Feedback(Xbox360ForceFeedback *this); // IUnknown static HRESULT Feedback360QueryInterface(void *that,REFIID iid,LPVOID *ppv) { Xbox360ForceFeedback *this=FFThis(that); CFUUIDRef interface; interface=CFUUIDCreateFromUUIDBytes(NULL,iid); // IOForceFeedbackDevice if(CFEqual(interface,kIOForceFeedbackDeviceInterfaceID)) *ppv=&this->iIOForceFeedbackDeviceInterface; // IUnknown || IOCFPlugInInterface else if(CFEqual(interface,IUnknownUUID)||CFEqual(interface,kIOCFPlugInInterfaceID)) *ppv=&this->iIOCFPlugInInterface; else *ppv=NULL; // Done CFRelease(interface); if((*ppv)==NULL) return E_NOINTERFACE; else { this->iIOCFPlugInInterface.pseudoVTable->AddRef(*ppv); return S_OK; } } static ULONG Feedback360AddRef(void *that) { Xbox360ForceFeedback *this=FFThis(that); this->refCount++; return this->refCount; } static ULONG Feedback360Release(void *that) { Xbox360ForceFeedback *this=FFThis(that); this->refCount--; if(this->refCount==0) { dealloc360Feedback(this); return 0; } else return this->refCount; } // IOCFPlugInInterface static IOReturn Feedback360Probe(void *that,CFDictionaryRef propertyTable,io_service_t service,SInt32 *order) { if ((service==0) || ((!IOObjectConformsTo(service,"Xbox360ControllerClass")) && (!IOObjectConformsTo(service,"Wireless360Controller")))) return kIOReturnBadArgument; return S_OK; } static IOReturn Feedback360Start(void *that,CFDictionaryRef propertyTable,io_service_t service) { return S_OK; } static IOReturn Feedback360Stop(void *that) { return S_OK; } // IOForceFeedbackDevice static HRESULT Feedback360GetVersion(void *this,ForceFeedbackVersion *version) { if((this==NULL)||(version==NULL)) return FFERR_INVALIDPARAM; version->apiVersion.majorRev=kFFPlugInAPIMajorRev; version->apiVersion.minorAndBugRev=kFFPlugInAPIMinorAndBugRev; version->apiVersion.stage=kFFPlugInAPIStage; version->apiVersion.nonRelRev=kFFPlugInAPINonRelRev; version->plugInVersion.majorRev=FeedbackDriverVersionMajor; version->plugInVersion.minorAndBugRev=FeedbackDriverVersionMinor; version->plugInVersion.stage=FeedbackDriverVersionStage; version->plugInVersion.nonRelRev=FeedbackDriverVersionNonRelRev; return S_OK; } static void Feedback360_Callback(void *that,unsigned char large,unsigned char small) { Xbox360ForceFeedback *this=(Xbox360ForceFeedback*)that; char buf[]={0x00,0x04,large,small}; if(!this->manual) Device_Send(&this->device,buf,sizeof(buf)); } static HRESULT Feedback360InitializeTerminate(void *that,NumVersion APIversion,io_object_t hidDevice,boolean_t begin) { Xbox360ForceFeedback *this=FFThis(that); // fprintf(stderr,"Feedback360InitializeTerminate(%p,[%i.%i.%i.%i],%p,%s)\n",this,APIversion.majorRev,APIversion.minorAndBugRev,APIversion.stage,APIversion.nonRelRev,hidDevice,begin?"true":"false"); if(this==NULL) return FFERR_INVALIDPARAM; if(begin) { // fprintf(stderr,"Feedback: Initialising...\n"); // Initialize if(APIversion.majorRev!=kFFPlugInAPIMajorRev) { // fprintf(stderr,"Feedback: Invalid version\n"); return FFERR_INVALIDPARAM; } // From probe if( (hidDevice==0) || ((!IOObjectConformsTo(hidDevice,"Xbox360ControllerClass")) && (!IOObjectConformsTo(hidDevice,"Wireless360Controller"))) ) { // fprintf(stderr,"Feedback: Invalid device\n"); return FFERR_INVALIDPARAM; } Emulate_Initialise(&this->emulator,10,Feedback360_Callback,this); if(!Device_Initialise(&this->device,hidDevice)) { // fprintf(stderr,"Feedback: Failed to initialise\n"); Emulate_Finalise(&this->emulator); return FFERR_NOINTERFACE; } this->manual=FALSE; } else { // fprintf(stderr,"Feedback: Terminating\n"); // Terminate Emulate_Finalise(&this->emulator); Device_Finalise(&this->device); } return FF_OK; } static HRESULT Feedback360DestroyEffect(void *that,FFEffectDownloadID downloadID) { Xbox360ForceFeedback *this=FFThis(that); Emulate_DestroyEffect(&this->emulator,downloadID); return FF_OK; } static bool Feedback360SupportedEffect(CFUUIDRef effect) { if(CFEqual(effect,kFFEffectType_SawtoothDown_ID)) return TRUE; if(CFEqual(effect,kFFEffectType_SawtoothUp_ID)) return TRUE; if(CFEqual(effect,kFFEffectType_Sine_ID)) return TRUE; if(CFEqual(effect,kFFEffectType_Spring_ID)) return TRUE; if(CFEqual(effect,kFFEffectType_Square_ID)) return TRUE; if(CFEqual(effect,kFFEffectType_Triangle_ID)) return TRUE; return FALSE; } static bool Feedback360ConvertEffect(const FFEFFECT *effect,ForceParams *params) { if((effect->cbTypeSpecificParams!=sizeof(FFPERIODIC))||(effect->lpvTypeSpecificParams==NULL)) return FALSE; // Settings params->startDelay=effect->dwStartDelay; params->gain=effect->dwGain; params->maxLevel=10000; // Envelope params->sustainLevel=((FFPERIODIC*)effect->lpvTypeSpecificParams)->dwMagnitude; // Documentation was a bit confusing here as to which value was right, compared to what a game actually used // params->sustainTime=effect->dwDuration; params->sustainTime=((FFPERIODIC*)effect->lpvTypeSpecificParams)->dwPeriod; if(effect->lpEnvelope==NULL) { params->attackLevel=params->sustainLevel; params->attackTime=0; params->fadeLevel=params->sustainLevel; params->fadeTime=0; } else { if(effect->lpEnvelope->dwSizeattackLevel=effect->lpEnvelope->dwAttackLevel; params->attackTime=effect->lpEnvelope->dwAttackTime; params->fadeLevel=effect->lpEnvelope->dwFadeLevel; params->fadeTime=effect->lpEnvelope->dwFadeTime; } // Done return TRUE; } static HRESULT Feedback360DownloadEffect(void *that,CFUUIDRef effectType,FFEffectDownloadID *downloadID,FFEFFECT *effect,FFEffectParameterFlag flags) { ForceParams params; Xbox360ForceFeedback *this=FFThis(that); if(!Feedback360SupportedEffect(effectType)) return FFERR_UNSUPPORTED; if(!(effect->dwFlags&FFEFF_SPHERICAL)) return FFERR_UNSUPPORTED; if(effect->dwTriggerButton!=FFEB_NOTRIGGER) return FFERR_UNSUPPORTED; if(!Feedback360ConvertEffect(effect,¶ms)) return FFERR_UNSUPPORTED; if(Emulate_IsPaused(&this->emulator)) return FFERR_DEVICEPAUSED; if(flags&FFEP_NODOWNLOAD) return FF_OK; if((*downloadID)==0) { *downloadID=Emulate_CreateEffect(&this->emulator,¶ms); if((*downloadID)==0) return FFERR_DEVICEFULL; } else { if(!Emulate_IsValidEffect(&this->emulator,*downloadID)) return FFERR_INVALIDDOWNLOADID; if(!Emulate_ChangeEffect(&this->emulator,*downloadID,¶ms)) return FFERR_EFFECTTYPEMISMATCH; } if(flags&FFEP_START) { // Restart } return FF_OK; } static HRESULT Feedback360Escape(void *that,FFEffectDownloadID downloadID,FFEFFESCAPE *escape) { Xbox360ForceFeedback *this=FFThis(that); if(this==NULL) return FFERR_INVALIDPARAM; if(downloadID!=0) return FFERR_UNSUPPORTED; if(escape->dwSizecbOutBuffer=0; switch(escape->dwCommand) { case 0x00: // Control motors if(escape->cbInBuffer!=1) return FFERR_INVALIDPARAM; this->manual=((unsigned char*)escape->lpvInBuffer)[0]!=0x00; break; case 0x01: // Set motors if(escape->cbInBuffer!=2) return FFERR_INVALIDPARAM; if(this->manual) { unsigned char *data=escape->lpvInBuffer; unsigned char buf[]={0x00,0x04,data[0],data[1]}; Device_Send(&this->device,buf,sizeof(buf)); } break; case 0x02: // Set LED if(escape->cbInBuffer!=1) return FFERR_INVALIDPARAM; { unsigned char *data=escape->lpvInBuffer; unsigned char buf[]={0x01,0x03,data[0]}; Device_Send(&this->device,buf,sizeof(buf)); } break; case 0x03: // Power off { unsigned char buf[] = {0x02, 0x02}; Device_Send(&this->device, buf, sizeof(buf)); } break; default: fprintf(stderr, "Xbox360Controller FF plugin: Unknown escape (%i)\n", (int)escape->dwCommand); return FFERR_UNSUPPORTED; } return FF_OK; } static HRESULT Feedback360GetEffectStatus(void *that,FFEffectDownloadID downloadID,FFEffectStatusFlag *statusCode) { Xbox360ForceFeedback *this=FFThis(that); if(!Emulate_IsValidEffect(&this->emulator,downloadID)) return FFERR_INVALIDDOWNLOADID; *statusCode=Emulate_IsPlaying(&this->emulator,downloadID)?FFEGES_PLAYING:FFEGES_NOTPLAYING; return FF_OK; } static HRESULT Feedback360GetForceFeedbackCapabilities(void *this,FFCAPABILITIES *capabilities) { capabilities->ffSpecVer.majorRev=kFFPlugInAPIMajorRev; capabilities->ffSpecVer.minorAndBugRev=kFFPlugInAPIMinorAndBugRev; capabilities->ffSpecVer.stage=kFFPlugInAPIStage; capabilities->ffSpecVer.nonRelRev=kFFPlugInAPINonRelRev; capabilities->supportedEffects=FFCAP_ET_SQUARE|FFCAP_ET_SINE|FFCAP_ET_TRIANGLE|FFCAP_ET_SAWTOOTHUP|FFCAP_ET_SAWTOOTHDOWN; capabilities->emulatedEffects=0; capabilities->subType=FFCAP_ST_VIBRATION; capabilities->numFfAxes=1; capabilities->ffAxes[0]=FFJOFS_X; capabilities->storageCapacity=256; capabilities->playbackCapacity=1; capabilities->driverVer.majorRev=FeedbackDriverVersionMajor; capabilities->driverVer.minorAndBugRev=FeedbackDriverVersionMinor; capabilities->driverVer.stage=FeedbackDriverVersionStage; capabilities->driverVer.nonRelRev=FeedbackDriverVersionNonRelRev; capabilities->firmwareVer.majorRev=1; capabilities->firmwareVer.minorAndBugRev=0; capabilities->firmwareVer.stage=developStage; capabilities->firmwareVer.nonRelRev=0; capabilities->hardwareVer.majorRev=1; capabilities->hardwareVer.minorAndBugRev=0; capabilities->hardwareVer.stage=developStage; capabilities->hardwareVer.nonRelRev=0; return S_OK; } static HRESULT Feedback360GetForceFeedbackState(void *that,ForceFeedbackDeviceState *deviceState) { Xbox360ForceFeedback *this=FFThis(that); if(deviceState->dwSizedwSize=sizeof(ForceFeedbackDeviceState); deviceState->dwState = Emulate_IsEmpty(&this->emulator)?FFGFFS_EMPTY:0 | Emulate_IsStopped(&this->emulator)?FFGFFS_STOPPED:0 | Emulate_IsPaused(&this->emulator)?FFGFFS_PAUSED:0 | Emulate_IsEnabled(&this->emulator)?FFGFFS_ACTUATORSON:FFGFFS_ACTUATORSOFF; deviceState->dwLoad=(Emulate_Effects_Used(&this->emulator)*100)/Emulate_Effects_Total(&this->emulator); return S_OK; } static HRESULT Feedback360SendForceFeedbackCommand(void *that,FFCommandFlag state) { Xbox360ForceFeedback *this=FFThis(that); switch(state) { case FFSFFC_RESET: Emulate_Reset(&this->emulator); return S_OK; case FFSFFC_STOPALL: Emulate_Stop(&this->emulator,0); // 0 == all effects return S_OK; case FFSFFC_PAUSE: case FFSFFC_CONTINUE: Emulate_SetPaused(&this->emulator,state==FFSFFC_PAUSE); return S_OK; case FFSFFC_SETACTUATORSON: case FFSFFC_SETACTUATORSOFF: Emulate_SetEnable(&this->emulator,state==FFSFFC_SETACTUATORSON); return S_OK; default: return FFERR_UNSUPPORTED; } } static HRESULT Feedback360SetProperty(void *that,FFProperty property,void *value) { Xbox360ForceFeedback *this=FFThis(that); switch(property) { case FFPROP_FFGAIN: { UInt32 uValue = *((UInt32*)value); if (uValue > 10000) return FFERR_INVALIDPARAM; Emulate_SetGain(&this->emulator, uValue, 10000); } return FF_OK; default: return FFERR_UNSUPPORTED; } } static HRESULT Feedback360StartEffect(void *that,FFEffectDownloadID downloadID,FFEffectStartFlag mode,UInt32 iterations) { Xbox360ForceFeedback *this=FFThis(that); if(mode&FFES_SOLO) Feedback360SendForceFeedbackCommand(that,FFSFFC_RESET); Emulate_Start(&this->emulator,downloadID,iterations); return S_OK; } static HRESULT Feedback360StopEffect(void *that,FFEffectDownloadID downloadID) { Xbox360ForceFeedback *this=FFThis(that); if(!Emulate_IsValidEffect(&this->emulator,downloadID)) return FFERR_INVALIDDOWNLOADID; Emulate_Stop(&this->emulator,downloadID); return S_OK; } // Function table static IOCFPlugInInterface functionMap360_IOCFPlugInInterface={ // Padding required for COM NULL, // IUnknown Feedback360QueryInterface, Feedback360AddRef, Feedback360Release, // IOCFPlugInInterface 1,0, // Version Feedback360Probe, Feedback360Start, Feedback360Stop }; static IOForceFeedbackDeviceInterface functionMap360_IOForceFeedbackDeviceInterface={ // Padding required for COM NULL, // IUnknown Feedback360QueryInterface, Feedback360AddRef, Feedback360Release, // IOForceFeedbackDevice Feedback360GetVersion, Feedback360InitializeTerminate, Feedback360DestroyEffect, Feedback360DownloadEffect, Feedback360Escape, Feedback360GetEffectStatus, Feedback360GetForceFeedbackCapabilities, Feedback360GetForceFeedbackState, Feedback360SendForceFeedbackCommand, Feedback360SetProperty, Feedback360StartEffect, Feedback360StopEffect }; // Constructor and destructor static IOCFPlugInInterface** alloc360Feedback(CFUUIDRef uuid) { Xbox360ForceFeedback *item; item=(Xbox360ForceFeedback*)malloc(sizeof(Xbox360ForceFeedback)); item->iIOCFPlugInInterface.pseudoVTable=(IUnknownVTbl*)&functionMap360_IOCFPlugInInterface; item->iIOCFPlugInInterface.obj=item; item->iIOForceFeedbackDeviceInterface.pseudoVTable=(IUnknownVTbl*)&functionMap360_IOForceFeedbackDeviceInterface; item->iIOForceFeedbackDeviceInterface.obj=item; item->factoryID=CFRetain(uuid); CFPlugInAddInstanceForFactory(uuid); item->refCount=1; return (IOCFPlugInInterface**)&item->iIOCFPlugInInterface.pseudoVTable; } static void dealloc360Feedback(Xbox360ForceFeedback *this) { CFUUIDRef uuid; uuid=this->factoryID; free(this); if(uuid) { CFPlugInRemoveInstanceForFactory(uuid); CFRelease(uuid); } } // External factory function void* Control360Factory(CFAllocatorRef allocator,CFUUIDRef uuid) { if(CFEqual(uuid,kIOForceFeedbackLibTypeID)) return (void*)alloc360Feedback(uuid); else return NULL; } ================================================ FILE: Feedback360/main.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro main.h - defines the structure used for the plugin COM object This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "emulator.h" #include "devlink.h" struct _Xbox360ForceFeedback; typedef struct _Xbox360InterfaceMap { IUnknownVTbl *pseudoVTable; struct _Xbox360ForceFeedback *obj; } Xbox360InterfaceMap; typedef struct _Xbox360ForceFeedback { Xbox360InterfaceMap iIOCFPlugInInterface; Xbox360InterfaceMap iIOForceFeedbackDeviceInterface; CFUUIDRef factoryID; UInt32 refCount; ForceEmulator emulator; DeviceLink device; bool manual; } Xbox360ForceFeedback; #define FFThis(interface) (((interface)==NULL)?NULL:(((Xbox360InterfaceMap*)(interface))->obj)) #define FeedbackDriverVersionMajor 1 #define FeedbackDriverVersionMinor 0 #define FeedbackDriverVersionStage developStage #define FeedbackDriverVersionNonRelRev 0 // B8ED278F-EC8A-4E8E-B4CF-13E2A9D68E83 #define FeedbackDriverUuid CFUUIDGetConstantUUIDWithBytes(NULL, \ 0xB8, 0xED, 0x27, 0x8F, 0xEC, 0x8A, 0x4E, 0x8E, \ 0xB4, 0xCF, 0x13, 0xE2, 0xA9, 0xD6, 0x8E, 0x83) // Factory function void* Control360Factory(CFAllocatorRef allocator,CFUUIDRef uuid); ================================================ FILE: Feedback360/version.plist ================================================ BuildVersion 12 CFBundleVersion 1.0 ProductBuildVersion 7K571 ProjectName DevToolsWizardTemplates SourceVersion 3870000 ================================================ FILE: Install360Controller/Install360Controller.pkgproj ================================================ PACKAGES PACKAGE_FILES DEFAULT_INSTALL_LOCATION / HIERARCHY CHILDREN CHILDREN CHILDREN GID 80 PATH Utilities PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 GID 80 PATH Applications PATH_TYPE 0 PERMISSIONS 509 TYPE 1 UID 0 CHILDREN CHILDREN CHILDREN CHILDREN CHILDREN GID 80 PATH ../360Daemon/build/Release/360Daemon PATH_TYPE 1 PERMISSIONS 493 TYPE 3 UID 0 CHILDREN CHILDREN GID 80 PATH ../360Daemon/Alert.tif PATH_TYPE 1 PERMISSIONS 420 TYPE 3 UID 0 GID 80 PATH Resources PATH_TYPE 0 PERMISSIONS 493 TYPE 2 UID 0 GID 80 PATH 360Daemon PATH_TYPE 0 PERMISSIONS 493 TYPE 2 UID 0 GID 80 PATH MICE PATH_TYPE 0 PERMISSIONS 493 TYPE 2 UID 0 GID 80 PATH Application Support PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Documentation PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Filesystems PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Frameworks PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Input Methods PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Internet Plug-Ins PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH LaunchAgents PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN CHILDREN GID 0 PATH ../360Daemon/com.mice.360Daemon.plist PATH_TYPE 1 PERMISSIONS 420 TYPE 3 UID 0 GID 0 PATH LaunchDaemons PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN CHILDREN GID 0 PATH ../Pref360Control/build/Deployment/Pref360Control.prefPane PATH_TYPE 1 PERMISSIONS 493 TYPE 3 UID 0 GID 0 PATH PreferencePanes PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Preferences PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 80 PATH Printers PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH PrivilegedHelperTools PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH QuickLook PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH QuickTime PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Screen Savers PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Scripts PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Services PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN GID 0 PATH Widgets PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 GID 0 PATH Library PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN CHILDREN CHILDREN BUNDLE_CAN_DOWNGRADE CHILDREN GID 0 PATH ../360Controller/build/Deployment/360Controller.kext PATH_TYPE 1 PERMISSIONS 493 TYPE 3 UID 0 CHILDREN GID 0 PATH ../Wireless360Controller/build/Release/Wireless360Controller.kext PATH_TYPE 1 PERMISSIONS 493 TYPE 3 UID 0 CHILDREN GID 0 PATH ../WirelessGamingReceiver/build/Release/WirelessGamingReceiver.kext PATH_TYPE 1 PERMISSIONS 493 TYPE 3 UID 0 GID 0 PATH Extensions PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 GID 0 PATH Library PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 GID 0 PATH System PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 CHILDREN CHILDREN GID 0 PATH Shared PATH_TYPE 0 PERMISSIONS 1023 TYPE 1 UID 0 GID 80 PATH Users PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 GID 0 PATH / PATH_TYPE 0 PERMISSIONS 493 TYPE 1 UID 0 PAYLOAD_TYPE 0 VERSION 2 PACKAGE_SCRIPTS POSTINSTALL_PATH PATH Scripts/finish.sh PATH_TYPE 1 PREINSTALL_PATH PATH Scripts/upgrade.sh PATH_TYPE 1 RESOURCES PACKAGE_SETTINGS AUTHENTICATION 1 CONCLUSION_ACTION 2 IDENTIFIER com.mice.pkg.Xbox360controller NAME Install360Controller OVERWRITE_PERMISSIONS VERSION 0.12 UUID 95C3DB03-4C99-4A29-AEC7-C73B3D9F6A04 PROJECT PROJECT_COMMENTS NOTES PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7 IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250 ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjExODcuMzQiPgo8c3R5bGUg dHlwZT0idGV4dC9jc3MiPgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5 Pgo8L2JvZHk+CjwvaHRtbD4K PROJECT_PRESENTATION INSTALLATION TYPE HIERARCHIES INSTALLER LIST DESCRIPTION OPTIONS HIDDEN STATE 0 PACKAGE_UUID 95C3DB03-4C99-4A29-AEC7-C73B3D9F6A04 REQUIREMENTS TITLE TOOLTIP TYPE 0 UUID CB32CFF6-F06D-4B81-B1A5-A040090A6BFB REMOVED INSTALLATION TYPE 0 INSTALLATION_STEPS ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewIntroductionController INSTALLER_PLUGIN Introduction LIST_TITLE_KEY InstallerSectionTitle ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewReadMeController INSTALLER_PLUGIN ReadMe LIST_TITLE_KEY InstallerSectionTitle ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewLicenseController INSTALLER_PLUGIN License LIST_TITLE_KEY InstallerSectionTitle ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewDestinationSelectController INSTALLER_PLUGIN TargetSelect LIST_TITLE_KEY InstallerSectionTitle ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewInstallationTypeController INSTALLER_PLUGIN PackageSelection LIST_TITLE_KEY InstallerSectionTitle ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewInstallationController INSTALLER_PLUGIN Install LIST_TITLE_KEY InstallerSectionTitle ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS ICPresentationViewSummaryController INSTALLER_PLUGIN Summary LIST_TITLE_KEY InstallerSectionTitle INTRODUCTION LOCALIZATIONS LANGUAGE English VALUE PATH Text/Welcome.rtf PATH_TYPE 1 LICENSE KEYWORDS LOCALIZATIONS LANGUAGE English VALUE PATH ../Licence.txt PATH_TYPE 1 MODE 0 README LOCALIZATIONS LANGUAGE English VALUE PATH ../Readme.rtf PATH_TYPE 1 SUMMARY LOCALIZATIONS TITLE LOCALIZATIONS LANGUAGE English VALUE Install360Controller PROJECT_REQUIREMENTS LIST POSTINSTALL_PATH PREINSTALL_PATH RESOURCES ROOT_VOLUME_ONLY PROJECT_SETTINGS ADVANCED_OPTIONS BUILD_FORMAT 0 BUILD_PATH PATH build PATH_TYPE 1 CERTIFICATE NAME Developer ID Installer: Colin Munro PATH /Users/colin/Library/Keychains/login.keychain EXCLUDED_FILES PATTERNS_ARRAY REGULAR_EXPRESSION STRING .DS_Store TYPE 0 PROTECTED PROXY_NAME Remove .DS_Store files PROXY_TOOLTIP Remove ".DS_Store" files created by the Finder. STATE PATTERNS_ARRAY REGULAR_EXPRESSION STRING .pbdevelopment TYPE 0 PROTECTED PROXY_NAME Remove .pbdevelopment files PROXY_TOOLTIP Remove ".pbdevelopment" files created by ProjectBuilder or Xcode. STATE PATTERNS_ARRAY REGULAR_EXPRESSION STRING CVS TYPE 1 REGULAR_EXPRESSION STRING .cvsignore TYPE 0 REGULAR_EXPRESSION STRING .cvspass TYPE 0 REGULAR_EXPRESSION STRING .svn TYPE 1 REGULAR_EXPRESSION STRING .git TYPE 1 REGULAR_EXPRESSION STRING .gitignore TYPE 0 PROTECTED PROXY_NAME Remove SCM metadata PROXY_TOOLTIP Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems. STATE PATTERNS_ARRAY REGULAR_EXPRESSION STRING classes.nib TYPE 0 REGULAR_EXPRESSION STRING designable.db TYPE 0 REGULAR_EXPRESSION STRING info.nib TYPE 0 PROTECTED PROXY_NAME Optimize nib files PROXY_TOOLTIP Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles. STATE PATTERNS_ARRAY REGULAR_EXPRESSION STRING Resources Disabled TYPE 1 PROTECTED PROXY_NAME Remove Resources Disabled folders PROXY_TOOLTIP Remove "Resources Disabled" folders. STATE SEPARATOR NAME Install360Controller TYPE 0 VERSION 2 ================================================ FILE: Install360Controller/Scripts/finish.sh ================================================ #!/bin/sh /usr/bin/touch /System/Library/Extensions exit 0 ================================================ FILE: Install360Controller/Scripts/upgrade.sh ================================================ #!/bin/sh # Clear out daemon if [ -d /Library/StartupItems/360ControlDaemon ]; then /bin/rm -r /Library/StartupItems/360ControlDaemon fi if [ -f /Library/LaunchDaemons/com.mice.360Daemon.plist ]; then launchctl stop com.mice.360Daemon /bin/rm /Library/LaunchDaemons/com.mice.360Daemon.plist fi if [ -d /Library/Application\ Support/MICE/360Daemon ]; then /bin/rm -r /Library/Application\ Support/MICE/360Daemon fi # Remove preference pane if [ -d /Library/PreferencePanes/Pref360Control.prefPane ]; then /bin/rm -r /Library/PreferencePanes/Pref360Control.prefPane fi # Remove drivers if [ -d /System/Library/Extensions/360Controller.kext ]; then /bin/rm -r /System/Library/Extensions/360Controller.kext fi if [ -d /System/Library/Extensions/Wireless360Controller.kext ]; then /bin/rm -r /System/Library/Extensions/Wireless360Controller.kext fi if [ -d /System/Library/Extensions/WirelessGamingReceiver.kext ]; then /bin/rm -r /System/Library/Extensions/WirelessGamingReceiver.kext fi exit 0 ================================================ FILE: Install360Controller/Text/Welcome.rtf ================================================ {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2} {\list\listtemplateid3\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid201\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid3} {\list\listtemplateid4\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid301\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid4} {\list\listtemplateid5\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid401\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid5} {\list\listtemplateid6\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid501\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid6} {\list\listtemplateid7\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid601\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid7} {\list\listtemplateid8\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid701\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid8} {\list\listtemplateid9\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid801\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid9} {\list\listtemplateid10\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid901\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid10} {\list\listtemplateid11\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1001\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid11}} {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}} \paperw12240\paperh15840\margl1440\margr1440\vieww14760\viewh12840\viewkind0 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \f0\b\fs42 \cf0 XBox 360 Controller Driver\ \b0\fs24 Version 0.12\ Copyright (C) 2005-2013 Colin Munro\ \ Welcome to the installer for the XBox 360 Controller driver for Mac OS X.\ \ \b Update 0.12: 4/01/2013\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls1\ilvl0\cf0 {\listtext \'95 }Fix that prevents non-ChatPad-compatible controllers from working\ {\listtext \'95 }Improvement to ChatPad support\ {\listtext \'95 }Improvement to wireless support (automatic and manual power-off)\ {\listtext \'95 }Updated Info.plist with many common devices\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.11: 10/01/2012\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls2\ilvl0\cf0 {\listtext \'95 }Temporary Lion fix (thanks to "codeman38")\ {\listtext \'95 }Adjustment to the automatic device match function\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.10: 8/05/2011\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls3\ilvl0\cf0 {\listtext \'95 }Various bugfixes\ {\listtext \'95 }New product IDs for Wireless Gaming Receiver\ {\listtext \'95 }Automatic device match function, allowing you to select and deselect which controllers you want it to match with\ {\listtext \'95 }Fix the incompatibility with Bioshock introduced with ChatPad support\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.09: 21/11/2009\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls4\ilvl0\cf0 {\listtext \'95 }Driver rearchitecture\ {\listtext \'95 }ChatPad support in wired controller\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \b \cf0 \ Update 0.08: 10/09/2009\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls5\ilvl0\cf0 {\listtext \'95 }64-bit support (untested)\ {\listtext \'95 }Fix for Snow Leopard\ {\listtext \'95 }Minor bugfixes\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.07: 16/12/2007\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls6\ilvl0\cf0 {\listtext \'95 }10.4 bugfix\ {\listtext \'95 }Extra controller IDs\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.06: 10/11/2007 \b0 \ \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls7\ilvl0\cf0 {\listtext \'95 }Improvements to the wireless support\ {\listtext \'95 }Daemon providing persistent settings and LED setting\ {\listtext \'95 }Bugfix to support Halo\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.05: 21/4/2007 \b0 \ \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls8\ilvl0\cf0 {\listtext \'95 }Improvements to the wireless support\ {\listtext \'95 }New increased compatibility with games\ {\listtext \'95 }Support for the Guitar Hero controller\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.04: 27/2/2007\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls9\ilvl0\cf0 {\listtext \'95 }Driver for the Microsoft Wireless Gaming Receiver for Windows\ {\listtext \'95 }Driver for the above to use the Wireless 360 Controller\ {\listtext \'95 }Updates to the Preference Pane to support the Wireless 360 Controller\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.03: 22/7/2006\ \b0 \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls10\ilvl0\cf0 {\listtext \'95 }More 3rd party vendor/product IDs\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Update 0.02: 11/2/2006 \b0 \ \ This update includes:\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls11\ilvl0\cf0 {\listtext \'95 }Universal binaries, for Intel Mac support\ {\listtext \'95 }Additional 3rd party vendor/product IDs (support for matching on interface instead of IDs still isn't working)\ {\listtext \'95 }Preference Pane now correctly detects devices being connected/disconnected\ {\listtext \'95 }Alternative deadzone mode\ {\listtext \'95 }D-pad moved from pointer to plain joypad buttons, for better support in games\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ Please visit {\field{\*\fldinst{HYPERLINK "http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver"}}{\fldrslt http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver}} for information on this software. Consider donating or buying via the Amazon associate links to support development of this driver!\ \ Ensure to read the following Read Me and License sections before installing!} ================================================ FILE: Licence.txt ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ================================================ FILE: Pref360Control/DeviceItem.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro DeviceItem.h - declaration of wrapper class for device handles This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import #import #import #import #import #import @interface DeviceItem : NSObject { IOHIDDeviceInterface122 **interface; FFDeviceObjectReference forceFeedback; io_service_t deviceHandle; NSString *deviceName; } + allocateDeviceItemForDevice:(io_service_t)device; - (NSString*)name; - (IOHIDDeviceInterface122**)hidDevice; - (FFDeviceObjectReference)ffDevice; - (io_service_t)rawDevice; @end ================================================ FILE: Pref360Control/DeviceItem.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro DeviceItem.m - implementation of device wrapper class This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import "DeviceItem.h" static NSString* GetDeviceName(io_service_t device) { CFMutableDictionaryRef serviceProperties; NSDictionary *properties; NSString *deviceName = nil; if (IORegistryEntryCreateCFProperties(device, &serviceProperties, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) return nil; properties = (NSDictionary*)serviceProperties; deviceName = [properties objectForKey:(NSString*)CFSTR(kIOHIDProductKey)]; if (deviceName == nil) deviceName = [properties objectForKey:@"USB Product Name"]; [deviceName retain]; CFRelease(serviceProperties); return deviceName; } @implementation DeviceItem + allocateDeviceItemForDevice:(io_service_t)device { DeviceItem *item; IOReturn ret; IOCFPlugInInterface **plugInInterface; SInt32 score=0; item=[[[DeviceItem alloc] init] autorelease]; if(item==nil) goto fail; ret=IOCreatePlugInInterfaceForService(device,kIOHIDDeviceUserClientTypeID,kIOCFPlugInInterfaceID,&plugInInterface,&score); if(ret!=kIOReturnSuccess) goto fail; ret=(*plugInInterface)->QueryInterface(plugInInterface,CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122),(LPVOID)&item->interface); (*plugInInterface)->Release(plugInInterface); if(ret!=kIOReturnSuccess) goto fail; item->forceFeedback=0; FFCreateDevice(device,&item->forceFeedback); item->deviceHandle=device; item->deviceName = GetDeviceName(device); return item; fail: IOObjectRelease(device); return NULL; } - (void)dealloc { if(deviceHandle != 0) IOObjectRelease(deviceHandle); if(interface != NULL) (*interface)->Release(interface); if(forceFeedback != 0) FFReleaseDevice(forceFeedback); [deviceName release]; [super dealloc]; } - (NSString*)name { return deviceName; } - (IOHIDDeviceInterface122**)hidDevice { return interface; } - (FFDeviceObjectReference)ffDevice { return forceFeedback; } - (io_service_t)rawDevice { return deviceHandle; } @end ================================================ FILE: Pref360Control/DeviceLister.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro DeviceLister.h - decleration of a class to display supported devices This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import @class Pref360ControlPref; @interface DeviceLister : NSObject { Pref360ControlPref *owner; IBOutlet NSWindow *sheet; IBOutlet NSTableView *list; NSMutableDictionary *entries; NSMutableArray *connected, *enabled; BOOL changed; } - (void)showWithOwner:(Pref360ControlPref*)pane; - (IBAction)done:(id)sender; @end ================================================ FILE: Pref360Control/DeviceLister.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro DeviceLister.m - implementation of a class to list supported devices This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import #import "DeviceLister.h" #import "Pref360ControlPref.h" #import "ControlPrefs.h" #define TOOL_FILENAME @"DriverTool" // Get some sort of CF type for a field in the IORegistry static id GetDeviceValue(io_service_t device, NSString *key) { CFTypeRef value; value = IORegistryEntrySearchCFProperty(device, kIOServicePlane, (CFStringRef)key, kCFAllocatorDefault, kIORegistryIterateRecursively); return [((NSObject*)value) autorelease]; } // Make sure a name is as nice as possible for eventually going into the XML for the driver static NSString* SanitiseName(NSString *name) { NSMutableString *output; int i; output = [NSMutableString stringWithCapacity:100]; for (i = 0; i < [name length]; i++) { unichar c = [name characterAtIndex:i]; if (c == ' ') c = '_'; else if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_'))) continue; [output appendFormat:@"%C", c]; } return output; } // Get the Device interface for a given IO service static IOUSBDeviceInterface** GetDeviceInterface(io_service_t device) { IOCFPlugInInterface **iodev; IOUSBDeviceInterface **dev; IOReturn err; SInt32 score; if ((IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score) == kIOReturnSuccess) && (iodev != NULL)) { err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&dev); (*iodev)->Release(iodev); if (err == kIOReturnSuccess) return dev; } return NULL; } // Get the Interface interface for a given IO service static IOUSBInterfaceInterface** GetInterfaceInterface(io_service_t interface) { IOCFPlugInInterface **iodev; IOUSBInterfaceInterface **intf; IOReturn err; SInt32 score; if ((IOCreatePlugInInterfaceForService(interface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score) == kIOReturnSuccess) && (iodev != NULL)) { err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID)&intf); (*iodev)->Release(iodev); if (err == kIOReturnSuccess) return intf; } return NULL; } // List of interfaces we expect on a normal Microsoft controller const struct { int numEndpoints; UInt8 classNum, subClassNum, protocolNum; } ControllerInterfaces[] = { // Endpoints Class Subclass Protocol {2, 255, 93, 1}, {4, 255, 93, 3}, {1, 255, 93, 2}, {0, 255, 253, 19}, }; // Detect if an IO service object is a Microsoft controller by running through and checking some things static BOOL IsXBox360Controller(io_service_t device) { IOUSBDeviceInterface **interface; IOUSBFindInterfaceRequest iRq; io_iterator_t iterator; io_service_t devInterface; IOUSBInterfaceInterface **interfaceInterface; int interfaceCount; UInt8 interfaceNum, classNum, subClassNum, protocolNum, endpointCount; BOOL devValid; // Get the interface to the device interface = GetDeviceInterface(device); if (interface == NULL) return NO; (*interface)->GetDeviceClass(interface, &classNum); (*interface)->GetDeviceSubClass(interface, &subClassNum); (*interface)->GetDeviceProtocol(interface, &protocolNum); devValid = (classNum == 0xFF) && (subClassNum == 0xFF) && (protocolNum == 0xFF); // Search the interfaces iRq.bInterfaceClass = kIOUSBFindInterfaceDontCare; iRq.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; iRq.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; iRq.bAlternateSetting = kIOUSBFindInterfaceDontCare; interfaceCount = 0; if ((*interface)->CreateInterfaceIterator(interface, &iRq, &iterator) == kIOReturnSuccess) { while ((devInterface = IOIteratorNext(iterator)) != 0) { interfaceInterface = GetInterfaceInterface(devInterface); if (interfaceInterface != NULL) { (*interfaceInterface)->GetInterfaceNumber(interfaceInterface, &interfaceNum); (*interfaceInterface)->GetInterfaceClass(interfaceInterface, &classNum); (*interfaceInterface)->GetInterfaceSubClass(interfaceInterface, &subClassNum); (*interfaceInterface)->GetInterfaceProtocol(interfaceInterface, &protocolNum); (*interfaceInterface)->GetNumEndpoints(interfaceInterface, &endpointCount); if (interfaceNum < (sizeof(ControllerInterfaces) / sizeof(ControllerInterfaces[0]))) { if ( (ControllerInterfaces[interfaceNum].classNum == classNum) && (ControllerInterfaces[interfaceNum].subClassNum == subClassNum) && (ControllerInterfaces[interfaceNum].protocolNum == protocolNum) && (ControllerInterfaces[interfaceNum].numEndpoints == endpointCount) ) { // Found another interface in the right place interfaceCount++; } } (*interfaceInterface)->Release(interfaceInterface); } IOObjectRelease(devInterface); } IOObjectRelease(iterator); } // Done (*interface)->Release(interface); return devValid && (interfaceCount >= 3); // Only 3 in case the security descriptor is missing? } @implementation DeviceLister - init { if (self = [super init]) { entries = [[NSMutableDictionary dictionaryWithCapacity:10] retain]; connected = [[NSMutableArray arrayWithCapacity:10] retain]; enabled = [[NSMutableArray arrayWithCapacity:10] retain]; } return self; } - (void)dealloc { [entries release]; [connected release]; [enabled release]; [super dealloc]; } - (NSString*)toolPath { // Find the path of our tool in our bundle - should it be in the driver's bundle? return [[[owner bundle] resourcePath] stringByAppendingPathComponent:TOOL_FILENAME]; } - (OSStatus)writeToolWithAuthorisation:(AuthorizationRef)authorisationRef { OSStatus result; NSString *toolPath; NSMutableArray *parameters; const char **argv; int i; toolPath = [self toolPath]; // Build array of parameters parameters = [NSMutableArray arrayWithCapacity:10]; [parameters addObject:@"edit"]; for (NSNumber *key in enabled) { NSString *name = [entries objectForKey:key]; NSUInteger keyValue = [key unsignedIntValue]; UInt16 vendor = (keyValue >> 16) & 0xFFFF; UInt16 product = keyValue & 0xFFFF; [parameters addObject:name]; [parameters addObject:[NSString stringWithFormat:@"%i", vendor]]; [parameters addObject:[NSString stringWithFormat:@"%i", product]]; } // Convert parameters to a C array argv = malloc(sizeof(char*) * ([parameters count] + 1)); i = 0; for (NSString *item in parameters) argv[i++] = [item UTF8String]; argv[i] = NULL; // Execute the command result = AuthorizationExecuteWithPrivileges(authorisationRef, [toolPath UTF8String], kAuthorizationFlagDefaults, (char**)argv, NULL); // Done free(argv); return result; } - (NSString*)readTool { NSTask *task; NSPipe *pipe, *error; NSData *data; NSString *response; NSArray *lines; // Prepare to run the tool task = [[[NSTask alloc] init] autorelease]; [task setLaunchPath:[self toolPath]]; // Hook up the pipe to catch the output pipe = [NSPipe pipe]; [task setStandardOutput:pipe]; error = [NSPipe pipe]; [task setStandardError:error]; // Run the tool [task launch]; [task waitUntilExit]; // Check result if ([task terminationStatus] != 0) { data = [[error fileHandleForReading] readDataToEndOfFile]; return [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; } // Read the data back data = [[pipe fileHandleForReading] readDataToEndOfFile]; response = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; // Parse the results lines = [response componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; for (NSString *line in lines) { NSArray *values = [line componentsSeparatedByString:@","]; if ([values count] != 3) continue; NSUInteger vendor = [[values objectAtIndex:1] intValue]; NSUInteger product = [[values objectAtIndex:2] intValue]; NSNumber *key = [NSNumber numberWithUnsignedInt:(int)((vendor << 16) | product)]; [enabled addObject:key]; if ([entries objectForKey:key] == nil) [entries setObject:SanitiseName([values objectAtIndex:0]) forKey:key]; } return nil; } // Get the list of devices we've seen from the settings - (NSString*)readKnownDevices { NSDictionary *known; NSArray *keys; known = GetKnownDevices(); keys = [known allKeys]; for (NSNumber *key in keys) { if ([entries objectForKey:key] == nil) [entries setObject:[known objectForKey:key] forKey:key]; } return nil; } // Find any matching devices currently plugged in - (NSString*)readIOKit { io_iterator_t iterator; io_service_t object; iterator = 0; IOServiceGetMatchingServices([owner masterPort], IOServiceMatching(kIOUSBDeviceClassName), &iterator); if (iterator != 0) { while ((object = IOIteratorNext(iterator)) != 0) { if (IsXBox360Controller(object)) { NSNumber *vendorValue, *productValue; UInt16 vendor,product; vendorValue = GetDeviceValue(object, @"idVendor"); vendor = [vendorValue intValue]; productValue = GetDeviceValue(object, @"idProduct"); product = [productValue intValue]; if ((vendorValue != nil) && (productValue != nil)) { NSNumber *key; key = [NSNumber numberWithUnsignedInt:(vendor << 16) | product]; [connected addObject:key]; if ([entries objectForKey:key] == nil) { NSString *name = GetDeviceValue(object, @"USB Product Name"); if (name == nil) name = [NSString stringWithFormat:@"Unknown_%.4x_%.4x", vendor, product]; else name = SanitiseName(name); [entries setObject:name forKey:key]; } } } IOObjectRelease(object); } IOObjectRelease(iterator); } return nil; } - (void)showFailure:(NSString*)message { NSAlert *alert = [NSAlert alertWithMessageText:nil defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", message]; [alert runModal]; } - (BOOL)loadDevices { NSString *error; // Initialise error = nil; [entries removeAllObjects]; [connected removeAllObjects]; [enabled removeAllObjects]; // These can be done in any order, depending on the behaviour desired if (error == nil) error = [self readKnownDevices]; if (error == nil) error = [self readTool]; if (error == nil) error = [self readIOKit]; // Check for errors if (error != nil) { [self showFailure:error]; return NO; } // Done SetKnownDevices(entries); [list reloadData]; changed = NO; return YES; } // attempt to authenticate so we can edit the driver's list of supported devices as root - (BOOL)trySave { OSStatus status; AuthorizationRef authorisationRef; BOOL success = NO; status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorisationRef); if (status != errAuthorizationSuccess) { [self showFailure:NSLocalizedString(@"Unable to create authorisation request", @"")]; return NO; } AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0}; AuthorizationRights rights = {1, &right}; status = AuthorizationCopyRights(authorisationRef, &rights, NULL, kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights, NULL); if (status != errAuthorizationSuccess) { [self showFailure:NSLocalizedString(@"Unable to acquire authorisation", @"")]; goto fail; } status = [self writeToolWithAuthorisation:authorisationRef]; if (status != errAuthorizationSuccess) { [self showFailure:NSLocalizedString(@"Failed to execute the driver tool", @"")]; goto fail; } success = YES; fail: AuthorizationFree(authorisationRef, kAuthorizationFlagDestroyRights); return success; } - (void)showWithOwner:(Pref360ControlPref*)pane { owner = pane; if (![self loadDevices]) return; [NSApp beginSheet:sheet modalForWindow:[NSApp mainWindow] modalDelegate:nil didEndSelector:nil contextInfo:NULL]; } - (IBAction)done:(id)sender { if (changed) [self trySave]; [NSApp endSheet:sheet]; [sheet close]; } // NSTableView data source - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { return [entries count]; } - (id)tableView:(NSTableView*)aTableView objectValueForTableColumn:(NSTableColumn*)aTableColumn row:(NSInteger)rowIndex { NSString *identifier = [aTableColumn identifier]; NSString *key = [[entries allKeys] objectAtIndex:rowIndex]; if ([identifier compare:@"enable"] == NSOrderedSame) { return [NSNumber numberWithBool:[enabled containsObject:key]]; } if ([identifier compare:@"name"] == NSOrderedSame) { NSColor *colour; if ([connected containsObject:key]) colour = [NSColor blueColor]; else colour = [NSColor blackColor]; return [[[NSAttributedString alloc] initWithString:[entries objectForKey:key] attributes:[NSDictionary dictionaryWithObject:colour forKey:NSForegroundColorAttributeName]] autorelease]; } return nil; } - (void)tableView:(NSTableView*)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn*)aTableColumn row:(NSInteger)rowIndex { if ([(NSString*)[aTableColumn identifier] compare:@"enable"] == NSOrderedSame) { NSString *key = [[entries allKeys] objectAtIndex:rowIndex]; BOOL contains = [enabled containsObject:key]; if ([(NSNumber*)anObject boolValue]) { if (!contains) { [enabled addObject:key]; changed = YES; } } else { if (contains) { [enabled removeObject:key]; changed = YES; } } } } @end ================================================ FILE: Pref360Control/English.lproj/Pref360ControlPref.nib/designable.nib ================================================ 1050 12C60 2844 1187.34 625.00 com.apple.InterfaceBuilder.CocoaPlugin 2844 NSBox NSButton NSButtonCell NSCustomObject NSCustomView NSImageCell NSImageView NSMenu NSMenuItem NSPopUpButton NSPopUpButtonCell NSProgressIndicator NSScrollView NSScroller NSSlider NSSliderCell NSTableColumn NSTableView NSTextField NSTextFieldCell NSView NSWindowTemplate com.apple.InterfaceBuilder.CocoaPlugin PluginDependencyRecalculationVersion Pref360ControlPref FirstResponder NSApplication 7 2 {{240, 597}, {595, 304}} 1081606144 << do not localize >> NSWindow View {595, 10} 256 256 {{107, 260}, {471, 26}} YES -2076180416 2048 LucidaGrande 13 1044 109199360 1 LucidaGrande 13 16 400 75 Item1 1048576 2147483647 1 NSImage NSMenuCheckmark NSImage NSMenuMixedState _popUpItemAction: YES OtherViews Item2 1048576 2147483647 _popUpItemAction: Item3 1048576 2147483647 _popUpItemAction: 3 YES YES 1 NO 256 {{40, 266}, {65, 17}} YES 67108864 71303168 RGV2aWNlOgo 6 System controlColor 3 MC42NjY2NjY2NjY3AA 6 System controlTextColor 3 MAA NO 256 {{43, 117}, {77, 77}} MyAnalogStick NSView 256 {{123, 43}, {77, 77}} MyDigitalStick NSView 256 {{226, 43}, {77, 77}} MyAnalogStick NSView 256 {{306, 117}, {77, 77}} MyMainButtons NSView 256 {{151, 141}, {126, 39}} MyCentreButtons NSView 256 {{43, 202}, {77, 18}} MyShoulderButton NSView 256 {{306, 202}, {77, 18}} MyShoulderButton NSView 1280 {{41, 224}, {161, 20}} 16392 255 1280 {{224, 224}, {161, 20}} 16392 255 256 {{41, 93}, {71, 18}} YES 67108864 0 Invert X 1211912448 2 NSSwitch 200 25 NO 256 {{41, 73}, {71, 18}} YES 67108864 0 Invert Y 1211912448 2 200 25 NO 256 {{309, 81}, {71, 18}} YES 67108864 0 Invert X 1211912448 2 200 25 NO 256 {{309, 61}, {71, 18}} YES 67108864 0 Invert Y 1211912448 2 200 25 NO 256 {{224, 16}, {161, 21}} YES 67108864 0 Helvetica 12 16 32768 0.0 50 0.0 0 1 NO NO NO 256 {{41, 53}, {64, 18}} YES 67108864 0 Linked 1211912448 2 200 25 NO 256 {{309, 41}, {64, 18}} YES 67108864 0 Linked 1211912448 2 200 25 NO 256 274 256 {{13, 193}, {153, 14}} YES 67108864 272629760 Xbox 360 Controller Driver LucidaGrande 11 3100 NO 256 {{13, 173}, {129, 17}} YES 67108864 272629760 Version 0.12 LucidaGrande 10 2843 NO 256 {{13, 157}, {129, 17}} YES 67108864 272629760 (C) 2006-13 Colin Munro NO 256 {{10, 138}, {129, 14}} YES 69206017 272629760 http://tattiebogle.net/ NO 256 {{10, 116}, {153, 14}} YES 69206017 272629760 http://mice-software.com/ NO 256 {{13, 11}, {150, 97}} YES 67108864 272629760 Rm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhpcyBkcml2ZXIsIHBsZWFzZSBzZWUgdGhlIHN1cHBsaWVk IFJlYWRtZSBhbmQgTGljZW5jZSBkb2N1bWVudHMuCgpQbGVhc2UgY29uc2lkZXIgZG9uYXRpbmcgaWYg eW91IGVuam95IHRoaXMgZHJpdmVyIQ NO {{2, 2}, {179, 218}} {{395, 16}, {183, 235}} {0, 0} 67108864 0 About 6 System textBackgroundColor 3 MQA 3 MCAwLjgwMDAwMDAxMTkAA 3 0 2 NO 256 Apple PDF pasteboard type Apple PICT pasteboard type Apple PNG pasteboard type NSFilenamesPboardType NeXT Encapsulated PostScript v1.2 pasteboard type NeXT TIFF v4.0 pasteboard type {{197, 190}, {32, 24}} YES 134217728 33554432 NSImage battNone 0 1 0 YES NO YES 268 {{17, 40}, {21, 156}} YES 67108864 0 32768 0.0 50 0.0 0 0 NO YES NO -2147483380 {{8, 254}, {39, 38}} YES 67108864 134217728 + LucidaGrande 18 16 -2034499584 7 200 25 NO -2147483380 {{62, 9}, {118, 32}} YES 67108864 134217728 Power off -2038284288 129 200 25 NO {595, 304} {{0, 0}, {1280, 1002}} {595, 32} {10000000000000, 10000000000000} YES 15 2 {{131, 166}, {519, 336}} 1685585920 Window NSWindow {490, 150} 256 274 2304 256 {477, 229} YES NO YES -2147483392 {{224, 0}, {16, 17}} enable 20 20 20 75497536 2048 3 MC4zMzMzMzI5ODU2AA 6 System headerTextColor 67108864 131072 1211912448 2 NSImage NSSwitch 200 25 1 YES YES name 451 40 1000 75497536 2048 337641536 2048 Text Cell 6 System controlBackgroundColor 1 YES 3 2 6 System gridColor 3 MC41AA 17 -700448768 4 15 0 YES 0 1 {{1, 1}, {477, 229}} 4 -2147483392 {{224, 17}, {15, 102}} NO _doScroller: 0.9925373134328358 -2147483392 {{-100, -100}, {223, 15}} NO 1 _doScroller: 0.57142859697341919 {{20, 60}, {479, 231}} 133650 QSAAAEEgAABBmAAAQZgAAA 0.25 4 1 268 {{17, 299}, {355, 17}} YES 68157504 272630784 Select the devices you would like to use with the driver: NO 289 {{409, 12}, {96, 32}} YES 67108864 134217728 Done -2038284288 129 200 25 NO 292 {{17, 16}, {323, 28}} YES 68157504 272630784 To save changes to this list, you must enter your password.
A restart will be required for changes to take effect. LucidaGrande 11 16 NO {519, 336} {{0, 0}, {1280, 1002}} {490, 172} {10000000000000, 10000000000000} YES DeviceLister _window 26 leftStickInvertY 127 rightStickInvertX 128 rightStickInvertY 129 deviceList 130 rightStickDeadzone 134 rightStick 136 leftTrigger 137 rightTrigger 138 leftShoulder 139 rightShoulder 140 digiStick 141 centreButtons 142 rightButtons 143 leftStick 144 leftStickInvertX 145 selectDevice: 146 changeSetting: 151 changeSetting: 152 changeSetting: 153 changeSetting: 154 changeSetting: 155 leftLinked 169 rightLinked 170 changeSetting: 171 changeSetting: 172 batteryLevel 175 changeSetting: 196 leftStickDeadzone 197 showDeviceList: 220 deviceLister 226 powerOff: 229 powerOff 230 dataSource 225 done: 222 sheet 223 list 224 0 -2 File's Owner -1 First Responder 12 PrefPane 6 98 103 104 105 106 107 108 109 110 111 112 114 115 116 117 120 156 157 158 174 177 178 179 180 181 182 184 185 186 193 99 102 101 100 -3 Application 161 187 163 188 165 189 166 190 167 191 168 192 194 195 198 199 200 DeviceSheet 201 202 203 204 205 207 208 209 211 214 215 216 217 218 219 221 227 228 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{326, 482}, {595, 304}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{349, 211}, {519, 336}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin 230 DeviceLister NSObject done: id done: done: id NSTableView NSWindow list NSTableView sheet NSWindow IBProjectSource ./Classes/DeviceLister.h MyAnalogStick NSView IBProjectSource ./Classes/MyAnalogStick.h MyCentreButtons NSView IBProjectSource ./Classes/MyCentreButtons.h MyDigitalStick NSView IBProjectSource ./Classes/MyDigitalStick.h MyMainButtons NSView IBProjectSource ./Classes/MyMainButtons.h MyShoulderButton NSView IBProjectSource ./Classes/MyShoulderButton.h NSPreferencePane NSObject NSView NSView NSView NSWindow _firstKeyView NSView _initialKeyView NSView _lastKeyView NSView _window NSWindow IBProjectSource ./Classes/NSPreferencePane.h Pref360ControlPref NSPreferencePane id id powerOff: id showDeviceList: id NSImageView MyCentreButtons NSPopUpButton DeviceLister MyDigitalStick NSButton MyShoulderButton MyAnalogStick NSSlider NSButton NSButton NSProgressIndicator NSButton MyMainButtons NSButton MyShoulderButton MyAnalogStick NSSlider NSButton NSButton NSProgressIndicator batteryLevel NSImageView centreButtons MyCentreButtons deviceList NSPopUpButton deviceLister DeviceLister digiStick MyDigitalStick leftLinked NSButton leftShoulder MyShoulderButton leftStick MyAnalogStick leftStickDeadzone NSSlider leftStickInvertX NSButton leftStickInvertY NSButton leftTrigger NSProgressIndicator powerOff NSButton rightButtons MyMainButtons rightLinked NSButton rightShoulder MyShoulderButton rightStick MyAnalogStick rightStickDeadzone NSSlider rightStickInvertX NSButton rightStickInvertY NSButton rightTrigger NSProgressIndicator IBProjectSource ./Classes/Pref360ControlPref.h 0 IBCocoaFramework com.apple.InterfaceBuilder.CocoaPlugin.macosx YES 3 {11, 11} {10, 3} {15, 15} {32, 24} ================================================ FILE: Pref360Control/Info.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable Pref360Control CFBundleIconFile CFBundleIdentifier com.mice.driver.360Controller.Prefs CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 NSMainNibFile Pref360ControlPref NSPrefPaneIconFile Pref360ControlPref.tiff NSPrincipalClass Pref360ControlPref CFBundleName XBox 360 Controllers NSPrefPaneIconLabel Xbox 360\nControllers ================================================ FILE: Pref360Control/MyAnalogStick.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyAnalogStick.h - declaration of analog stick view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import @interface MyAnalogStick : NSView { int deadzone; int x,y; BOOL pressed,linked; } - (void)setDeadzone:(int)pos; - (void)setPositionX:(int)xPos y:(int)yPos; - (void)setPositionX:(int)xPos; - (void)setPositionY:(int)xPos; - (void)setPressed:(BOOL)pressedState; - (void)setLinked:(BOOL)linkedState; @end ================================================ FILE: Pref360Control/MyAnalogStick.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyAnalogStick.m - implementation of analog stick view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import "MyAnalogStick.h" #define PRESSED_INSET 5 #define AREA_INSET 4 @implementation MyAnalogStick - (id)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { deadzone=0; x=0; y=0; pressed=FALSE; linked=FALSE; } return self; } - (void)drawRect:(NSRect)rect { NSRect area,deadRect,posRect; // Compute positions // Area area=[self bounds]; // Deadzone deadRect.size.width=(deadzone*area.size.width)/32768; deadRect.size.height=(deadzone*area.size.height)/32768; deadRect.origin.x=area.origin.x+((area.size.width-deadRect.size.width)/2); deadRect.origin.y=area.origin.y+((area.size.height-deadRect.size.height)/2); // Position posRect.size.width=4; posRect.size.height=4; posRect.origin.x=area.origin.x+AREA_INSET+(((x+32768)*(area.size.width-(AREA_INSET*2)))/65536)-(posRect.size.width/2); posRect.origin.y=area.origin.y+area.size.height-AREA_INSET-(((y+32768)*(area.size.height-(AREA_INSET*2)))/65536)-(posRect.size.height/2); // Draw border NSDrawLightBezel(area,area); // Draw pressed state if(pressed) { NSRect pressArea; pressArea=area; pressArea.origin.x+=PRESSED_INSET; pressArea.origin.y+=PRESSED_INSET; pressArea.size.width-=PRESSED_INSET*2; pressArea.size.height-=PRESSED_INSET*2; [[NSColor blackColor] set]; NSRectFill(pressArea); } // Draw deadzone if(deadzone!=0) { [[NSColor redColor] set]; if(linked) NSFrameRect(deadRect); else { NSRect trueRect; trueRect=deadRect; trueRect.origin.x=area.origin.x; trueRect.size.width=area.size.width; NSFrameRect(trueRect); trueRect=deadRect; trueRect.origin.y=area.origin.y; trueRect.size.height=area.size.height; NSFrameRect(trueRect); } } // Draw position if(pressed) [[NSColor whiteColor] set]; else [[NSColor blackColor] set]; NSRectFill(posRect); } - (void)setDeadzone:(int)pos { deadzone=pos; [self setNeedsDisplay:YES]; } - (void)setPositionX:(int)xPos y:(int)yPos { x=xPos; y=yPos; [self setNeedsDisplay:YES]; } - (void)setPositionX:(int)xPos { x=xPos; [self setNeedsDisplay:YES]; } - (void)setPositionY:(int)yPos { y=yPos; [self setNeedsDisplay:YES]; } - (void)setPressed:(BOOL)pressedState { pressed=pressedState; [self setNeedsDisplay:YES]; } - (void)setLinked:(BOOL)linkedState { linked=linkedState; [self setNeedsDisplay:YES]; } @end ================================================ FILE: Pref360Control/MyCentreButtons.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyCentreButtons.h - definition of view to draw the central buttons This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import @interface MyCentreButtons : NSView { BOOL back,start,appSpecific; } - (void)setBack:(BOOL)bBack; - (void)setStart:(BOOL)bStart; - (void)setSpecific:(BOOL)bSpecific; @end ================================================ FILE: Pref360Control/MyCentreButtons.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyCentreButtons.m - implementation of central button view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#import "MyCentreButtons.h" @implementation MyCentreButtons - (id)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { back=start=appSpecific=FALSE; } return self; } - (void)drawButton:(NSString*)button inRectangle:(NSRect)rect pressed:(BOOL)down { NSBezierPath *path; NSSize size; NSDictionary *attributes; NSPoint point; NSColor *colour; // Draw circle path=[NSBezierPath bezierPathWithOvalInRect:rect]; colour=[NSColor blackColor]; [colour set]; if(down) { [path fill]; colour=[NSColor whiteColor]; } else [path stroke]; // Draw text attributes=[NSDictionary dictionaryWithObject:colour forKey:NSForegroundColorAttributeName]; size=[button sizeWithAttributes:attributes]; point.x=rect.origin.x+((rect.size.width-size.width)/2); point.y=rect.origin.y+((rect.size.height-size.height)/2); [button drawAtPoint:point withAttributes:attributes]; } - (void)drawRect:(NSRect)rect { NSRect area,button; area=[self bounds]; button.size.height=area.size.height/2; button.size.width=area.size.width/4; button.origin.x=area.origin.x; button.origin.y=area.origin.y+((area.size.height-button.size.height)/2); [self drawButton:@"Back" inRectangle:button pressed:back]; button.origin.x=area.origin.x+area.size.width-button.size.width; [self drawButton:@"Start" inRectangle:button pressed:start]; button.size.height=area.size.height-2; button.size.width=button.size.height; button.origin.x=area.origin.x+((area.size.width-button.size.width)/2); button.origin.y=area.origin.y+1; [self drawButton:@"" inRectangle:button pressed:appSpecific]; } - (void)setBack:(BOOL)bBack { back=bBack; [self setNeedsDisplay:TRUE]; } - (void)setStart:(BOOL)bStart { start=bStart; [self setNeedsDisplay:TRUE]; } - (void)setSpecific:(BOOL)bSpecific { appSpecific=bSpecific; [self setNeedsDisplay:TRUE]; } @end ================================================ FILE: Pref360Control/MyDigitalStick.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyDigitalStick.h - declaration of view to draw digital stick view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import @interface MyDigitalStick : NSView { NSBezierPath *up,*down,*left,*right; BOOL bUp,bDown,bLeft,bRight; } - (void)setUp:(BOOL)upState; - (void)setDown:(BOOL)downState; - (void)setLeft:(BOOL)leftState; - (void)setRight:(BOOL)rightState; @end ================================================ FILE: Pref360Control/MyDigitalStick.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyDigitalStick.m - implementation of digital stick view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import "MyDigitalStick.h" #define INSET_AMOUNT 10 @implementation MyDigitalStick - (NSBezierPath*)makeTriangle:(int)start inRectangle:(NSRect)rect; { NSBezierPath *path; NSPoint centre,point; const int mult[][2]={ {0,0}, {1,0}, {1,1}, {0,1}, {0,0} }; // Find central part centre.x=rect.origin.x+(rect.size.width/2); centre.y=rect.origin.y+(rect.size.height/2); // Create path path=[NSBezierPath bezierPath]; // Make triangle [path moveToPoint:centre]; point.x=rect.origin.x+(rect.size.width*mult[start][0]); point.y=rect.origin.y+(rect.size.height*mult[start][1]); [path lineToPoint:point]; point.x=rect.origin.x+(rect.size.width*mult[start+1][0]); point.y=rect.origin.y+(rect.size.height*mult[start+1][1]); [path lineToPoint:point]; [path closePath]; // Done return [path retain]; } - (id)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { NSRect rect,triangle; bUp=bDown=bLeft=bRight=FALSE; rect=[self bounds]; triangle.origin.x+=INSET_AMOUNT; triangle.origin.y+=INSET_AMOUNT; triangle.size.width-=INSET_AMOUNT*2; triangle.size.height-=INSET_AMOUNT*2; triangle.size.width=rect.size.width/3; triangle.size.height=rect.size.height/3; triangle.origin.y=rect.origin.y+(triangle.size.height*2); triangle.origin.x=rect.origin.x+triangle.size.width; up=[self makeTriangle:0 inRectangle:triangle]; triangle.origin.y=rect.origin.y; down=[self makeTriangle:2 inRectangle:triangle]; triangle.origin.y=rect.origin.y+triangle.size.height; triangle.origin.x=rect.origin.x; left=[self makeTriangle:1 inRectangle:triangle]; triangle.origin.x=rect.origin.x+(triangle.size.width*2); right=[self makeTriangle:3 inRectangle:triangle]; } return self; } - (void)dealloc { [up release]; [down release]; [left release]; [right release]; [super dealloc]; } - (void)drawRect:(NSRect)rect { NSRect area; area=[self bounds]; NSDrawLightBezel(area,area); [[NSColor blackColor] set]; if(bUp) [up fill]; if(bDown) [down fill]; if(bLeft) [left fill]; if(bRight) [right fill]; } - (void)setUp:(BOOL)upState { bUp=upState; [self setNeedsDisplay:TRUE]; } - (void)setDown:(BOOL)downState { bDown=downState; [self setNeedsDisplay:TRUE]; } - (void)setLeft:(BOOL)leftState { bLeft=leftState; [self setNeedsDisplay:TRUE]; } - (void)setRight:(BOOL)rightState { bRight=rightState; [self setNeedsDisplay:TRUE]; } @end ================================================ FILE: Pref360Control/MyMainButtons.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyMainButtons.h - declaration of A/B/X/Y button view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import @interface MyMainButtons : NSView { BOOL a,b,x,y; } - (void)setA:(BOOL)aVal; - (void)setB:(BOOL)bVal; - (void)setX:(BOOL)xVal; - (void)setY:(BOOL)yVal; @end ================================================ FILE: Pref360Control/MyMainButtons.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyMainButtons.m - implementation of A/B/X/Y button view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import "MyMainButtons.h" #define MINI_OFFSET 2 @implementation MyMainButtons - (id)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { a=b=x=y=FALSE; } return self; } - (void)drawButton:(NSString*)button inRectangle:(NSRect)rect pressed:(BOOL)down { NSBezierPath *path; NSSize size; NSDictionary *attributes; NSPoint point; NSColor *colour; NSRect bling; // Draw circle path=[NSBezierPath bezierPathWithOvalInRect:rect]; if(down) { [path fill]; // colour=[NSColor whiteColor]; } else { [path stroke]; // colour=[NSColor blackColor]; } colour=[NSColor blackColor]; bling=rect; bling.origin.x-=1; bling.origin.y-=1; bling.size.width+=2; bling.size.height+=2; path=[NSBezierPath bezierPathWithOvalInRect:bling]; [colour set]; [path stroke]; // Draw text attributes=[NSDictionary dictionaryWithObject:colour forKey:NSForegroundColorAttributeName]; size=[button sizeWithAttributes:attributes]; point.x=rect.origin.x+((rect.size.width-size.width)/2); point.y=rect.origin.y+((rect.size.height-size.height)/2); [button drawAtPoint:point withAttributes:attributes]; } - (void)drawRect:(NSRect)rect { NSRect area,bit; area=[self bounds]; bit.size.width=area.size.width/3; bit.size.height=area.size.height/3; bit.origin.x=area.origin.x+bit.size.width; bit.origin.y=area.origin.y+(bit.size.height*2)-MINI_OFFSET; [[NSColor yellowColor] set]; [self drawButton:@"Y" inRectangle:bit pressed:y]; bit.origin.y=area.origin.y+MINI_OFFSET; [[NSColor greenColor] set]; [self drawButton:@"A" inRectangle:bit pressed:a]; bit.origin.y=area.origin.y+bit.size.height; bit.origin.x=area.origin.x+MINI_OFFSET; [[NSColor blueColor] set]; [self drawButton:@"X" inRectangle:bit pressed:x]; bit.origin.x=area.origin.x+(bit.size.width*2)-MINI_OFFSET; [[NSColor redColor] set]; [self drawButton:@"B" inRectangle:bit pressed:b]; } - (void)setA:(BOOL)aVal { a=aVal; [self setNeedsDisplay:TRUE]; } - (void)setB:(BOOL)bVal { b=bVal; [self setNeedsDisplay:TRUE]; } - (void)setX:(BOOL)xVal { x=xVal; [self setNeedsDisplay:TRUE]; } - (void)setY:(BOOL)yVal { y=yVal; [self setNeedsDisplay:TRUE]; } @end ================================================ FILE: Pref360Control/MyShoulderButton.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyShoulderButton.h - simple button view declaration This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import @interface MyShoulderButton : NSView { BOOL pressed; } - (void)setPressed:(BOOL)b; @end ================================================ FILE: Pref360Control/MyShoulderButton.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro MyShoulderButton.m - implementation of simple button view This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import "MyShoulderButton.h" #define INSET_AMOUNT 2 @implementation MyShoulderButton - (id)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { pressed=FALSE; } return self; } - (void)drawRect:(NSRect)rect { NSRect area; area=[self bounds]; NSDrawLightBezel(area,area); if(pressed) { area.origin.x+=INSET_AMOUNT; area.origin.y+=INSET_AMOUNT; area.size.width-=INSET_AMOUNT*2; area.size.height-=INSET_AMOUNT*2; [[NSColor blueColor] set]; NSRectFill(area); } } - (void)setPressed:(BOOL)b { pressed=b; [self setNeedsDisplay:TRUE]; } @end ================================================ FILE: Pref360Control/Pref360Control.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 3B04BE7313763D04005FA9F8 /* DeviceLister.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B04BE7113763D04005FA9F8 /* DeviceLister.h */; }; 3B04BE7413763D04005FA9F8 /* DeviceLister.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B04BE7213763D04005FA9F8 /* DeviceLister.m */; }; 3B04BEA61376416D005FA9F8 /* DriverTool in Resources */ = {isa = PBXBuildFile; fileRef = 3B04BEA51376416D005FA9F8 /* DriverTool */; }; 3B47D9ED0B93C2BF00F200B8 /* battNone.tif in Resources */ = {isa = PBXBuildFile; fileRef = 3B47D9EC0B93C2BF00F200B8 /* battNone.tif */; }; 3B47D9F20B93C31400F200B8 /* batt1.tif in Resources */ = {isa = PBXBuildFile; fileRef = 3B47D9EE0B93C31400F200B8 /* batt1.tif */; }; 3B47D9F30B93C31400F200B8 /* batt0.tif in Resources */ = {isa = PBXBuildFile; fileRef = 3B47D9EF0B93C31400F200B8 /* batt0.tif */; }; 3B47D9F40B93C31400F200B8 /* batt3.tif in Resources */ = {isa = PBXBuildFile; fileRef = 3B47D9F00B93C31400F200B8 /* batt3.tif */; }; 3B47D9F50B93C31400F200B8 /* batt2.tif in Resources */ = {isa = PBXBuildFile; fileRef = 3B47D9F10B93C31400F200B8 /* batt2.tif */; }; 3B86987F0CE2A22100283CEC /* ControlPrefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B86987D0CE2A22100283CEC /* ControlPrefs.h */; }; 3B8698800CE2A22100283CEC /* ControlPrefs.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B86987E0CE2A22100283CEC /* ControlPrefs.m */; }; 3B8B91321376FC120047D446 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B8B91311376FC120047D446 /* Security.framework */; }; 3BBEAB01096B2C4C00F2E37B /* MyAnalogStick.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BBEAAFF096B2C4C00F2E37B /* MyAnalogStick.h */; }; 3BBEAB02096B2C4C00F2E37B /* MyAnalogStick.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBEAB00096B2C4C00F2E37B /* MyAnalogStick.m */; }; 3BBEAB05096B2C5200F2E37B /* MyCentreButtons.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBEAB03096B2C5200F2E37B /* MyCentreButtons.m */; }; 3BBEAB06096B2C5200F2E37B /* MyCentreButtons.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BBEAB04096B2C5200F2E37B /* MyCentreButtons.h */; }; 3BBEAB09096B2C5600F2E37B /* MyDigitalStick.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBEAB07096B2C5600F2E37B /* MyDigitalStick.m */; }; 3BBEAB0A096B2C5600F2E37B /* MyDigitalStick.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BBEAB08096B2C5600F2E37B /* MyDigitalStick.h */; }; 3BBEAB0D096B2C5B00F2E37B /* MyMainButtons.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BBEAB0B096B2C5B00F2E37B /* MyMainButtons.h */; }; 3BBEAB0E096B2C5B00F2E37B /* MyMainButtons.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBEAB0C096B2C5B00F2E37B /* MyMainButtons.m */; }; 3BBEAB11096B2C6000F2E37B /* MyShoulderButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BBEAB0F096B2C6000F2E37B /* MyShoulderButton.h */; }; 3BBEAB12096B2C6000F2E37B /* MyShoulderButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBEAB10096B2C6000F2E37B /* MyShoulderButton.m */; }; 3BBEAB2D096B6EDE00F2E37B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BBEAB2C096B6EDE00F2E37B /* IOKit.framework */; }; 3BC41F32096C85CB00664A42 /* DeviceItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BC41F30096C85CB00664A42 /* DeviceItem.h */; }; 3BC41F33096C85CB00664A42 /* DeviceItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BC41F31096C85CB00664A42 /* DeviceItem.m */; }; 3BC41F47096C8D0300664A42 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BC41F46096C8D0300664A42 /* ForceFeedback.framework */; }; 8D202CEA0486D31800D8A456 /* Pref360Control_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32DBCFA20370C41700C91783 /* Pref360Control_Prefix.pch */; }; 8D202CEB0486D31800D8A456 /* Pref360ControlPref.h in Headers */ = {isa = PBXBuildFile; fileRef = F506C03C013D9D7901CA16C8 /* Pref360ControlPref.h */; }; 8D202CED0486D31800D8A456 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 8D202CEE0486D31800D8A456 /* Pref360ControlPref.tiff in Resources */ = {isa = PBXBuildFile; fileRef = F506C040013D9D8001CA16C8 /* Pref360ControlPref.tiff */; }; 8D202CEF0486D31800D8A456 /* Pref360ControlPref.nib in Resources */ = {isa = PBXBuildFile; fileRef = F506C042013D9D8C01CA16C8 /* Pref360ControlPref.nib */; }; 8D202CF10486D31800D8A456 /* Pref360ControlPref.m in Sources */ = {isa = PBXBuildFile; fileRef = F506C03D013D9D7901CA16C8 /* Pref360ControlPref.m */; }; 8D202CF30486D31800D8A456 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; 8D202CF40486D31800D8A456 /* PreferencePanes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F506C035013D953901CA16C8 /* PreferencePanes.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 32DBCFA20370C41700C91783 /* Pref360Control_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pref360Control_Prefix.pch; sourceTree = ""; }; 3B04BE7113763D04005FA9F8 /* DeviceLister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceLister.h; sourceTree = ""; }; 3B04BE7213763D04005FA9F8 /* DeviceLister.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeviceLister.m; sourceTree = ""; }; 3B04BEA51376416D005FA9F8 /* DriverTool */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = DriverTool; path = ../DriverTool/build/Release/DriverTool; sourceTree = SOURCE_ROOT; }; 3B47D9EC0B93C2BF00F200B8 /* battNone.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = battNone.tif; sourceTree = ""; }; 3B47D9EE0B93C31400F200B8 /* batt1.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = batt1.tif; sourceTree = ""; }; 3B47D9EF0B93C31400F200B8 /* batt0.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = batt0.tif; sourceTree = ""; }; 3B47D9F00B93C31400F200B8 /* batt3.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = batt3.tif; sourceTree = ""; }; 3B47D9F10B93C31400F200B8 /* batt2.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = batt2.tif; sourceTree = ""; }; 3B86987D0CE2A22100283CEC /* ControlPrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ControlPrefs.h; path = ../360Daemon/ControlPrefs.h; sourceTree = SOURCE_ROOT; }; 3B86987E0CE2A22100283CEC /* ControlPrefs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ControlPrefs.m; path = ../360Daemon/ControlPrefs.m; sourceTree = SOURCE_ROOT; }; 3B8B91311376FC120047D446 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 3BBEAAFF096B2C4C00F2E37B /* MyAnalogStick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MyAnalogStick.h; sourceTree = ""; }; 3BBEAB00096B2C4C00F2E37B /* MyAnalogStick.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MyAnalogStick.m; sourceTree = ""; }; 3BBEAB03096B2C5200F2E37B /* MyCentreButtons.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MyCentreButtons.m; sourceTree = ""; }; 3BBEAB04096B2C5200F2E37B /* MyCentreButtons.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MyCentreButtons.h; sourceTree = ""; }; 3BBEAB07096B2C5600F2E37B /* MyDigitalStick.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MyDigitalStick.m; sourceTree = ""; }; 3BBEAB08096B2C5600F2E37B /* MyDigitalStick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MyDigitalStick.h; sourceTree = ""; }; 3BBEAB0B096B2C5B00F2E37B /* MyMainButtons.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MyMainButtons.h; sourceTree = ""; }; 3BBEAB0C096B2C5B00F2E37B /* MyMainButtons.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MyMainButtons.m; sourceTree = ""; }; 3BBEAB0F096B2C6000F2E37B /* MyShoulderButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MyShoulderButton.h; sourceTree = ""; }; 3BBEAB10096B2C6000F2E37B /* MyShoulderButton.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MyShoulderButton.m; sourceTree = ""; }; 3BBEAB2C096B6EDE00F2E37B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 3BC41F30096C85CB00664A42 /* DeviceItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceItem.h; sourceTree = ""; }; 3BC41F31096C85CB00664A42 /* DeviceItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeviceItem.m; sourceTree = ""; }; 3BC41F46096C8D0300664A42 /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = /System/Library/Frameworks/ForceFeedback.framework; sourceTree = ""; }; 8D202CF70486D31800D8A456 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8D202CF80486D31800D8A456 /* Pref360Control.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Pref360Control.prefPane; sourceTree = BUILT_PRODUCTS_DIR; }; F506C035013D953901CA16C8 /* PreferencePanes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PreferencePanes.framework; path = /System/Library/Frameworks/PreferencePanes.framework; sourceTree = ""; }; F506C03C013D9D7901CA16C8 /* Pref360ControlPref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pref360ControlPref.h; sourceTree = ""; }; F506C03D013D9D7901CA16C8 /* Pref360ControlPref.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pref360ControlPref.m; sourceTree = ""; }; F506C040013D9D8001CA16C8 /* Pref360ControlPref.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Pref360ControlPref.tiff; sourceTree = ""; }; F506C043013D9D8C01CA16C8 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Pref360ControlPref.nib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8D202CF20486D31800D8A456 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8D202CF30486D31800D8A456 /* Cocoa.framework in Frameworks */, 8D202CF40486D31800D8A456 /* PreferencePanes.framework in Frameworks */, 3BBEAB2D096B6EDE00F2E37B /* IOKit.framework in Frameworks */, 3BC41F47096C8D0300664A42 /* ForceFeedback.framework in Frameworks */, 3B8B91321376FC120047D446 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* Pref360Control */ = { isa = PBXGroup; children = ( 08FB77AFFE84173DC02AAC07 /* Classes */, 32DBCFA10370C40200C91783 /* Other Sources */, 089C167CFE841241C02AAC07 /* Resources */, 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, 19C28FB8FE9D52D311CA2CBB /* Products */, ); name = Pref360Control; sourceTree = ""; }; 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { isa = PBXGroup; children = ( 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, ); name = "Frameworks and Libraries"; sourceTree = ""; }; 089C167CFE841241C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 3B04BEA51376416D005FA9F8 /* DriverTool */, 8D202CF70486D31800D8A456 /* Info.plist */, 089C167DFE841241C02AAC07 /* InfoPlist.strings */, F506C040013D9D8001CA16C8 /* Pref360ControlPref.tiff */, F506C042013D9D8C01CA16C8 /* Pref360ControlPref.nib */, 3B47D9EC0B93C2BF00F200B8 /* battNone.tif */, 3B47D9EF0B93C31400F200B8 /* batt0.tif */, 3B47D9EE0B93C31400F200B8 /* batt1.tif */, 3B47D9F10B93C31400F200B8 /* batt2.tif */, 3B47D9F00B93C31400F200B8 /* batt3.tif */, ); name = Resources; sourceTree = ""; }; 08FB77AFFE84173DC02AAC07 /* Classes */ = { isa = PBXGroup; children = ( 3B86987D0CE2A22100283CEC /* ControlPrefs.h */, 3B86987E0CE2A22100283CEC /* ControlPrefs.m */, F506C03C013D9D7901CA16C8 /* Pref360ControlPref.h */, F506C03D013D9D7901CA16C8 /* Pref360ControlPref.m */, 3BBEAAFF096B2C4C00F2E37B /* MyAnalogStick.h */, 3BBEAB00096B2C4C00F2E37B /* MyAnalogStick.m */, 3BBEAB04096B2C5200F2E37B /* MyCentreButtons.h */, 3BBEAB03096B2C5200F2E37B /* MyCentreButtons.m */, 3BBEAB08096B2C5600F2E37B /* MyDigitalStick.h */, 3BBEAB07096B2C5600F2E37B /* MyDigitalStick.m */, 3BBEAB0B096B2C5B00F2E37B /* MyMainButtons.h */, 3BBEAB0C096B2C5B00F2E37B /* MyMainButtons.m */, 3BBEAB0F096B2C6000F2E37B /* MyShoulderButton.h */, 3BBEAB10096B2C6000F2E37B /* MyShoulderButton.m */, 3BC41F30096C85CB00664A42 /* DeviceItem.h */, 3BC41F31096C85CB00664A42 /* DeviceItem.m */, 3B04BE7113763D04005FA9F8 /* DeviceLister.h */, 3B04BE7213763D04005FA9F8 /* DeviceLister.m */, ); name = Classes; sourceTree = ""; }; 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( 3BC41F46096C8D0300664A42 /* ForceFeedback.framework */, 3BBEAB2C096B6EDE00F2E37B /* IOKit.framework */, 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, F506C035013D953901CA16C8 /* PreferencePanes.framework */, 3B8B91311376FC120047D446 /* Security.framework */, ); name = "Linked Frameworks"; sourceTree = ""; }; 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( 089C1672FE841209C02AAC07 /* Foundation.framework */, 089C167FFE841241C02AAC07 /* AppKit.framework */, ); name = "Other Frameworks"; sourceTree = ""; }; 19C28FB8FE9D52D311CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8D202CF80486D31800D8A456 /* Pref360Control.prefPane */, ); name = Products; sourceTree = ""; }; 32DBCFA10370C40200C91783 /* Other Sources */ = { isa = PBXGroup; children = ( 32DBCFA20370C41700C91783 /* Pref360Control_Prefix.pch */, ); name = "Other Sources"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 8D202CE90486D31800D8A456 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 8D202CEA0486D31800D8A456 /* Pref360Control_Prefix.pch in Headers */, 8D202CEB0486D31800D8A456 /* Pref360ControlPref.h in Headers */, 3BBEAB01096B2C4C00F2E37B /* MyAnalogStick.h in Headers */, 3BBEAB06096B2C5200F2E37B /* MyCentreButtons.h in Headers */, 3BBEAB0A096B2C5600F2E37B /* MyDigitalStick.h in Headers */, 3BBEAB0D096B2C5B00F2E37B /* MyMainButtons.h in Headers */, 3BBEAB11096B2C6000F2E37B /* MyShoulderButton.h in Headers */, 3BC41F32096C85CB00664A42 /* DeviceItem.h in Headers */, 3B86987F0CE2A22100283CEC /* ControlPrefs.h in Headers */, 3B04BE7313763D04005FA9F8 /* DeviceLister.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 8D202CE80486D31800D8A456 /* Pref360Control */ = { isa = PBXNativeTarget; buildConfigurationList = 3BBDC6A5097946B50023AAD8 /* Build configuration list for PBXNativeTarget "Pref360Control" */; buildPhases = ( 8D202CE90486D31800D8A456 /* Headers */, 8D202CEC0486D31800D8A456 /* Resources */, 8D202CF00486D31800D8A456 /* Sources */, 8D202CF20486D31800D8A456 /* Frameworks */, 8D202CF50486D31800D8A456 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = Pref360Control; productInstallPath = "$(HOME)/Library/PreferencePanes"; productName = Pref360Control; productReference = 8D202CF80486D31800D8A456 /* Pref360Control.prefPane */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 3BBDC6A9097946B50023AAD8 /* Build configuration list for PBXProject "Pref360Control" */; compatibilityVersion = "Xcode 3.0"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 089C166AFE841209C02AAC07 /* Pref360Control */; projectDirPath = ""; projectRoot = ""; targets = ( 8D202CE80486D31800D8A456 /* Pref360Control */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 8D202CEC0486D31800D8A456 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D202CED0486D31800D8A456 /* InfoPlist.strings in Resources */, 8D202CEE0486D31800D8A456 /* Pref360ControlPref.tiff in Resources */, 8D202CEF0486D31800D8A456 /* Pref360ControlPref.nib in Resources */, 3B47D9ED0B93C2BF00F200B8 /* battNone.tif in Resources */, 3B47D9F20B93C31400F200B8 /* batt1.tif in Resources */, 3B47D9F30B93C31400F200B8 /* batt0.tif in Resources */, 3B47D9F40B93C31400F200B8 /* batt3.tif in Resources */, 3B47D9F50B93C31400F200B8 /* batt2.tif in Resources */, 3B04BEA61376416D005FA9F8 /* DriverTool in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 8D202CF50486D31800D8A456 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8D202CF00486D31800D8A456 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D202CF10486D31800D8A456 /* Pref360ControlPref.m in Sources */, 3BBEAB02096B2C4C00F2E37B /* MyAnalogStick.m in Sources */, 3BBEAB05096B2C5200F2E37B /* MyCentreButtons.m in Sources */, 3BBEAB09096B2C5600F2E37B /* MyDigitalStick.m in Sources */, 3BBEAB0E096B2C5B00F2E37B /* MyMainButtons.m in Sources */, 3BBEAB12096B2C6000F2E37B /* MyShoulderButton.m in Sources */, 3BC41F33096C85CB00664A42 /* DeviceItem.m in Sources */, 3B8698800CE2A22100283CEC /* ControlPrefs.m in Sources */, 3B04BE7413763D04005FA9F8 /* DeviceLister.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C167EFE841241C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; F506C042013D9D8C01CA16C8 /* Pref360ControlPref.nib */ = { isa = PBXVariantGroup; children = ( F506C043013D9D8C01CA16C8 /* English */, ); name = Pref360ControlPref.nib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 3BBDC6A6097946B50023AAD8 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; "GCC_ENABLE_OBJC_GC[arch=x86_64]" = supported; GCC_ENABLE_TRIGRAPHS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Pref360Control_Prefix.pch; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; LIBRARY_SEARCH_PATHS = ""; LIBRARY_STYLE = Bundle; MACOSX_DEPLOYMENT_TARGET = 10.5; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-bundle", "-twolevel_namespace", ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Pref360Control; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = prefPane; ZERO_LINK = YES; }; name = Development; }; 3BBDC6A7097946B50023AAD8 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; "GCC_ENABLE_OBJC_GC[arch=x86_64]" = supported; GCC_ENABLE_TRIGRAPHS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Pref360Control_Prefix.pch; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; LIBRARY_SEARCH_PATHS = ""; LIBRARY_STYLE = Bundle; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-bundle", "-twolevel_namespace", ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Pref360Control; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = prefPane; ZERO_LINK = NO; }; name = Deployment; }; 3BBDC6A8097946B50023AAD8 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; "GCC_ENABLE_OBJC_GC[arch=x86_64]" = supported; GCC_ENABLE_TRIGRAPHS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Pref360Control_Prefix.pch; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; LIBRARY_SEARCH_PATHS = ""; LIBRARY_STYLE = Bundle; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-bundle", "-twolevel_namespace", ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Pref360Control; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = prefPane; }; name = Default; }; 3BBDC6AA097946B50023AAD8 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Development; }; 3BBDC6AB097946B50023AAD8 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Deployment; }; 3BBDC6AC097946B50023AAD8 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; MACOSX_DEPLOYMENT_TARGET = 10.5; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 3BBDC6A5097946B50023AAD8 /* Build configuration list for PBXNativeTarget "Pref360Control" */ = { isa = XCConfigurationList; buildConfigurations = ( 3BBDC6A6097946B50023AAD8 /* Development */, 3BBDC6A7097946B50023AAD8 /* Deployment */, 3BBDC6A8097946B50023AAD8 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 3BBDC6A9097946B50023AAD8 /* Build configuration list for PBXProject "Pref360Control" */ = { isa = XCConfigurationList; buildConfigurations = ( 3BBDC6AA097946B50023AAD8 /* Development */, 3BBDC6AB097946B50023AAD8 /* Deployment */, 3BBDC6AC097946B50023AAD8 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } ================================================ FILE: Pref360Control/Pref360ControlPref.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Pref360ControlPref.h - definition for the pref pane class This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #import #import #import #import #import #import #include "MyCentreButtons.h" #include "MyDigitalStick.h" #include "MyAnalogStick.h" #include "MyMainButtons.h" #include "MyShoulderButton.h" @class DeviceLister; @interface Pref360ControlPref : NSPreferencePane { // Window components IBOutlet MyCentreButtons *centreButtons; IBOutlet NSPopUpButton *deviceList; IBOutlet MyDigitalStick *digiStick; IBOutlet MyShoulderButton *leftShoulder; IBOutlet MyAnalogStick *leftStick; IBOutlet NSButton *leftLinked; IBOutlet NSSlider *leftStickDeadzone; IBOutlet NSButton *leftStickInvertX; IBOutlet NSButton *leftStickInvertY; IBOutlet NSProgressIndicator *leftTrigger; IBOutlet MyMainButtons *rightButtons; IBOutlet MyShoulderButton *rightShoulder; IBOutlet MyAnalogStick *rightStick; IBOutlet NSButton *rightLinked; IBOutlet NSSlider *rightStickDeadzone; IBOutlet NSButton *rightStickInvertX; IBOutlet NSButton *rightStickInvertY; IBOutlet NSProgressIndicator *rightTrigger; IBOutlet NSImageView *batteryLevel; IBOutlet DeviceLister *deviceLister; IBOutlet NSButton *powerOff; // Internal info mach_port_t masterPort; NSMutableArray *deviceArray; IOHIDElementCookie axis[6],buttons[15]; IOHIDDeviceInterface122 **device; IOHIDQueueInterface **hidQueue; FFDeviceObjectReference ffDevice; io_registry_entry_t registryEntry; int largeMotor,smallMotor; IONotificationPortRef notifyPort; CFRunLoopSourceRef notifySource; io_iterator_t onIteratorWired, offIteratorWired; io_iterator_t onIteratorWireless, offIteratorWireless; } - (void)mainViewDidLoad; - (void)eventQueueFired:(void*)sender withResult:(IOReturn)result; - (void)handleDeviceChange; - (IBAction)showDeviceList:(id)sender; - (IBAction)powerOff:(id)sender; - (mach_port_t)masterPort; @end ================================================ FILE: Pref360Control/Pref360ControlPref.m ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Pref360ControlPref.m - main source of the pref pane This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #import "Pref360ControlPref.h" #import "DeviceItem.h" #import "ControlPrefs.h" #import "DeviceLister.h" #define NO_ITEMS @"No devices found" // Passes a C callback back to the Objective C class static void CallbackFunction(void *target,IOReturn result,void *refCon,void *sender) { if(target!=NULL) [((Pref360ControlPref*)target) eventQueueFired:sender withResult:result]; } // Handle callback for when our device is connected or disconnected. Both events are // actually handled identically. static void callbackHandleDevice(void *param,io_iterator_t iterator) { io_service_t object=0; BOOL update; update=FALSE; while((object=IOIteratorNext(iterator))!=0) { IOObjectRelease(object); update=TRUE; } if(update) [(Pref360ControlPref*)param handleDeviceChange]; } @implementation Pref360ControlPref // Set the pattern on the LEDs - (void)updateLED:(int)ledIndex { FFEFFESCAPE escape; unsigned char c; if(ffDevice==0) return; c=ledIndex; escape.dwSize=sizeof(escape); escape.dwCommand=0x02; escape.cbInBuffer=sizeof(c); escape.lpvInBuffer=&c; escape.cbOutBuffer=0; escape.lpvOutBuffer=NULL; FFDeviceEscape(ffDevice,&escape); } // Enables and disables the rumble motor "override" - (void)setMotorOverride:(BOOL)enable { FFEFFESCAPE escape; char c; if(ffDevice==0) return; // If true, the motors will no longer obey any Force Feedback Framework // effects, and the motors may be controlled directly. False and the // motors will perform effects but can not be directly controlled. c=enable?0x01:0x00; escape.dwSize=sizeof(escape); escape.dwCommand=0x00; escape.cbInBuffer=sizeof(c); escape.lpvInBuffer=&c; escape.cbOutBuffer=0; escape.lpvOutBuffer=NULL; FFDeviceEscape(ffDevice,&escape); } // If the direct rumble control is enabled, this will set the motors // to the desired speed. - (void)testMotorsLarge:(unsigned char)large small:(unsigned char)small { FFEFFESCAPE escape; char c[2]; if(ffDevice==0) return; c[0]=large; c[1]=small; escape.dwSize=sizeof(escape); escape.dwCommand=0x01; escape.cbInBuffer=sizeof(c); escape.lpvInBuffer=c; escape.cbOutBuffer=0; escape.lpvOutBuffer=NULL; FFDeviceEscape(ffDevice,&escape); } // Update axis GUI component - (void)axisChanged:(int)index newValue:(int)value { switch(index) { case 0: [leftStick setPositionX:value]; break; case 1: [leftStick setPositionY:value]; break; case 2: [rightStick setPositionX:value]; break; case 3: [rightStick setPositionY:value]; break; case 4: [leftTrigger setDoubleValue:value]; largeMotor=value; // [self testMotorsLarge:largeMotor small:smallMotor]; break; case 5: [rightTrigger setDoubleValue:value]; smallMotor=value; // [self testMotorsLarge:largeMotor small:smallMotor]; break; default: break; } } // Update button GUI component - (void)buttonChanged:(int)index newValue:(int)value { BOOL b; b=value!=0; switch(index) { case 0: [rightButtons setA:b]; break; case 1: [rightButtons setB:b]; break; case 2: [rightButtons setX:b]; break; case 3: [rightButtons setY:b]; break; case 4: [leftShoulder setPressed:b]; break; case 5: [rightShoulder setPressed:b]; break; case 6: [leftStick setPressed:b]; break; case 7: [rightStick setPressed:b]; break; case 8: [centreButtons setStart:b]; break; case 9: [centreButtons setBack:b]; break; case 10: [centreButtons setSpecific:b]; break; case 11: [digiStick setUp:b]; break; case 12: [digiStick setDown:b]; break; case 13: [digiStick setLeft:b]; break; case 14: [digiStick setRight:b]; break; default: break; } } // Handle message from I/O Kit indicating something happened on the device - (void)eventQueueFired:(void*)sender withResult:(IOReturn)result { AbsoluteTime zeroTime={0,0}; IOHIDEventStruct event; BOOL found; int i; if(sender!=hidQueue) return; while(result==kIOReturnSuccess) { result=(*hidQueue)->getNextEvent(hidQueue,&event,zeroTime,0); if(result!=kIOReturnSuccess) continue; // Check axis for(i=0,found=FALSE;(i<6)&&(!found);i++) { if(event.elementCookie==axis[i]) { [self axisChanged:i newValue:event.value]; found=TRUE; } } if(found) continue; // Check buttons for(i=0,found=FALSE;(i<15)&&(!found);i++) { if(event.elementCookie==buttons[i]) { [self buttonChanged:i newValue:event.value]; found=TRUE; } } if(found) continue; // Cookie wasn't for us? } } // Enable input components - (void)inputEnable:(BOOL)enable { [leftStickDeadzone setEnabled:enable]; [leftStickInvertX setEnabled:enable]; [leftStickInvertY setEnabled:enable]; [leftLinked setEnabled:enable]; [rightStickDeadzone setEnabled:enable]; [rightStickInvertX setEnabled:enable]; [rightStickInvertY setEnabled:enable]; [rightLinked setEnabled:enable]; } // Reset GUI components - (void)resetDisplay { NSBundle *bundle; [leftStick setPositionX:0 y:0]; [leftStick setPressed:FALSE]; [leftStick setDeadzone:0]; [digiStick setUp:FALSE]; [digiStick setDown:FALSE]; [digiStick setLeft:FALSE]; [digiStick setRight:FALSE]; [centreButtons setBack:FALSE]; [centreButtons setSpecific:FALSE]; [centreButtons setStart:FALSE]; [rightStick setPositionX:0 y:0]; [rightStick setPressed:FALSE]; [rightStick setDeadzone:0]; [rightButtons setA:FALSE]; [rightButtons setB:FALSE]; [rightButtons setX:FALSE]; [rightButtons setY:FALSE]; [leftShoulder setPressed:FALSE]; [leftTrigger setDoubleValue:0]; [rightShoulder setPressed:FALSE]; [rightTrigger setDoubleValue:0]; // Reset inputs [leftStickDeadzone setIntValue:0]; [leftStickInvertX setState:NSOffState]; [leftStickInvertY setState:NSOffState]; [rightStickDeadzone setIntValue:0]; [rightStickInvertX setState:NSOffState]; [rightStickInvertY setState:NSOffState]; // Disable inputs [self inputEnable:NO]; [powerOff setHidden:YES]; // Hide battery icon bundle = [NSBundle bundleForClass:[self class]]; [batteryLevel setImage:[[[NSImage alloc] initByReferencingFile:[bundle pathForResource:@"battNone" ofType:@"tif"]] autorelease]]; } // Stop using the HID device - (void)stopDevice { if(registryEntry==0) return; // [self testMotorsLarge:0 small:0]; // [self setMotorOverride:FALSE]; // [self updateLED:0x00]; if(hidQueue!=NULL) { CFRunLoopSourceRef eventSource; (*hidQueue)->stop(hidQueue); eventSource=(*hidQueue)->getAsyncEventSource(hidQueue); if((eventSource!=NULL)&&CFRunLoopContainsSource(CFRunLoopGetCurrent(),eventSource,kCFRunLoopCommonModes)) CFRunLoopRemoveSource(CFRunLoopGetCurrent(),eventSource,kCFRunLoopCommonModes); (*hidQueue)->Release(hidQueue); hidQueue=NULL; } if(device!=NULL) { (*device)->close(device); device=NULL; } registryEntry=0; } // Start using a HID device - (void)startDevice { int i,j; CFArrayRef elements; CFDictionaryRef element; CFTypeRef object; long number; IOHIDElementCookie cookie; long usage,usagePage; CFRunLoopSourceRef eventSource; IOReturn ret; [self resetDisplay]; i=(int)[deviceList indexOfSelectedItem]; if(([deviceArray count]==0)||(i==-1)) { NSLog(@"No devices found? :( device count==%i, i==%i",(int)[deviceArray count],i); return; } { DeviceItem *item=[deviceArray objectAtIndex:i]; device=[item hidDevice]; ffDevice=[item ffDevice]; registryEntry=[item rawDevice]; } if((*device)->copyMatchingElements(device,NULL,&elements)!=kIOReturnSuccess) { NSLog(@"Can't get elements list"); // Make note of failure? return; } for(i=0;i=1)&&(usage<=15)) { // Button 1-11 buttons[usage-1]=cookie; } break; default: break; } } // Start queue if((*device)->open(device,0)!=kIOReturnSuccess) { NSLog(@"Can't open device"); // Make note of failure? return; } hidQueue=(*device)->allocQueue(device); if(hidQueue==NULL) { NSLog(@"Unable to allocate queue"); // Error? return; } ret=(*hidQueue)->create(hidQueue,0,32); if(ret!=kIOReturnSuccess) { NSLog(@"Unable to create the queue"); // Error? return; } // Create event source ret=(*hidQueue)->createAsyncEventSource(hidQueue,&eventSource); if(ret!=kIOReturnSuccess) { NSLog(@"Unable to create async event source"); // Error? return; } // Set callback ret=(*hidQueue)->setEventCallout(hidQueue,CallbackFunction,self,NULL); if(ret!=kIOReturnSuccess) { NSLog(@"Unable to set event callback"); // Error? return; } // Add to runloop CFRunLoopAddSource(CFRunLoopGetCurrent(),eventSource,kCFRunLoopCommonModes); // Add some elements for(i=0;i<6;i++) (*hidQueue)->addElement(hidQueue,axis[i],0); for(i=0;i<15;i++) (*hidQueue)->addElement(hidQueue,buttons[i],0); // Start ret=(*hidQueue)->start(hidQueue); if(ret!=kIOReturnSuccess) { NSLog(@"Unable to start queue - 0x%.8x",ret); // Error? return; } // Read existing properties { // CFDictionaryRef dict=(CFDictionaryRef)IORegistryEntryCreateCFProperty(registryEntry,CFSTR("DeviceData"),NULL,0); CFDictionaryRef dict = (CFDictionaryRef)[GetController(GetSerialNumber(registryEntry)) retain]; if(dict!=0) { CFBooleanRef boolValue; CFNumberRef intValue; if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertLeftX"),(void*)&boolValue)) { [leftStickInvertX setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; } else NSLog(@"No value for InvertLeftX"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertLeftY"),(void*)&boolValue)) { [leftStickInvertY setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; } else NSLog(@"No value for InvertLeftY"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("RelativeLeft"),(void*)&boolValue)) { BOOL enable=CFBooleanGetValue(boolValue); [leftLinked setState:enable?NSOnState:NSOffState]; [leftStick setLinked:enable]; } else NSLog(@"No value for RelativeLeft"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadzoneLeft"),(void*)&intValue)) { UInt16 i; CFNumberGetValue(intValue,kCFNumberShortType,&i); [leftStickDeadzone setIntValue:i]; [leftStick setDeadzone:i]; } else NSLog(@"No value for DeadzoneLeft"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertRightX"),(void*)&boolValue)) { [rightStickInvertX setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; } else NSLog(@"No value for InvertRightX"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertRightY"),(void*)&boolValue)) { [rightStickInvertY setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; } else NSLog(@"No value for InvertRightY"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("RelativeRight"),(void*)&boolValue)) { BOOL enable=CFBooleanGetValue(boolValue); [rightLinked setState:enable?NSOnState:NSOffState]; [rightStick setLinked:enable]; } else NSLog(@"No value for RelativeRight"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadzoneRight"),(void*)&intValue)) { UInt16 i; CFNumberGetValue(intValue,kCFNumberShortType,&i); [rightStickDeadzone setIntValue:i]; [rightStick setDeadzone:i]; } else NSLog(@"No value for DeadzoneRight"); CFRelease(dict); } else NSLog(@"No settings found"); } // Enable GUI components [self inputEnable:YES]; // Set LED and manual motor control // [self updateLED:0x0a]; // [self setMotorOverride:TRUE]; // [self testMotorsLarge:0 small:0]; largeMotor=0; smallMotor=0; // Battery level? { NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path; CFTypeRef prop; path = nil; if (IOObjectConformsTo(registryEntry, "WirelessHIDDevice")) { prop = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("BatteryLevel"), NULL, 0); if (prop != nil) { unsigned char level; if (CFNumberGetValue(prop, kCFNumberCharType, &level)) path = [bundle pathForResource:[NSString stringWithFormat:@"batt%i", level / 64] ofType:@"tif"]; CFRelease(prop); } [powerOff setHidden:NO]; } if (path == nil) path = [bundle pathForResource:@"battNone" ofType:@"tif"]; [batteryLevel setImage:[[[NSImage alloc] initByReferencingFile:path] autorelease]]; } } // Clear out the device lists - (void)deleteDeviceList { [deviceList removeAllItems]; [deviceArray removeAllObjects]; } // Update the device list from the I/O Kit - (void)updateDeviceList { CFMutableDictionaryRef hidDictionary; IOReturn ioReturn; io_iterator_t iterator; io_object_t hidDevice, parent; int count; DeviceItem *item; // Scrub old items [self stopDevice]; [self deleteDeviceList]; // Add new items hidDictionary=IOServiceMatching(kIOHIDDeviceKey); ioReturn=IOServiceGetMatchingServices(masterPort,hidDictionary,&iterator); if((ioReturn!=kIOReturnSuccess)||(iterator==0)) { [deviceList addItemWithTitle:NO_ITEMS]; return; } count=0; while((hidDevice=IOIteratorNext(iterator))) { parent = 0; IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent); BOOL deviceWired = IOObjectConformsTo(parent, "Xbox360Peripheral") && IOObjectConformsTo(hidDevice, "Xbox360ControllerClass"); BOOL deviceWireless = IOObjectConformsTo(hidDevice, "WirelessHIDDevice"); if ((!deviceWired) && (!deviceWireless)) { IOObjectRelease(hidDevice); continue; } item=[DeviceItem allocateDeviceItemForDevice:hidDevice]; if(item==NULL) continue; // Add to item NSString *name; name = [item name]; if (name == nil) name = @"Generic Controller"; [deviceList addItemWithTitle:[NSString stringWithFormat:@"%i: %@ (%@)", ++count, name, deviceWireless ? @"Wireless" : @"Wired"]]; [deviceArray addObject:item]; } IOObjectRelease(iterator); if(count==0) [deviceList addItemWithTitle:NO_ITEMS]; [self startDevice]; } // Start up - (void)mainViewDidLoad { io_object_t object; // Get master port, for accessing I/O Kit IOMasterPort(MACH_PORT_NULL,&masterPort); // Set up notification of USB device addition/removal notifyPort=IONotificationPortCreate(masterPort); notifySource=IONotificationPortGetRunLoopSource(notifyPort); CFRunLoopAddSource(CFRunLoopGetCurrent(),notifySource,kCFRunLoopCommonModes); // Prepare other fields deviceArray=[[NSMutableArray arrayWithCapacity:1] retain]; device=NULL; hidQueue=NULL; // Activate callbacks // Wired IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, IOServiceMatching(kIOUSBDeviceClassName), callbackHandleDevice, self, &onIteratorWired); callbackHandleDevice(self, onIteratorWired); IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, IOServiceMatching(kIOUSBDeviceClassName), callbackHandleDevice, self, &offIteratorWired); while((object = IOIteratorNext(offIteratorWired)) != 0) IOObjectRelease(object); // Wireless IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, IOServiceMatching("WirelessHIDDevice"), callbackHandleDevice, self, &onIteratorWireless); callbackHandleDevice(self, onIteratorWireless); IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, IOServiceMatching("WirelessHIDDevice"), callbackHandleDevice, self, &offIteratorWireless); while((object = IOIteratorNext(offIteratorWireless)) != 0) IOObjectRelease(object); } // Shut down - (void)dealloc { int i; DeviceItem *item; FFEFFESCAPE escape; unsigned char c; // Remove notification source IOObjectRelease(onIteratorWired); IOObjectRelease(onIteratorWireless); IOObjectRelease(offIteratorWired); IOObjectRelease(offIteratorWireless); CFRunLoopRemoveSource(CFRunLoopGetCurrent(),notifySource,kCFRunLoopCommonModes); CFRunLoopSourceInvalidate(notifySource); IONotificationPortDestroy(notifyPort); // Release device and info [self stopDevice]; for (i = 0; i < [deviceArray count]; i++) { item = [deviceArray objectAtIndex:i]; if ([item ffDevice] == 0) continue; c = 0x06 + (i % 0x04); escape.dwSize = sizeof(escape); escape.dwCommand = 0x02; escape.cbInBuffer = sizeof(c); escape.lpvInBuffer = &c; escape.cbOutBuffer = 0; escape.lpvOutBuffer = NULL; FFDeviceEscape([item ffDevice], &escape); } [self deleteDeviceList]; [deviceArray release]; // Close master port mach_port_deallocate(mach_task_self(),masterPort); // Done [super dealloc]; } - (mach_port_t)masterPort { return masterPort; } // Handle selection from drop down menu - (void)selectDevice:(id)sender { [self startDevice]; } // Handle changing a setting - (void)changeSetting:(id)sender { CFDictionaryRef dict; CFStringRef keys[8]; CFTypeRef values[8]; UInt16 i; // Set keys and values keys[0]=CFSTR("InvertLeftX"); values[0]=([leftStickInvertX state]==NSOnState)?kCFBooleanTrue:kCFBooleanFalse; keys[1]=CFSTR("InvertLeftY"); values[1]=([leftStickInvertY state]==NSOnState)?kCFBooleanTrue:kCFBooleanFalse; keys[2]=CFSTR("InvertRightX"); values[2]=([rightStickInvertX state]==NSOnState)?kCFBooleanTrue:kCFBooleanFalse; keys[3]=CFSTR("InvertRightY"); values[3]=([rightStickInvertY state]==NSOnState)?kCFBooleanTrue:kCFBooleanFalse; keys[4]=CFSTR("DeadzoneLeft"); i=[leftStickDeadzone doubleValue]; values[4]=CFNumberCreate(NULL,kCFNumberShortType,&i); keys[5]=CFSTR("DeadzoneRight"); i=[rightStickDeadzone doubleValue]; values[5]=CFNumberCreate(NULL,kCFNumberShortType,&i); keys[6]=CFSTR("RelativeLeft"); values[6]=([leftLinked state]==NSOnState)?kCFBooleanTrue:kCFBooleanFalse; keys[7]=CFSTR("RelativeRight"); values[7]=([rightLinked state]==NSOnState)?kCFBooleanTrue:kCFBooleanFalse; // Create dictionary dict=CFDictionaryCreate(NULL,(const void**)keys,(const void**)values,sizeof(keys)/sizeof(keys[0]),&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks); // Set property IORegistryEntrySetCFProperties(registryEntry, dict); SetController(GetSerialNumber(registryEntry), (NSDictionary*)dict); // Update UI [leftStick setLinked:([leftLinked state]==NSOnState)]; [leftStick setDeadzone:[leftStickDeadzone doubleValue]]; [rightStick setLinked:([rightLinked state]==NSOnState)]; [rightStick setDeadzone:[rightStickDeadzone doubleValue]]; } // Handle I/O Kit device add/remove - (void)handleDeviceChange { // Ideally, this function would make a note of the controller's Location ID, then // reselect it when the list is updated, if it's still in the list. [self updateDeviceList]; } - (IBAction)showDeviceList:(id)sender { [deviceLister showWithOwner:self]; } - (IBAction)powerOff:(id)sender { FFEFFESCAPE escape; if(ffDevice==0) return; escape.dwSize=sizeof(escape); escape.dwCommand=0x03; escape.cbInBuffer=0; escape.lpvInBuffer=NULL; escape.cbOutBuffer=0; escape.lpvOutBuffer=NULL; FFDeviceEscape(ffDevice,&escape); } @end ================================================ FILE: Pref360Control/Pref360Control_Prefix.pch ================================================ // // Prefix header for all source files of the 'Pref360Control' target in the 'Pref360Control' project. // #ifdef __OBJC__ #import #import #endif ================================================ FILE: Pref360Control/version.plist ================================================ BuildVersion 328 CFBundleShortVersionString 1.0 CFBundleVersion 1.0 ProductBuildVersion 7K571 ProjectName PreferencePaneTemplate SourceVersion 120000 ================================================ FILE: Readme.rtf ================================================ {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}} {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} \paperw12240\paperh15840\margl1440\margr1440\vieww9000\viewh8400\viewkind0 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \f0\b\fs36 \cf0 XBox 360 Controller driver for Mac OS X \b0\fs24 \ Copyright (C) 2006-2013 Colin Munro\ {\field{\*\fldinst{HYPERLINK "http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller"}}{\fldrslt http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller}}\ \ \b About \b0 \ This driver supports the Microsoft Xbox 360 controller, including access to rumble motors and LEDs, on the Mac OS X platform. It includes a plugin for the Apple Force Feedback Framework so some games will be able to activate them, along with a Preference Pane with which allows you to test everything is installed correctly. Both wired 360 controllers connected via USB, and wireless 360 controllers connected via the Wireless Gaming Receiver for Windows, are supported.\ \ \b Licence \b0 \ This driver is licensed under the GNU Public License. A copy of this license is included in the distribution file, please inspect it before using the binary or source.\ \ \b Installation \b0 \ Simply complete the installer package to install the driver. The driver will recommend you restart - if you do not, the driver will only be usable if the controller is already connected or connected within a minute after the installer completes. If you are interested in installing as a developer please see below.\ \ \b Usage \b0 \ The driver exposes a standard game pad with a number of standard controls, so any game that supports gaming devices should work. In some cases this may need an update from the manufacturer of the game or a patched version. The Preference Pane uses the standard Mac OS X Frameworks for accessing HID devices and accessing Force Feedback capabilities, so should be a good test that the installation is functional.\ \ \b Known Problems/Todo \b0 \ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls1\ilvl0\cf0 {\listtext \'95 }The rumble motor test on the triggers of the Preference Pane bypasses the Force Feedback Framework functionality, so isn't actually testing it. It really should, for completeness (and it'd help adding support for more complex effects) - this test is now disabled in the normal release anyway\ {\listtext \'95 }Force Feedback plugin may make effects run slower (e.g. longer time) than they should\ {\listtext \'95 }Driver probably needs to be more resilient to errors and odd cases\ {\listtext \'95 }Better Force Feedback "emulation"\ {\listtext \'95 }Extra settings? E.g. trigger deadzones, control remapping.\ {\listtext \'95 }Someone has requested old Xbox Controller support too.\ \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural \ls2\ilvl0 \b \cf0 \ Contact me \b0 \ \pard\tx0\tx220\tx660\tx720\tx740\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \ls2\ilvl0\cf0 Please feel free to contact me with any comments, questions and so on using the form at the URL at the top of the file.\ \ \pard\tx0\tx220\tx660\tx720\tx740\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \ls2\ilvl0 \b \cf0 Developer info \b0 \ Anything below this probably doesn't affect end users, so you can stop reading now if you just want to use the driver.\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \cf0 \ \b Building \b0 \ (This section does not yet discuss the source of the wireless drivers)\ The distribution currently consists of 3 projects - one for the driver (implemented in C++, as an I/O Kit C++ class), one for the force feedback support plugin (implemented in C, as an I/O Kit COM plugin) and one for the Preference Pane (implemented in Objective C as a preference pane plugin). Ideally these 3 targets should be in the same project, but I've not worked on this yet.\ \ To build, use the standard Xcode build for Deployment on each of the 3 projects. Build Feedback360 before 360Controller, as the 360Controller project includes a script to copy the Feedback360 bundle to the correct place in the .kext to make it work.\ \ To debug the driver, sudo cp -R 360Controller.kext /tmp/ to assign the correct properties - note that the Force Feedback plugin only seems to be found by OSX if the driver is in /System/Library/Extensions so I could only debug it in place.\ \ To test the Preference Pane, just double-click the resulting file.\ \ \b Debugging \b0 \ Most of the debugging I did was via printing out text. In 360Controller, you can use IOLog(), and the output will appear in system.log. In Feedback360 normal fprintf(stderr,...), and the output will appear on the console of whatever application is attempting to use Force Feedback. In Pref360Control NSLog() works as it's an Objective C program, and will output to the console of the Preferences application.\ \ \b Installer \b0 \ Included is an installer project for Iceberg. Download Iceberg at {\field{\*\fldinst{HYPERLINK "http://s.sudre.free.fr/Software/Iceberg.html"}}{\fldrslt http://s.sudre.free.fr/Software/Iceberg.html}}\ \ \b Other information \b0 \ I wrote the driver from scratch, using Apple documentation and drivers simply as a reference and not basing it upon any existing source. As such, some things may be done strangely or incorrectly, so excuse any weirdness. I've also tried to include comments to explain generally what's going on :)\ } ================================================ FILE: Wireless360Controller/IOKitDriver.pbproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 39; objects = { 06AA1265FFB2107B11CA28AA = { buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OPTIMIZATION_CFLAGS = "-O0"; ZERO_LINK = YES; }; isa = PBXBuildStyle; name = Development; }; 06AA1266FFB2107B11CA28AA = { buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; ZERO_LINK = NO; }; isa = PBXBuildStyle; name = Deployment; }; //060 //061 //062 //063 //064 //080 //081 //082 //083 //084 089C1669FE841209C02AAC07 = { buildSettings = { }; buildStyles = ( 06AA1265FFB2107B11CA28AA, 06AA1266FFB2107B11CA28AA, ); hasScannedForEncodings = 1; isa = PBXProject; mainGroup = 089C166AFE841209C02AAC07; projectDirPath = ""; targets = ( 32D94FC30562CBF700B6AF17, ); }; 089C166AFE841209C02AAC07 = { children = ( 247142CAFF3F8F9811CA285C, 8DA80CCF06AD972A00E5AC22, 089C167CFE841241C02AAC07, 19C28FB6FE9D52B211CA2CBB, ); isa = PBXGroup; name = "«PROJECTNAME»"; refType = 4; sourceTree = ""; }; 089C167CFE841241C02AAC07 = { children = ( 32D94FCF0562CBF700B6AF17, 089C167DFE841241C02AAC07, ); isa = PBXGroup; name = Resources; refType = 4; sourceTree = ""; }; 089C167DFE841241C02AAC07 = { children = ( 089C167EFE841241C02AAC07, ); isa = PBXVariantGroup; name = InfoPlist.strings; refType = 4; sourceTree = ""; }; 089C167EFE841241C02AAC07 = { fileEncoding = 10; isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; refType = 4; sourceTree = ""; }; //080 //081 //082 //083 //084 //190 //191 //192 //193 //194 19C28FB6FE9D52B211CA2CBB = { children = ( 32D94FD00562CBF700B6AF17, ); isa = PBXGroup; name = Products; refType = 4; sourceTree = ""; }; //190 //191 //192 //193 //194 //1A0 //1A1 //1A2 //1A3 //1A4 1A224C3EFF42367911CA2CB7 = { fileEncoding = 4; isa = PBXFileReference; lastKnownFileType = file; path = "«PROJECTNAMEASIDENTIFIER».h"; refType = 4; sourceTree = ""; }; 1A224C3FFF42367911CA2CB7 = { fileEncoding = 4; isa = PBXFileReference; lastKnownFileType = file; path = "«PROJECTNAMEASIDENTIFIER».cpp"; refType = 4; sourceTree = ""; }; //1A0 //1A1 //1A2 //1A3 //1A4 //240 //241 //242 //243 //244 247142CAFF3F8F9811CA285C = { children = ( 1A224C3EFF42367911CA2CB7, 1A224C3FFF42367911CA2CB7, ); isa = PBXGroup; name = Source; path = ""; refType = 4; sourceTree = ""; }; //240 //241 //242 //243 //244 //320 //321 //322 //323 //324 32D94FC30562CBF700B6AF17 = { buildPhases = ( 32D94FC40562CBF700B6AF17, 32D94FC50562CBF700B6AF17, 32D94FC70562CBF700B6AF17, 32D94FC90562CBF700B6AF17, 32D94FCB0562CBF700B6AF17, 32D94FCC0562CBF700B6AF17, 32D94FCD0562CBF700B6AF17, ); buildRules = ( ); buildSettings = { INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = "com.yourcompany.driver.«PROJECTNAMEASIDENTIFIER»"; MODULE_VERSION = 1.0.0d1; PRODUCT_NAME = "«PROJECTNAME»"; WRAPPER_EXTENSION = kext; }; dependencies = ( ); isa = PBXNativeTarget; name = "«PROJECTNAME»"; productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; productName = "«PROJECTNAME»"; productReference = 32D94FD00562CBF700B6AF17; productType = "com.apple.product-type.kernel-extension.iokit"; }; 32D94FC40562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXShellScriptBuildPhase; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; }; 32D94FC50562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( 32D94FC60562CBF700B6AF17, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FC60562CBF700B6AF17 = { fileRef = 1A224C3EFF42367911CA2CB7; isa = PBXBuildFile; settings = { }; }; 32D94FC70562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( 32D94FC80562CBF700B6AF17, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FC80562CBF700B6AF17 = { fileRef = 089C167DFE841241C02AAC07; isa = PBXBuildFile; settings = { }; }; 32D94FC90562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( 32D94FCA0562CBF700B6AF17, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FCA0562CBF700B6AF17 = { fileRef = 1A224C3FFF42367911CA2CB7; isa = PBXBuildFile; settings = { ATTRIBUTES = ( ); }; }; 32D94FCB0562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXFrameworksBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FCC0562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FCD0562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXShellScriptBuildPhase; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; }; 32D94FCF0562CBF700B6AF17 = { isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; refType = 4; sourceTree = ""; }; 32D94FD00562CBF700B6AF17 = { explicitFileType = wrapper.cfbundle; includeInIndex = 0; isa = PBXFileReference; path = "«PROJECTNAME».kext"; refType = 3; sourceTree = BUILT_PRODUCTS_DIR; }; //320 //321 //322 //323 //324 //8D0 //8D1 //8D2 //8D3 //8D4 8DA80CCF06AD972A00E5AC22 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; refType = 0; sourceTree = ""; }; }; rootObject = 089C1669FE841209C02AAC07; } ================================================ FILE: Wireless360Controller/Info.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.mice.driver.Wireless360Controller CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType KEXT CFBundleSignature ???? CFBundleVersion 1.0.0d12 IOKitPersonalities Wireless360Controller CFBundleIdentifier com.mice.driver.Wireless360Controller IOCFPlugInTypes F4545CE5-BF5B-11D6-A4BB-0003933E3E3E 360Controller.kext/Contents/PlugIns/Feedback360.plugin IOClass Wireless360Controller IOKitDebug 65536 IOProviderClass WirelessDevice Wireless360Device 0 OSBundleLibraries com.apple.iokit.IOHIDFamily 1.2 com.apple.kpi.iokit 8.0.0 com.apple.kpi.libkern 8.0.0 com.apple.kpi.mach 8.0.0 com.mice.driver.WirelessGamingReceiver 1.0.0d1 ================================================ FILE: Wireless360Controller/Wireless360Controller.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Wireless360Controller.cpp - main source of the standard wireless controller driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "Wireless360Controller.h" #include "../WirelessGamingReceiver/WirelessDevice.h" #include "../360Controller/ControlStruct.h" #include "../360Controller/xbox360hid.h" #define kDriverSettingKey "DeviceData" OSDefineMetaClassAndStructors(Wireless360Controller, WirelessHIDDevice) #define super WirelessHIDDevice static inline XBox360_SShort getAbsolute(XBox360_SShort value) { XBox360_SShort reverse; #ifdef __LITTLE_ENDIAN__ reverse=value; #elif __BIG_ENDIAN__ reverse=((value&0xFF00)>>8)|((value&0x00FF)<<8); #else #error Unknown CPU byte order #endif return (reverse<0)?~reverse:reverse; } bool Wireless360Controller::init(OSDictionary *propTable) { bool res = super::init(propTable); // Default settings invertLeftX=invertLeftY=FALSE; invertRightX=invertRightY=FALSE; deadzoneLeft=deadzoneRight=0; relativeLeft=relativeRight=FALSE; readSettings(); // Done return res; } // Read the settings from the registry void Wireless360Controller::readSettings(void) { OSDictionary *dataDictionary; OSBoolean *value; OSNumber *number; dataDictionary=OSDynamicCast(OSDictionary,getProperty(kDriverSettingKey)); if(dataDictionary==NULL) return; value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertLeftX")); if(value!=NULL) invertLeftX=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertLeftY")); if(value!=NULL) invertLeftY=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertRightX")); if(value!=NULL) invertRightX=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("InvertRightY")); if(value!=NULL) invertRightY=value->getValue(); number=OSDynamicCast(OSNumber,dataDictionary->getObject("DeadzoneLeft")); if(number!=NULL) deadzoneLeft=number->unsigned32BitValue(); number=OSDynamicCast(OSNumber,dataDictionary->getObject("DeadzoneRight")); if(number!=NULL) deadzoneRight=number->unsigned32BitValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("RelativeLeft")); if(value!=NULL) relativeLeft=value->getValue(); value=OSDynamicCast(OSBoolean,dataDictionary->getObject("RelativeRight")); if(value!=NULL) relativeRight=value->getValue(); /* IOLog("Xbox360ControllerClass preferences loaded:\n invertLeft X: %s, Y: %s\n invertRight X: %s, Y:%s\n deadzone Left: %d, Right: %d\n\n", invertLeftX?"True":"False",invertLeftY?"True":"False", invertRightX?"True":"False",invertRightY?"True":"False", deadzoneLeft,deadzoneRight); */ } // Adjusts the report for any settings specified by the user void Wireless360Controller::fiddleReport(unsigned char *data, int length) { XBOX360_IN_REPORT *report = (XBOX360_IN_REPORT*)data; if (invertLeftX) report->left.x = ~report->left.x; if (!invertLeftY) report->left.y = ~report->left.y; if (invertRightX) report->right.x = ~report->right.x; if (!invertRightY) report->right.y = ~report->right.y; if (deadzoneLeft != 0) { if (relativeLeft) { if ((getAbsolute(report->left.x) < deadzoneLeft) && (getAbsolute(report->left.y) < deadzoneLeft)) { report->left.x = 0; report->left.y = 0; } } else { if (getAbsolute(report->left.x) < deadzoneLeft) report->left.x = 0; if (getAbsolute(report->left.y) < deadzoneLeft) report->left.y = 0; } } if (deadzoneRight != 0) { if (relativeRight) { if ((getAbsolute(report->right.x) < deadzoneRight) && (getAbsolute(report->right.y) < deadzoneRight)) { report->right.x = 0; report->right.y = 0; } } else { if (getAbsolute(report->right.x) < deadzoneRight) report->right.x = 0; if (getAbsolute(report->right.y) < deadzoneRight) report->right.y = 0; } } } void Wireless360Controller::receivedHIDupdate(unsigned char *data, int length) { fiddleReport(data, length); super::receivedHIDupdate(data, length); } void Wireless360Controller::SetRumbleMotors(unsigned char large, unsigned char small) { char buf[] = {0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00}; WirelessDevice *device; device = OSDynamicCast(WirelessDevice, getProvider()); if (device != NULL) device->SendPacket(buf, sizeof(buf)); } IOReturn Wireless360Controller::setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { char data[2]; // IOLog("setReport(%p, %d, %d)\n", report, reportType, options); if (report->readBytes(0, data, 2) < 2) return kIOReturnUnsupported; // Rumble if (data[0] == 0x00) { if ((data[1] != report->getLength()) || (data[1] != 0x04)) return kIOReturnUnsupported; report->readBytes(2, data, 2); SetRumbleMotors(data[0], data[1]); return kIOReturnSuccess; } return super::setReport(report, reportType, options); } IOReturn Wireless360Controller::newReportDescriptor(IOMemoryDescriptor ** descriptor ) const { IOBufferMemoryDescriptor *buffer; buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, sizeof(ReportDescriptor)); if (buffer == NULL) return kIOReturnNoResources; buffer->writeBytes(0, ReportDescriptor, sizeof(ReportDescriptor)); *descriptor = buffer; return kIOReturnSuccess; } // Called by the userspace IORegistryEntrySetCFProperties function IOReturn Wireless360Controller::setProperties(OSObject *properties) { OSDictionary *dictionary; dictionary=OSDynamicCast(OSDictionary,properties); if(dictionary!=NULL) { setProperty(kDriverSettingKey,dictionary); readSettings(); return kIOReturnSuccess; } else return kIOReturnBadArgument; } // Get info OSString* Wireless360Controller::newManufacturerString() const { return OSString::withCString("Microsoft"); } OSNumber* Wireless360Controller::newPrimaryUsageNumber() const { // Gamepad return OSNumber::withNumber(0x05, 8); } OSNumber* Wireless360Controller::newPrimaryUsagePageNumber() const { // Generic Desktop return OSNumber::withNumber(0x01, 8); } OSNumber* Wireless360Controller::newProductIDNumber() const { return OSNumber::withNumber((unsigned long long)0x28e, 16); } OSString* Wireless360Controller::newProductString() const { return OSString::withCString("Wireless 360 Controller"); } OSString* Wireless360Controller::newTransportString() const { return OSString::withCString("Wireless"); } OSNumber* Wireless360Controller::newVendorIDNumber() const { return OSNumber::withNumber((unsigned long long)0x45e, 16); } ================================================ FILE: Wireless360Controller/Wireless360Controller.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro Wireless360Controller.h - declaration of the wireless controller driver class This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __WIRELESS360CONTROLLER_H__ #define __WIRELESS360CONTROLLER_H__ #include "../WirelessGamingReceiver/WirelessHIDDevice.h" class Wireless360Controller : public WirelessHIDDevice { OSDeclareDefaultStructors(Wireless360Controller); public: bool init(OSDictionary *propTable = NULL); void SetRumbleMotors(unsigned char large, unsigned char small); IOReturn setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options); IOReturn newReportDescriptor(IOMemoryDescriptor ** descriptor ) const; IOReturn setProperties(OSObject *properties); virtual OSString* newManufacturerString() const; virtual OSNumber* newPrimaryUsageNumber() const; virtual OSNumber* newPrimaryUsagePageNumber() const; virtual OSNumber* newProductIDNumber() const; virtual OSString* newProductString() const; virtual OSString* newTransportString() const; virtual OSNumber* newVendorIDNumber() const; protected: void readSettings(void); void receivedHIDupdate(unsigned char *data, int length); // Settings bool invertLeftX,invertLeftY; bool invertRightX,invertRightY; short deadzoneLeft,deadzoneRight; bool relativeLeft,relativeRight; private: void fiddleReport(unsigned char *data, int length); }; #endif // __WIRELESS360CONTROLLER_H__ ================================================ FILE: Wireless360Controller/Wireless360Controller.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 32D94FC60562CBF700B6AF17 /* Wireless360Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A224C3EFF42367911CA2CB7 /* Wireless360Controller.h */; }; 32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 32D94FCA0562CBF700B6AF17 /* Wireless360Controller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A224C3FFF42367911CA2CB7 /* Wireless360Controller.cpp */; settings = {ATTRIBUTES = (); }; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1A224C3EFF42367911CA2CB7 /* Wireless360Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Wireless360Controller.h; sourceTree = ""; }; 1A224C3FFF42367911CA2CB7 /* Wireless360Controller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Wireless360Controller.cpp; sourceTree = ""; }; 32D94FCF0562CBF700B6AF17 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32D94FD00562CBF700B6AF17 /* Wireless360Controller.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Wireless360Controller.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 8DA8362C06AD9B9200E5AC22 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 32D94FCB0562CBF700B6AF17 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* Wireless360Controller */ = { isa = PBXGroup; children = ( 247142CAFF3F8F9811CA285C /* Source */, 8DA8362C06AD9B9200E5AC22 /* Kernel.framework */, 089C167CFE841241C02AAC07 /* Resources */, 19C28FB6FE9D52B211CA2CBB /* Products */, ); name = Wireless360Controller; sourceTree = ""; }; 089C167CFE841241C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 32D94FCF0562CBF700B6AF17 /* Info.plist */, 089C167DFE841241C02AAC07 /* InfoPlist.strings */, ); name = Resources; sourceTree = ""; }; 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( 32D94FD00562CBF700B6AF17 /* Wireless360Controller.kext */, ); name = Products; sourceTree = ""; }; 247142CAFF3F8F9811CA285C /* Source */ = { isa = PBXGroup; children = ( 1A224C3EFF42367911CA2CB7 /* Wireless360Controller.h */, 1A224C3FFF42367911CA2CB7 /* Wireless360Controller.cpp */, ); name = Source; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 32D94FC50562CBF700B6AF17 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 32D94FC60562CBF700B6AF17 /* Wireless360Controller.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 32D94FC30562CBF700B6AF17 /* Wireless360Controller */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB91D908733DB10010E9CD /* Build configuration list for PBXNativeTarget "Wireless360Controller" */; buildPhases = ( 32D94FC50562CBF700B6AF17 /* Headers */, 32D94FC70562CBF700B6AF17 /* Resources */, 32D94FC90562CBF700B6AF17 /* Sources */, 32D94FCB0562CBF700B6AF17 /* Frameworks */, 32D94FCC0562CBF700B6AF17 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = Wireless360Controller; productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; productName = Wireless360Controller; productReference = 32D94FD00562CBF700B6AF17 /* Wireless360Controller.kext */; productType = "com.apple.product-type.kernel-extension.iokit"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB91DD08733DB10010E9CD /* Build configuration list for PBXProject "Wireless360Controller" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 089C166AFE841209C02AAC07 /* Wireless360Controller */; projectDirPath = ""; projectRoot = ""; targets = ( 32D94FC30562CBF700B6AF17 /* Wireless360Controller */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 32D94FC70562CBF700B6AF17 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 32D94FCC0562CBF700B6AF17 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 32D94FC90562CBF700B6AF17 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 32D94FCA0562CBF700B6AF17 /* Wireless360Controller.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C167EFE841241C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1DEB91DA08733DB10010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = com.mice.driver.Wireless360Controller; MODULE_VERSION = 1.0.0d11; PRODUCT_NAME = Wireless360Controller; WRAPPER_EXTENSION = kext; ZERO_LINK = YES; }; name = Debug; }; 1DEB91DB08733DB10010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = com.mice.driver.Wireless360Controller; MODULE_VERSION = 1.0.0d11; PRODUCT_NAME = Wireless360Controller; WRAPPER_EXTENSION = kext; }; name = Release; }; 1DEB91DE08733DB10010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; PREBINDING = NO; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Debug; }; 1DEB91DF08733DB10010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; PREBINDING = NO; PROVISIONING_PROFILE = ""; SDKROOT = ""; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB91D908733DB10010E9CD /* Build configuration list for PBXNativeTarget "Wireless360Controller" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB91DA08733DB10010E9CD /* Debug */, 1DEB91DB08733DB10010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1DEB91DD08733DB10010E9CD /* Build configuration list for PBXProject "Wireless360Controller" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB91DE08733DB10010E9CD /* Debug */, 1DEB91DF08733DB10010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } ================================================ FILE: Wireless360Controller/version.plist ================================================ BuildVersion 12 CFBundleVersion 1.0 ProductBuildVersion 7K571 ProjectName DevToolsWizardTemplates SourceVersion 3870000 ================================================ FILE: WirelessGamingReceiver/English.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ NSHumanReadableCopyright = "© Colin Munro, 2007-11"; ================================================ FILE: WirelessGamingReceiver/IOKitDriver.pbproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 39; objects = { 06AA1265FFB2107B11CA28AA = { buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OPTIMIZATION_CFLAGS = "-O0"; ZERO_LINK = YES; }; isa = PBXBuildStyle; name = Development; }; 06AA1266FFB2107B11CA28AA = { buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; ZERO_LINK = NO; }; isa = PBXBuildStyle; name = Deployment; }; //060 //061 //062 //063 //064 //080 //081 //082 //083 //084 089C1669FE841209C02AAC07 = { buildSettings = { }; buildStyles = ( 06AA1265FFB2107B11CA28AA, 06AA1266FFB2107B11CA28AA, ); hasScannedForEncodings = 1; isa = PBXProject; mainGroup = 089C166AFE841209C02AAC07; projectDirPath = ""; targets = ( 32D94FC30562CBF700B6AF17, ); }; 089C166AFE841209C02AAC07 = { children = ( 247142CAFF3F8F9811CA285C, 8DA80CCF06AD972A00E5AC22, 089C167CFE841241C02AAC07, 19C28FB6FE9D52B211CA2CBB, ); isa = PBXGroup; name = "«PROJECTNAME»"; refType = 4; sourceTree = ""; }; 089C167CFE841241C02AAC07 = { children = ( 32D94FCF0562CBF700B6AF17, 089C167DFE841241C02AAC07, ); isa = PBXGroup; name = Resources; refType = 4; sourceTree = ""; }; 089C167DFE841241C02AAC07 = { children = ( 089C167EFE841241C02AAC07, ); isa = PBXVariantGroup; name = InfoPlist.strings; refType = 4; sourceTree = ""; }; 089C167EFE841241C02AAC07 = { fileEncoding = 10; isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; refType = 4; sourceTree = ""; }; //080 //081 //082 //083 //084 //190 //191 //192 //193 //194 19C28FB6FE9D52B211CA2CBB = { children = ( 32D94FD00562CBF700B6AF17, ); isa = PBXGroup; name = Products; refType = 4; sourceTree = ""; }; //190 //191 //192 //193 //194 //1A0 //1A1 //1A2 //1A3 //1A4 1A224C3EFF42367911CA2CB7 = { fileEncoding = 4; isa = PBXFileReference; lastKnownFileType = file; path = "«PROJECTNAMEASIDENTIFIER».h"; refType = 4; sourceTree = ""; }; 1A224C3FFF42367911CA2CB7 = { fileEncoding = 4; isa = PBXFileReference; lastKnownFileType = file; path = "«PROJECTNAMEASIDENTIFIER».cpp"; refType = 4; sourceTree = ""; }; //1A0 //1A1 //1A2 //1A3 //1A4 //240 //241 //242 //243 //244 247142CAFF3F8F9811CA285C = { children = ( 1A224C3EFF42367911CA2CB7, 1A224C3FFF42367911CA2CB7, ); isa = PBXGroup; name = Source; path = ""; refType = 4; sourceTree = ""; }; //240 //241 //242 //243 //244 //320 //321 //322 //323 //324 32D94FC30562CBF700B6AF17 = { buildPhases = ( 32D94FC40562CBF700B6AF17, 32D94FC50562CBF700B6AF17, 32D94FC70562CBF700B6AF17, 32D94FC90562CBF700B6AF17, 32D94FCB0562CBF700B6AF17, 32D94FCC0562CBF700B6AF17, 32D94FCD0562CBF700B6AF17, ); buildRules = ( ); buildSettings = { INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = "com.yourcompany.driver.«PROJECTNAMEASIDENTIFIER»"; MODULE_VERSION = 1.0.0d1; PRODUCT_NAME = "«PROJECTNAME»"; WRAPPER_EXTENSION = kext; }; dependencies = ( ); isa = PBXNativeTarget; name = "«PROJECTNAME»"; productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; productName = "«PROJECTNAME»"; productReference = 32D94FD00562CBF700B6AF17; productType = "com.apple.product-type.kernel-extension.iokit"; }; 32D94FC40562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXShellScriptBuildPhase; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; }; 32D94FC50562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( 32D94FC60562CBF700B6AF17, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FC60562CBF700B6AF17 = { fileRef = 1A224C3EFF42367911CA2CB7; isa = PBXBuildFile; settings = { }; }; 32D94FC70562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( 32D94FC80562CBF700B6AF17, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FC80562CBF700B6AF17 = { fileRef = 089C167DFE841241C02AAC07; isa = PBXBuildFile; settings = { }; }; 32D94FC90562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( 32D94FCA0562CBF700B6AF17, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FCA0562CBF700B6AF17 = { fileRef = 1A224C3FFF42367911CA2CB7; isa = PBXBuildFile; settings = { ATTRIBUTES = ( ); }; }; 32D94FCB0562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXFrameworksBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FCC0562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 32D94FCD0562CBF700B6AF17 = { buildActionMask = 2147483647; files = ( ); isa = PBXShellScriptBuildPhase; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; }; 32D94FCF0562CBF700B6AF17 = { isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; refType = 4; sourceTree = ""; }; 32D94FD00562CBF700B6AF17 = { explicitFileType = wrapper.cfbundle; includeInIndex = 0; isa = PBXFileReference; path = "«PROJECTNAME».kext"; refType = 3; sourceTree = BUILT_PRODUCTS_DIR; }; //320 //321 //322 //323 //324 //8D0 //8D1 //8D2 //8D3 //8D4 8DA80CCF06AD972A00E5AC22 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; refType = 0; sourceTree = ""; }; }; rootObject = 089C1669FE841209C02AAC07; } ================================================ FILE: WirelessGamingReceiver/Info.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.mice.driver.WirelessGamingReceiver CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType KEXT CFBundleSignature ???? CFBundleVersion 1.0.0d12 IOKitPersonalities WirelessGamingReceiverForWindows CFBundleIdentifier com.mice.driver.WirelessGamingReceiver idProduct 1817 idVendor 1118 IOClass WirelessGamingReceiver IOKitDebug 65535 IOProviderClass IOUSBDevice WirelessGamingReceiverForWindowsAlternate CFBundleIdentifier com.mice.driver.WirelessGamingReceiver idProduct 657 idVendor 1118 IOClass WirelessGamingReceiver IOKitDebug 65535 IOProviderClass IOUSBDevice OSBundleCompatibleVersion 1.0.0d1 OSBundleLibraries com.apple.iokit.IOHIDFamily 1.2 com.apple.iokit.IOUSBFamily 1.8 com.apple.kpi.iokit 8.0.0 com.apple.kpi.libkern 8.0.0 com.apple.kpi.mach 8.0.0 ================================================ FILE: WirelessGamingReceiver/WirelessDevice.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro WirelessDevice.cpp - generic Wireless 360 device driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "WirelessDevice.h" #include "WirelessGamingReceiver.h" OSDefineMetaClassAndStructors(WirelessDevice, IOService) #define super IOService // Initialise wireless device bool WirelessDevice::init(OSDictionary *dictionary) { if (!super::init(dictionary)) return false; index = -1; function = NULL; return true; } // Checks if there's any data for us bool WirelessDevice::IsDataAvailable(void) { if (index == -1) return false; WirelessGamingReceiver *receiver = OSDynamicCast(WirelessGamingReceiver, getProvider()); if (receiver == NULL) return false; return receiver->IsDataQueued(index); } // Gets the next item from our buffer IOMemoryDescriptor* WirelessDevice::NextPacket(void) { if (index == -1) return NULL; WirelessGamingReceiver *receiver = OSDynamicCast(WirelessGamingReceiver, getProvider()); if (receiver == NULL) return NULL; return receiver->ReadBuffer(index); } // Sends a buffer for this controller void WirelessDevice::SendPacket(const void *data, size_t length) { if (index == -1) return; WirelessGamingReceiver *receiver = OSDynamicCast(WirelessGamingReceiver, getProvider()); if (receiver == NULL) return; receiver->QueueWrite(index, data, (UInt32)length); } // Registers a callback function void WirelessDevice::RegisterWatcher(void *target, WirelessDeviceWatcher function, void *parameter) { this->target = target; this->parameter = parameter; this->function = function; if ((function != NULL) && IsDataAvailable()) NewData(); } // For internal use, sets this instances index on the wireless gaming receiver void WirelessDevice::SetIndex(int i) { index = i; } // Called when new data arrives void WirelessDevice::NewData(void) { if (function != NULL) function(target, this, parameter); } // Gets the location ID for this device OSNumber* WirelessDevice::newLocationIDNumber() const { OSNumber *owner; UInt32 location = 0; if (index == -1) return NULL; WirelessGamingReceiver *receiver = OSDynamicCast(WirelessGamingReceiver, getProvider()); if (receiver == NULL) return NULL; owner = receiver->newLocationIDNumber(); if (owner != NULL) { location = owner->unsigned32BitValue() + 1 + index; owner->release(); } return OSNumber::withNumber(location, 32); } ================================================ FILE: WirelessGamingReceiver/WirelessDevice.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro WirelessDevice.h - declaration of the base wireless 360 device driver class This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __WIRELESSDEVICE_H__ #define __WIRELESSDEVICE_H__ #include class WirelessDevice; typedef void (*WirelessDeviceWatcher)(void *target, WirelessDevice *sender, void *parameter); class WirelessDevice : public IOService { OSDeclareDefaultStructors(WirelessDevice); public: bool init(OSDictionary *dictionary = 0); // Controller interface bool IsDataAvailable(void); IOMemoryDescriptor* NextPacket(void); void SendPacket(const void *data, size_t length); void RegisterWatcher(void *target, WirelessDeviceWatcher function, void *parameter); OSNumber* newLocationIDNumber() const; private: friend class WirelessGamingReceiver; void SetIndex(int i); void NewData(void); private: int index; // callback void *target, *parameter; WirelessDeviceWatcher function; }; #endif // __WIRELESSDEVICE_H__ ================================================ FILE: WirelessGamingReceiver/WirelessGamingReceiver.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro WirelessGamingReceiver.cpp - main source of the wireless receiver driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "WirelessGamingReceiver.h" #include "WirelessDevice.h" #include "devices.h" //#define PROTOCOL_DEBUG OSDefineMetaClassAndStructors(WirelessGamingReceiver, IOService) // Holds data for asynchronous reads typedef struct { int index; IOBufferMemoryDescriptor *buffer; } WGRREAD; // Get maximum packet size for a pipe static UInt32 GetMaxPacketSize(IOUSBPipe *pipe) { const IOUSBEndpointDescriptor *ed; ed=pipe->GetEndpointDescriptor(); if(ed==NULL) return 0; else return ed->wMaxPacketSize; } // Start device bool WirelessGamingReceiver::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest interfaceRequest; IOUSBFindEndpointRequest pipeRequest; IOUSBInterface *interface; int iConnection, iOther, i; if (!IOService::start(provider)) { // IOLog("start - superclass failed\n"); return false; } device = OSDynamicCast(IOUSBDevice, provider); if (device == NULL) { // IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if (device->GetNumConfigurations() < 1) { device = NULL; // IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd = device->GetFullConfigurationDescriptor(0); if (cd == NULL) { device = NULL; // IOLog("start - couldn't get configuration descriptor\n"); goto fail; } if (!device->open(this)) { device = NULL; // IOLog("start - failed to open device\n"); goto fail; } if (device->SetConfiguration(this, cd->bConfigurationValue, true) != kIOReturnSuccess) { // IOLog("start - unable to set configuration\n"); goto fail; } for (i = 0; i < WIRELESS_CONNECTIONS; i++) { connections[i].controller = NULL; connections[i].controllerIn = NULL; connections[i].controllerOut = NULL; connections[i].other = NULL; connections[i].otherIn = NULL; connections[i].otherOut = NULL; connections[i].inputArray = NULL; connections[i].service = NULL; connections[i].controllerStarted = false; } pipeRequest.interval = 0; pipeRequest.maxPacketSize = 0; pipeRequest.type = kUSBInterrupt; interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare; interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; interfaceRequest.bAlternateSetting = 0; interface = NULL; iConnection = 0; iOther = 0; while ((interface = device->FindNextInterface(interface, &interfaceRequest)) != NULL) { switch(interface->GetInterfaceProtocol()) { case 129: // Controller if (!interface->open(this)) { // IOLog("start: Failed to open control interface\n"); goto fail; } connections[iConnection].controller = interface; pipeRequest.direction = kUSBIn; connections[iConnection].controllerIn = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iConnection].controllerIn == NULL) { // IOLog("start: Failed to open control input pipe\n"); goto fail; } else connections[iConnection].controllerIn->retain(); pipeRequest.direction = kUSBOut; connections[iConnection].controllerOut = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iConnection].controllerOut == NULL) { // IOLog("start: Failed to open control output pipe\n"); goto fail; } else connections[iConnection].controllerOut->retain(); iConnection++; break; case 130: // It is a mystery if (!interface->open(this)) { // IOLog("start: Failed to open mystery interface\n"); goto fail; } connections[iOther].other = interface; pipeRequest.direction = kUSBIn; connections[iOther].otherIn = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iOther].otherIn == NULL) { // IOLog("start: Failed to open mystery input pipe\n"); goto fail; } else connections[iOther].otherIn->retain(); pipeRequest.direction = kUSBOut; connections[iOther].otherOut = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iOther].otherOut == NULL) { // IOLog("start: Failed to open mystery output pipe\n"); goto fail; } else connections[iOther].otherOut->retain(); iOther++; break; default: // IOLog("start: Ignoring interface (protocol %d)\n", interface->GetInterfaceProtocol()); break; } } if (iConnection != iOther) IOLog("start - interface mismatch?\n"); connectionCount = iConnection; for (i = 0; i < connectionCount; i++) { connections[i].inputArray = OSArray::withCapacity(5); if (connections[i].inputArray == NULL) { // IOLog("start: Failed to allocate packet buffer %d\n", i); goto fail; } if (!QueueRead(i)) { // IOLog("start: Failed to start read %d\n", i); goto fail; } } // IOLog("start: Transform and roll out (%d interfaces)\n", connectionCount); return true; fail: ReleaseAll(); return false; } // Stop the device void WirelessGamingReceiver::stop(IOService *provider) { ReleaseAll(); IOService::stop(provider); } // Handle message from provider IOReturn WirelessGamingReceiver::message(UInt32 type,IOService *provider,void *argument) { // IOLog("Message\n"); /* switch(type) { case kIOMessageServiceIsTerminated: case kIOMessageServiceIsRequestingClose: if(device->isOpen(this)) ReleaseAll(); return kIOReturnSuccess; default: */ return IOService::message(type,provider,argument); // } } // Queue a read on a controller bool WirelessGamingReceiver::QueueRead(int index) { IOUSBCompletion complete; IOReturn err; WGRREAD *data; data = (WGRREAD*)IOMalloc(sizeof(WGRREAD)); if (data == NULL) return false; data->index = index; data->buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(connections[index].controllerIn)); if (data->buffer == NULL) { IOFree(data, sizeof(WGRREAD)); return false; } complete.target = this; complete.action = _ReadComplete; complete.parameter = data; err = connections[index].controllerIn->Read(data->buffer, 0, 0, data->buffer->getLength(), &complete); if (err == kIOReturnSuccess) return true; data->buffer->release(); IOFree(data, sizeof(WGRREAD)); // IOLog("read - failed to start (0x%.8x)\n", err); return false; } // Handle a completed read on a controller void WirelessGamingReceiver::ReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { WGRREAD *data = (WGRREAD*)parameter; bool reread = true; switch (status) { case kIOReturnOverrun: // IOLog("read - kIOReturnOverrun, clearing stall\n"); connections[data->index].controllerIn->ClearStall(); // fall through case kIOReturnSuccess: ProcessMessage(data->index, (unsigned char*)data->buffer->getBytesNoCopy(), (int)data->buffer->getLength() - bufferSizeRemaining); break; case kIOReturnNotResponding: // IOLog("read - kIOReturnNotResponding\n"); // fall through default: reread = false; break; } int newIndex = data->index; data->buffer->release(); IOFree(data, sizeof(WGRREAD)); if (reread) QueueRead(newIndex); } // Queue an asynchronous write on a controller bool WirelessGamingReceiver::QueueWrite(int index, const void *bytes, UInt32 length) { IOBufferMemoryDescriptor *outBuffer; IOUSBCompletion complete; IOReturn err; outBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length); if (outBuffer == NULL) { // IOLog("send - unable to allocate buffer\n"); return false; } outBuffer->writeBytes(0, bytes, length); complete.target = this; complete.action = _WriteComplete; complete.parameter = outBuffer; err = connections[index].controllerOut->Write(outBuffer, 0, 0, length, &complete); if (err == kIOReturnSuccess) return true; else { // IOLog("send - failed to start (0x%.8x)\n",err); return false; } } // Handle a completed write on a controller void WirelessGamingReceiver::WriteComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining) { IOMemoryDescriptor *memory=(IOMemoryDescriptor*)parameter; if(status!=kIOReturnSuccess) { IOLog("write - Error writing: 0x%.8x\n",status); } memory->release(); } // Release any allocated objects void WirelessGamingReceiver::ReleaseAll(void) { int i; for (i = 0; i < connectionCount; i++) { if (connections[i].service != NULL) { connections[i].service->terminate(kIOServiceRequired); connections[i].service->detachAll(gIOServicePlane); connections[i].service->release(); connections[i].service = NULL; } if (connections[i].controllerIn != NULL) { connections[i].controllerIn->Abort(); connections[i].controllerIn->release(); connections[i].controllerIn = NULL; } if (connections[i].controllerOut != NULL) { connections[i].controllerOut->Abort(); connections[i].controllerOut->release(); connections[i].controllerOut = NULL; } if (connections[i].controller != NULL) { connections[i].controller->close(this); connections[i].controller = NULL; } if (connections[i].otherIn != NULL) { connections[i].otherIn->Abort(); connections[i].otherIn->release(); connections[i].otherIn = NULL; } if (connections[i].otherOut != NULL) { connections[i].otherOut->Abort(); connections[i].otherOut->release(); connections[i].otherOut = NULL; } if (connections[i].other != NULL) { connections[i].other->close(this); connections[i].other = NULL; } if (connections[i].inputArray != NULL) { connections[i].inputArray->release(); connections[i].inputArray = NULL; } connections[i].controllerStarted = false; } if (device != NULL) { device->close(this); device = NULL; } } // Static wrapper for read notifications void WirelessGamingReceiver::_ReadComplete(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { if (target != NULL) ((WirelessGamingReceiver*)target)->ReadComplete(parameter, status, bufferSizeRemaining); } // Static wrapper for write notifications void WirelessGamingReceiver::_WriteComplete(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { if (target != NULL) ((WirelessGamingReceiver*)target)->WriteComplete(parameter, status, bufferSizeRemaining); } // Processes a message for a controller void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data, int length) { #ifdef PROTOCOL_DEBUG char s[1024]; int i; for (i = 0; i < length; i++) { s[(i * 2) + 0] = "0123456789ABCDEF"[(data[i] & 0xF0) >> 4]; s[(i * 2) + 1] = "0123456789ABCDEF"[data[i] & 0x0F]; } s[i * 2] = '\0'; IOLog("Got data (%d, %d bytes): %s\n", index, length, s); #endif // Handle device connections if ((length == 2) && (data[0] == 0x08)) { if (data[1] == 0x00) { // Device disconnected #ifdef PROTOCOL_DEBUG IOLog("process: Device detached\n"); #endif if (connections[index].service != NULL) { connections[index].service->SetIndex(-1); if (connections[index].controllerStarted) connections[index].service->terminate(kIOServiceRequired | kIOServiceSynchronous); connections[index].service->detach(this); connections[index].service->release(); connections[index].service = NULL; connections[index].controllerStarted = false; } } else { // Device connected #ifdef PROTOCOL_DEBUG IOLog("process: Attempting to add new device\n"); #endif if (connections[index].service == NULL) { bool ready; int i, j; IOMemoryDescriptor *data; char c; ready = false; j = connections[index].inputArray->getCount(); for (i = 0; !ready && (i < j); i++) { data = OSDynamicCast(IOMemoryDescriptor, connections[index].inputArray->getObject(i)); data->readBytes(1, &c, 1); if (c == 0x0f) ready = true; } InstantiateService(index); if (ready) { #ifdef PROTOCOL_DEBUG IOLog("Registering wireless device"); #endif connections[index].controllerStarted = true; connections[index].service->registerService(); } } } return; } // Add anything else to the queue IOMemoryDescriptor *copy = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length); copy->writeBytes(0, data, length); connections[index].inputArray->setObject(copy); if (connections[index].service == NULL) InstantiateService(index); if (connections[index].service != NULL) { connections[index].service->NewData(); if (!connections[index].controllerStarted) { char c; copy->readBytes(1, &c, 1); if (c == 0x0f) { #ifdef PROTOCOL_DEBUG IOLog("Registering wireless device"); #endif connections[index].controllerStarted = true; connections[index].service->registerService(); } } } copy->release(); } // Create a new node for the attached controller void WirelessGamingReceiver::InstantiateService(int index) { connections[index].service = new WirelessDevice; if (connections[index].service != NULL) { const OSString *keys[1] = { OSString::withCString(kIOWirelessDeviceType), }; const OSObject *objects[1] = { OSNumber::withNumber((unsigned long long)0, 32), }; OSDictionary *dictionary = OSDictionary::withObjects(objects, keys, 1, 0); if (connections[index].service->init(dictionary)) { connections[index].service->attach(this); connections[index].service->SetIndex(index); // connections[index].service->registerService(); // IOLog("process: Device attached\n"); if (IsDataQueued(index)) connections[index].service->NewData(); connections[index].service->start(this); } else { connections[index].service->release(); connections[index].service = NULL; // IOLog("process: Device attach failure\n"); } } } // Check a controller's queue bool WirelessGamingReceiver::IsDataQueued(int index) { return connections[index].inputArray->getCount() > 0; } // Read a controller's queue IOMemoryDescriptor* WirelessGamingReceiver::ReadBuffer(int index) { IOMemoryDescriptor *data; data = OSDynamicCast(IOMemoryDescriptor, connections[index].inputArray->getObject(0)); if (data != NULL) data->retain(); connections[index].inputArray->removeObject(0); return data; } // Get our location ID OSNumber* WirelessGamingReceiver::newLocationIDNumber() const { OSNumber *number; UInt32 location = 0; if (device) { if ((number = OSDynamicCast(OSNumber, device->getProperty("locationID")))) { location = number->unsigned32BitValue(); } else { // Make up an address if ((number = OSDynamicCast(OSNumber, device->getProperty("USB Address")))) location |= number->unsigned8BitValue() << 24; if ((number = OSDynamicCast(OSNumber, device->getProperty("idProduct")))) location |= number->unsigned8BitValue() << 16; } } return OSNumber::withNumber(location, 32); } ================================================ FILE: WirelessGamingReceiver/WirelessGamingReceiver.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro WirelessGamingReceiver.h - declaration of the wireless receiver driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __WIRELESSGAMINGRECEIVER_H__ #define __WIRELESSGAMINGRECEIVER_H__ #include #include // This value is defined by the hardware and fixed #define WIRELESS_CONNECTIONS 4 class WirelessDevice; typedef struct { // Controller IOUSBInterface *controller; IOUSBPipe *controllerIn, *controllerOut; // Mystery IOUSBInterface *other; IOUSBPipe *otherIn, *otherOut; // Runtime data OSArray *inputArray; WirelessDevice *service; bool controllerStarted; } WIRELESS_CONNECTION; class WirelessGamingReceiver : public IOService { OSDeclareDefaultStructors(WirelessGamingReceiver); public: bool start(IOService *provider); void stop(IOService *provider); IOReturn message(UInt32 type,IOService *provider,void *argument); // For WirelessDevice to use OSNumber* newLocationIDNumber() const; private: friend class WirelessDevice; bool IsDataQueued(int index); IOMemoryDescriptor* ReadBuffer(int index); bool QueueWrite(int index, const void *bytes, UInt32 length); private: IOUSBDevice *device; WIRELESS_CONNECTION connections[WIRELESS_CONNECTIONS]; int connectionCount; void InstantiateService(int index); void ProcessMessage(int index, const unsigned char *data, int length); bool QueueRead(int index); void ReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); void WriteComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); void ReleaseAll(void); static void _ReadComplete(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining); static void _WriteComplete(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining); }; #endif // __WIRELESSGAMINGRECEIVER_H__ ================================================ FILE: WirelessGamingReceiver/WirelessGamingReceiver.xcodeproj/colin.mode1 ================================================ ActivePerspectiveName Project AllowedModules BundleLoadPath MaxInstances n Module PBXSmartGroupTreeModule Name Groups and Files Outline View BundleLoadPath MaxInstances n Module PBXNavigatorGroup Name Editor BundleLoadPath MaxInstances n Module XCTaskListModule Name Task List BundleLoadPath MaxInstances n Module XCDetailModule Name File and Smart Group Detail Viewer BundleLoadPath MaxInstances 1 Module PBXBuildResultsModule Name Detailed Build Results Viewer BundleLoadPath MaxInstances 1 Module PBXProjectFindModule Name Project Batch Find Tool BundleLoadPath MaxInstances n Module PBXRunSessionModule Name Run Log BundleLoadPath MaxInstances n Module PBXBookmarksModule Name Bookmarks Tool BundleLoadPath MaxInstances n Module PBXClassBrowserModule Name Class Browser BundleLoadPath MaxInstances n Module PBXCVSModule Name Source Code Control Tool BundleLoadPath MaxInstances n Module PBXDebugBreakpointsModule Name Debug Breakpoints Tool BundleLoadPath MaxInstances n Module XCDockableInspector Name Inspector BundleLoadPath MaxInstances n Module PBXOpenQuicklyModule Name Open Quickly Tool BundleLoadPath MaxInstances 1 Module PBXDebugSessionModule Name Debugger BundleLoadPath MaxInstances 1 Module PBXDebugCLIModule Name Debug Console Description DefaultDescriptionKey DockingSystemVisible Extension mode1 FavBarConfig PBXProjectModuleGUID 3B21EBD60B8CEAED00B5CACA XCBarModuleItemNames XCBarModuleItems FirstTimeWindowDisplayed Identifier com.apple.perspectives.project.mode1 MajorVersion 31 MinorVersion 1 Name Default Notifications OpenEditors Content PBXProjectModuleGUID 3BE527360BDC379700984E1F PBXProjectModuleLabel WirelessGamingReceiver.cpp PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 3BE527370BDC379700984E1F PBXProjectModuleLabel WirelessGamingReceiver.cpp _historyCapacity 0 bookmark 3BD5A2FD0C56D76C005B4E24 history 3BD5A2FC0C56D76C005B4E24 SplitCount 1 StatusBarVisibility Geometry Frame {{0, 20}, {806, 677}} PBXModuleWindowStatusBarHidden2 RubberWindowFrame 38 258 806 718 0 0 1280 1002 Content PBXProjectModuleGUID 3B54B4630BDA9ECF00329AC0 PBXProjectModuleLabel WirelessHIDDevice.cpp PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 3B54B4640BDA9ECF00329AC0 PBXProjectModuleLabel WirelessHIDDevice.cpp _historyCapacity 0 bookmark 3BD5A2FE0C56D76C005B4E24 history 3B4FC9F60C49C3B3007CF491 SplitCount 1 StatusBarVisibility Geometry Frame {{0, 20}, {1059, 503}} PBXModuleWindowStatusBarHidden2 RubberWindowFrame 34 458 1059 544 0 0 1280 1002 Content PBXProjectModuleGUID 3BD1A9390C49BC33006510F7 PBXProjectModuleLabel WirelessHIDDevice.h PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 3BD1A93A0C49BC33006510F7 PBXProjectModuleLabel WirelessHIDDevice.h _historyCapacity 0 bookmark 3BD5A2FF0C56D76C005B4E24 history 3B4FC9F70C49C3B3007CF491 SplitCount 1 StatusBarVisibility Geometry Frame {{0, 20}, {1059, 503}} PBXModuleWindowStatusBarHidden2 RubberWindowFrame 155 150 1059 544 0 0 1280 1002 Content PBXProjectModuleGUID 3B216B380C08E9A4000BE7F3 PBXProjectModuleLabel WirelessGamingReceiver.h PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 3B216B390C08E9A4000BE7F3 PBXProjectModuleLabel WirelessGamingReceiver.h _historyCapacity 0 bookmark 3BD5A3000C56D76C005B4E24 history 3B4FC9F80C49C3B3007CF491 SplitCount 1 StatusBarVisibility Geometry Frame {{0, 20}, {688, 361}} PBXModuleWindowStatusBarHidden2 RubberWindowFrame 481 168 688 402 0 0 1280 1002 Content PBXProjectModuleGUID 3B216B3B0C08E9A4000BE7F3 PBXProjectModuleLabel IOUSBDevice.cpp PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 3B216B3C0C08E9A4000BE7F3 PBXProjectModuleLabel IOUSBDevice.cpp _historyCapacity 0 bookmark 3BD5A3010C56D76C005B4E24 history 3B4FC9F90C49C3B3007CF491 SplitCount 1 StatusBarVisibility Geometry Frame {{0, 20}, {806, 677}} PBXModuleWindowStatusBarHidden2 RubberWindowFrame 61 237 806 718 0 0 1280 1002 Content PBXProjectModuleGUID 3B216B410C08E9A4000BE7F3 PBXProjectModuleLabel WirelessDevice.h PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 3B216B420C08E9A4000BE7F3 PBXProjectModuleLabel WirelessDevice.h _historyCapacity 0 bookmark 3BD5A3030C56D76C005B4E24 history 3B4FC9FB0C49C3B3007CF491 SplitCount 1 StatusBarVisibility Geometry Frame {{0, 20}, {1059, 503}} PBXModuleWindowStatusBarHidden2 RubberWindowFrame 175 169 1059 544 0 0 1280 1002 PerspectiveWidths -1 -1 Perspectives ChosenToolbarItems active-target-popup active-buildstyle-popup action NSToolbarFlexibleSpaceItem buildOrClean build-and-runOrDebug com.apple.ide.PBXToolbarStopButton get-info toggle-editor NSToolbarFlexibleSpaceItem com.apple.pbx.toolbar.searchfield ControllerClassBaseName IconName WindowOfProjectWithEditor Identifier perspective.project IsVertical Layout ContentConfiguration PBXBottomSmartGroupGIDs 1C37FBAC04509CD000000102 1C37FAAC04509CD000000102 1C08E77C0454961000C914BD 1C37FABC05509CD000000102 1C37FABC05539CD112110102 E2644B35053B69B200211256 1C37FABC04509CD000100104 1CC0EA4004350EF90044410B 1CC0EA4004350EF90041110B PBXProjectModuleGUID 1CE0B1FE06471DED0097A5F4 PBXProjectModuleLabel Files PBXProjectStructureProvided yes PBXSmartGroupTreeModuleColumnData PBXSmartGroupTreeModuleColumnWidthsKey 186 PBXSmartGroupTreeModuleColumnsKey_v4 MainColumn PBXSmartGroupTreeModuleOutlineStateKey_v7 PBXSmartGroupTreeModuleOutlineStateExpansionKey 089C166AFE841209C02AAC07 1C37FABC05509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey {{0, 0}, {186, 338}} PBXTopSmartGroupGIDs XCIncludePerspectivesSwitch XCSharingToken com.apple.Xcode.GFSharingToken GeometryConfiguration Frame {{0, 0}, {203, 356}} GroupTreeTableConfiguration MainColumn 186 RubberWindowFrame 7 576 690 397 0 0 1280 1002 Module PBXSmartGroupTreeModule Proportion 203pt Dock ContentConfiguration PBXProjectModuleGUID 1CE0B20306471E060097A5F4 PBXProjectModuleLabel MyNewFile14.java PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 1CE0B20406471E060097A5F4 PBXProjectModuleLabel MyNewFile14.java SplitCount 1 StatusBarVisibility GeometryConfiguration Frame {{0, 0}, {482, 0}} RubberWindowFrame 7 576 690 397 0 0 1280 1002 Module PBXNavigatorGroup Proportion 0pt BecomeActive ContentConfiguration PBXProjectModuleGUID 1CE0B20506471E060097A5F4 PBXProjectModuleLabel Detail GeometryConfiguration Frame {{0, 5}, {482, 351}} RubberWindowFrame 7 576 690 397 0 0 1280 1002 Module XCDetailModule Proportion 351pt Proportion 482pt Name Project ServiceClasses XCModuleDock PBXSmartGroupTreeModule XCModuleDock PBXNavigatorGroup XCDetailModule TableOfContents 3BD5A2FA0C56D76C005B4E24 1CE0B1FE06471DED0097A5F4 3BD5A2FB0C56D76C005B4E24 1CE0B20306471E060097A5F4 1CE0B20506471E060097A5F4 ToolbarConfiguration xcode.toolbar.config.default ControllerClassBaseName IconName WindowOfProject Identifier perspective.morph IsVertical 0 Layout BecomeActive 1 ContentConfiguration PBXBottomSmartGroupGIDs 1C37FBAC04509CD000000102 1C37FAAC04509CD000000102 1C08E77C0454961000C914BD 1C37FABC05509CD000000102 1C37FABC05539CD112110102 E2644B35053B69B200211256 1C37FABC04509CD000100104 1CC0EA4004350EF90044410B 1CC0EA4004350EF90041110B PBXProjectModuleGUID 11E0B1FE06471DED0097A5F4 PBXProjectModuleLabel Files PBXProjectStructureProvided yes PBXSmartGroupTreeModuleColumnData PBXSmartGroupTreeModuleColumnWidthsKey 186 PBXSmartGroupTreeModuleColumnsKey_v4 MainColumn PBXSmartGroupTreeModuleOutlineStateKey_v7 PBXSmartGroupTreeModuleOutlineStateExpansionKey 29B97314FDCFA39411CA2CEA 1C37FABC05509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey {{0, 0}, {186, 337}} PBXTopSmartGroupGIDs XCIncludePerspectivesSwitch 1 XCSharingToken com.apple.Xcode.GFSharingToken GeometryConfiguration Frame {{0, 0}, {203, 355}} GroupTreeTableConfiguration MainColumn 186 RubberWindowFrame 373 269 690 397 0 0 1440 878 Module PBXSmartGroupTreeModule Proportion 100% Name Morph PreferredWidth 300 ServiceClasses XCModuleDock PBXSmartGroupTreeModule TableOfContents 11E0B1FE06471DED0097A5F4 ToolbarConfiguration xcode.toolbar.config.default.short PerspectivesBarVisible ShelfIsVisible SourceDescription file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' StatusbarIsVisible TimeStamp 0.0 ToolbarDisplayMode 1 ToolbarIsVisible ToolbarSizeMode 1 Type Perspectives UpdateMessage The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? WindowJustification 5 WindowOrderList 3B21ED2D0B8E33A000B5CACA 3B216B410C08E9A4000BE7F3 3B216B3B0C08E9A4000BE7F3 3B216B380C08E9A4000BE7F3 3BD1A9390C49BC33006510F7 3B54B4630BDA9ECF00329AC0 /Users/colin/Projects2/OSX/360 Controller/WirelessGamingReceiver/WirelessGamingReceiver.xcodeproj 3BE527360BDC379700984E1F WindowString 7 576 690 397 0 0 1280 1002 WindowTools FirstTimeWindowDisplayed Identifier windowTool.build IsVertical Layout Dock ContentConfiguration PBXProjectModuleGUID 1CD0528F0623707200166675 PBXProjectModuleLabel StatusBarVisibility GeometryConfiguration Frame {{0, 0}, {668, 312}} RubberWindowFrame 36 380 668 594 0 0 1280 1002 Module PBXNavigatorGroup Proportion 312pt ContentConfiguration PBXProjectModuleGUID XCMainBuildResultsModuleGUID PBXProjectModuleLabel Build XCBuildResultsTrigger_Collapse 1021 XCBuildResultsTrigger_Open 1011 GeometryConfiguration Frame {{0, 317}, {668, 236}} RubberWindowFrame 36 380 668 594 0 0 1280 1002 Module PBXBuildResultsModule Proportion 236pt Proportion 553pt Name Build Results ServiceClasses PBXBuildResultsModule StatusbarIsVisible TableOfContents 3B21ED2D0B8E33A000B5CACA 3BD5A3040C56D76C005B4E24 1CD0528F0623707200166675 XCMainBuildResultsModuleGUID ToolbarConfiguration xcode.toolbar.config.build WindowString 36 380 668 594 0 0 1280 1002 WindowToolGUID 3B21ED2D0B8E33A000B5CACA WindowToolIsVisible Identifier windowTool.debugger Layout Dock ContentConfiguration Debugger HorizontalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {317, 164}} {{317, 0}, {377, 164}} VerticalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {694, 164}} {{0, 164}, {694, 216}} LauncherConfigVersion 8 PBXProjectModuleGUID 1C162984064C10D400B95A72 PBXProjectModuleLabel Debug - GLUTExamples (Underwater) GeometryConfiguration DebugConsoleDrawerSize {100, 120} DebugConsoleVisible None DebugConsoleWindowFrame {{200, 200}, {500, 300}} DebugSTDIOWindowFrame {{200, 200}, {500, 300}} Frame {{0, 0}, {694, 380}} RubberWindowFrame 321 238 694 422 0 0 1440 878 Module PBXDebugSessionModule Proportion 100% Proportion 100% Name Debugger ServiceClasses PBXDebugSessionModule StatusbarIsVisible 1 TableOfContents 1CD10A99069EF8BA00B06720 1C0AD2AB069F1E9B00FABCE6 1C162984064C10D400B95A72 1C0AD2AC069F1E9B00FABCE6 ToolbarConfiguration xcode.toolbar.config.debug WindowString 321 238 694 422 0 0 1440 878 WindowToolGUID 1CD10A99069EF8BA00B06720 WindowToolIsVisible 0 FirstTimeWindowDisplayed Identifier windowTool.find IsVertical Layout Dock Dock ContentConfiguration PBXProjectModuleGUID 1CDD528C0622207200134675 PBXProjectModuleLabel StatusBarVisibility GeometryConfiguration Frame {{0, 0}, {781, 212}} RubberWindowFrame 53 509 781 470 0 0 1280 1002 Module PBXNavigatorGroup Proportion 781pt Proportion 212pt BecomeActive ContentConfiguration PBXProjectModuleGUID 1CD0528E0623707200166675 PBXProjectModuleLabel Project Find GeometryConfiguration Frame {{0, 217}, {781, 212}} RubberWindowFrame 53 509 781 470 0 0 1280 1002 Module PBXProjectFindModule Proportion 212pt Proportion 429pt Name Project Find ServiceClasses PBXProjectFindModule StatusbarIsVisible TableOfContents 1C530D57069F1CE1000CFCEE 3BCC40340BDA6D7200B1619B 3BCC40350BDA6D7200B1619B 1CDD528C0622207200134675 1CD0528E0623707200166675 WindowString 53 509 781 470 0 0 1280 1002 WindowToolGUID 1C530D57069F1CE1000CFCEE WindowToolIsVisible Identifier MENUSEPARATOR Identifier windowTool.debuggerConsole Layout Dock BecomeActive 1 ContentConfiguration PBXProjectModuleGUID 1C78EAAC065D492600B07095 PBXProjectModuleLabel Debugger Console GeometryConfiguration Frame {{0, 0}, {440, 358}} RubberWindowFrame 650 41 440 400 0 0 1280 1002 Module PBXDebugCLIModule Proportion 358pt Proportion 358pt Name Debugger Console ServiceClasses PBXDebugCLIModule StatusbarIsVisible 1 TableOfContents 1C78EAAD065D492600B07095 1C78EAAE065D492600B07095 1C78EAAC065D492600B07095 WindowString 650 41 440 400 0 0 1280 1002 Identifier windowTool.run Layout Dock ContentConfiguration LauncherConfigVersion 3 PBXProjectModuleGUID 1CD0528B0623707200166675 PBXProjectModuleLabel Run Runner HorizontalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {493, 167}} {{0, 176}, {493, 267}} VerticalSplitView _collapsingFrameDimension 0.0 _indexOfCollapsedView 0 _percentageOfCollapsedView 0.0 isCollapsed yes sizes {{0, 0}, {405, 443}} {{414, 0}, {514, 443}} GeometryConfiguration Frame {{0, 0}, {460, 159}} RubberWindowFrame 316 696 459 200 0 0 1280 1002 Module PBXRunSessionModule Proportion 159pt Proportion 159pt Name Run Log ServiceClasses PBXRunSessionModule StatusbarIsVisible 1 TableOfContents 1C0AD2B3069F1EA900FABCE6 1C0AD2B4069F1EA900FABCE6 1CD0528B0623707200166675 1C0AD2B5069F1EA900FABCE6 ToolbarConfiguration xcode.toolbar.config.run WindowString 316 696 459 200 0 0 1280 1002 WindowToolGUID 1C0AD2B3069F1EA900FABCE6 WindowToolIsVisible 0 Identifier windowTool.scm Layout Dock ContentConfiguration PBXProjectModuleGUID 1C78EAB2065D492600B07095 PBXProjectModuleLabel <No Editor> PBXSplitModuleInNavigatorKey Split0 PBXProjectModuleGUID 1C78EAB3065D492600B07095 SplitCount 1 StatusBarVisibility 1 GeometryConfiguration Frame {{0, 0}, {452, 0}} RubberWindowFrame 743 379 452 308 0 0 1280 1002 Module PBXNavigatorGroup Proportion 0pt BecomeActive 1 ContentConfiguration PBXProjectModuleGUID 1CD052920623707200166675 PBXProjectModuleLabel SCM GeometryConfiguration ConsoleFrame {{0, 259}, {452, 0}} Frame {{0, 7}, {452, 259}} RubberWindowFrame 743 379 452 308 0 0 1280 1002 TableConfiguration Status 30 FileName 199 Path 197.09500122070312 TableFrame {{0, 0}, {452, 250}} Module PBXCVSModule Proportion 262pt Proportion 266pt Name SCM ServiceClasses PBXCVSModule StatusbarIsVisible 1 TableOfContents 1C78EAB4065D492600B07095 1C78EAB5065D492600B07095 1C78EAB2065D492600B07095 1CD052920623707200166675 ToolbarConfiguration xcode.toolbar.config.scm WindowString 743 379 452 308 0 0 1280 1002 Identifier windowTool.breakpoints IsVertical 0 Layout Dock BecomeActive 1 ContentConfiguration PBXBottomSmartGroupGIDs 1C77FABC04509CD000000102 PBXProjectModuleGUID 1CE0B1FE06471DED0097A5F4 PBXProjectModuleLabel Files PBXProjectStructureProvided no PBXSmartGroupTreeModuleColumnData PBXSmartGroupTreeModuleColumnWidthsKey 168 PBXSmartGroupTreeModuleColumnsKey_v4 MainColumn PBXSmartGroupTreeModuleOutlineStateKey_v7 PBXSmartGroupTreeModuleOutlineStateExpansionKey 1C77FABC04509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey {{0, 0}, {168, 350}} PBXTopSmartGroupGIDs XCIncludePerspectivesSwitch 0 GeometryConfiguration Frame {{0, 0}, {185, 368}} GroupTreeTableConfiguration MainColumn 168 RubberWindowFrame 315 424 744 409 0 0 1440 878 Module PBXSmartGroupTreeModule Proportion 185pt ContentConfiguration PBXProjectModuleGUID 1CA1AED706398EBD00589147 PBXProjectModuleLabel Detail GeometryConfiguration Frame {{190, 0}, {554, 368}} RubberWindowFrame 315 424 744 409 0 0 1440 878 Module XCDetailModule Proportion 554pt Proportion 368pt MajorVersion 2 MinorVersion 0 Name Breakpoints ServiceClasses PBXSmartGroupTreeModule XCDetailModule StatusbarIsVisible 1 TableOfContents 1CDDB66807F98D9800BB5817 1CDDB66907F98D9800BB5817 1CE0B1FE06471DED0097A5F4 1CA1AED706398EBD00589147 ToolbarConfiguration xcode.toolbar.config.breakpoints WindowString 315 424 744 409 0 0 1440 878 WindowToolGUID 1CDDB66807F98D9800BB5817 WindowToolIsVisible 1 Identifier windowTool.debugAnimator Layout Dock Module PBXNavigatorGroup Proportion 100% Proportion 100% Name Debug Visualizer ServiceClasses PBXNavigatorGroup StatusbarIsVisible 1 ToolbarConfiguration xcode.toolbar.config.debugAnimator WindowString 100 100 700 500 0 0 1280 1002 Identifier windowTool.bookmarks Layout Dock Module PBXBookmarksModule Proportion 100% Proportion 100% Name Bookmarks ServiceClasses PBXBookmarksModule StatusbarIsVisible 0 WindowString 538 42 401 187 0 0 1280 1002 Identifier windowTool.classBrowser Layout Dock BecomeActive 1 ContentConfiguration OptionsSetName Hierarchy, all classes PBXProjectModuleGUID 1CA6456E063B45B4001379D8 PBXProjectModuleLabel Class Browser - NSObject GeometryConfiguration ClassesFrame {{0, 0}, {374, 96}} ClassesTreeTableConfiguration PBXClassNameColumnIdentifier 208 PBXClassBookColumnIdentifier 22 Frame {{0, 0}, {630, 331}} MembersFrame {{0, 105}, {374, 395}} MembersTreeTableConfiguration PBXMemberTypeIconColumnIdentifier 22 PBXMemberNameColumnIdentifier 216 PBXMemberTypeColumnIdentifier 97 PBXMemberBookColumnIdentifier 22 PBXModuleWindowStatusBarHidden2 1 RubberWindowFrame 385 179 630 352 0 0 1440 878 Module PBXClassBrowserModule Proportion 332pt Proportion 332pt Name Class Browser ServiceClasses PBXClassBrowserModule StatusbarIsVisible 0 TableOfContents 1C0AD2AF069F1E9B00FABCE6 1C0AD2B0069F1E9B00FABCE6 1CA6456E063B45B4001379D8 ToolbarConfiguration xcode.toolbar.config.classbrowser WindowString 385 179 630 352 0 0 1440 878 WindowToolGUID 1C0AD2AF069F1E9B00FABCE6 WindowToolIsVisible 0 ================================================ FILE: WirelessGamingReceiver/WirelessGamingReceiver.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 32D94FC60562CBF700B6AF17 /* WirelessGamingReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A224C3EFF42367911CA2CB7 /* WirelessGamingReceiver.h */; }; 32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 32D94FCA0562CBF700B6AF17 /* WirelessGamingReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A224C3FFF42367911CA2CB7 /* WirelessGamingReceiver.cpp */; settings = {ATTRIBUTES = (); }; }; 3B21ED670B8E688A00B5CACA /* WirelessDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B21ED660B8E688A00B5CACA /* WirelessDevice.h */; }; 3B21ED6C0B8E690F00B5CACA /* WirelessDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B21ED6B0B8E690F00B5CACA /* WirelessDevice.cpp */; }; 3BE667180B9109C5009679FC /* WirelessHIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BE667170B9109C5009679FC /* WirelessHIDDevice.h */; }; 3BE6671C0B910A02009679FC /* WirelessHIDDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3BE6671B0B910A02009679FC /* WirelessHIDDevice.cpp */; }; 3BE6677B0B91DC55009679FC /* devices.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BE6677A0B91DC55009679FC /* devices.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1A224C3EFF42367911CA2CB7 /* WirelessGamingReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WirelessGamingReceiver.h; sourceTree = ""; }; 1A224C3FFF42367911CA2CB7 /* WirelessGamingReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WirelessGamingReceiver.cpp; sourceTree = ""; }; 32D94FCF0562CBF700B6AF17 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32D94FD00562CBF700B6AF17 /* WirelessGamingReceiver.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WirelessGamingReceiver.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 3B21ED660B8E688A00B5CACA /* WirelessDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WirelessDevice.h; sourceTree = ""; }; 3B21ED6B0B8E690F00B5CACA /* WirelessDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WirelessDevice.cpp; sourceTree = ""; }; 3BE667170B9109C5009679FC /* WirelessHIDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WirelessHIDDevice.h; sourceTree = ""; }; 3BE6671B0B910A02009679FC /* WirelessHIDDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WirelessHIDDevice.cpp; sourceTree = ""; }; 3BE6677A0B91DC55009679FC /* devices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = devices.h; sourceTree = ""; }; 8DA8362C06AD9B9200E5AC22 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 32D94FCB0562CBF700B6AF17 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* WirelessGamingReceiver */ = { isa = PBXGroup; children = ( 247142CAFF3F8F9811CA285C /* Source */, 8DA8362C06AD9B9200E5AC22 /* Kernel.framework */, 089C167CFE841241C02AAC07 /* Resources */, 19C28FB6FE9D52B211CA2CBB /* Products */, ); name = WirelessGamingReceiver; sourceTree = ""; }; 089C167CFE841241C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 32D94FCF0562CBF700B6AF17 /* Info.plist */, 089C167DFE841241C02AAC07 /* InfoPlist.strings */, ); name = Resources; sourceTree = ""; }; 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( 32D94FD00562CBF700B6AF17 /* WirelessGamingReceiver.kext */, ); name = Products; sourceTree = ""; }; 247142CAFF3F8F9811CA285C /* Source */ = { isa = PBXGroup; children = ( 3BE6677A0B91DC55009679FC /* devices.h */, 3BE6671B0B910A02009679FC /* WirelessHIDDevice.cpp */, 3BE667170B9109C5009679FC /* WirelessHIDDevice.h */, 3B21ED6B0B8E690F00B5CACA /* WirelessDevice.cpp */, 3B21ED660B8E688A00B5CACA /* WirelessDevice.h */, 1A224C3FFF42367911CA2CB7 /* WirelessGamingReceiver.cpp */, 1A224C3EFF42367911CA2CB7 /* WirelessGamingReceiver.h */, ); name = Source; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 32D94FC50562CBF700B6AF17 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 32D94FC60562CBF700B6AF17 /* WirelessGamingReceiver.h in Headers */, 3B21ED670B8E688A00B5CACA /* WirelessDevice.h in Headers */, 3BE667180B9109C5009679FC /* WirelessHIDDevice.h in Headers */, 3BE6677B0B91DC55009679FC /* devices.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 32D94FC30562CBF700B6AF17 /* WirelessGamingReceiver */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB91D908733DB10010E9CD /* Build configuration list for PBXNativeTarget "WirelessGamingReceiver" */; buildPhases = ( 32D94FC50562CBF700B6AF17 /* Headers */, 32D94FC70562CBF700B6AF17 /* Resources */, 32D94FC90562CBF700B6AF17 /* Sources */, 32D94FCB0562CBF700B6AF17 /* Frameworks */, 32D94FCC0562CBF700B6AF17 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = WirelessGamingReceiver; productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; productName = WirelessGamingReceiver; productReference = 32D94FD00562CBF700B6AF17 /* WirelessGamingReceiver.kext */; productType = "com.apple.product-type.kernel-extension.iokit"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB91DD08733DB10010E9CD /* Build configuration list for PBXProject "WirelessGamingReceiver" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 089C166AFE841209C02AAC07 /* WirelessGamingReceiver */; projectDirPath = ""; projectRoot = ""; targets = ( 32D94FC30562CBF700B6AF17 /* WirelessGamingReceiver */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 32D94FC70562CBF700B6AF17 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 32D94FCC0562CBF700B6AF17 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 32D94FC90562CBF700B6AF17 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 32D94FCA0562CBF700B6AF17 /* WirelessGamingReceiver.cpp in Sources */, 3B21ED6C0B8E690F00B5CACA /* WirelessDevice.cpp in Sources */, 3BE6671C0B910A02009679FC /* WirelessHIDDevice.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C167EFE841241C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1DEB91DA08733DB10010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = com.mice.driver.WirelessGamingReceiver; MODULE_VERSION = 1.0.0d11; PRODUCT_NAME = WirelessGamingReceiver; PROVISIONING_PROFILE = ""; WRAPPER_EXTENSION = kext; ZERO_LINK = YES; }; name = Debug; }; 1DEB91DB08733DB10010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application: Colin Munro"; CURRENT_PROJECT_VERSION = 1.0.0d12; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; MODULE_NAME = com.mice.driver.WirelessGamingReceiver; MODULE_VERSION = 1.0.0d11; PRODUCT_NAME = WirelessGamingReceiver; PROVISIONING_PROFILE = ""; WRAPPER_EXTENSION = kext; }; name = Release; }; 1DEB91DE08733DB10010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = ""; PREBINDING = NO; SDKROOT = ""; }; name = Debug; }; 1DEB91DF08733DB10010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; PREBINDING = NO; SDKROOT = ""; SYMROOT = build; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB91D908733DB10010E9CD /* Build configuration list for PBXNativeTarget "WirelessGamingReceiver" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB91DA08733DB10010E9CD /* Debug */, 1DEB91DB08733DB10010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1DEB91DD08733DB10010E9CD /* Build configuration list for PBXProject "WirelessGamingReceiver" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB91DE08733DB10010E9CD /* Debug */, 1DEB91DF08733DB10010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } ================================================ FILE: WirelessGamingReceiver/WirelessHIDDevice.cpp ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro WirelessHIDDevice.cpp - generic wireless 360 device driver with HID support This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "WirelessHIDDevice.h" #include "WirelessDevice.h" #include "devices.h" #define POWEROFF_TIMEOUT (2 * 60) OSDefineMetaClassAndAbstractStructors(WirelessHIDDevice, IOHIDDevice) #define super IOHIDDevice // Some sort of message to send const char weirdStart[] = {0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; void WirelessHIDDevice::ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender) { WirelessHIDDevice *device; device = OSDynamicCast(WirelessHIDDevice, owner); // Automatic shutoff device->serialTimerCount++; if (device->serialTimerCount > POWEROFF_TIMEOUT) device->PowerOff(); // Reset sender->setTimeoutMS(1000); } // Sets the LED with the same format as the wired controller void WirelessHIDDevice::SetLEDs(int mode) { char buf[] = {0x00, 0x00, 0x08, 0x40 + (mode % 0x0e), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; WirelessDevice *device; device = OSDynamicCast(WirelessDevice, getProvider()); if (device != NULL) { device->SendPacket(buf, sizeof(buf)); device->SendPacket(weirdStart, sizeof(weirdStart)); } } // Returns the battery level unsigned char WirelessHIDDevice::GetBatteryLevel(void) { return battery; } void WirelessHIDDevice::PowerOff(void) { char buf[] = {0x00, 0x00, 0x08, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; WirelessDevice *device; device = OSDynamicCast(WirelessDevice, getProvider()); if (device != NULL) { device->SendPacket(buf, sizeof(buf)); // device->SendPacket(weirdStart, sizeof(weirdStart)); } } // Called from userspace to do something, like set the LEDs IOReturn WirelessHIDDevice::setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { char data[2]; if (report->readBytes(0, data, 2) < 2) return kIOReturnUnsupported; switch (data[0]) { case 0x01: // LED if ((data[1] != report->getLength()) || (data[1] != 0x03)) return kIOReturnUnsupported; report->readBytes(2, data, 1); SetLEDs(data[0]); return kIOReturnSuccess; case 0x02: // Power PowerOff(); return kIOReturnSuccess; default: return super::setReport(report, reportType, options); } } // Start up the driver bool WirelessHIDDevice::handleStart(IOService *provider) { WirelessDevice *device; IOWorkLoop *workloop; if (!super::handleStart(provider)) goto fail; device = OSDynamicCast(WirelessDevice, provider); if (device == NULL) goto fail; serialTimerCount = 0; serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { IOLog("start - failed to create timer for chatpad\n"); goto fail; } workloop = getWorkLoop(); if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) { IOLog("start - failed to connect timer for chatpad\n"); goto fail; } device->RegisterWatcher(this, _receivedData, NULL); device->SendPacket(weirdStart, sizeof(weirdStart)); serialTimer->setTimeoutMS(1000); return true; fail: return false; } // Shut down the driver void WirelessHIDDevice::handleStop(IOService *provider) { WirelessDevice *device; device = OSDynamicCast(WirelessDevice, provider); if (device != NULL) device->RegisterWatcher(NULL, NULL, NULL); if (serialTimer != NULL) { serialTimer->cancelTimeout(); IOWorkLoop *workloop = getWorkLoop(); if (workloop != NULL) workloop->removeEventSource(serialTimer); serialTimer->release(); serialTimer = NULL; } super::handleStop(provider); } // Handle new data from the device void WirelessHIDDevice::receivedData(void) { IOMemoryDescriptor *data; WirelessDevice *device = OSDynamicCast(WirelessDevice, getProvider()); if (device == NULL) return; while ((data = device->NextPacket()) != NULL) { receivedMessage(data); data->release(); } } const char *HexData = "0123456789ABCDEF"; // Process new data void WirelessHIDDevice::receivedMessage(IOMemoryDescriptor *data) { unsigned char buf[29]; if (data->getLength() != 29) return; data->readBytes(0, buf, 29); switch (buf[1]) { case 0x0f: // Initial info if (buf[16] == 0x13) receivedUpdate(0x13, buf + 17); serialString[0] = HexData[(buf[0x0A] & 0xF0) >> 4]; serialString[1] = HexData[buf[0x0A] & 0x0F]; serialString[2] = HexData[(buf[0x0B] & 0xF0) >> 4]; serialString[3] = HexData[buf[0x0B] & 0x0F]; serialString[4] = HexData[(buf[0x0C] & 0xF0) >> 4]; serialString[5] = HexData[buf[0x0C] & 0x0F]; serialString[6] = HexData[(buf[0x0D] & 0xF0) >> 4]; serialString[7] = HexData[buf[0x0D] & 0x0F]; serialString[8] = '\0'; IOLog("Got serial number: %s", serialString); break; case 0x01: // HID info update if (buf[3] == 0xf0) receivedHIDupdate(buf + 4, buf[5]); break; case 0x00: // Info update receivedUpdate(buf[3], buf + 4); break; default: break; } } // Received an update of a specific value void WirelessHIDDevice::receivedUpdate(unsigned char type, unsigned char *data) { switch (type) { case 0x13: // Battery level battery = data[0]; { OSObject *prop = OSNumber::withNumber(battery, 8); if (prop != NULL) { setProperty(kIOWirelessBatteryLevel, prop); prop->release(); } } break; default: break; } } // Received a normal HID update from the device void WirelessHIDDevice::receivedHIDupdate(unsigned char *data, int length) { IOReturn err; IOMemoryDescriptor *report; serialTimerCount = 0; report = IOMemoryDescriptor::withAddress(data, length, kIODirectionNone); err = handleReport(report, kIOHIDReportTypeInput); report->release(); if (err != kIOReturnSuccess) IOLog("handleReport return: 0x%.8x\n", err); } // Wrapper for notification of receiving data void WirelessHIDDevice::_receivedData(void *target, WirelessDevice *sender, void *parameter) { ((WirelessHIDDevice*)target)->receivedData(); } // Get a location ID for this device, as some games require it OSNumber* WirelessHIDDevice::newLocationIDNumber() const { WirelessDevice *device; device = OSDynamicCast(WirelessDevice, getProvider()); if (device == NULL) return NULL; return device->newLocationIDNumber(); } // Get the serial number of the device OSString* WirelessHIDDevice::newSerialNumberString() const { return OSString::withCString(serialString); } ================================================ FILE: WirelessGamingReceiver/WirelessHIDDevice.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro WirelessHIDDevice.h - declaration of generic wireless HID device This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __WIRELESSHIDDEVICE_H__ #define __WIRELESSHIDDEVICE_H__ #include class WirelessDevice; class WirelessHIDDevice : public IOHIDDevice { OSDeclareDefaultStructors(WirelessHIDDevice); public: void SetLEDs(int mode); void PowerOff(void); unsigned char GetBatteryLevel(void); IOReturn setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options); OSNumber* newLocationIDNumber() const; OSString* newSerialNumberString() const; protected: bool handleStart(IOService *provider); void handleStop(IOService *provider); virtual void receivedData(void); virtual void receivedMessage(IOMemoryDescriptor *data); virtual void receivedUpdate(unsigned char type, unsigned char *data); virtual void receivedHIDupdate(unsigned char *data, int length); private: static void _receivedData(void *target, WirelessDevice *sender, void *parameter); static void ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender); IOTimerEventSource *serialTimer; int serialTimerCount; unsigned char battery; char serialString[10]; }; #endif // __WIRELESSHIDDEVICE_H__ ================================================ FILE: WirelessGamingReceiver/devices.h ================================================ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro devics.h - contains constants for the wireless driver This file is part of Xbox360Controller. Xbox360Controller 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 2 of the License, or (at your option) any later version. Xbox360Controller 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DEVICES_H__ #define __DEVICES_H__ #define kIOWirelessDeviceType "Wireless360Device" #define kIOWirelessBatteryLevel "BatteryLevel" #endif // __DEVICES_H__ ================================================ FILE: WirelessGamingReceiver/version.plist ================================================ BuildVersion 12 CFBundleVersion 1.0 ProductBuildVersion 7K571 ProjectName DevToolsWizardTemplates SourceVersion 3870000 ================================================ FILE: build ================================================ #!/bin/bash zip -r ../360ControllerSource.zip * cd Feedback360 xcodebuild -configuration Deployment if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../DriverTool xcodebuild -configuration Release if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../360Controller xcodebuild -configuration Deployment if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../360Daemon xcodebuild -configuration Release if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../WirelessGamingReceiver xcodebuild -configuration Release if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../Wireless360Controller xcodebuild -configuration Release if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../Pref360Control xcodebuild -configuration Deployment if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" exit 1 fi cd ../Install360Controller packagesbuild -v Install360Controller.pkgproj mv build 360ControllerInstall hdiutil create -srcfolder 360ControllerInstall -format UDZO ../../360ControllerInstall.dmg mv 360ControllerInstall build cd .. echo "** File contents **" lipo -info 360Controller/build/Deployment/360Controller.kext/Contents/MacOS/360Controller lipo -info 360Controller/build/Deployment/360Controller.kext/Contents/PlugIns/Feedback360.plugin/Contents/MacOS/Feedback360 lipo -info 360Daemon/build/Release/360Daemon lipo -info Pref360Control/build/Deployment/Pref360Control.prefPane/Contents/MacOS/Pref360Control lipo -info Pref360Control/build/Deployment/Pref360Control.prefPane/Contents/Resources/DriverTool lipo -info WirelessGamingReceiver/build/Release/WirelessGamingReceiver.kext/Contents/MacOS/WirelessGamingReceiver lipo -info Wireless360Controller/build/Release/Wireless360Controller.kext/Contents/MacOS/Wireless360Controller echo "** File signatures **" sudo spctl -a -v 360Controller/build/Deployment/360Controller.kext sudo spctl -a -v 360Controller/build/Deployment/360Controller.kext/Contents/PlugIns/Feedback360.plugin sudo spctl -a -v 360Daemon/build/Release/360Daemon sudo spctl -a -v Pref360Control/build/Deployment/Pref360Control.prefPane sudo spctl -a -v Pref360Control/build/Deployment/Pref360Control.prefPane/Contents/Resources/DriverTool sudo spctl -a -v WirelessGamingReceiver/build/Release/WirelessGamingReceiver.kext sudo spctl -a -v Wireless360Controller/build/Release/Wireless360Controller.kext sudo spctl -a -v --type install Install360Controller/build/Install360Controller.pkg echo "*** DONE ***"