RetroArch/ui/drivers/cocoa/cocoa_common.m

320 lines
10 KiB
Mathematica
Raw Normal View History

/* RetroArch - A frontend for libretro.
* Copyright (C) 2013-2014 - Jason Fetters
2017-01-22 13:40:32 +01:00
* Copyright (C) 2011-2017 - Daniel De Matteis
2019-02-03 15:49:35 -08:00
*
* RetroArch 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 Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch 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 RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#import <AvailabilityMacros.h>
#include <sys/stat.h>
2015-04-20 12:52:16 +02:00
#include "cocoa_common.h"
2016-06-07 16:47:48 +02:00
#include "../ui_cocoa.h"
2016-09-08 11:59:44 +02:00
#include <retro_assert.h>
2016-06-08 07:41:59 +02:00
#include "../../../verbosity.h"
#include "../../../input/drivers/cocoa_input.h"
2019-06-17 11:18:27 +02:00
#include "../../../retroarch.h"
2015-12-05 17:15:32 +01:00
#ifdef HAVE_COCOATOUCH
#import "GCDWebUploader.h"
#import "WebServer.h"
#endif
2019-09-22 11:19:54 +02:00
/* forward declarations */
void cocoagl_gfx_ctx_update(void);
2019-11-20 06:25:40 +01:00
void *glkitview_init(void);
2019-11-19 20:58:13 +01:00
2019-11-20 06:25:40 +01:00
#ifdef HAVE_COCOATOUCH
@interface CocoaView()<GCDWebUploaderDelegate> {
2019-11-20 06:25:40 +01:00
}
@end
#endif
2015-04-20 20:39:39 +02:00
@implementation CocoaView
2016-10-05 02:00:11 +02:00
#if defined(HAVE_COCOA_METAL)
- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)newScale fromWindow:(NSWindow *)window {
return YES;
}
#endif
2016-10-05 02:00:11 +02:00
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
2016-10-05 02:00:11 +02:00
- (void)scrollWheel:(NSEvent *)theEvent {
cocoa_input_data_t *apple = (cocoa_input_data_t*)input_driver_get_data();
(void)apple;
}
#endif
2015-04-20 20:39:39 +02:00
+ (CocoaView*)get
{
2019-09-22 11:19:54 +02:00
CocoaView *view = (BRIDGE CocoaView*)nsview_get_ptr();
if (!view)
{
2019-11-20 06:25:40 +01:00
view = [CocoaView new];
nsview_set_ptr(view);
2019-09-22 11:19:54 +02:00
}
return view;
}
- (id)init
{
self = [super init];
2019-02-03 15:49:35 -08:00
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
[self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
#endif
#if defined(HAVE_COCOA)
ui_window_cocoa_t cocoa_view;
cocoa_view.data = (CocoaView*)self;
2019-02-03 15:49:35 -08:00
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSColorPboardType, NSFilenamesPboardType, nil]];
#elif defined(HAVE_COCOA_METAL)
[self registerForDraggedTypes:@[NSColorPboardType, NSFilenamesPboardType]];
2015-04-20 00:38:55 +02:00
#elif defined(HAVE_COCOATOUCH)
self.view = (BRIDGE GLKView*)glkitview_init();
2019-02-03 15:49:35 -08:00
#if TARGET_OS_IOS
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(showNativeMenu)];
swipe.numberOfTouchesRequired = 4;
swipe.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipe];
#endif
2019-02-03 15:49:35 -08:00
#endif
#if defined(HAVE_COCOA)
video_driver_display_type_set(RARCH_DISPLAY_OSX);
video_driver_display_set(0);
video_driver_display_userdata_set((uintptr_t)self);
#elif defined(HAVE_COCOA_METAL)
video_driver_display_type_set(RARCH_DISPLAY_OSX);
video_driver_display_set(0);
video_driver_display_userdata_set((uintptr_t)self);
#endif
2019-02-03 15:49:35 -08:00
return self;
}
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
- (void)setFrame:(NSRect)frameRect
{
[super setFrame:frameRect];
cocoagl_gfx_ctx_update();
}
/* Stop the annoying sound when pressing a key. */
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (BOOL)isFlipped
{
return YES;
}
- (void)keyDown:(NSEvent*)theEvent
{
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
NSPasteboard *pboard = [sender draggingPasteboard];
2019-02-03 15:49:35 -08:00
if ( [[pboard types] containsObject:NSFilenamesPboardType] )
{
if (sourceDragMask & NSDragOperationCopy)
return NSDragOperationCopy;
}
2019-02-03 15:49:35 -08:00
return NSDragOperationNone;
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
NSPasteboard *pboard = [sender draggingPasteboard];
2019-02-03 15:49:35 -08:00
if ( [[pboard types] containsObject:NSURLPboardType])
{
NSURL *fileURL = [NSURL URLFromPasteboard:pboard];
NSString *s = [fileURL path];
if (s != nil)
{
RARCH_LOG("Drop name is: %s\n", [s UTF8String]);
}
}
return YES;
}
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
[self setNeedsDisplay: YES];
}
#elif TARGET_OS_IOS
-(void) showNativeMenu {
dispatch_async(dispatch_get_main_queue(), ^{
[[RetroArch_iOS get] toggleUI];
});
}
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeBottom;
}
-(BOOL)prefersHomeIndicatorAutoHidden
{
return NO;
}
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
if (@available(iOS 11, *)) {
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[self adjustViewFrameForSafeArea];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
}];
}
}
-(void)adjustViewFrameForSafeArea {
// This is for adjusting the view frame to account for the notch in iPhone X phones
if (@available(iOS 11, *)) {
RAScreen *screen = (BRIDGE RAScreen*)get_chosen_screen();
CGRect screenSize = [screen bounds];
UIEdgeInsets inset = [[UIApplication sharedApplication] delegate].window.safeAreaInsets;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect newFrame = screenSize;
if ( orientation == UIInterfaceOrientationPortrait ) {
newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y + inset.top, screenSize.size.width, screenSize.size.height - inset.top);
} else if ( orientation == UIInterfaceOrientationLandscapeLeft ) {
newFrame = CGRectMake(screenSize.origin.x + inset.right, screenSize.origin.y, screenSize.size.width - inset.right * 2, screenSize.size.height);
} else if ( orientation == UIInterfaceOrientationLandscapeRight ) {
newFrame = CGRectMake(screenSize.origin.x + inset.left, screenSize.origin.y, screenSize.size.width - inset.left * 2, screenSize.size.height);
}
self.view.frame = newFrame;
}
}
- (void)viewWillLayoutSubviews
{
float width = 0.0f, height = 0.0f, tenpctw, tenpcth;
RAScreen *screen = (BRIDGE RAScreen*)get_chosen_screen();
UIInterfaceOrientation orientation = self.interfaceOrientation;
2015-11-05 22:13:49 +01:00
CGRect screenSize = [screen bounds];
SEL selector = NSSelectorFromString(BOXSTRING("coordinateSpace"));
2019-02-03 15:49:35 -08:00
if ([screen respondsToSelector:selector])
{
screenSize = [[screen coordinateSpace] bounds];
width = CGRectGetWidth(screenSize);
height = CGRectGetHeight(screenSize);
}
else
{
width = ((int)orientation < 3) ? CGRectGetWidth(screenSize) : CGRectGetHeight(screenSize);
height = ((int)orientation < 3) ? CGRectGetHeight(screenSize) : CGRectGetWidth(screenSize);
}
2019-02-03 15:49:35 -08:00
tenpctw = width / 10.0f;
tenpcth = height / 10.0f;
2019-02-03 15:49:35 -08:00
[self adjustViewFrameForSafeArea];
}
/* NOTE: This version runs on iOS6+. */
- (NSUInteger)supportedInterfaceOrientations
{
2016-05-02 14:54:08 +02:00
return (NSUInteger)apple_frontend_settings.orientation_flags;
}
/* NOTE: This version runs on iOS2-iOS5, but not iOS6+. */
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
switch (interfaceOrientation)
{
case UIInterfaceOrientationPortrait:
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskPortrait);
case UIInterfaceOrientationPortraitUpsideDown:
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskPortraitUpsideDown);
case UIInterfaceOrientationLandscapeLeft:
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskLandscapeLeft);
case UIInterfaceOrientationLandscapeRight:
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskLandscapeRight);
default:
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskAll);
}
2019-02-03 15:49:35 -08:00
return YES;
}
#endif
#ifdef HAVE_COCOATOUCH
- (void)viewDidAppear:(BOOL)animated
{
#if TARGET_OS_IOS
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
}
#elif TARGET_OS_TV
2019-02-03 15:49:35 -08:00
#endif
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
#if TARGET_OS_TV
[[WebServer sharedInstance] startUploader];
[WebServer sharedInstance].webUploader.delegate = self;
#endif
}
#pragma mark GCDWebServerDelegate
- (void)webServerDidCompleteBonjourRegistration:(GCDWebServer*)server {
NSMutableString *servers = [[NSMutableString alloc] init];
if ( server.serverURL != nil ) {
[servers appendString:[NSString stringWithFormat:@"%@",server.serverURL]];
}
if ( servers.length > 0 ) {
[servers appendString:@"\n\n"];
}
if ( server.bonjourServerURL != nil ) {
[servers appendString:[NSString stringWithFormat:@"%@",server.bonjourServerURL]];
}
#if TARGET_OS_TV
2019-02-03 08:59:24 -10:00
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Welcome to RetroArch" message:[NSString stringWithFormat:@"To transfer files from your computer, go to one of these addresses on your web browser:\n\n%@",servers] preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}]];
[self presentViewController:alert animated:YES completion:^{
}];
#elif TARGET_OS_IOS
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Web Server Started" message:[NSString stringWithFormat:@"To transfer ROMs from your computer, go to one of these addresses on your web browser:\n\n%@",servers] preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Stop Server" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[WebServer sharedInstance] webUploader].delegate = nil;
[[WebServer sharedInstance] stopUploader];
}]];
[self presentViewController:alert animated:YES completion:^{
}];
#endif
}
2019-09-22 10:28:51 +02:00
#endif
@end