mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-22 10:42:54 +02:00
v108.11
* added (primary-monitor only) fullscreen support for macOS * improved settings windows a bit * correct Program::focused() move from Video::exclusive()->fullScreen()
This commit is contained in:
@@ -9,6 +9,16 @@ struct VideoCGL;
|
||||
}
|
||||
-(id) initWith:(VideoCGL*)video pixelFormat:(NSOpenGLPixelFormat*)pixelFormat;
|
||||
-(void) reshape;
|
||||
-(BOOL) acceptsFirstResponder;
|
||||
@end
|
||||
|
||||
@interface RubyWindowCGL : NSWindow <NSWindowDelegate> {
|
||||
@public
|
||||
VideoCGL* video;
|
||||
}
|
||||
-(id) initWith:(VideoCGL*)video;
|
||||
-(BOOL) canBecomeKeyWindow;
|
||||
-(BOOL) canBecomeMainWindow;
|
||||
@end
|
||||
|
||||
struct VideoCGL : VideoDriver, OpenGL {
|
||||
@@ -23,11 +33,16 @@ struct VideoCGL : VideoDriver, OpenGL {
|
||||
auto driver() -> string override { return "OpenGL 3.2"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto hasFullScreen() -> bool override { return true; }
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFlush() -> bool override { return true; }
|
||||
auto hasShader() -> bool override { return true; }
|
||||
|
||||
auto setFullScreen(bool fullScreen) -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
@@ -100,9 +115,16 @@ struct VideoCGL : VideoDriver, OpenGL {
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!self.context) return false;
|
||||
if(!self.fullScreen && !self.context) return false;
|
||||
|
||||
@autoreleasepool {
|
||||
if(self.fullScreen) {
|
||||
window = [[RubyWindowCGL alloc] initWith:this];
|
||||
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
[window toggleFullScreen:nil];
|
||||
//[NSApp setPresentationOptions:NSApplicationPresentationFullScreen];
|
||||
}
|
||||
|
||||
NSOpenGLPixelFormatAttribute attributeList[] = {
|
||||
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
|
||||
NSOpenGLPFAColorSize, 24,
|
||||
@@ -111,7 +133,7 @@ private:
|
||||
0
|
||||
};
|
||||
|
||||
auto context = (NSView*)self.context;
|
||||
auto context = self.fullScreen ? [window contentView] : (NSView*)self.context;
|
||||
auto size = [context frame].size;
|
||||
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease];
|
||||
auto openGLContext = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
|
||||
@@ -123,7 +145,7 @@ private:
|
||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||
[context addSubview:view];
|
||||
[openGLContext setView:view];
|
||||
|
||||
[[view window] makeFirstResponder:view];
|
||||
[view lockFocus];
|
||||
|
||||
OpenGL::initialize(self.shader);
|
||||
@@ -142,15 +164,26 @@ private:
|
||||
_ready = false;
|
||||
OpenGL::terminate();
|
||||
|
||||
if(!view) return;
|
||||
@autoreleasepool {
|
||||
[view removeFromSuperview];
|
||||
[view release];
|
||||
view = nil;
|
||||
if(view) {
|
||||
[view removeFromSuperview];
|
||||
[view release];
|
||||
view = nil;
|
||||
}
|
||||
|
||||
if(window) {
|
||||
//[NSApp setPresentationOptions:NSApplicationPresentationDefault];
|
||||
[window toggleFullScreen:nil];
|
||||
[window setCollectionBehavior:NSWindowCollectionBehaviorDefault];
|
||||
[window close];
|
||||
[window release];
|
||||
window = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RubyVideoCGL* view = nullptr;
|
||||
RubyWindowCGL* window = nullptr;
|
||||
|
||||
bool _ready = false;
|
||||
};
|
||||
@@ -168,4 +201,39 @@ private:
|
||||
video->output(0, 0);
|
||||
}
|
||||
|
||||
-(BOOL) acceptsFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void) keyDown:(NSEvent*)event {
|
||||
}
|
||||
|
||||
-(void) keyUp:(NSEvent*)event {
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RubyWindowCGL : NSWindow
|
||||
|
||||
-(id) initWith:(VideoCGL*)videoPointer {
|
||||
auto primaryRect = [[[NSScreen screens] objectAtIndex:0] frame];
|
||||
if(self = [super initWithContentRect:primaryRect styleMask:0 backing:NSBackingStoreBuffered defer:YES]) {
|
||||
video = videoPointer;
|
||||
[self setDelegate:self];
|
||||
[self setReleasedWhenClosed:NO];
|
||||
[self setAcceptsMouseMovedEvents:YES];
|
||||
[self setTitle:@""];
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL) canBecomeKeyWindow {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL) canBecomeMainWindow {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -327,14 +327,14 @@ auto Video::hasMonitors() -> vector<Monitor> {
|
||||
auto displayID = [screenID unsignedIntValue];
|
||||
auto displayPort = CGDisplayIOServicePort(displayID);
|
||||
auto dictionary = IODisplayCreateInfoDictionary(displayPort, 0);
|
||||
if(auto names = CFDictionaryGetValue(dictionary, CFSTR(kDisplayProductName))) {
|
||||
if(auto names = (CFDictionaryRef)CFDictionaryGetValue(dictionary, CFSTR(kDisplayProductName))) {
|
||||
auto languageKeys = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
CFDictionaryApplyFunction((CFDictionaryRef)names, MonitorKeyArrayCallback, (void*)languageKeys);
|
||||
CFDictionaryApplyFunction(names, MonitorKeyArrayCallback, (void*)languageKeys);
|
||||
auto orderLanguageKeys = CFBundleCopyPreferredLocalizationsFromArray(languageKeys);
|
||||
CFRelease(languageKeys);
|
||||
if(orderLanguageKeys && CFArrayGetCount(orderLanguageKeys)) {
|
||||
auto languageKey = CFArrayGetValueAtIndex(orderLanguageKeys, 0);
|
||||
auto localName = CFDictionaryGetValue((CFDictionaryRef)names, languageKey);
|
||||
auto localName = CFDictionaryGetValue(names, languageKey);
|
||||
monitor.name = {1 + monitors.size(), ": ", [(__bridge NSString*)localName UTF8String]};
|
||||
CFRelease(localName);
|
||||
}
|
||||
|
Reference in New Issue
Block a user