Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
GLUTPreferencesController.m
/* This program is freely distributable without licensing fees |
and is provided without guarantee or warrantee expressed or |
implied. This program is -not- in the public domain. */ |
#import "macx_glut.h" |
#import "GLUTPreferencesController.h" |
// preferences dictionary keys |
NSString *GLUTUseMacOSXCoordsKey = @"GLUTUseMacOSXCoordsKey"; |
NSString *GLUTUseCurrWDKey = @"GLUTUseCurrWDKey"; |
NSString *GLUTUseExtendedDesktopKey = @"GLUTUseExtendedDesktopKey"; |
NSString *GLUTIconicKey = @"GLUTIconicKey"; |
NSString *GLUTDebugModeKey = @"GLUTDebugModeKey"; |
NSString *GLUTInitWidthKey = @"GLUTInitWidthKey"; |
NSString *GLUTInitHeightKey = @"GLUTInitHeightKey"; |
NSString *GLUTInitXKey = @"GLUTInitXKey"; |
NSString *GLUTInitYKey = @"GLUTInitYKey"; |
NSString *GLUTIdleTimeIntervalKey = @"GLUTIdleTimeIntervalKey"; |
NSString *GLUTGameModeFadeIntervalKey = @"GLUTGameModeFadeIntervalKey"; |
NSString *GLUTGamemodeCaptureSingleKey = @"GLUTGamemodeCaptureSingleKey"; |
NSString *GLUTSyncToVBLKey = @"GLUTSyncToVBLKey"; |
NSString *GLUTEmulateMouseButtonsKey = @"GLUTEmulateMouseButtonsKey"; |
NSString *GLUTMouseFirstModifiersKey = @"GLUTMouseFirstModifiersKey"; |
NSString *GLUTMouseSecondModifiersKey = @"GLUTMouseSecondModifiersKey"; |
NSString *GLUTDeviceActionKey = @"GLUTDeviceActionKey"; |
NSString *GLUTDeviceVendorIDKey = @"GLUTDeviceVendorIDKey"; |
NSString *GLUTDeviceProductIDKey = @"GLUTDeviceProductIDKey"; |
NSString *GLUTDeviceLocIDKey = @"GLUTDeviceLocIDKey"; |
NSString *GLUTDeviceUsageKey = @"GLUTDeviceUsageKey"; |
NSString *GLUTDeviceUsagePageKey = @"GLUTDeviceUsagePageKey"; |
NSString *GLUTDeviceUsageEKey = @"GLUTDeviceUsageEKey"; |
NSString *GLUTDeviceUsagePageEKey = @"GLUTDeviceUsagePageEKey"; |
NSString *GLUTDeviceCookieKey = @"GLUTDeviceCookieKey"; |
NSString *GLUTDeviceMinReportKey = @"GLUTDeviceMinReportKey"; |
NSString *GLUTDeviceMaxReportKey = @"GLUTDeviceMaxReportKey"; |
NSString *GLUTDeviceInvertMulKey = @"GLUTDeviceInvertMulKey"; |
NSString *GLUTJoystickDeviceKey = @"GLUTJoystickDeviceKey"; |
NSString *GLUTSpaceballDeviceKey = @"GLUTSpaceballDeviceKey"; |
NSString *GLUTPreferencesName = @"com.apple.glut"; |
enum { |
kGLUTAlternateTag, |
kGLUTControlTag, |
kGLUTShiftTag, |
kGLUTCommandTag |
}; |
NSDictionary * defaults; |
int hidDevicesMatchedFlag = 0; |
// utility routine to load prefs at start |
void __glutLoadPrefs (void) |
{ |
defaults = [[NSUserDefaults standardUserDefaults] persistentDomainForName: GLUTPreferencesName]; |
[defaults retain]; |
// set values and re-init (ensure to check to see if keyed object exists) |
if ([defaults objectForKey: GLUTUseMacOSXCoordsKey]) |
__glutUseMacOSCoords = [[defaults objectForKey: GLUTUseMacOSXCoordsKey] boolValue]; |
if ([defaults objectForKey: GLUTUseCurrWDKey]) |
__glutUseInitWD = [[defaults objectForKey: GLUTUseCurrWDKey] boolValue]; |
if ([defaults objectForKey: GLUTUseExtendedDesktopKey]) |
__glutUseExtendedDesktop = [[defaults objectForKey: GLUTUseExtendedDesktopKey] boolValue]; |
if ([defaults objectForKey: GLUTIconicKey]) |
__glutIconic = [[defaults objectForKey: GLUTIconicKey] boolValue]; |
if ([defaults objectForKey: GLUTDebugModeKey]) |
__glutDebug = [[defaults objectForKey: GLUTDebugModeKey] boolValue]; |
if ([defaults objectForKey: GLUTInitWidthKey]) |
__glutInitWidth = [[defaults objectForKey: GLUTInitWidthKey] intValue]; |
if ([defaults objectForKey: GLUTInitHeightKey]) |
__glutInitHeight = [[defaults objectForKey: GLUTInitHeightKey] intValue]; |
if ([defaults objectForKey: GLUTInitXKey]) |
__glutInitX = [[defaults objectForKey: GLUTInitXKey] intValue]; |
if ([defaults objectForKey: GLUTInitYKey]) |
__glutInitY = [[defaults objectForKey: GLUTInitYKey] intValue]; |
if ([defaults objectForKey: GLUTIdleTimeIntervalKey]) |
__glutIdleTimeInterval = [[defaults objectForKey: GLUTIdleTimeIntervalKey] floatValue]; |
if ([defaults objectForKey: GLUTGameModeFadeIntervalKey]) |
__glutGameModeFadeInterval = [[defaults objectForKey: GLUTGameModeFadeIntervalKey] floatValue]; |
if ([defaults objectForKey: GLUTGamemodeCaptureSingleKey]) |
__glutCaptureAllDisplays = 1 - [[defaults objectForKey: GLUTGamemodeCaptureSingleKey] boolValue]; |
if ([defaults objectForKey: GLUTSyncToVBLKey]) |
__glutSyncToVBL = [[defaults objectForKey: GLUTSyncToVBLKey] boolValue]; |
if ([defaults objectForKey: GLUTEmulateMouseButtonsKey]) |
__glutEmulateMouseButtons = [[defaults objectForKey: GLUTEmulateMouseButtonsKey] boolValue]; |
if ([defaults objectForKey: GLUTMouseFirstModifiersKey]) |
__glutMouseFirstModifiers = [[defaults objectForKey: GLUTMouseFirstModifiersKey] intValue]; |
if ([defaults objectForKey: GLUTMouseSecondModifiersKey]) |
__glutMouseSecondModifiers = [[defaults objectForKey: GLUTMouseSecondModifiersKey] intValue]; |
} |
// This function looks for the devices specified in the preferences file. If it finds them, it uses them, |
// otherwise those preferences are ignored, but not deleted. |
void __glutMatchHIDPrefsToDevices (void) |
{ |
if (hidDevicesMatchedFlag == 1) |
{ |
return; |
} |
hidDevicesMatchedFlag = 1; |
// read pref array |
// note: this modifies glut settings directly (we do not dup settings for cancel for joystick and spaceball yet. |
if ([defaults objectForKey: GLUTJoystickDeviceKey]) { |
id actionDict = nil; |
pRecDevice pFirstDevice = NULL; |
NSEnumerator * enumer = [[defaults objectForKey: GLUTJoystickDeviceKey] objectEnumerator]; |
// while array entries |
while (nil != (actionDict = [enumer nextObject])) { |
pRecElement pElement = NULL; |
pRecDevice pDevice = NULL; |
int action = 0; |
recSaveHID configRec; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.actionCookie = [[actionDict objectForKey: GLUTDeviceActionKey] longValue]; |
else |
configRec.actionCookie = 0; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.vendorID = [[actionDict objectForKey: GLUTDeviceVendorIDKey] longValue]; |
else |
configRec.vendorID = 0; |
if ([actionDict objectForKey: GLUTDeviceProductIDKey]) |
configRec.productID = [[actionDict objectForKey: GLUTDeviceProductIDKey] longValue]; |
else |
configRec.productID = 0; |
if ([actionDict objectForKey: GLUTDeviceLocIDKey]) |
configRec.locID = [[actionDict objectForKey: GLUTDeviceLocIDKey] longValue]; |
else |
configRec.locID = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageKey]) |
configRec.usage = [[actionDict objectForKey: GLUTDeviceUsageKey] longValue]; |
else |
configRec.usage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageKey]) |
configRec.usagePage = [[actionDict objectForKey: GLUTDeviceUsagePageKey] longValue]; |
else |
configRec.usagePage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageEKey]) |
configRec.usageE = [[actionDict objectForKey: GLUTDeviceUsageEKey] longValue]; |
else |
configRec.usageE = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageEKey]) |
configRec.usagePageE = [[actionDict objectForKey: GLUTDeviceUsagePageEKey] longValue]; |
else |
configRec.usagePageE = 0; |
if ([actionDict objectForKey: GLUTDeviceMinReportKey]) |
configRec.minReport = [[actionDict objectForKey: GLUTDeviceMinReportKey] longValue]; |
else |
configRec.minReport = 0; |
if ([actionDict objectForKey: GLUTDeviceMaxReportKey]) |
configRec.maxReport = [[actionDict objectForKey: GLUTDeviceMaxReportKey] longValue]; |
else |
configRec.maxReport = 0; |
if ([actionDict objectForKey: GLUTDeviceCookieKey]) |
configRec.cookie = (IOHIDElementCookie)[[actionDict objectForKey: GLUTDeviceCookieKey] unsignedLongValue]; |
else |
configRec.cookie = 0; |
// find device and element for configRec and find controlling action |
action = HIDGetElementConfig (&configRec, &pDevice, &pElement); |
struct _GLUTinputActionRec * inputARec = __glutGetJoystickDeviceElement (action); |
if (NULL == pFirstDevice) |
pFirstDevice = pDevice; |
if (pDevice && pElement && (pFirstDevice == pDevice)) { // valid device and element and we match the same device |
// fill information in |
inputARec->pDevice = pDevice; |
inputARec->pElement = pElement; |
if ([actionDict objectForKey: GLUTDeviceInvertMulKey]) |
inputARec->invertMul = [[actionDict objectForKey: GLUTDeviceInvertMulKey] longValue]; |
else |
inputARec->invertMul = 1; |
} else { // device for action not found so blank current device |
inputARec->pDevice = NULL; |
inputARec->pElement = NULL; |
inputARec->invertMul = 1; |
} |
} |
} |
if ([defaults objectForKey: GLUTSpaceballDeviceKey]) { |
id actionDict = nil; |
pRecDevice pFirstDevice = NULL; |
NSEnumerator * enumer = [[defaults objectForKey: GLUTSpaceballDeviceKey] objectEnumerator]; |
// while array entries |
while (nil != (actionDict = [enumer nextObject])) { |
pRecElement pElement = NULL; |
pRecDevice pDevice = NULL; |
int action = 0; |
recSaveHID configRec; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.actionCookie = [[actionDict objectForKey: GLUTDeviceActionKey] longValue]; |
else |
configRec.actionCookie = 0; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.vendorID = [[actionDict objectForKey: GLUTDeviceVendorIDKey] longValue]; |
else |
configRec.vendorID = 0; |
if ([actionDict objectForKey: GLUTDeviceProductIDKey]) |
configRec.productID = [[actionDict objectForKey: GLUTDeviceProductIDKey] longValue]; |
else |
configRec.productID = 0; |
if ([actionDict objectForKey: GLUTDeviceLocIDKey]) |
configRec.locID = [[actionDict objectForKey: GLUTDeviceLocIDKey] longValue]; |
else |
configRec.locID = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageKey]) |
configRec.usage = [[actionDict objectForKey: GLUTDeviceUsageKey] longValue]; |
else |
configRec.usage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageKey]) |
configRec.usagePage = [[actionDict objectForKey: GLUTDeviceUsagePageKey] longValue]; |
else |
configRec.usagePage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageEKey]) |
configRec.usageE = [[actionDict objectForKey: GLUTDeviceUsageEKey] longValue]; |
else |
configRec.usageE = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageEKey]) |
configRec.usagePageE = [[actionDict objectForKey: GLUTDeviceUsagePageEKey] longValue]; |
else |
configRec.usagePageE = 0; |
if ([actionDict objectForKey: GLUTDeviceMinReportKey]) |
configRec.minReport = [[actionDict objectForKey: GLUTDeviceMinReportKey] longValue]; |
else |
configRec.minReport = 0; |
if ([actionDict objectForKey: GLUTDeviceMaxReportKey]) |
configRec.maxReport = [[actionDict objectForKey: GLUTDeviceMaxReportKey] longValue]; |
else |
configRec.maxReport = 0; |
if ([actionDict objectForKey: GLUTDeviceCookieKey]) |
configRec.cookie = (IOHIDElementCookie)[[actionDict objectForKey: GLUTDeviceCookieKey] unsignedLongValue]; |
else |
configRec.cookie = 0; |
// find device and element for configRec and find controling action |
action = HIDGetElementConfig (&configRec, &pDevice, &pElement); |
struct _GLUTinputActionRec * inputARec = __glutGetSpaceballDeviceElement (action); // get pointer to record |
if (NULL == pFirstDevice) |
pFirstDevice = pDevice; |
if (pDevice && pElement && (pFirstDevice == pDevice)) { // valid device and element and we match the same device |
// fill information in |
inputARec->pDevice = pDevice; |
inputARec->pElement = pElement; |
if ([actionDict objectForKey: GLUTDeviceInvertMulKey]) |
inputARec->invertMul = [[actionDict objectForKey: GLUTDeviceInvertMulKey] longValue]; |
else |
inputARec->invertMul = 1; |
} else { // device for action not found so blank current device |
inputARec->pDevice = NULL; |
inputARec->pElement = NULL; |
inputARec->invertMul = 1; |
} |
} |
} |
// we have done our matching, and no longer need the prefs dictionary |
[defaults release]; |
// do not save prefs here so if a device is missing and on a later run returned their saved prefs are not hosed... |
} |
@interface GLUTPreferencesController(GLUTPrivate) |
- (void)updateLaunchUI:(NSDictionary *)defaults; |
- (void)updateDevicesUI:(NSDictionary *)defaults; |
- (void)updateUI:(NSDictionary *)defaults; |
- (void)updateObjectState; |
- (void)updateLaunchState; |
- (void)updateMouseState; |
- (int) modifierToIndex:(unsigned int)modifier; // converts a key modifier to the index of the menu item |
- (unsigned int) indexToModifier:(int)index; // does the opposite |
- (void)updateDevicesThread:(id)object; |
- (void)waitForDevicesThread; |
@end |
///////////////////////////////////////////// |
#pragma mark - |
@implementation GLUTPreferencesController |
- (id)init |
{ |
if((self = [self initWithWindowNibName: @"GLUTPreferences"]) != nil) { |
[self setWindowFrameAutosaveName: @""]; |
[self setShouldCascadeWindows: NO]; |
updatingDevices = NO; |
return self; |
} |
return nil; |
} |
- (void)dealloc |
{ |
[self waitForDevicesThread]; |
[mouseAssignWarningIcon release]; |
[joyAssignWarningIcon release]; |
[spaceAssignWarningIcon release]; |
[super dealloc]; |
} |
- (void)finalize |
{ |
[self waitForDevicesThread]; |
[super finalize]; |
} |
- (void)windowDidLoad |
{ |
NSImage * cautionIcon; |
NSString * path; |
[[self window] center]; |
[super windowDidLoad]; |
// fix for default button |
NSEnumerator * enumer = [[[[self window] contentView] subviews] objectEnumerator]; |
id object = nil; |
while (nil != (object = [enumer nextObject])) |
if (([object isKindOfClass:[NSButton class]]) && |
([[object title] isEqual:@"Set Defaults"])) { |
[object setAction: @selector(setDefault:)]; |
[object setTarget: self]; |
} |
// launch |
[launchUseMacOSXCoords setState: __glutUseMacOSCoords]; |
[launchUseCurrWD setState: __glutUseInitWD]; |
[launchUseExtendedDesktop setState: __glutUseExtendedDesktop]; |
[launchIconic setState: __glutIconic]; |
[launchDebugMode setState: __glutDebug]; |
[launchInitWidth setIntValue: __glutInitWidth]; |
[launchInitHeight setIntValue: __glutInitHeight]; |
[launchInitX setIntValue: __glutInitX]; |
[launchInitY setIntValue: __glutInitY]; |
[launchMenuIdle setFloatValue: __glutIdleTimeInterval]; |
[launchFadeTime setFloatValue: __glutGameModeFadeInterval]; |
[launchGamemodeCaptureSingle setState: (1 - __glutCaptureAllDisplays)]; |
[launchSyncToVBL setState: __glutSyncToVBL]; |
/* Mouse */ |
[mouseDetected setStringValue:[NSString stringWithFormat:@"%d %@", __glutGetNumberOfMouseButtons(), |
NSLocalizedStringFromTableInBundle(@" button mouse detected.", @"GLUTUI", __glutGetFrameworkBundle(), @" button mouse detected.")]]; |
[mouseAssignWarningText setStringValue: @""]; |
[mouseEmulation setState: __glutEmulateMouseButtons]; |
[mouseRightConfigMenu selectItemAtIndex:[self modifierToIndex:__glutMouseFirstModifiers]]; |
[mouseMiddleConfigMenu selectItemAtIndex:[self modifierToIndex:__glutMouseSecondModifiers]]; |
/* Joystick */ |
// joyInputMenu will be left as it is in the nib |
struct _GLUTinputActionRec * inputARec = __glutGetJoystickDeviceElement ([joyInputMenu indexOfSelectedItem]); |
[joyInverted setState:inputARec->invertMul]; |
if (inputARec->pElement && inputARec->pElement->name) |
[joyElement setStringValue:[NSString stringWithFormat:@"%s", inputARec->pElement->name]]; |
else |
[joyElement setStringValue:NSLocalizedStringFromTableInBundle(@"Not assigned.", @"GLUTUI", __glutGetFrameworkBundle(), @"Not assigned.")]; |
[joyAssignNote setStringValue: @""]; |
/* Spaceball */ |
// spaceInputMenu will be left as it is in the nib |
inputARec = __glutGetSpaceballDeviceElement ([joyInputMenu indexOfSelectedItem]); |
[spaceInverted setState:inputARec->invertMul]; |
if (inputARec->pElement && inputARec->pElement->name) |
[spaceElement setStringValue:[NSString stringWithFormat:@"%s", inputARec->pElement->name]]; |
else |
[spaceElement setStringValue:NSLocalizedStringFromTableInBundle(@"Not assigned.", @"GLUTUI", __glutGetFrameworkBundle(), @"Not assigned.")]; |
[spaceAssignNote setStringValue: @""]; |
mouseTabItemView = [mouseAssignWarningIcon superview]; |
joyTabItemView = [joyAssignWarningIcon superview]; |
spaceTabItemView = [spaceAssignWarningIcon superview]; |
path = [__glutGetFrameworkBundle() pathForImageResource: @"Caution.tiff"]; |
cautionIcon = [[[NSImage alloc] initWithContentsOfFile: path] autorelease]; |
[mouseAssignWarningIcon setImage: cautionIcon]; |
[mouseAssignWarningIcon retain]; |
[mouseAssignWarningIcon removeFromSuperview]; |
[joyAssignWarningIcon setImage: cautionIcon]; |
[joyAssignWarningIcon retain]; |
[joyAssignWarningIcon removeFromSuperview]; |
[spaceAssignWarningIcon setImage: cautionIcon]; |
[spaceAssignWarningIcon retain]; |
[spaceAssignWarningIcon removeFromSuperview]; |
} |
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem |
{ |
// Make sure that the threads are synced up before switching off first tab |
if([tabView indexOfTabViewItem:tabViewItem] > 0) |
[self waitForDevicesThread]; |
[self joyElement:self]; |
[self spaceElement:self]; |
[self mouseEanbleEmulation:self]; // update display |
} |
- (IBAction)setDefault:(id)sender |
{ |
[self waitForDevicesThread]; |
NSDictionary * prefsDefaults = [NSDictionary dictionaryWithObjectsAndKeys: |
[NSNumber numberWithBool: kUseMacOSCoords], GLUTUseMacOSXCoordsKey, |
[NSNumber numberWithBool: kUseInitWD], GLUTUseCurrWDKey, |
[NSNumber numberWithBool: kUseExtendedDesktop], GLUTUseExtendedDesktopKey, |
[NSNumber numberWithBool: kIconic], GLUTIconicKey, |
[NSNumber numberWithBool: kDebug], GLUTDebugModeKey, |
[NSNumber numberWithInt: kInitWidth], GLUTInitWidthKey, |
[NSNumber numberWithInt: kInitHeight], GLUTInitHeightKey, |
[NSNumber numberWithInt: kInitX], GLUTInitXKey, |
[NSNumber numberWithInt: kInitY], GLUTInitYKey, |
[NSNumber numberWithFloat: GLUT_DEFAULT_IDLE_INTERVAL], GLUTIdleTimeIntervalKey, |
[NSNumber numberWithFloat: GLUT_DEFAULT_FADE_INTERVAL], GLUTGameModeFadeIntervalKey, |
[NSNumber numberWithBool: (1 - kCaptureAllDisplays)], GLUTGamemodeCaptureSingleKey, |
[NSNumber numberWithBool: kSyncToVBL], GLUTSyncToVBLKey, |
[NSNumber numberWithBool: kEmulateMouseButtons], GLUTEmulateMouseButtonsKey, |
[NSNumber numberWithInt: kMouseFirstModifiers], GLUTMouseFirstModifiersKey, |
[NSNumber numberWithInt: kMouseSecondModifiers], GLUTMouseSecondModifiersKey, |
nil]; |
// no joystick or spaceball defaults |
__glutInitJoystickInput(NULL); // reset to default |
__glutInitSpaceballInput(NULL); |
[self updateUI:prefsDefaults]; |
} |
- (IBAction)showWindow:(id)sender |
{ |
(void) [self window]; // make sure that the window is loaded |
#if GLUT_DEFER_PREFS_DEVICE_QUERY |
// Select the first tab (launch tab) each time the prefs window is opened. |
// This allows for the device information to be gathered via a seperate thread. |
[prefsTabView selectTabViewItemAtIndex:0]; |
#endif |
[self updateLaunchUI:[[NSUserDefaults standardUserDefaults] persistentDomainForName: GLUTPreferencesName]]; |
// update HID list on every show |
if( !updatingDevices ) |
{ |
updatingDevices = YES; |
[NSThread detachNewThreadSelector:@selector(updateDevicesThread:) |
toTarget:self withObject:nil]; |
} |
#if !GLUT_DEFER_PREFS_DEVICE_QUERY |
// We have to wait for this to finish when we can't guarantee |
// that the prefs tab opens up to the launch tab. |
[self waitForDevicesThread]; |
#endif |
[super showWindow:sender]; |
} |
- (IBAction)ok:(id)sender |
{ |
int i; |
struct _GLUTinputActionRec * inputARec = NULL; |
recSaveHID configRec; |
[self waitForDevicesThread]; |
NSMutableArray * JoyActionArray = [NSMutableArray arrayWithCapacity: kNumJoystickActions]; |
NSMutableArray * SBActionArray = [NSMutableArray arrayWithCapacity: kNumSpaceballActions]; |
NSMutableDictionary * prefsDefaults = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
[NSNumber numberWithBool: [launchUseMacOSXCoords state]], GLUTUseMacOSXCoordsKey, |
[NSNumber numberWithBool: [launchUseCurrWD state]], GLUTUseCurrWDKey, |
[NSNumber numberWithBool: [launchUseExtendedDesktop state]], GLUTUseExtendedDesktopKey, |
[NSNumber numberWithBool: [launchIconic state]], GLUTIconicKey, |
[NSNumber numberWithBool: [launchDebugMode state]], GLUTDebugModeKey, |
[NSNumber numberWithInt: [launchInitWidth intValue]], GLUTInitWidthKey, |
[NSNumber numberWithInt: [launchInitHeight intValue]], GLUTInitHeightKey, |
[NSNumber numberWithInt: [launchInitX intValue]], GLUTInitXKey, |
[NSNumber numberWithInt: [launchInitY intValue]], GLUTInitYKey, |
[NSNumber numberWithFloat: [launchMenuIdle floatValue]], GLUTIdleTimeIntervalKey, |
[NSNumber numberWithFloat: [launchFadeTime floatValue]], GLUTGameModeFadeIntervalKey, |
[NSNumber numberWithBool: [launchGamemodeCaptureSingle state]], GLUTGamemodeCaptureSingleKey, |
[NSNumber numberWithBool: [launchSyncToVBL state]], GLUTSyncToVBLKey, |
[NSNumber numberWithBool: [mouseEmulation state]], GLUTEmulateMouseButtonsKey, |
[NSNumber numberWithInt: [self indexToModifier:[mouseRightConfigMenu indexOfSelectedItem]]], GLUTMouseFirstModifiersKey, |
[NSNumber numberWithInt: [self indexToModifier:[mouseMiddleConfigMenu indexOfSelectedItem]]], GLUTMouseSecondModifiersKey, |
nil]; |
for (i = 0; i < kNumJoystickActions; i++) { |
inputARec = __glutGetJoystickDeviceElement (i); |
HIDSetElementConfig (&configRec, inputARec->pDevice, inputARec->pElement, i); |
NSDictionary * deviceDict = [NSDictionary dictionaryWithObjectsAndKeys: |
[NSNumber numberWithInt: configRec.actionCookie], GLUTDeviceActionKey, |
[NSNumber numberWithInt: configRec.vendorID], GLUTDeviceVendorIDKey, |
[NSNumber numberWithInt: configRec.productID], GLUTDeviceProductIDKey, |
[NSNumber numberWithInt: configRec.locID], GLUTDeviceLocIDKey, |
[NSNumber numberWithInt: configRec.usage], GLUTDeviceUsageKey, |
[NSNumber numberWithInt: configRec.usagePage], GLUTDeviceUsagePageKey, |
[NSNumber numberWithInt: configRec.usageE], GLUTDeviceUsageEKey, |
[NSNumber numberWithInt: configRec.usagePageE], GLUTDeviceUsagePageEKey, |
[NSNumber numberWithInt: configRec.minReport], GLUTDeviceMinReportKey, |
[NSNumber numberWithInt: configRec.maxReport], GLUTDeviceMaxReportKey, |
[NSNumber numberWithUnsignedInt: (unsigned int)((long)configRec.cookie)], GLUTDeviceCookieKey, |
[NSNumber numberWithInt: inputARec->invertMul], GLUTDeviceInvertMulKey, |
nil]; |
[JoyActionArray addObject:deviceDict]; |
} |
[prefsDefaults setObject:JoyActionArray forKey:GLUTJoystickDeviceKey]; |
for (i = 0; i < kNumSpaceballActions; i++) { |
inputARec = __glutGetSpaceballDeviceElement (i); |
HIDSetElementConfig (&configRec, inputARec->pDevice, inputARec->pElement, i); |
NSDictionary * deviceDict = [NSDictionary dictionaryWithObjectsAndKeys: |
[NSNumber numberWithInt: configRec.actionCookie], GLUTDeviceActionKey, |
[NSNumber numberWithInt: configRec.vendorID], GLUTDeviceVendorIDKey, |
[NSNumber numberWithInt: configRec.productID], GLUTDeviceProductIDKey, |
[NSNumber numberWithInt: configRec.locID], GLUTDeviceLocIDKey, |
[NSNumber numberWithInt: configRec.usage], GLUTDeviceUsageKey, |
[NSNumber numberWithInt: configRec.usagePage], GLUTDeviceUsagePageKey, |
[NSNumber numberWithInt: configRec.usageE], GLUTDeviceUsageEKey, |
[NSNumber numberWithInt: configRec.usagePageE], GLUTDeviceUsagePageEKey, |
[NSNumber numberWithUnsignedInt: configRec.minReport], GLUTDeviceMinReportKey, |
[NSNumber numberWithUnsignedInt: configRec.maxReport], GLUTDeviceMaxReportKey, |
[NSNumber numberWithUnsignedInt: (unsigned int)((long)configRec.cookie)], GLUTDeviceCookieKey, |
[NSNumber numberWithUnsignedInt: inputARec->invertMul], GLUTDeviceInvertMulKey, |
nil]; |
[SBActionArray addObject:deviceDict]; |
} |
[prefsDefaults setObject:SBActionArray forKey:GLUTSpaceballDeviceKey]; |
[[NSUserDefaults standardUserDefaults] setPersistentDomain: prefsDefaults forName: GLUTPreferencesName]; |
[self updateObjectState]; // update all glut objects from window |
[super close]; |
} |
- (IBAction)cancel:(id)sender |
{ |
[super close]; |
} |
- (void)updateLaunchUI: (NSDictionary *)prefsDefaults |
{ |
if ([prefsDefaults objectForKey: GLUTUseMacOSXCoordsKey]) |
[launchUseMacOSXCoords setState: [[prefsDefaults objectForKey: GLUTUseMacOSXCoordsKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTUseCurrWDKey]) |
[launchUseCurrWD setState: [[prefsDefaults objectForKey: GLUTUseCurrWDKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTUseExtendedDesktopKey]) |
[launchUseExtendedDesktop setState: [[prefsDefaults objectForKey: GLUTUseExtendedDesktopKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTIconicKey]) |
[launchIconic setState: [[prefsDefaults objectForKey: GLUTIconicKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTDebugModeKey]) |
[launchDebugMode setState: [[prefsDefaults objectForKey: GLUTDebugModeKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTInitWidthKey]) |
[launchInitWidth setIntValue: [[prefsDefaults objectForKey: GLUTInitWidthKey] intValue]]; |
if ([prefsDefaults objectForKey: GLUTInitHeightKey]) |
[launchInitHeight setIntValue: [[prefsDefaults objectForKey: GLUTInitHeightKey] intValue]]; |
if ([prefsDefaults objectForKey: GLUTInitXKey]) |
[launchInitX setIntValue: [[prefsDefaults objectForKey: GLUTInitXKey] intValue]]; |
if ([prefsDefaults objectForKey: GLUTInitYKey]) |
[launchInitY setIntValue: [[prefsDefaults objectForKey: GLUTInitYKey] intValue]]; |
if ([prefsDefaults objectForKey: GLUTIdleTimeIntervalKey]) |
[launchMenuIdle setFloatValue: [[prefsDefaults objectForKey: GLUTIdleTimeIntervalKey] floatValue]]; |
if ([prefsDefaults objectForKey: GLUTGameModeFadeIntervalKey]) |
[launchFadeTime setFloatValue: [[prefsDefaults objectForKey: GLUTGameModeFadeIntervalKey] floatValue]]; |
if ([prefsDefaults objectForKey: GLUTGamemodeCaptureSingleKey]) |
[launchGamemodeCaptureSingle setState: [[prefsDefaults objectForKey: GLUTGamemodeCaptureSingleKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTSyncToVBLKey]) |
[launchSyncToVBL setState: [[prefsDefaults objectForKey: GLUTSyncToVBLKey] boolValue]]; |
// force view/control update |
[launchInitWidth setNeedsDisplay]; |
[launchInitHeight setNeedsDisplay]; |
[launchInitX setNeedsDisplay]; |
[launchInitY setNeedsDisplay]; |
[launchMenuIdle setNeedsDisplay]; |
[launchFadeTime setNeedsDisplay]; |
} |
- (void)updateDevicesUI: (NSDictionary *)prefsDefaults |
{ |
if ([prefsDefaults objectForKey: GLUTEmulateMouseButtonsKey]) |
[mouseEmulation setState: [[prefsDefaults objectForKey: GLUTEmulateMouseButtonsKey] boolValue]]; |
if ([prefsDefaults objectForKey: GLUTMouseFirstModifiersKey]) |
[mouseRightConfigMenu selectItemAtIndex: [self modifierToIndex:[[prefsDefaults objectForKey: GLUTMouseFirstModifiersKey] intValue]]]; |
if ([prefsDefaults objectForKey: GLUTMouseSecondModifiersKey]) |
[mouseMiddleConfigMenu selectItemAtIndex: [self modifierToIndex:[[prefsDefaults objectForKey: GLUTMouseSecondModifiersKey] intValue]]]; |
// read pref array |
// note: this modifies glut settings directly (we do not dup settings for cancel for joystick and spaceball yet. |
if ([prefsDefaults objectForKey: GLUTJoystickDeviceKey]) { |
id actionDict = nil; |
pRecDevice pFirstDevice = NULL; |
NSEnumerator * enumer = [[prefsDefaults objectForKey: GLUTJoystickDeviceKey] objectEnumerator]; |
// while array entries |
while (nil != (actionDict = [enumer nextObject])) { |
pRecElement pElement = NULL; |
pRecDevice pDevice = NULL; |
int action = 0; |
recSaveHID configRec; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.actionCookie = [[actionDict objectForKey: GLUTDeviceActionKey] longValue]; |
else |
configRec.actionCookie = 0; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.vendorID = [[actionDict objectForKey: GLUTDeviceVendorIDKey] longValue]; |
else |
configRec.vendorID = 0; |
if ([actionDict objectForKey: GLUTDeviceProductIDKey]) |
configRec.productID = [[actionDict objectForKey: GLUTDeviceProductIDKey] longValue]; |
else |
configRec.productID = 0; |
if ([actionDict objectForKey: GLUTDeviceLocIDKey]) |
configRec.locID = [[actionDict objectForKey: GLUTDeviceLocIDKey] longValue]; |
else |
configRec.locID = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageKey]) |
configRec.usage = [[actionDict objectForKey: GLUTDeviceUsageKey] longValue]; |
else |
configRec.usage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageKey]) |
configRec.usagePage = [[actionDict objectForKey: GLUTDeviceUsagePageKey] longValue]; |
else |
configRec.usagePage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageEKey]) |
configRec.usageE = [[actionDict objectForKey: GLUTDeviceUsageEKey] longValue]; |
else |
configRec.usageE = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageEKey]) |
configRec.usagePageE = [[actionDict objectForKey: GLUTDeviceUsagePageEKey] longValue]; |
else |
configRec.usagePageE = 0; |
if ([actionDict objectForKey: GLUTDeviceMinReportKey]) |
configRec.minReport = [[actionDict objectForKey: GLUTDeviceMinReportKey] longValue]; |
else |
configRec.minReport = 0; |
if ([actionDict objectForKey: GLUTDeviceMaxReportKey]) |
configRec.maxReport = [[actionDict objectForKey: GLUTDeviceMaxReportKey] longValue]; |
else |
configRec.maxReport = 0; |
if ([actionDict objectForKey: GLUTDeviceCookieKey]) |
configRec.cookie = (IOHIDElementCookie)[[actionDict objectForKey: GLUTDeviceCookieKey] unsignedLongValue]; |
else |
configRec.cookie = 0; |
// find device and element for configRec and find controling action |
action = HIDGetElementConfig (&configRec, &pDevice, &pElement); |
struct _GLUTinputActionRec * inputARec = __glutGetJoystickDeviceElement (action); |
if (NULL == pFirstDevice) |
pFirstDevice = pDevice; |
if (pDevice && pElement && (pFirstDevice == pDevice)) { // valid device and element and we match the same device |
// fill information in |
inputARec->pDevice = pDevice; |
inputARec->pElement = pElement; |
if ([actionDict objectForKey: GLUTDeviceInvertMulKey]) |
inputARec->invertMul = [[actionDict objectForKey: GLUTDeviceInvertMulKey] longValue]; |
else |
inputARec->invertMul = 1; |
} else { // device for action not found so blank current device |
inputARec->pDevice = NULL; |
inputARec->pElement = NULL; |
inputARec->invertMul = 1; |
} |
} |
} |
if ([prefsDefaults objectForKey: GLUTSpaceballDeviceKey]) { |
id actionDict = nil; |
pRecDevice pFirstDevice = NULL; |
NSEnumerator * enumer = [[prefsDefaults objectForKey: GLUTSpaceballDeviceKey] objectEnumerator]; |
// while array entries |
while (nil != (actionDict = [enumer nextObject])) { |
pRecElement pElement = NULL; |
pRecDevice pDevice = NULL; |
int action = 0; |
recSaveHID configRec; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.actionCookie = [[actionDict objectForKey: GLUTDeviceActionKey] longValue]; |
else |
configRec.actionCookie = 0; |
if ([actionDict objectForKey: GLUTDeviceActionKey]) |
configRec.vendorID = [[actionDict objectForKey: GLUTDeviceVendorIDKey] longValue]; |
else |
configRec.vendorID = 0; |
if ([actionDict objectForKey: GLUTDeviceProductIDKey]) |
configRec.productID = [[actionDict objectForKey: GLUTDeviceProductIDKey] longValue]; |
else |
configRec.productID = 0; |
if ([actionDict objectForKey: GLUTDeviceLocIDKey]) |
configRec.locID = [[actionDict objectForKey: GLUTDeviceLocIDKey] longValue]; |
else |
configRec.locID = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageKey]) |
configRec.usage = [[actionDict objectForKey: GLUTDeviceUsageKey] longValue]; |
else |
configRec.usage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageKey]) |
configRec.usagePage = [[actionDict objectForKey: GLUTDeviceUsagePageKey] longValue]; |
else |
configRec.usagePage = 0; |
if ([actionDict objectForKey: GLUTDeviceUsageEKey]) |
configRec.usageE = [[actionDict objectForKey: GLUTDeviceUsageEKey] longValue]; |
else |
configRec.usageE = 0; |
if ([actionDict objectForKey: GLUTDeviceUsagePageEKey]) |
configRec.usagePageE = [[actionDict objectForKey: GLUTDeviceUsagePageEKey] longValue]; |
else |
configRec.usagePageE = 0; |
if ([actionDict objectForKey: GLUTDeviceMinReportKey]) |
configRec.minReport = [[actionDict objectForKey: GLUTDeviceMinReportKey] longValue]; |
else |
configRec.minReport = 0; |
if ([actionDict objectForKey: GLUTDeviceMaxReportKey]) |
configRec.maxReport = [[actionDict objectForKey: GLUTDeviceMaxReportKey] longValue]; |
else |
configRec.maxReport = 0; |
if ([actionDict objectForKey: GLUTDeviceCookieKey]) |
configRec.cookie = (IOHIDElementCookie)[[actionDict objectForKey: GLUTDeviceCookieKey] unsignedLongValue]; |
else |
configRec.cookie = 0; |
// find device and element for configRec and find controling action |
action = HIDGetElementConfig (&configRec, &pDevice, &pElement); |
struct _GLUTinputActionRec * inputARec = __glutGetSpaceballDeviceElement (action); |
if (NULL == pFirstDevice) |
pFirstDevice = pDevice; |
if (pDevice && pElement && (pFirstDevice == pDevice)) { // valid device and element and we match the same device |
// fill information in |
inputARec->pDevice = pDevice; |
inputARec->pElement = pElement; |
if ([actionDict objectForKey: GLUTDeviceInvertMulKey]) |
inputARec->invertMul = [[actionDict objectForKey: GLUTDeviceInvertMulKey] longValue]; |
else |
inputARec->invertMul = 1; |
} else { // device for action not found so blank current device |
inputARec->pDevice = NULL; |
inputARec->pElement = NULL; |
inputARec->invertMul = 1; |
} |
} |
} |
// ensure joystick and spaceball displays are set up |
[self joyElement:self]; |
[self spaceElement:self]; |
[self mouseEanbleEmulation:self]; // update display |
} |
- (void)updateUI: (NSDictionary *)prefsDefaults |
{ |
// read dictionanary and set as appropriate |
// set values and re-init (ensure to check to see if keyed object exists) |
[self updateLaunchUI:prefsDefaults]; |
[self updateDevicesUI:prefsDefaults]; |
} |
- (void)updateDevicesThread:(id)object |
{ |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
GLUTDeviceEnumerator enumer; |
__glutCollectInputDevices(); |
// update joystick menu |
[joyDeviceMenu removeAllItems]; |
__glutGetInputDeviceEnumeratorOfClass (GLUT_JOYSTICK_DEVICE, &enumer); |
pRecDevice pDevice = __glutGetNextInputDevice (&enumer); |
while (pDevice) { |
[joyDeviceMenu addItemWithTitle:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]; |
pDevice = __glutGetNextInputDevice (&enumer); |
} |
if (0 == [joyDeviceMenu numberOfItems]) // no devices found |
[joyDeviceMenu addItemWithTitle:NSLocalizedStringFromTableInBundle(@"No devices with 2+ axis found.", @"GLUTUI", __glutGetFrameworkBundle(), @"No devices with 2+ axis found.")]; |
// update spaceball menu |
[spaceDeviceMenu removeAllItems]; |
__glutGetInputDeviceEnumeratorOfClass (GLUT_SPACEBALL_DEVICE, &enumer); |
pDevice = __glutGetNextInputDevice (&enumer); |
while (pDevice) { |
[spaceDeviceMenu addItemWithTitle:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]; |
pDevice = __glutGetNextInputDevice (&enumer); |
} |
if (0 == [spaceDeviceMenu numberOfItems]) // no devices found |
[spaceDeviceMenu addItemWithTitle:NSLocalizedStringFromTableInBundle(@"No devices with 6+ axis found.", @"GLUTUI", __glutGetFrameworkBundle(), @"No devices with 6+ axis found.")]; |
// ensure the device list and assignments are up to date |
[self updateDevicesUI:[[NSUserDefaults standardUserDefaults] persistentDomainForName: GLUTPreferencesName]]; |
__glutUpdateJoystickInput (); |
pDevice = __glutGetJoystickDevice (); |
if (pDevice) |
[joyDeviceMenu selectItemWithTitle:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]; |
__glutUpdateSpaceballInput (); |
pDevice = __glutGetSpaceballDevice (); |
if (pDevice) |
[spaceDeviceMenu selectItemWithTitle:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]; |
updatingDevices = NO; |
[pool drain]; |
} |
- (void)waitForDevicesThread |
{ |
while( YES == updatingDevices ) |
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05f]]; |
} |
- (void)updateObjectState // after OK |
{ |
// everything joystick related is already set //ggs: fix me |
[self updateLaunchState]; |
[self updateMouseState]; |
} |
///////////////////////////////////////////// |
#pragma mark - |
#pragma mark Launch Section |
#pragma mark - |
- (IBAction)launchUseMacOSCoords:(id)sender |
{ |
// no action required |
} |
- (IBAction)launchUseCurrWD:(id)sender |
{ |
// no action required |
} |
- (IBAction)launchUseExtDesktop:(id)sender |
{ |
// no action required |
} |
- (IBAction)launchIconic:(id)sender |
{ |
// no action required |
} |
- (IBAction)launchDebugMode:(id)sender |
{ |
// no action required |
} |
- (IBAction)launchGamemodeCaptureSingle:(id)sender |
{ |
// no action required |
} |
- (void)updateLaunchState // after OK |
{ |
// set values and re-init |
__glutUseMacOSCoords = [launchUseMacOSXCoords state]; |
__glutUseInitWD = [launchUseCurrWD state]; |
__glutUseExtendedDesktop = [launchUseExtendedDesktop state]; |
// reset width and height in __glutEngineInit below |
__glutIconic = [launchIconic state]; |
__glutDebug = [launchDebugMode state]; |
if ([launchInitWidth intValue] > 0) |
__glutInitWidth = [launchInitWidth intValue]; |
if ([launchInitHeight intValue] > 0) |
__glutInitHeight = [launchInitHeight intValue]; |
if (NO == __glutUseMacOSCoords) { |
if([launchInitX intValue] >= 0) |
__glutInitX = [launchInitX intValue]; |
} else |
__glutInitX = [launchInitX intValue]; |
if (NO == __glutUseMacOSCoords) { |
if([launchInitY intValue] >= 0) |
__glutInitY = [launchInitY intValue]; |
} else |
__glutInitY = [launchInitY intValue]; |
__glutIdleTimeInterval = [launchMenuIdle floatValue]; |
__glutGameModeFadeInterval = [launchFadeTime floatValue]; |
__glutCaptureAllDisplays = 1 - [launchGamemodeCaptureSingle state]; |
__glutSyncToVBL = [launchSyncToVBL state]; |
__glutEngineInit (); // handles any set up glut engine needs |
} |
///////////////////////////////////////////// |
#pragma mark - |
#pragma mark Joystick Section |
#pragma mark - |
- (IBAction)joyDevice:(id)sender |
{ |
[joyAssignNote setStringValue:@" "]; |
[joyAssignNote display]; |
[joyAssignWarningIcon removeFromSuperview]; |
// reset all inputs for new device put up warning |
// find name and compare to current |
// if found slect and reset inputs |
// if not found post error and reset to default |
GLUTDeviceEnumerator enumer; |
NSString * title = [joyDeviceMenu titleOfSelectedItem]; |
__glutGetInputDeviceEnumeratorOfClass (GLUT_JOYSTICK_DEVICE, &enumer); |
pRecDevice pCurrentDevice = __glutGetJoystickDevice(), pFoundDevice = NULL, pDevice = __glutGetNextInputDevice (&enumer); |
while (pDevice && !pFoundDevice) { |
if (NSOrderedSame == [title compare:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]) |
pFoundDevice = pDevice; |
pDevice = __glutGetNextInputDevice (&enumer); |
} |
if (pCurrentDevice != pFoundDevice) { |
if (pFoundDevice) { |
__glutInitJoystickInput (pFoundDevice); |
[joyInputMenu selectItemAtIndex:0]; // reset position |
[self joyElement:self]; // force assigment update |
[joyDeviceMenu selectItemWithTitle:[NSString stringWithFormat:@"%s %s",pFoundDevice->manufacturer, pFoundDevice->product]]; |
[joyAssignNote setStringValue: NSLocalizedStringFromTableInBundle(@"New device select, all inputs reset.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"New device select, all inputs reset.")]; |
} else { // reset |
__glutInitJoystickInput (NULL); |
[joyInputMenu selectItemAtIndex:0]; // reset position |
[self joyElement:self]; // force assigment update |
pDevice = __glutGetJoystickDevice (); |
if (pDevice) |
[joyDeviceMenu selectItemWithTitle:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]; |
[joyAssignNote setStringValue: NSLocalizedStringFromTableInBundle(@"Selected device not found.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Selected device not found.")]; |
} |
[joyAssignNote display]; |
[joyTabItemView addSubview: joyAssignWarningIcon]; |
} |
} |
- (IBAction)joyAssign:(id)sender |
{ |
[joyAssignNote setStringValue:@" "]; |
[joyAssignNote display]; |
[joyAssignWarningIcon removeFromSuperview]; |
pRecDevice pDevice = NULL; |
pRecElement pElement = NULL; |
struct _GLUTinputActionRec * inputARec = __glutGetJoystickDeviceElement ([joyInputMenu indexOfSelectedItem]); |
if (inputARec && inputARec->pDevice) |
pDevice = inputARec->pDevice; |
else |
pDevice = __glutGetJoystickDevice (); |
// this currently does not accunt for restricting the input to axis or buttons |
if ([joyInputMenu indexOfSelectedItem] < kActionButton1) { |
[joyAssignNote setStringValue: [NSString stringWithFormat:@"%@ %s %@", |
NSLocalizedStringFromTableInBundle(@"Move", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Move"), |
pDevice->product, |
NSLocalizedStringFromTableInBundle(@"axis to assign.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"axis to assign.")]]; |
} else { |
[joyAssignNote setStringValue: [NSString stringWithFormat:@"%@ %s %@", |
NSLocalizedStringFromTableInBundle(@"Press", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Press"), |
pDevice->product, |
NSLocalizedStringFromTableInBundle(@"button to assign.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"button to assign.")]]; |
} |
[joyAssignNote display]; |
[joyAssignWarningIcon removeFromSuperview]; |
[joyElement setStringValue:NSLocalizedStringFromTableInBundle(@"Unassigned", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Unassigned")]; |
[joyElement display]; |
// assign to next input that moves on chosen device |
if (HIDConfigureSingleDeviceAction (pDevice, &pElement, 5.0)) { |
if (pElement) { |
inputARec->pDevice = pDevice; // ensure device is set |
inputARec->pElement = pElement; |
if ([joyInputMenu indexOfSelectedItem] < kActionButton1) { |
pElement->userMin = -1000; |
pElement->userMax = 1000; |
} else { |
pElement->userMin = 0; |
pElement->userMax = 1; |
} |
} |
[self joyElement:self]; // force assigment update |
} else { |
[self joyElement:self]; // force assigment update |
[joyAssignNote setStringValue: [NSString stringWithFormat:@"%@ %s", |
NSLocalizedStringFromTableInBundle(@"Please choose input on", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Please choose input on"), |
pDevice->product]]; |
[joyAssignNote display]; |
[joyTabItemView addSubview: joyAssignWarningIcon]; |
} |
} |
- (IBAction)joyElement:(id)sender |
{ |
[joyAssignNote setStringValue:@" "]; |
[joyAssignNote display]; |
[joyAssignWarningIcon removeFromSuperview]; |
// get menu item and update string |
NSString * outString; |
struct _GLUTinputActionRec * inputARec = __glutGetJoystickDeviceElement ([joyInputMenu indexOfSelectedItem]); |
if (inputARec && inputARec->pDevice) { |
[joyInverted setEnabled:YES]; |
[joyElement setEnabled:YES]; |
[joyInputMenu setEnabled:YES]; |
[joyAssign setEnabled:YES]; |
if (inputARec->pElement) { |
outString = [[NSString alloc] initWithFormat: @"%s",inputARec->pElement->name]; |
// this is normally supplied by the device and cannot be simply localized |
// set inverted check |
[joyInverted setIntValue: ((-inputARec->invertMul + 1) / 2)]; // so -1 = checked and 1 = not checked |
} else { |
outString = [[NSString alloc] initWithFormat:NSLocalizedStringFromTableInBundle(@"No device input assigned.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"No device input assigned.")]; |
} |
} else { |
outString = [[NSString alloc] initWithFormat:NSLocalizedStringFromTableInBundle(@"No device.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"No device.")]; |
[joyInverted setEnabled:NO]; |
[joyElement setEnabled:NO]; |
[joyInputMenu setEnabled:NO]; |
[joyAssign setEnabled:NO]; |
} |
[joyElement setStringValue:outString]; |
} |
- (IBAction)joyInvert:(id)sender |
{ |
struct _GLUTinputActionRec * inputARec = __glutGetJoystickDeviceElement ([joyInputMenu indexOfSelectedItem]); |
inputARec->invertMul = -[joyInverted intValue] * 2 + 1; // so checked = -1 and not checked = 1 |
} |
///////////////////////////////////////////// |
#pragma mark - |
#pragma mark Spaceball Section |
#pragma mark - |
- (IBAction)spaceDevice:(id)sender |
{ |
[spaceAssignNote setStringValue:@" "]; |
[spaceAssignNote display]; |
[spaceAssignWarningIcon removeFromSuperview]; |
// reset all inputs for new device put up warning |
// find name and compare to current |
// if found slect and reset inputs |
// if not found post error and reset to default |
GLUTDeviceEnumerator enumer; |
NSString * title = [spaceDeviceMenu titleOfSelectedItem]; |
__glutGetInputDeviceEnumeratorOfClass (GLUT_SPACEBALL_DEVICE, &enumer); |
pRecDevice pCurrentDevice = __glutGetSpaceballDevice(), pFoundDevice = NULL, pDevice = __glutGetNextInputDevice (&enumer); |
while (pDevice && !pFoundDevice) { |
if (NSOrderedSame == [title compare:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]) |
pFoundDevice = pDevice; |
pDevice = __glutGetNextInputDevice (&enumer); |
} |
if (pCurrentDevice != pFoundDevice) { |
if (pFoundDevice) { |
__glutInitSpaceballInput (pFoundDevice); |
[spaceInputMenu selectItemAtIndex:0]; // reset position |
[self spaceElement:self]; // force assigment update |
[spaceDeviceMenu selectItemWithTitle:[NSString stringWithFormat:@"%s %s",pFoundDevice->manufacturer, pFoundDevice->product]]; |
[spaceAssignNote setStringValue: NSLocalizedStringFromTableInBundle(@"New device select, all inputs reset.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"New device select, all inputs reset.")]; |
} else { // reset |
__glutInitSpaceballInput (NULL); |
[spaceInputMenu selectItemAtIndex:0]; // reset position |
[self spaceElement:self]; // force assigment update |
pDevice = __glutGetSpaceballDevice (); |
if (pDevice) |
[spaceDeviceMenu selectItemWithTitle:[NSString stringWithFormat:@"%s %s",pDevice->manufacturer, pDevice->product]]; |
[spaceAssignNote setStringValue: NSLocalizedStringFromTableInBundle(@"Selected device not found.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Selected device not found.")]; |
} |
[spaceAssignNote display]; |
[spaceTabItemView addSubview: spaceAssignWarningIcon]; |
} |
} |
- (IBAction)spaceAssign:(id)sender |
{ |
[spaceAssignNote setStringValue:@" "]; |
[spaceAssignNote display]; |
[spaceAssignWarningIcon removeFromSuperview]; |
pRecDevice pDevice = NULL; |
pRecElement pElement = NULL; |
struct _GLUTinputActionRec * inputARec = __glutGetSpaceballDeviceElement ([spaceInputMenu indexOfSelectedItem]); |
if (inputARec && inputARec->pDevice) |
pDevice = inputARec->pDevice; |
else |
pDevice = __glutGetSpaceballDevice (); |
// this currently does not accunt for restricting the input to axis or buttons |
if ([spaceInputMenu indexOfSelectedItem] < kActionButton1) { |
[spaceAssignNote setStringValue: [NSString stringWithFormat:@"%@ %s %@", |
NSLocalizedStringFromTableInBundle(@"Move", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Move"), |
pDevice->product, |
NSLocalizedStringFromTableInBundle(@"axis to assign.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"axis to assign.")]]; |
} else { |
[spaceAssignNote setStringValue: [NSString stringWithFormat:@"%@ %s %@", |
NSLocalizedStringFromTableInBundle(@"Press", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Press"), |
pDevice->product, |
NSLocalizedStringFromTableInBundle(@"button to assign.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"button to assign.")]]; |
} |
[spaceAssignNote display]; |
[spaceAssignWarningIcon removeFromSuperview]; |
[spaceElement setStringValue:NSLocalizedStringFromTableInBundle(@"Unassigned", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Unassigned")]; |
[spaceElement display]; |
// assign to next input that moves on chosen device |
if (HIDConfigureSingleDeviceAction (pDevice, &pElement, 5.0)) { |
if (pElement) { |
inputARec->pDevice = pDevice; // ensure device is set |
inputARec->pElement = pElement; |
if ([spaceInputMenu indexOfSelectedItem] < kSBActionXRotation) { |
pElement->userMin = -1000; |
pElement->userMax = 1000; |
} else if ([spaceInputMenu indexOfSelectedItem] < kSBActionButton1) { |
pElement->userMin = -1800; |
pElement->userMax = 1800; |
} else { |
pElement->userMin = 0; |
pElement->userMax = 1; |
} |
} |
[self spaceElement:self]; // force assigment update |
} else { |
[self spaceElement:self]; // force assigment update |
[spaceAssignNote setStringValue: [NSString stringWithFormat:@"%@ %s", |
NSLocalizedStringFromTableInBundle(@"Please choose input on", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Please choose input on"), |
pDevice->product]]; |
[spaceAssignNote display]; |
[spaceTabItemView addSubview: spaceAssignWarningIcon]; |
} |
} |
- (IBAction)spaceElement:(id)sender |
{ |
[spaceAssignNote setStringValue:@" "]; |
[spaceAssignNote display]; |
[spaceAssignWarningIcon removeFromSuperview]; |
// get menu item and update string |
NSString * outString; |
struct _GLUTinputActionRec * inputARec = __glutGetSpaceballDeviceElement ([spaceInputMenu indexOfSelectedItem]); |
if (inputARec && inputARec->pDevice) { |
[spaceInverted setEnabled:YES]; |
[spaceElement setEnabled:YES]; |
[spaceInputMenu setEnabled:YES]; |
[spaceAssign setEnabled:YES]; |
if (inputARec->pElement) { |
outString = [[NSString alloc] initWithFormat: @"%s",inputARec->pElement->name]; |
// this is normally supplied by the device and cannot be simply localized |
// set inverted check |
[spaceInverted setIntValue: ((-inputARec->invertMul + 1) / 2)]; // so -1 = checked and 1 = not checked |
} else { |
outString = [[NSString alloc] initWithFormat:NSLocalizedStringFromTableInBundle(@"No device input assigned.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"No device input assigned.")]; |
} |
} else { |
outString = [[NSString alloc] initWithFormat:NSLocalizedStringFromTableInBundle(@"No device.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"No device.")]; |
[spaceInverted setEnabled:NO]; |
[spaceElement setEnabled:NO]; |
[spaceInputMenu setEnabled:NO]; |
[spaceAssign setEnabled:NO]; |
} |
[spaceElement setStringValue:outString]; |
} |
- (IBAction)spaceInvert:(id)sender |
{ |
struct _GLUTinputActionRec * inputARec = __glutGetSpaceballDeviceElement ([spaceInputMenu indexOfSelectedItem]); |
if (inputARec) |
inputARec->invertMul = -[spaceInverted intValue] * 2 + 1; // so checked = -1 and not checked = 1 |
} |
///////////////////////////////////////////// |
#pragma mark - |
#pragma mark Mouse Section |
#pragma mark - |
- (IBAction)mouseEanbleEmulation:(id)sender |
{ |
[mouseAssignWarningText setStringValue: @" "]; |
[mouseAssignWarningText display]; |
[mouseAssignWarningIcon removeFromSuperview]; |
if ([mouseEmulation state]) { |
[mouseRightConfigMenu setEnabled:YES]; |
[mouseMiddleConfigMenu setEnabled:YES]; |
} else { |
[mouseRightConfigMenu setEnabled:NO]; |
[mouseMiddleConfigMenu setEnabled:NO]; |
} |
} |
- (IBAction)mouseMiddleMenu:(id)sender |
{ |
[mouseAssignWarningText setStringValue: @" "]; |
[mouseAssignWarningText display]; |
[mouseAssignWarningIcon removeFromSuperview]; |
if ([mouseRightConfigMenu indexOfSelectedItem] == [mouseMiddleConfigMenu indexOfSelectedItem]) { |
// can't be the same |
[mouseAssignWarningText setStringValue: [NSString stringWithFormat:@"%@", |
NSLocalizedStringFromTableInBundle(@"Button modifiers must not be the same.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Button modifiers must not be the same.")]]; |
[mouseAssignWarningText display]; |
[mouseTabItemView addSubview: mouseAssignWarningIcon]; |
[mouseMiddleConfigMenu selectItemAtIndex: (([mouseRightConfigMenu indexOfSelectedItem] + 1) % 4)]; |
} |
} |
- (IBAction)mouseRightMenu:(id)sender |
{ |
[mouseAssignWarningText setStringValue: @" "]; |
[mouseAssignWarningText display]; |
[mouseAssignWarningIcon removeFromSuperview]; |
if ([mouseRightConfigMenu indexOfSelectedItem] == [mouseMiddleConfigMenu indexOfSelectedItem]) { |
// can't be the same |
[mouseAssignWarningText setStringValue: [NSString stringWithFormat:@"%@", |
NSLocalizedStringFromTableInBundle(@"Button modifiers must not be the same.", @"GLUTUI", |
__glutGetFrameworkBundle(), |
@"Button modifiers must not be the same.")]]; |
[mouseAssignWarningText display]; |
[mouseTabItemView addSubview: mouseAssignWarningIcon]; |
[mouseRightConfigMenu selectItemAtIndex: (([mouseMiddleConfigMenu indexOfSelectedItem] + 1) % 4)]; |
} |
} |
- (void)updateMouseState |
{ |
__glutEmulateMouseButtons = [mouseEmulation state]; |
__glutMouseFirstModifiers = [self indexToModifier:[mouseRightConfigMenu indexOfSelectedItem]]; |
__glutMouseSecondModifiers = [self indexToModifier:[mouseMiddleConfigMenu indexOfSelectedItem]]; |
} |
- (int) modifierToIndex:(unsigned int)modifier |
{ |
// dialog order Control Option Command Shift |
switch (modifier) { |
case NSControlKeyMask: |
return 0; |
break; |
case NSAlternateKeyMask: |
return 1; |
break; |
case NSCommandKeyMask: |
return 2; |
break; |
case NSShiftKeyMask: |
return 3; |
break; |
default: |
return 0; |
} |
} |
- (unsigned int) indexToModifier:(int)buttonIndex |
{ |
// dialog order Control Option Command Shift |
switch (buttonIndex) { |
case 0: |
return NSControlKeyMask; |
break; |
case 1: |
return NSAlternateKeyMask; |
break; |
case 2: |
return NSCommandKeyMask; |
break; |
case 3: |
return NSShiftKeyMask; |
break; |
default: |
return 0; |
} |
} |
@end |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-08