aboutsummaryrefslogtreecommitdiff
path: root/vendor/gioui.org/app/internal/window/gl_macos.m
blob: 0d7f772bead7b75b7f47d8721e92a91b722703d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: Unlicense OR MIT

// +build darwin,!ios

@import AppKit;

#include <CoreFoundation/CoreFoundation.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl3.h>
#include "_cgo_export.h"

static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) {
	NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil];
	if (!event.hasPreciseScrollingDeltas) {
		// dx and dy are in rows and columns.
		dx *= 10;
		dy *= 10;
	}
	gio_onMouse((__bridge CFTypeRef)view, typ, [NSEvent pressedMouseButtons], p.x, p.y, dx, dy, [event timestamp], [event modifierFlags]);
}

@interface GioView : NSOpenGLView 
@end

@implementation GioView
- (instancetype)initWithFrame:(NSRect)frameRect
				  pixelFormat:(NSOpenGLPixelFormat *)format {
	return [super initWithFrame:frameRect pixelFormat:format];
}
- (void)prepareOpenGL {
	[super prepareOpenGL];
	// Bind a default VBA to emulate OpenGL ES 2.
	GLuint defVBA;
	glGenVertexArrays(1, &defVBA);
	glBindVertexArray(defVBA);
	glEnable(GL_FRAMEBUFFER_SRGB);
}
- (BOOL)isFlipped {
	return YES;
}
- (void)update {
	[super update];
	[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)r {
	gio_onDraw((__bridge CFTypeRef)self);
}
- (void)mouseDown:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0);
}
- (void)mouseUp:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_UP, 0, 0);
}
- (void)middleMouseDown:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0);
}
- (void)middletMouseUp:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_UP, 0, 0);
}
- (void)rightMouseDown:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0);
}
- (void)rightMouseUp:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_UP, 0, 0);
}
- (void)mouseMoved:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_MOVE, 0, 0);
}
- (void)mouseDragged:(NSEvent *)event {
	handleMouse(self, event, GIO_MOUSE_MOVE, 0, 0);
}
- (void)scrollWheel:(NSEvent *)event {
	CGFloat dx = -event.scrollingDeltaX;
	CGFloat dy = -event.scrollingDeltaY;
	handleMouse(self, event, GIO_MOUSE_SCROLL, dx, dy);
}
- (void)keyDown:(NSEvent *)event {
	NSString *keys = [event charactersIgnoringModifiers];
	gio_onKeys((__bridge CFTypeRef)self, (char *)[keys UTF8String], [event timestamp], [event modifierFlags]);
	[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
- (void)insertText:(id)string {
	const char *utf8 = [string UTF8String];
	gio_onText((__bridge CFTypeRef)self, (char *)utf8);
}
- (void)doCommandBySelector:(SEL)sel {
	// Don't pass commands up the responder chain.
	// They will end up in a beep.
}
@end

CFTypeRef gio_createGLView(void) {
	@autoreleasepool {
		NSOpenGLPixelFormatAttribute attr[] = {
			NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
			NSOpenGLPFAColorSize,     24,
			NSOpenGLPFADepthSize,     16,
			NSOpenGLPFAAccelerated,
			// Opt-in to automatic GPU switching. CGL-only property.
			kCGLPFASupportsAutomaticGraphicsSwitching,
			NSOpenGLPFAAllowOfflineRenderers,
			0
		};
		id pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];

		NSRect frame = NSMakeRect(0, 0, 0, 0);
		GioView* view = [[GioView alloc] initWithFrame:frame pixelFormat:pixFormat];

		[view setWantsBestResolutionOpenGLSurface:YES];
		[view setWantsLayer:YES]; // The default in Mojave.

		return CFBridgingRetain(view);
	}
}

void gio_setNeedsDisplay(CFTypeRef viewRef) {
	NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef;
	[view setNeedsDisplay:YES];
}

CFTypeRef gio_contextForView(CFTypeRef viewRef) {
	NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef;
	return (__bridge CFTypeRef)view.openGLContext;
}

void gio_clearCurrentContext(void) {
	[NSOpenGLContext clearCurrentContext];
}

void gio_makeCurrentContext(CFTypeRef ctxRef) {
	NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
	[ctx makeCurrentContext];
}

void gio_lockContext(CFTypeRef ctxRef) {
	NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
	CGLLockContext([ctx CGLContextObj]);
}

void gio_unlockContext(CFTypeRef ctxRef) {
	NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
	CGLUnlockContext([ctx CGLContextObj]);
}