From 78a266d599d08b2792efaeb6e9391cdff56c1281 Mon Sep 17 00:00:00 2001 From: FRAU KOUJIRO Date: Tue, 15 Apr 2014 16:51:40 -0700 Subject: cocoa: decouple events from application somewhat --- osdep/macosx_application.m | 55 ++++++++++++----------------- osdep/macosx_application_objc.h | 16 --------- osdep/macosx_events.m | 78 ++++++++++++++++++++++++++++++++--------- osdep/macosx_events_objc.h | 33 +++++++++++++++++ 4 files changed, 118 insertions(+), 64 deletions(-) create mode 100644 osdep/macosx_events_objc.h (limited to 'osdep') diff --git a/osdep/macosx_application.m b/osdep/macosx_application.m index 047dfeab65..f6061fe76a 100644 --- a/osdep/macosx_application.m +++ b/osdep/macosx_application.m @@ -23,16 +23,20 @@ #include "common/msg.h" #include "input/input.h" #include "input/event.h" -#include "input/keycodes.h" -#include "osdep/macosx_application_objc.h" +#import "osdep/macosx_application_objc.h" #include "osdep/macosx_compat.h" +#import "osdep/macosx_events_objc.h" #define MPV_PROTOCOL @"mpv://" static pthread_t playback_thread_id; -@interface Application (PrivateMethods) +@interface Application () +{ + EventsResponder *_eventsResponder; +} + - (NSMenuItem *)menuItemWithParent:(NSMenu *)parent title:(NSString *)title action:(SEL)selector @@ -61,17 +65,14 @@ Application *mpv_shared_app(void) @synthesize argumentsList = _arguments_list; @synthesize willStopOnOpenEvent = _will_stop_on_open_event; -@synthesize inputContext = _input_context; -@synthesize eventsResponder = _events_responder; @synthesize menuItems = _menu_items; -@synthesize input_ready = _input_ready; - (void)sendEvent:(NSEvent *)event { [super sendEvent:event]; - if (self.inputContext) - mp_input_wakeup(self.inputContext); + if (_eventsResponder.inputContext) + mp_input_wakeup(_eventsResponder.inputContext); } - (id)init @@ -80,19 +81,8 @@ Application *mpv_shared_app(void) self.menuItems = [[[NSMutableDictionary alloc] init] autorelease]; self.files = nil; self.argumentsList = [[[NSMutableArray alloc] init] autorelease]; - self.eventsResponder = [[[EventsResponder alloc] init] autorelease]; + _eventsResponder = [EventsResponder sharedInstance]; self.willStopOnOpenEvent = NO; - self.input_ready = [[[NSCondition alloc] init] autorelease]; - - [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask|NSKeyUpMask - handler:^(NSEvent *event) { - BOOL equivalent = [[NSApp mainMenu] performKeyEquivalent:event]; - if (equivalent) { - return (NSEvent *)nil; - } else { - return [self.eventsResponder handleKey:event]; - } - }]; NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager]; [em setEventHandler:self @@ -174,9 +164,10 @@ Application *mpv_shared_app(void) - (void)stopMPV:(char *)cmd { - if (self.inputContext) { - mp_cmd_t *cmdt = mp_input_parse_cmd(self.inputContext, bstr0(cmd), ""); - mp_input_queue_cmd(self.inputContext, cmdt); + struct input_ctx *inputContext = _eventsResponder.inputContext; + if (inputContext) { + mp_cmd_t *cmdt = mp_input_parse_cmd(inputContext, bstr0(cmd), ""); + mp_input_queue_cmd(inputContext, cmdt); } else { terminate_cocoa_application(); } @@ -289,7 +280,7 @@ Application *mpv_shared_app(void) size_t bytes = [obj lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1); }]; - mp_event_drop_files(self.inputContext, num_files, files_utf8); + mp_event_drop_files(_eventsResponder.inputContext, num_files, files_utf8); talloc_free(files_utf8); } @@ -327,10 +318,10 @@ int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[]) macosx_finder_args_preinit(&argc, &argv); pthread_create(&playback_thread_id, NULL, playback_thread, &ctx); - [mpv_shared_app().input_ready lock]; - while (!mpv_shared_app().inputContext) - [mpv_shared_app().input_ready wait]; - [mpv_shared_app().input_ready unlock]; + [_eventsResponder.input_ready lock]; + while (!_eventsResponder.inputContext) + [_eventsResponder.input_ready wait]; + [_eventsResponder.input_ready unlock]; cocoa_run_runloop(); @@ -387,10 +378,10 @@ void cocoa_stop_runloop(void) void cocoa_set_input_context(struct input_ctx *input_context) { - [mpv_shared_app().input_ready lock]; - mpv_shared_app().inputContext = input_context; - [mpv_shared_app().input_ready signal]; - [mpv_shared_app().input_ready unlock]; + [_eventsResponder.input_ready lock]; + _eventsResponder.inputContext = input_context; + [_eventsResponder.input_ready signal]; + [_eventsResponder.input_ready unlock]; } void cocoa_post_fake_event(void) diff --git a/osdep/macosx_application_objc.h b/osdep/macosx_application_objc.h index 3a3b75335f..d203711054 100644 --- a/osdep/macosx_application_objc.h +++ b/osdep/macosx_application_objc.h @@ -18,19 +18,6 @@ #import #include "osdep/macosx_application.h" -#import "ar/HIDRemote.h" - -@interface EventsResponder : NSObject -- (BOOL)handleMediaKey:(NSEvent *)event; -- (NSEvent *)handleKey:(NSEvent *)event; -- (void)startAppleRemote; -- (void)stopAppleRemote; -- (void)startMediaKeys; -- (void)restartMediaKeys; -- (void)stopMediaKeys; -- (int)mapKeyModifiers:(int)cocoaModifiers; -- (int)keyModifierMask:(NSEvent *)event; -@end @interface Application : NSApplication - (void)initialize_menu; @@ -38,13 +25,10 @@ - (void)stopPlayback; - (void)handleFilesArray:(NSArray *)files; -@property(nonatomic, assign) struct input_ctx *inputContext; -@property(nonatomic, retain) EventsResponder *eventsResponder; @property(nonatomic, retain) NSMutableDictionary *menuItems; @property(nonatomic, retain) NSArray *files; @property(nonatomic, retain) NSMutableArray *argumentsList; @property(nonatomic, assign) BOOL willStopOnOpenEvent; -@property(nonatomic, retain) NSCondition *input_ready; @end Application *mpv_shared_app(void); diff --git a/osdep/macosx_events.m b/osdep/macosx_events.m index 6a21e96bef..7a525f7dd5 100644 --- a/osdep/macosx_events.m +++ b/osdep/macosx_events.m @@ -27,12 +27,30 @@ #include "talloc.h" #include "input/input.h" +#include "input/keycodes.h" // doesn't make much sense, but needed to access keymap functionality #include "video/out/vo.h" -#import "osdep/macosx_application_objc.h" -#include "osdep/macosx_events.h" #include "osdep/macosx_compat.h" +#import "osdep/macosx_events_objc.h" + +@interface EventsResponder () +{ + CFMachPortRef _mk_tap_port; + HIDRemote *_remote; +} + +- (BOOL)handleMediaKey:(NSEvent *)event; +- (NSEvent *)handleKey:(NSEvent *)event; +- (void)startAppleRemote; +- (void)stopAppleRemote; +- (void)startMediaKeys; +- (void)restartMediaKeys; +- (void)stopMediaKeys; +- (int)mapKeyModifiers:(int)cocoaModifiers; +- (int)keyModifierMask:(NSEvent *)event; +@end + #define NSLeftAlternateKeyMask (0x000020 | NSAlternateKeyMask) #define NSRightAlternateKeyMask (0x000040 | NSAlternateKeyMask) @@ -93,14 +111,12 @@ static int convert_key(unsigned key, unsigned charcode) void cocoa_init_apple_remote(void) { - Application *app = mpv_shared_app(); - [app.eventsResponder startAppleRemote]; + [[EventsResponder sharedInstance] startAppleRemote]; } void cocoa_uninit_apple_remote(void) { - Application *app = mpv_shared_app(); - [app.eventsResponder stopAppleRemote]; + [[EventsResponder sharedInstance] stopAppleRemote]; } static int mk_code(NSEvent *event) @@ -150,34 +166,64 @@ static CGEventRef tap_event_callback(CGEventTapProxy proxy, CGEventType type, } void cocoa_init_media_keys(void) { - [mpv_shared_app().eventsResponder startMediaKeys]; + [[EventsResponder sharedInstance] startMediaKeys]; } void cocoa_uninit_media_keys(void) { - [mpv_shared_app().eventsResponder stopMediaKeys]; + [[EventsResponder sharedInstance] stopMediaKeys]; } void cocoa_put_key(int keycode) { - if (mpv_shared_app().inputContext) - mp_input_put_key(mpv_shared_app().inputContext, keycode); + struct input_ctx *inputContext = [EventsResponder sharedInstance].inputContext; + if (inputContext) + mp_input_put_key(inputContext, keycode); } void cocoa_put_key_with_modifiers(int keycode, int modifiers) { - keycode |= [mpv_shared_app().eventsResponder mapKeyModifiers:modifiers]; + keycode |= [[EventsResponder sharedInstance] mapKeyModifiers:modifiers]; cocoa_put_key(keycode); } -@implementation EventsResponder { - CFMachPortRef _mk_tap_port; - HIDRemote *_remote; +@implementation EventsResponder + +@synthesize inputContext = _input_context; +@synthesize input_ready = _input_ready; + ++ (EventsResponder *)sharedInstance +{ + static EventsResponder *responder = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + responder = [EventsResponder new]; + }); + return responder; +} + +- (id)init +{ + self = [super init]; + if (self) { + _input_ready = [NSCondition new]; + + [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask|NSKeyUpMask + handler:^(NSEvent *event) { + BOOL equivalent = [[NSApp mainMenu] performKeyEquivalent:event]; + if (equivalent) { + return (NSEvent *)nil; + } else { + return [self handleKey:event]; + } + }]; + } + return self; } - (BOOL)useAltGr { - if (mpv_shared_app().inputContext) - return mp_input_use_alt_gr(mpv_shared_app().inputContext); + if (self.inputContext) + return mp_input_use_alt_gr(self.inputContext); else return YES; } diff --git a/osdep/macosx_events_objc.h b/osdep/macosx_events_objc.h new file mode 100644 index 0000000000..226d8cb562 --- /dev/null +++ b/osdep/macosx_events_objc.h @@ -0,0 +1,33 @@ +/* + * Cocoa Application Event Handling + * + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#import +#import "ar/HIDRemote.h" +#include "osdep/macosx_events.h" + +struct input_ctx; + +@interface EventsResponder : NSObject + ++ (EventsResponder *)sharedInstance; + +@property(nonatomic, assign) struct input_ctx *inputContext; +@property(nonatomic, retain) NSCondition *input_ready; + +@end -- cgit v1.2.3