X-Git-Url: http://git.ithinksw.org/MenuTunes.git/blobdiff_plain/796f8360ac05b39085aef9f202f635a04ba6834e..081a5fa6db149252a499575da751c45f340312bd:/iTunesRemote.m diff --git a/iTunesRemote.m b/iTunesRemote.m index 5bab47e..5781211 100755 --- a/iTunesRemote.m +++ b/iTunesRemote.m @@ -1,353 +1,106 @@ +/* Copyright (c) 2002 - 2003 by iThink Software. All Rights Reserved. */ + #import "iTunesRemote.h" + @implementation iTunesRemote -+ (id)remote -{ ++ (id)remote { return [[[iTunesRemote alloc] init] autorelease]; } -- (NSString *)title -{ - return @"iTunes Plug-in"; -} - -- (NSString *)information; -{ - return @"Default MenuTunes plugin to control iTunes. Written by iThink Software."; -} - -- (NSImage *)icon -{ +- (id)valueOfProperty:(ITMTRemoteProperty)property { + // Get from Info.plist return nil; } -- (BOOL)begin -{ - iTunesPSN = [self iTunesPSN]; - - //We won't need this once we're pure AEs - asComponent = OpenDefaultComponent(kOSAComponentType, kAppleScriptSubtype); - - //Register for application termination in NSWorkspace - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; - - return YES; +- (NSDictionary *)propertiesAndValues { + // Get from Info.plist + return nil; } -- (BOOL)halt -{ - iTunesPSN.highLongOfPSN = kNoProcess; - - //We won't need this once we're pure AEs - CloseComponent(asComponent); - - //Unregister for application termination in NSWorkspace - [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; - - return YES; +- (ITMTPlayerStyle)playerStyle { + return ITMTSinglePlayerStyle; } -- (BOOL)isAppRunning -{ - NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications]; - int i; - - for (i = 0; i < [apps count]; i++) { - if ([[[apps objectAtIndex:i] objectForKey:@"NSApplicationName"] - isEqualToString:@"iTunes"]) { +- (BOOL)activate { + if ( !_activated ) { + if ( [self iTunesIsRunning] ) { + _currentPSN = [self iTunesPSN]; + } else { + if ( [self launchiTunes] ) { + _currentPSN = [self iTunesPSN]; + } else { + return NO; + } + } + if ( ( _player = [iTunesPlayer sharedPlayerForRemote:self] ) ) { + _activated = YES; return YES; } + } else { + return NO; } - return NO; } -- (PlayerState)playerState -{ - NSString *result = [self runScriptAndReturnResult:@"get player state"]; - - if ([result isEqualToString:@"playing"]) { - return playing; - } else if ([result isEqualToString:@"paused"]) { - return paused; - } else if ([result isEqualToString:@"stopped"]) { - return stopped; - } else if ([result isEqualToString:@"rewinding"]) { - return rewinding; - } else if ([result isEqualToString:@"fast forwarding"]) { - return forwarding; +- (BOOL)deactivate { + if ( _activated ) { + _currentPSN = kNoProcess; + _player = nil; + _activated = NO; + return YES; + } else { + return NO; } - - return stopped; } -- (NSArray *)playlists -{ - int i; - int numPresets = [[self runScriptAndReturnResult:@"get number of playlists"] intValue]; - NSMutableArray *presets = [[NSMutableArray alloc] init]; - for (i = 1; i <= numPresets; i++) { - [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of playlist %i", i]]]; +- (ITMTPlayer *)currentPlayer { + if (_activated) { + return _player; + } else { + return nil; } - - return [NSArray arrayWithArray:presets]; -} - -- (int)numberOfSongsInPlaylistAtIndex:(int)index -{ - NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get number of tracks in playlist %i", index]]; - return [result intValue]; -} - -- (NSString *)classOfPlaylistAtIndex:(int)index -{ - //Not working yet. It returns the 4 character code instead of a name. - /*NSString *result; - result = [[ITAppleEventCenter sharedCenter] - sendTwoTierAEWithRequestedKey:@"pcls" - fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]];*/ - NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get class of playlist %i", index]]; - return result; -} - -- (int)currentPlaylistIndex -{ - int result; - result = [[ITAppleEventCenter sharedCenter] - sendTwoTierAEWithRequestedKeyForNumber:@"pidx" - fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; - return result; -} - -- (NSString *)songTitleAtIndex:(int)index -{ - NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of track %i of current playlist", index]]; - return result; -} - -- (int)currentSongIndex -{ - int result; - result = [[ITAppleEventCenter sharedCenter] - sendTwoTierAEWithRequestedKeyForNumber:@"pidx" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; - return result; -} - -- (NSString *)currentSongTitle -{ - return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pnam" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; -} - -- (NSString *)currentSongArtist -{ - return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pArt" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; -} - -- (NSString *)currentSongAlbum -{ - return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pAlb" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; -} - -- (NSString *)currentSongGenre -{ - return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pGen" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; -} - -- (NSString *)currentSongLength -{ - return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pTim" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; } -- (NSString *)currentSongRemaining -{ - long duration = [[ITAppleEventCenter sharedCenter] - sendTwoTierAEWithRequestedKeyForNumber:@"pDur" - fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; - long current = [[ITAppleEventCenter sharedCenter] - sendAEWithRequestedKeyForNumber:@"pPos" - eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; - - return [[NSNumber numberWithLong:duration - current] stringValue]; -} - -- (NSArray *)eqPresets; -{ - int i; - int numPresets = [[self runScriptAndReturnResult:@"get number of EQ presets"] intValue]; - NSMutableArray *presets = [[NSMutableArray alloc] init]; - - for (i = 1; i <= numPresets; i++) { - [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of EQ preset %i", i]]]; +- (NSArray *)players { + if (_activated) { + return [NSArray arrayWithObject:_player]; + } else { + return nil; } - - return [NSArray arrayWithArray:presets]; -} - -- (int)currentEQPresetIndex -{ - int result; - result = [[ITAppleEventCenter sharedCenter] - sendTwoTierAEWithRequestedKeyForNumber:@"pidx" - fromObjectByKey:@"pEQP" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; - return result; -} - -- (BOOL)play -{ - [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Play" - appPSN:[self iTunesPSN]]; - return YES; -} - -- (BOOL)pause -{ - [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Paus" - appPSN:[self iTunesPSN]]; - return YES; -} - -- (BOOL)goToNextSong -{ - [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Next" - appPSN:[self iTunesPSN]]; - return YES; -} - -- (BOOL)goToPreviousSong -{ - [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Prev" - appPSN:[self iTunesPSN]]; - return YES; -} - -- (BOOL)fastForward -{ - [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Fast" - appPSN:[self iTunesPSN]]; - return YES; -} - -- (BOOL)rewind -{ - [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Rwnd" - appPSN:[self iTunesPSN]]; - return YES; } +#pragma mark - +#pragma mark INTERNAL METHODS +#pragma mark - -- (BOOL)switchToPlaylistAtIndex:(int)index -{ - [self runScriptAndReturnResult:[NSString stringWithFormat: - @"play playlist %i", index]]; - return NO; -} - -- (BOOL)switchToSongAtIndex:(int)index -{ - [self runScriptAndReturnResult:[NSString stringWithFormat: - @"play track %i of current playlist", index]]; +- (BOOL)launchiTunes { return NO; } -- (BOOL)switchToEQAtIndex:(int)index -{ - [self runScriptAndReturnResult:[NSString stringWithFormat: - @"set current EQ preset to EQ preset %i", index]]; - [self runScriptAndReturnResult:@"set EQ enabled to 1"]; +- (BOOL)iTunesIsRunning { return NO; } - (ProcessSerialNumber)iTunesPSN { - NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications]; ProcessSerialNumber number; - int i; - number.highLongOfPSN = kNoProcess; + number.lowLongOfPSN = 0; - for (i = 0; i < [apps count]; i++) + while ( (GetNextProcess(&number) == noErr) ) { - NSDictionary *curApp = [apps objectAtIndex:i]; - - if ([[curApp objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"]) + CFStringRef name; + if ( (CopyProcessName(&number, &name) == noErr) ) { - number.highLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberHigh"] intValue]; - number.lowLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberLow"] intValue]; + if ([(NSString *)name isEqualToString:@"iTunes"]) + { + return number; + } + [(NSString *)name release]; } } return number; } -- (void)applicationLaunched:(NSNotification *)note -{ - NSDictionary *info = [note userInfo]; - - if ([[info objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"]) { - iTunesPSN.highLongOfPSN = [[info objectForKey:@"NSApplicationProcessSerialNumberHigh"] longValue]; - iTunesPSN.lowLongOfPSN = [[info objectForKey:@"NSApplicationProcessSerialNumberLow"] longValue]; - - [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTRemoteAppDidLaunchNotification" object:nil]; - } -} - -- (void)applicationTerminated:(NSNotification *)note -{ - NSDictionary *info = [note userInfo]; - - if ([[info objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"]) { - iTunesPSN.highLongOfPSN = kNoProcess; - [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTRemoteAppDidTerminateNotification" object:nil]; - } -} - -//This is just temporary -- (NSString *)runScriptAndReturnResult:(NSString *)script -{ - AEDesc scriptDesc, resultDesc; - Size length; - NSString *result; - Ptr buffer; - - script = [NSString stringWithFormat:@"tell application \"iTunes\"\n%@\nend tell", script]; - - AECreateDesc(typeChar, [script cString], [script cStringLength], -&scriptDesc); - - OSADoScript(asComponent, &scriptDesc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultDesc); - - length = AEGetDescDataSize(&resultDesc); - buffer = malloc(length); - - AEGetDescData(&resultDesc, buffer, length); - AEDisposeDesc(&scriptDesc); - AEDisposeDesc(&resultDesc); - result = [NSString stringWithCString:buffer length:length]; - if ( (! [result isEqualToString:@""]) && - ([result characterAtIndex:0] == '\"') && - ([result characterAtIndex:[result length] - 1] == '\"') ) { - result = [result substringWithRange:NSMakeRange(1, [result length] - 2)]; - } - free(buffer); - buffer = nil; - return result; -} - @end