2007-10-03 18:26:39 -04:00
//
// MediaKeysApplication . m
// Cog
//
// Created by Vincent Spader on 10 / 3 / 07.
// Copyright 2007 __MyCompanyName __ . All rights reserved .
//
# import "MediaKeysApplication.h"
# import "AppController.h"
2013-10-12 18:26:52 -03:00
# import "SPMediaKeyTap.h"
# import "Logging.h"
2007-10-03 18:26:39 -04:00
2019-11-14 00:13:59 -03:00
# import < MediaPlayer / MPNowPlayingInfoCenter . h >
# import < MediaPlayer / MPRemoteCommandCenter . h >
# import < MediaPlayer / MPRemoteCommand . h >
# import < MediaPlayer / MPMediaItem . h >
# import < MediaPlayer / MPRemoteCommandEvent . h >
2007-10-03 18:26:39 -04:00
@ implementation MediaKeysApplication
2013-10-12 18:26:52 -03:00
+ ( void ) initialize ;
2007-10-03 18:26:39 -04:00
{
2013-10-12 18:26:52 -03:00
if ( [ self class ] ! = [ MediaKeysApplication class ] ) return ;
// Register defaults for the whitelist of apps that want to use media keys
[ [ NSUserDefaults standardUserDefaults ] registerDefaults : [ NSDictionary dictionaryWithObjectsAndKeys :
[ SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers ] , kMediaKeyUsingBundleIdentifiersDefaultsKey ,
nil ] ] ;
}
- ( void ) finishLaunching {
[ super finishLaunching ] ;
2019-11-14 00:13:59 -03:00
2013-10-12 18:41:57 -03:00
[ [ NSUserDefaults standardUserDefaults ] addObserver : self
forKeyPath : @ "allowLastfmMediaKeys"
options : NSKeyValueObservingOptionNew
context : nil ] ;
2019-11-14 00:13:59 -03:00
2020-03-06 01:34:15 -03:00
if ( @ available ( macOS 10.14 , * ) ) {
MPRemoteCommandCenter * remoteCommandCenter = [ MPRemoteCommandCenter sharedCommandCenter ] ;
2019-11-14 00:13:59 -03:00
2020-03-06 01:34:15 -03:00
[ remoteCommandCenter . playCommand setEnabled : YES ] ;
[ remoteCommandCenter . pauseCommand setEnabled : YES ] ;
[ remoteCommandCenter . togglePlayPauseCommand setEnabled : YES ] ;
[ remoteCommandCenter . stopCommand setEnabled : YES ] ;
[ remoteCommandCenter . changePlaybackPositionCommand setEnabled : YES ] ;
[ remoteCommandCenter . nextTrackCommand setEnabled : YES ] ;
[ remoteCommandCenter . previousTrackCommand setEnabled : YES ] ;
[ [ remoteCommandCenter playCommand ] addTarget : self action : @ selector ( clickPlay ) ] ;
[ [ remoteCommandCenter pauseCommand ] addTarget : self action : @ selector ( clickPause ) ] ;
[ [ remoteCommandCenter togglePlayPauseCommand ] addTarget : self action : @ selector ( clickPlay ) ] ;
[ [ remoteCommandCenter stopCommand ] addTarget : self action : @ selector ( clickStop ) ] ;
[ [ remoteCommandCenter changePlaybackPositionCommand ] addTarget : self action : @ selector ( clickSeek : ) ] ;
[ [ remoteCommandCenter nextTrackCommand ] addTarget : self action : @ selector ( clickNext ) ] ;
[ [ remoteCommandCenter previousTrackCommand ] addTarget : self action : @ selector ( clickPrev ) ] ;
2020-02-28 05:40:29 -03:00
}
2020-03-06 01:34:15 -03:00
else
2020-02-28 05:40:29 -03:00
{
2019-11-14 00:13:59 -03:00
keyTap = [ [ SPMediaKeyTap alloc ] initWithDelegate : self ] ;
if ( [ SPMediaKeyTap usesGlobalMediaKeyTap ] ) {
[ keyTap startWatchingMediaKeys ] ;
}
else
ALog ( @ "Media key monitoring disabled" ) ;
2018-06-27 23:50:26 -04:00
}
2019-11-14 00:13:59 -03:00
}
2019-11-15 00:24:13 -03:00
- ( MPRemoteCommandHandlerStatus ) clickPlay {
[ ( AppController * ) [ self delegate ] clickPlay ] ;
return MPRemoteCommandHandlerStatusSuccess ;
}
- ( MPRemoteCommandHandlerStatus ) clickPause {
[ ( AppController * ) [ self delegate ] clickPause ] ;
return MPRemoteCommandHandlerStatusSuccess ;
}
- ( MPRemoteCommandHandlerStatus ) clickStop {
[ ( AppController * ) [ self delegate ] clickStop ] ;
return MPRemoteCommandHandlerStatusSuccess ;
}
- ( MPRemoteCommandHandlerStatus ) clickNext {
[ ( AppController * ) [ self delegate ] clickNext ] ;
return MPRemoteCommandHandlerStatusSuccess ;
}
- ( MPRemoteCommandHandlerStatus ) clickPrev {
[ ( AppController * ) [ self delegate ] clickPrev ] ;
return MPRemoteCommandHandlerStatusSuccess ;
}
- ( MPRemoteCommandHandlerStatus ) clickSeek : ( MPChangePlaybackPositionCommandEvent * ) event {
2019-11-14 00:13:59 -03:00
[ ( AppController * ) [ self delegate ] clickSeek : event . positionTime ] ;
2019-11-15 00:24:13 -03:00
return MPRemoteCommandHandlerStatusSuccess ;
2007-10-03 18:26:39 -04:00
}
- ( void ) sendEvent : ( NSEvent * ) event
{
2013-10-12 18:26:52 -03:00
BOOL shouldHandleMediaKeyEventLocally = ! [ SPMediaKeyTap usesGlobalMediaKeyTap ] ;
2021-01-26 23:30:19 -03:00
if ( shouldHandleMediaKeyEventLocally && [ event type ] = = NSEventTypeSystemDefined && [ event subtype ] = = 8 )
{
[ self mediaKeyTap : nil receivedMediaKeyEvent : event ] ;
}
2007-10-03 18:26:39 -04:00
2021-01-26 23:30:19 -03:00
[ super sendEvent : event ] ;
2007-10-03 18:26:39 -04:00
}
2013-10-12 18:26:52 -03:00
- ( void ) mediaKeyTap : ( SPMediaKeyTap * ) keyTap receivedMediaKeyEvent : ( NSEvent * ) event ;
{
2021-01-26 23:30:19 -03:00
NSAssert ( [ event type ] = = NSEventTypeSystemDefined && [ event subtype ] = = SPSystemDefinedEventMediaKeys , @ "Unexpected NSEvent in mediaKeyTap:receivedMediaKeyEvent:" ) ;
2013-10-12 18:26:52 -03:00
int keyCode = ( ( [ event data1 ] & 0 xFFFF0000 ) > > 16 ) ;
int keyFlags = ( [ event data1 ] & 0 x0000FFFF ) ;
BOOL keyIsPressed = ( ( ( keyFlags & 0 xFF00 ) > > 8 ) ) = = 0 xA ;
if ( ! keyIsPressed ) // pressed and released
{
switch ( keyCode )
{
case NX_KEYTYPE _PLAY :
2020-02-28 05:40:29 -03:00
[ self clickPlay ] ;
2013-10-12 18:26:52 -03:00
break ;
case NX_KEYTYPE _NEXT :
case NX_KEYTYPE _FAST :
2020-02-28 05:40:29 -03:00
[ self clickNext ] ;
2013-10-12 18:26:52 -03:00
break ;
case NX_KEYTYPE _PREVIOUS :
case NX_KEYTYPE _REWIND :
2020-02-28 05:40:29 -03:00
[ self clickPrev ] ;
2013-10-12 18:26:52 -03:00
break ;
}
}
}
2013-10-12 18:41:57 -03:00
- ( void ) observeValueForKeyPath : ( NSString * ) keyPath ofObject : ( id ) object change : ( NSDictionary * ) change context : ( void * ) context {
if ( [ keyPath isEqualToString : @ "allowLastfmMediaKeys" ] )
{
NSUserDefaults * defs = [ NSUserDefaults standardUserDefaults ] ;
BOOL allowLastfmMediaKeys = [ defs boolForKey : @ "allowLastfmMediaKeys" ] ;
NSArray * old = [ defs arrayForKey : kMediaKeyUsingBundleIdentifiersDefaultsKey ] ;
NSMutableArray * new = [ old mutableCopy ] ;
NSArray * lastfmIds = [ NSArray arrayWithObjects : @ "fm.last.Last.fm" , @ "fm.last.Scrobbler" , nil ] ;
if ( allowLastfmMediaKeys )
{
[ new addObjectsFromArray : lastfmIds ] ;
}
else
{
[ new removeObjectsInArray : lastfmIds ] ;
}
[ defs setObject : new forKey : kMediaKeyUsingBundleIdentifiersDefaultsKey ] ;
}
else
{
[ super observeValueForKeyPath : keyPath ofObject : object change : change context : context ] ;
}
}
2007-10-03 18:26:39 -04:00
@ end