+++ /dev/null
-//
-// HotKeyCenter.m
-//
-// Created by Quentin D. Carnicelli on Thu Jun 06 2002.
-// Copyright (c) 2002 Subband inc.. All rights reserved.
-//
-// Feedback welcome at qdc@subband.com
-// This code is provided AS IS, so don't hurt yourself with it...
-//
-
-#import "HotKeyCenter.h"
-#import "KeyCombo.h"
-
-#import <Carbon/Carbon.h>
-
-#define kHotKeyCenterSignature 'HKyC'
-
-//*** _HotKeyData
-@interface _HotKeyData : NSObject
-{
- @public
- BOOL mRegistered;
- EventHotKeyRef mRef;
- KeyCombo *mCombo;
- id mTarget;
- SEL mAction;
-}
-@end
-
-@implementation _HotKeyData
-@end
-
-//**** HotKeyCenter
-@interface HotKeyCenter (Private)
- - (OSStatus)handleHotKeyEvent: (EventRef)inEvent;
-
- - (BOOL)_registerHotKeyIfNeeded:(_HotKeyData *)hk;
- - (void)_unregisterHotKeyIfNeeded:(_HotKeyData *)hk;
-
- + (BOOL)_systemSupportsHotKeys;
- - (void)_hotKeyUp:(_HotKeyData *)hotKey;
- - (void)_hotKeyDown:(_HotKeyData *)hotKey;
- - (void)_hotKeyDownWithRef:(EventHotKeyRef)ref;
- - (void)_hotKeyUpWithRef:(EventHotKeyRef)ref;
- - (_HotKeyData*)_findHotKeyWithRef:(EventHotKeyRef)ref;
-
- pascal OSErr keyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *refCon);
-@end
-
-@implementation HotKeyCenter
-
-static id _sharedHKCenter = nil;
-
-+ (id)sharedCenter
-{
- if (_sharedHKCenter != nil)
- {
- return _sharedHKCenter;
- }
-
- _sharedHKCenter = [[HotKeyCenter alloc] init];
-
- if ([self _systemSupportsHotKeys])
- {
- EventTypeSpec eventSpec[2] =
- {
- { kEventClassKeyboard, kEventHotKeyPressed },
- { kEventClassKeyboard, kEventHotKeyReleased }
- };
-
- InstallEventHandler( GetEventDispatcherTarget(), NewEventHandlerUPP((EventHandlerProcPtr) keyEventHandler), 2, eventSpec, nil, nil);
- }
-
- return _sharedHKCenter;
-}
-
-- (id)init
-{
- if ( (self = [super init]) )
- {
- mEnabled = YES;
- mHotKeys = [[NSMutableDictionary alloc] init];
- }
- return self;
-}
-
-- (void)dealloc
-{
- [mHotKeys release];
- [super dealloc];
-}
-
-- (BOOL)addHotKey:(NSString *)name combo:(KeyCombo *)combo target:(id)target action:(SEL)action
-{
- _HotKeyData *oldHotKey;
- _HotKeyData *newHotKey;
-
- NSParameterAssert(name != nil);
- NSParameterAssert(combo != nil);
- NSParameterAssert(target != nil);
- NSParameterAssert(action != nil);
-
- //** Check if we have one of these yet
- oldHotKey = [mHotKeys objectForKey:name];
-
- if (oldHotKey) //Registered already?
- {
- [self removeHotKey:name];
- }
-
- //** Save the hot key to our own list
- newHotKey = [[[_HotKeyData alloc] init] autorelease];
- newHotKey->mRegistered = NO;
- newHotKey->mRef = nil;
- newHotKey->mCombo = [combo retain];
- newHotKey->mTarget = target; //Retain this?
- newHotKey->mAction = action;
-
- [mHotKeys setObject:newHotKey forKey:name];
-
- return [self _registerHotKeyIfNeeded:newHotKey];
-}
-
-- (void)removeHotKey:(NSString *)name;
-{
- _HotKeyData *hotKey;
-
- hotKey = [mHotKeys objectForKey:name];
- if (hotKey == nil) //Not registered
- return;
-
- [self _unregisterHotKeyIfNeeded:hotKey];
- [hotKey->mCombo release];
-
- //Drop it from our hot key list
- [mHotKeys removeObjectForKey: name];
-}
-
-- (NSArray *)allNames
-{
- return [mHotKeys allKeys];
-}
-
-- (KeyCombo *)keyComboForName:(NSString *)name
-{
- _HotKeyData * hotKey;
-
- hotKey = [mHotKeys objectForKey:name];
- if( hotKey == nil ) //Not registered
- return nil;
-
- return hotKey->mCombo;
-}
-
-- (void)setEnabled:(BOOL)enabled
-{
- NSEnumerator *enumerator;
- _HotKeyData *hotKey;
-
- enumerator = [mHotKeys objectEnumerator];
-
- while ((hotKey = [enumerator nextObject]) != nil)
- {
- if (enabled)
- [self _registerHotKeyIfNeeded:hotKey];
- else
- [self _unregisterHotKeyIfNeeded:hotKey];
- }
-
- mEnabled = enabled;
-}
-
-- (BOOL)enabled
-{
- return mEnabled;
-}
-
-- (void)sendEvent:(NSEvent *)event;
-{
- long subType;
- EventHotKeyRef hotKeyRef;
-
- //We only have to intercept sendEvent to do hot keys on old system versions
- if ([HotKeyCenter _systemSupportsHotKeys] == YES)
- return;
-
- if ([event type] == NSSystemDefined)
- {
- subType = [event subtype];
-
- if (subType == 6) //6 is hot key down
- {
- hotKeyRef = (EventHotKeyRef)[event data1]; //data1 is our hot key ref
- if (hotKeyRef != nil)
- {
- [self _hotKeyDownWithRef:hotKeyRef];
- }
- }
- else if (subType == 9) //9 is hot key up
- {
- hotKeyRef = (EventHotKeyRef)[event data1];
- if (hotKeyRef != nil)
- {
- [self _hotKeyUpWithRef:hotKeyRef];
- }
- }
- }
-}
-
-- (OSStatus)handleHotKeyEvent:(EventRef)inEvent
-{
- OSStatus err;
- EventHotKeyID hotKeyID;
- _HotKeyData *hk;
-
- //Shouldnt get here on non-hotkey supporting system versions
- NSAssert([HotKeyCenter _systemSupportsHotKeys] == YES, @"");
- NSAssert(GetEventClass(inEvent) == kEventClassKeyboard, @"Got unhandled event class");
-
- err = GetEventParameter(inEvent, kEventParamDirectObject, typeEventHotKeyID, nil, sizeof(EventHotKeyID), nil, &hotKeyID);
-
- if (err)
- {
- return err;
- }
-
- NSAssert(hotKeyID.signature == kHotKeyCenterSignature, @"Got unknown hot key");
-
- hk = (_HotKeyData *)hotKeyID.id;
- NSAssert(hk != nil, @"Got bad hot key");
-
- switch (GetEventKind(inEvent))
- {
- case kEventHotKeyPressed:
- [self _hotKeyDown:hk];
- break;
-
- case kEventHotKeyReleased:
- [self _hotKeyUp:hk];
- break;
-
- default:
- break;
- }
-
- return noErr;
-}
-
-+ (BOOL)_systemSupportsHotKeys
-{
- SInt32 vers;
- Gestalt(gestaltSystemVersion,&vers);
- return (vers >= 0x00001020);
-}
-
-- (BOOL)_registerHotKeyIfNeeded:(_HotKeyData *)hk
-{
- KeyCombo *combo;
-
- NSParameterAssert(hk != nil);
-
- combo = hk->mCombo;
-
- if( mEnabled == YES && hk->mRegistered == NO && [combo isValid] == YES )
- {
- EventHotKeyID keyID;
- OSStatus err;
-
- keyID.signature = kHotKeyCenterSignature;
- keyID.id = (unsigned long)hk;
- err = RegisterEventHotKey([combo keyCode], [combo modifiers],
- keyID, GetEventDispatcherTarget(), 0, &hk->mRef);
- if (err)
- {
- return NO;
- }
-
- hk->mRegistered = YES;
- }
-
- return YES;
-}
-
-- (void)_unregisterHotKeyIfNeeded:(_HotKeyData *)hk
-{
- NSParameterAssert(hk != nil);
-
- if (hk->mRegistered && hk->mRef != nil)
- {
- UnregisterEventHotKey(hk->mRef);
- }
-}
-
-- (void)_hotKeyDown:(_HotKeyData *)hotKey
-{
- id target = hotKey->mTarget;
- SEL action = hotKey->mAction;
- [target performSelector:action withObject:self];
-}
-
-- (void)_hotKeyUp: (_HotKeyData *)hotKey
-{
-}
-
-- (void)_hotKeyDownWithRef:(EventHotKeyRef)ref
-{
- _HotKeyData *hotKey;
-
- hotKey = [self _findHotKeyWithRef:ref];
- if (hotKey)
- {
- [self _hotKeyDown:hotKey];
- }
-}
-
-- (void)_hotKeyUpWithRef:(EventHotKeyRef)ref
-{
-}
-
-- (_HotKeyData *)_findHotKeyWithRef:(EventHotKeyRef)ref
-{
- NSEnumerator *enumerator;
- _HotKeyData *hotKey;
-
- enumerator = [mHotKeys objectEnumerator];
-
- while ((hotKey = [enumerator nextObject]) != nil)
- {
- if (hotKey->mRef == ref)
- {
- return hotKey;
- }
- }
-
- return nil;
-}
-
-pascal OSErr keyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *refCon)
-{
- return [[HotKeyCenter sharedCenter] handleHotKeyEvent:inEvent];
-}
-
-@end
-
+++ /dev/null
-#import "KeyBroadcaster.h"
-#import <Carbon/Carbon.h>
-
-@interface KeyBroadcaster (Private)
-- (void)_broadcastKeyCode:(short)keyCode andModifiers:(long)modifiers;
-@end
-
-@implementation KeyBroadcaster
-
-- (void)keyDown:(NSEvent *)event
-{
- short keyCode;
- long modifiers;
-
- keyCode = [event keyCode];
- modifiers = [event modifierFlags];
-
- modifiers = [KeyBroadcaster cocoaToCarbonModifiers:modifiers];
- if (modifiers > 0) {
- [self _broadcastKeyCode:keyCode andModifiers:modifiers];
- }
-}
-
-- (BOOL)performKeyEquivalent:(NSEvent *)event
-{
- [self keyDown:event];
- return YES;
-}
-
-- (void)_broadcastKeyCode:(short)keyCode andModifiers:(long)modifiers
-{
- NSNumber *keycodeNum = [NSNumber numberWithShort:keyCode];
- NSNumber *modifiersNum = [NSNumber numberWithLong:modifiers];
- NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:
- keycodeNum, @"KeyCode", modifiersNum, @"Modifiers", nil, nil];
- [[NSNotificationCenter defaultCenter] postNotificationName:@"KeyBroadcasterEvent" object:self userInfo:info];
-}
-
-+ (long)cocoaToCarbonModifiers:(long)modifiers
-{
- long carbonModifiers = 0;
- int i;
- static long cocoaToCarbon[6][2] =
- {
- { NSCommandKeyMask, cmdKey },
- { NSAlternateKeyMask, optionKey },
- { NSControlKeyMask, controlKey },
- { NSShiftKeyMask, shiftKey },
- };
- for (i = 0; i < 6; i++)
- {
- if (modifiers & cocoaToCarbon[i][0])
- {
- carbonModifiers += cocoaToCarbon[i][1];
- }
- }
- return carbonModifiers;
-}
-
-@end
+++ /dev/null
-//
-// KeyCombo.m
-//
-// Created by Quentin D. Carnicelli on Tue Jun 18 2002.
-// Copyright (c) 2001 Subband inc.. All rights reserved.
-//
-
-#import "KeyCombo.h"
-
-#import <AppKit/NSEvent.h>
-#import <Carbon/Carbon.h>
-
-@interface KeyCombo (Private)
- + (NSString*)_stringForModifiers:(long)modifiers;
- + (NSString*)_stringForKeyCode:(short)keyCode;
-@end
-
-
-@implementation KeyCombo
-
-+ (id)keyCombo
-{
- return [[[self alloc] init] autorelease];
-}
-
-+ (id)clearKeyCombo
-{
- return [self keyComboWithKeyCode:-1 andModifiers:-1];
-}
-
-+ (id)keyComboWithKeyCode: (short)keycode andModifiers: (long)modifiers
-{
- return [[[self alloc] initWithKeyCode:keycode andModifiers:modifiers] autorelease];
-}
-
-- (id)initWithKeyCode: (short)keycode andModifiers: (long)modifiers
-{
- if ( (self = [super init]) )
- {
- mKeyCode = keycode;
- mModifiers = modifiers;
- }
- return self;
-}
-
-- (id)init
-{
- return [self initWithKeyCode: -1 andModifiers: -1];
-}
-
-- (id)copyWithZone:(NSZone *)zone;
-{
- return [self retain];
-}
-
-- (id)initWithCoder:(NSCoder *)aDecoder
-{
- if ( (self = [super init]) ) {
- [aDecoder decodeValueOfObjCType: @encode(short) at: &mKeyCode];
- [aDecoder decodeValueOfObjCType: @encode(long) at: &mModifiers];
- }
-
- return self;
-}
-
-- (void)encodeWithCoder:(NSCoder *)aCoder
-{
- [aCoder encodeValueOfObjCType:@encode(short) at:&mKeyCode];
- [aCoder encodeValueOfObjCType:@encode(long) at:&mModifiers];
-}
-
-- (BOOL)isEqual:(KeyCombo *)object
-{
- return ( ([object isKindOfClass:[KeyCombo class]]) &&
- ([object keyCode] == [self keyCode]) &&
- ([object modifiers] == [self modifiers]) );
-}
-
-- (NSString *)description
-{
- return [self userDisplayRep];
-}
-
-- (short)keyCode
-{
- return mKeyCode;
-}
-
-- (short)modifiers
-{
- return mModifiers;
-}
-
-- (BOOL)isValid
-{
- return ((mKeyCode >= 0) && (mModifiers >= 0));
-}
-
-- (NSString *)userDisplayRep
-{
- if ( ! [self isValid] ) {
- return @"";
- } else {
- return [NSString stringWithFormat: @"%@%@",
- [KeyCombo _stringForModifiers: mModifiers],
- [KeyCombo _stringForKeyCode: mKeyCode]];
- }
-}
-
-+ (NSString *)_stringForModifiers: (long)modifiers
-{
- static long modToChar[4][2] = {
- { cmdKey, 0x23180000 },
- { optionKey, 0x23250000 },
- { controlKey, 0x23030000 },
- { shiftKey, 0x21e70000 }
- };
-
- NSString *str = [NSString string];
- NSString *charStr;
- long i;
-
- for (i = 0; i < 4; i++) {
- if (modifiers & modToChar[i][0]) {
- charStr = [NSString stringWithCharacters:(const unichar *)&modToChar[i][1] length:1];
- str = [str stringByAppendingString:charStr];
- }
- }
-
- return str;
-}
-
-+ (NSString *)_stringForKeyCode:(short)keyCode
-{
- NSDictionary *dict;
- id key;
- NSString *str;
-
- dict = [self keyCodesDictionary];
- key = [NSString stringWithFormat: @"%d", keyCode];
- str = [dict objectForKey: key];
-
- if( !str ) {
- str = [NSString stringWithFormat: @"%X", keyCode];
- }
-
- return str;
-}
-
-+ (NSDictionary *)keyCodesDictionary
-{
- static NSDictionary *keyCodes = nil;
-
- if (keyCodes == nil) {
- NSString *path;
- NSString *contents;
-
- path = [[NSBundle bundleForClass: [KeyCombo class]] pathForResource: @"KeyCodes" ofType: @"plist"];
-
- contents = [NSString stringWithContentsOfFile: path];
- keyCodes = [[contents propertyList] retain];
- }
-
- return keyCodes;
-}
-
-@end
-
-@implementation NSUserDefaults (KeyComboAdditions)
-
-- (void)setKeyCombo:(KeyCombo *)combo forKey:(NSString *)key
-{
- NSData *data;
- if (combo) {
- data = [NSArchiver archivedDataWithRootObject:combo];
- } else {
- data = nil;
- }
- [self setObject:data forKey:key];
-}
-
-- (KeyCombo *)keyComboForKey:(NSString *)key
-{
- NSData *data = [self objectForKey:key];
- KeyCombo *combo;
-
- if (data) {
- combo = [NSUnarchiver unarchiveObjectWithData:data];
- } else {
- combo = nil;
- }
-
- return combo;
-}
-
-@end
-
-
-
-
-