github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/mobile/app/darwin.m (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin 6 7 #include "_cgo_export.h" 8 #include <pthread.h> 9 #include <stdio.h> 10 11 #import <Cocoa/Cocoa.h> 12 #import <Foundation/Foundation.h> 13 #import <OpenGL/gl.h> 14 #import <QuartzCore/CVReturn.h> 15 #import <QuartzCore/CVBase.h> 16 17 static CVReturn displayLinkDraw(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) 18 { 19 NSOpenGLView* view = displayLinkContext; 20 NSOpenGLContext *currentContext = [view openGLContext]; 21 drawgl((GLintptr)currentContext); 22 return kCVReturnSuccess; 23 } 24 25 void lockContext(GLintptr context) { 26 NSOpenGLContext* ctx = (NSOpenGLContext*)context; 27 [ctx makeCurrentContext]; 28 CGLLockContext([ctx CGLContextObj]); 29 } 30 31 void unlockContext(GLintptr context) { 32 NSOpenGLContext* ctx = (NSOpenGLContext*)context; 33 [ctx flushBuffer]; 34 CGLUnlockContext([ctx CGLContextObj]); 35 36 } 37 38 uint64 threadID() { 39 uint64 id; 40 if (pthread_threadid_np(pthread_self(), &id)) { 41 abort(); 42 } 43 return id; 44 } 45 46 47 @interface MobileGLView : NSOpenGLView 48 { 49 CVDisplayLinkRef displayLink; 50 } 51 @end 52 53 @implementation MobileGLView 54 - (void)prepareOpenGL { 55 [self setWantsBestResolutionOpenGLSurface:YES]; 56 GLint swapInt = 1; 57 [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; 58 59 CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); 60 CVDisplayLinkSetOutputCallback(displayLink, &displayLinkDraw, self); 61 62 CGLContextObj cglContext = [[self openGLContext] CGLContextObj]; 63 CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj]; 64 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat); 65 CVDisplayLinkStart(displayLink); 66 } 67 68 - (void)reshape { 69 // Calculate screen PPI. 70 // 71 // Note that the backingScaleFactor converts from logical 72 // pixels to actual pixels, but both of these units vary 73 // independently from real world size. E.g. 74 // 75 // 13" Retina Macbook Pro, 2560x1600, 227ppi, backingScaleFactor=2, scale=3.15 76 // 15" Retina Macbook Pro, 2880x1800, 220ppi, backingScaleFactor=2, scale=3.06 77 // 27" iMac, 2560x1440, 109ppi, backingScaleFactor=1, scale=1.51 78 // 27" Retina iMac, 5120x2880, 218ppi, backingScaleFactor=2, scale=3.03 79 NSScreen *screen = [NSScreen mainScreen]; 80 double screenPixW = [screen frame].size.width * [screen backingScaleFactor]; 81 82 CGDirectDisplayID display = (CGDirectDisplayID)[[[screen deviceDescription] valueForKey:@"NSScreenNumber"] intValue]; 83 CGSize screenSizeMM = CGDisplayScreenSize(display); // in millimeters 84 float ppi = 25.4 * screenPixW / screenSizeMM.width; 85 float pixelsPerPt = ppi/72.0; 86 87 // The width and height reported to the geom package are the 88 // bounds of the OpenGL view. Several steps are necessary. 89 // First, [self bounds] gives us the number of logical pixels 90 // in the view. Multiplying this by the backingScaleFactor 91 // gives us the number of actual pixels. 92 NSRect r = [self bounds]; 93 int w = r.size.width * [screen backingScaleFactor]; 94 int h = r.size.height * [screen backingScaleFactor]; 95 96 setGeom(pixelsPerPt, w, h); 97 } 98 99 - (void)mouseDown:(NSEvent *)theEvent { 100 double scale = [[NSScreen mainScreen] backingScaleFactor]; 101 NSPoint p = [theEvent locationInWindow]; 102 eventMouseDown(p.x * scale, p.y * scale); 103 } 104 105 - (void)mouseUp:(NSEvent *)theEvent { 106 double scale = [[NSScreen mainScreen] backingScaleFactor]; 107 NSPoint p = [theEvent locationInWindow]; 108 eventMouseEnd(p.x * scale, p.y * scale); 109 } 110 111 - (void)mouseDragged:(NSEvent *)theEvent { 112 double scale = [[NSScreen mainScreen] backingScaleFactor]; 113 NSPoint p = [theEvent locationInWindow]; 114 eventMouseDragged(p.x * scale, p.y * scale); 115 } 116 @end 117 118 void 119 runApp(void) { 120 [NSAutoreleasePool new]; 121 [NSApplication sharedApplication]; 122 [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 123 124 id menuBar = [[NSMenu new] autorelease]; 125 id menuItem = [[NSMenuItem new] autorelease]; 126 [menuBar addItem:menuItem]; 127 [NSApp setMainMenu:menuBar]; 128 129 id menu = [[NSMenu new] autorelease]; 130 id name = [[NSProcessInfo processInfo] processName]; 131 id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Quit" 132 action:@selector(terminate:) keyEquivalent:@"q"] 133 autorelease]; 134 [menu addItem:quitMenuItem]; 135 [menuItem setSubmenu:menu]; 136 137 NSRect rect = NSMakeRect(0, 0, 400, 400); 138 139 id window = [[[NSWindow alloc] initWithContentRect:rect 140 styleMask:NSTitledWindowMask 141 backing:NSBackingStoreBuffered 142 defer:NO] 143 autorelease]; 144 [window setStyleMask:[window styleMask] | NSResizableWindowMask]; 145 [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; 146 [window makeKeyAndOrderFront:nil]; 147 [window setTitle:name]; 148 149 NSOpenGLPixelFormatAttribute attr[] = { 150 NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, 151 NSOpenGLPFAColorSize, 24, 152 NSOpenGLPFAAlphaSize, 8, 153 NSOpenGLPFADepthSize, 16, 154 NSOpenGLPFAAccelerated, 155 NSOpenGLPFADoubleBuffer, 156 0 157 }; 158 id pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr]; 159 id view = [[MobileGLView alloc] initWithFrame:rect pixelFormat:pixFormat]; 160 [window setContentView:view]; 161 162 [NSApp activateIgnoringOtherApps:YES]; 163 [NSApp run]; 164 }