123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- #include <AppKit/AppKit.h>
- #include <Carbon/Carbon.h>
- #include <OpenGL/gl.h>
- #include <OpenGL/OpenGL.h>
- #include <brl.mod/systemdefault.mod/system.h>
- enum{
- FLAGS_BACKBUFFER= 0x2,
- FLAGS_ALPHABUFFER= 0x4,
- FLAGS_DEPTHBUFFER= 0x8,
- FLAGS_STENCILBUFFER=0x10,
- FLAGS_ACCUMBUFFER= 0x20,
- FLAGS_BORDERLESS= 0x40,
- FLAGS_FULLSCREEN_DESKTOP= 0x80,
- FLAGS_FULLSCREEN= 0x80000000
- };
- enum{
- MODE_WIDGET= 1,
- MODE_WINDOW= 2,
- MODE_DISPLAY= 3
- };
- @interface BBGLWindow : NSWindow{
- }
- @end
- @implementation BBGLWindow
- -(void)sendEvent:(NSEvent*)event{
- bbSystemEmitOSEvent( event,[self contentView],&bbNullObject );
- switch( [event type] ){
- case NSKeyDown:case NSKeyUp:
- //prevent 'beeps'!
- return;
- }
- [super sendEvent:event];
- }
- -(BOOL)windowShouldClose:(id)sender{
- bbSystemEmitEvent( BBEVENT_APPTERMINATE,&bbNullObject,0,0,0,0,&bbNullObject );
- return NO;
- }
- - (BOOL)canBecomeKeyWindow{
- return YES;
- }
- @end
- typedef struct BBGLContext BBGLContext;
- struct BBGLContext{
- int mode,width,height,depth,hertz;
- BBInt64 flags;
- int sync;
- NSView *view;
- BBGLWindow *window;
- NSOpenGLContext *glContext;
- };
- static BBGLContext *_currentContext;
- static BBGLContext *_displayContext;
- static CFDictionaryRef oldDisplayMode;
- extern void bbFlushAutoreleasePool();
- void bbGLGraphicsClose( BBGLContext *context );
- void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,BBInt64 *flags );
- void bbGLGraphicsSetGraphics( BBGLContext *context );
- static int _initAttrs( CGLPixelFormatAttribute attrs[16],BBInt64 flags ){
- int n=0;
- if( flags & FLAGS_BACKBUFFER ) attrs[n++]=kCGLPFADoubleBuffer;
- if( flags & FLAGS_ALPHABUFFER ){ attrs[n++]=kCGLPFAAlphaSize;attrs[n++]=1; }
- if( flags & FLAGS_DEPTHBUFFER ){ attrs[n++]=kCGLPFADepthSize;attrs[n++]=24; }
- if( flags & FLAGS_STENCILBUFFER ){ attrs[n++]=kCGLPFAStencilSize;attrs[n++]=1; }
- if( flags & FLAGS_ACCUMBUFFER ){ attrs[n++]=kCGLPFAAccumSize;attrs[n++]=1; }
- if( flags & FLAGS_FULLSCREEN ){
- attrs[n++]=kCGLPFAFullScreen;
- attrs[n++]=kCGLPFADisplayMask;
- attrs[n++]=CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay );
- }else{
- attrs[n++]=kCGLPFANoRecovery;
- }
- attrs[n]=0;
- return n;
- }
- static NSOpenGLContext *_sharedContext;
- static void _validateSize( BBGLContext *context ){
- NSRect rect;
-
- if( !context || context->mode!=MODE_WIDGET ) return;
-
- rect=[context->view bounds];
- if( rect.size.width==context->width && rect.size.height==context->height ) return;
-
- context->width=rect.size.width;
- context->height=rect.size.height;
- if( context->glContext ) [context->glContext update];
- }
- static void _validateContext( BBGLContext *context ){
- BBInt64 flags;
- NSOpenGLContext *shared;
- NSOpenGLContext *glContext;
- NSOpenGLPixelFormat *glFormat;
- CGLPixelFormatAttribute attrs[16];
-
- if( !context || context->glContext ) return;
- flags=context->flags;
-
- // if( context->mode==MODE_DISPLAY ) flags|=FLAGS_FULLSCREEN;
- _initAttrs( attrs,flags );
- glFormat=[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
- glContext=[[NSOpenGLContext alloc] initWithFormat:glFormat shareContext:_sharedContext];
- [glFormat release];
- if( !glContext ) bbExThrowCString( "Unable to create GL Context" );
-
- switch( context->mode ){
- case MODE_WIDGET:
- [glContext setView:context->view];
- break;
- case MODE_WINDOW:
- case MODE_DISPLAY:
- [glContext setView:[context->window contentView]];
- break;
- }
- context->glContext=glContext;
- }
- void bbGLGraphicsShareContexts(){
- NSOpenGLPixelFormat *glFormat;
- CGLPixelFormatAttribute attrs[16];
-
- if( _sharedContext ) return;
- _initAttrs( attrs,0 );
- glFormat=[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
- _sharedContext=[[NSOpenGLContext alloc] initWithFormat:glFormat shareContext:0];
- [glFormat release];
- }
- int bbGLGraphicsGraphicsModes( int *modes,int count ){
- int i=0,n=0,sz;
- CFArrayRef displayModeArray;
- displayModeArray = CGDisplayCopyAllDisplayModes(kCGDirectMainDisplay, NULL);
- sz=CFArrayGetCount( displayModeArray );
-
- while( i<sz && n<count ){
- CGDisplayModeRef displayMode;
- int width,height,depth,hertz;
- CFStringRef format;
- displayMode=(CGDisplayModeRef)CFArrayGetValueAtIndex( displayModeArray,i++ );
- format = CGDisplayModeCopyPixelEncoding(displayMode);
- width = CGDisplayModeGetWidth(displayMode);
- height = CGDisplayModeGetHeight(displayMode);
- hertz = (CGDisplayModeGetRefreshRate(displayMode) + 0.5);
- if (CFStringCompare(format, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
- depth = 32;
- } else if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
- depth = 16;
- } else if (CFStringCompare(format, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
- depth = 30;
- } else if (CFStringCompare(format, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
- depth = 8;
- } else {
- depth = 0;
- }
-
- CFRelease(format);
-
- if (hertz == 0) {
-
- CVDisplayLinkRef link = NULL;
- CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &link);
-
- if (link != NULL) {
- CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
- if ((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0) {
- hertz = (long) ((time.timeScale / (double) time.timeValue) + 0.5);
- }
- }
- }
-
- *modes++=width;
- *modes++=height;
- *modes++=depth;
- *modes++=hertz;
- ++n;
- }
-
- return n;
- }
- BBGLContext *bbGLGraphicsAttachGraphics( NSView *view,BBInt64 flags ){
- NSRect rect;
- BBGLContext *context;
- rect=[view bounds];
-
- context=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( context,0,sizeof(BBGLContext) );
- context->mode=MODE_WIDGET;
- context->width=rect.size.width;
- context->height=rect.size.height;
- context->flags=flags;
- context->sync=-1;
-
- context->view=view;
-
- return context;
- }
- BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hertz,BBInt64 flags, int x, int y ){
- int mode;
- BBGLWindow *window=0;
- BBGLContext *context;
- int sysv=0;
-
- Gestalt( 'sysv',&sysv );
- if( depth ){
-
- CFDictionaryRef displayMode;
- CGCaptureAllDisplays();
-
- oldDisplayMode=CGDisplayCurrentMode( kCGDirectMainDisplay );
- CFRetain( (CFTypeRef)oldDisplayMode );
- if( !hertz ){
- displayMode=CGDisplayBestModeForParameters( kCGDirectMainDisplay,depth,width,height,0 );
- }else{
- displayMode=CGDisplayBestModeForParametersAndRefreshRate( kCGDirectMainDisplay,depth,width,height,hertz,0 );
- }
- if( CGDisplaySwitchToMode( kCGDirectMainDisplay,displayMode ) ){
- CFRelease( (CFTypeRef)oldDisplayMode );
- bbExThrowCString( "Unable to set display mode" );
- }
- #if MAC_OS_X_VERSION_MAX_ALLOWED < 101500
- HideMenuBar();
- #endif
- window=[[NSWindow alloc]
- initWithContentRect:NSMakeRect( 0,0,width,height )
- styleMask:NSBorderlessWindowMask
- backing:NSBackingStoreBuffered
- willUseFullScreenPresentationOptions:NSApplicationPresentationAutoHideToolbar | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationFullScreen
- defer:YES];
-
- [window setOpaque:YES];
- [window setBackgroundColor:[NSColor blackColor]];
- [window setLevel:CGShieldingWindowLevel()];
- [window makeKeyAndOrderFront:NSApp];
-
- mode=MODE_DISPLAY;
-
- }else{
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- NSWindowStyleMask mask = (flags & FLAGS_BORDERLESS) ? 0 : NSTitledWindowMask|NSClosableWindowMask;
- if (flags & FLAGS_FULLSCREEN_DESKTOP) mask |= NSWindowStyleMaskFullScreen;
-
- window=[[BBGLWindow alloc]
- initWithContentRect:NSMakeRect( x, y,width,height )
- styleMask:mask
- backing:NSBackingStoreBuffered
- defer:YES];
- if( !window ) return 0;
-
- [window setDelegate:window];
- [window setAcceptsMouseMovedEvents:YES];
- char *p=bbStringToUTF8String(bbAppTitle);
- [window setTitle:[NSString stringWithUTF8String:p]];
- [window center];
- bbMemFree(p);
- [window makeKeyAndOrderFront:NSApp];
-
- mode=MODE_WINDOW;
- }
-
- context=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( context,0,sizeof(BBGLContext) );
-
- context->mode=mode;
- context->width=width;
- context->height=height;
- context->depth=depth;
- context->hertz=hertz;
- context->flags=flags;
- context->sync=-1;
- context->window=window;
-
- if( mode==MODE_DISPLAY ) _displayContext=context;
-
- return context;
- }
- void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz, BBInt64 *flags ){
- _validateSize( context );
- *width=context->width;
- *height=context->height;
- *depth=context->depth;
- *hertz=context->hertz;
- *flags=context->flags;
- }
- void bbGLGraphicsClose( BBGLContext *context ){
- if( context==_currentContext ) bbGLGraphicsSetGraphics( 0 );
- [context->glContext clearDrawable];
- [context->glContext release];
-
- switch( context->mode ){
- case MODE_WINDOW:
- case MODE_DISPLAY:
- bbSystemViewClosed( [context->window contentView] );
- [context->window close];
- break;
- }
- if( context==_displayContext ){
- CGDisplaySwitchToMode( kCGDirectMainDisplay,oldDisplayMode );
- CFRelease( (CFTypeRef)oldDisplayMode );
- CGReleaseAllDisplays();
- CGDisplayShowCursor( kCGDirectMainDisplay );
- #if MAC_OS_X_VERSION_MAX_ALLOWED < 101500
- ShowMenuBar();
- #endif
- _displayContext=0;
- }
- free( context );
- }
- void bbGLGraphicsSetGraphics( BBGLContext *context ){
- if( context ){
- _validateSize( context );
- _validateContext( context );
- [context->glContext makeCurrentContext];
- }else{
- [NSOpenGLContext clearCurrentContext];
- }
- _currentContext=context;
- }
- static int updated;
- void bbGLGraphicsFlip( int sync ){
- if( !_currentContext ) return;
-
- sync=sync ? 1 : 0;
-
- static int _sync=-1;
-
- if( sync!=_currentContext->sync ){
- _currentContext->sync=sync;
- [_currentContext->glContext setValues:(long*)&sync forParameter:kCGLCPSwapInterval];
- }
-
- [_currentContext->glContext flushBuffer];
- // update the context, at least once - mojave needs this or nothing is rendered.
- if (!updated) {
- updated = 1;
- [_currentContext->glContext update];
- }
- }
|