aboutsummaryrefslogtreecommitdiffstats
path: root/pugl
diff options
context:
space:
mode:
Diffstat (limited to 'pugl')
-rw-r--r--pugl/detail/mac.h59
-rw-r--r--pugl/detail/mac.m426
-rw-r--r--pugl/detail/mac_cairo.m166
-rw-r--r--pugl/detail/mac_gl.m184
4 files changed, 445 insertions, 390 deletions
diff --git a/pugl/detail/mac.h b/pugl/detail/mac.h
new file mode 100644
index 0000000..9a5997d
--- /dev/null
+++ b/pugl/detail/mac.h
@@ -0,0 +1,59 @@
+/*
+ Copyright 2012-2019 David Robillard <http://drobilla.net>
+ Copyright 2017 Hanspeter Portner <dev@open-music-kontrollers.ch>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/**
+ @file win.h Shared definitions for MacOS implementation.
+*/
+
+#include "pugl/pugl.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include <stdint.h>
+
+@interface PuglWrapperView : NSView<NSTextInputClient>
+{
+@public
+ PuglView* puglview;
+ NSTrackingArea* trackingArea;
+ NSMutableAttributedString* markedText;
+ NSTimer* timer;
+ NSTimer* urgentTimer;
+}
+
+- (void) dispatchConfigure:(NSRect)bounds;
+
+@end
+
+@interface PuglWindow : NSWindow
+{
+@public
+ PuglView* puglview;
+}
+
+- (void) setPuglview:(PuglView*)view;
+
+@end
+
+struct PuglInternalsImpl {
+ NSApplication* app;
+ PuglWrapperView* wrapperView;
+ NSView* drawView;
+ id window;
+ NSEvent* nextEvent;
+ uint32_t mods;
+};
diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m
index 2316ca3..ce82d78 100644
--- a/pugl/detail/mac.m
+++ b/pugl/detail/mac.m
@@ -22,15 +22,8 @@
#define GL_SILENCE_DEPRECATION 1
#include "pugl/detail/implementation.h"
-#include "pugl/gl.h"
+#include "pugl/detail/mac.h"
#include "pugl/pugl.h"
-#include "pugl/pugl_gl_backend.h"
-
-#ifdef PUGL_HAVE_CAIRO
-#include "pugl/pugl_cairo_backend.h"
-
-#include <cairo-quartz.h>
-#endif
#import <Cocoa/Cocoa.h>
@@ -38,35 +31,6 @@
#include <stdlib.h>
-#ifndef __MAC_10_10
-#define NSOpenGLProfileVersion4_1Core NSOpenGLProfileVersion3_2Core
-typedef NSUInteger NSEventModifierFlags;
-typedef NSUInteger NSWindowStyleMask;
-#endif
-
-@class PuglWrapperView;
-@class PuglOpenGLView;
-@class PuglCairoView;
-
-struct PuglInternalsImpl {
- NSApplication* app;
- PuglWrapperView* wrapperView;
- NSView* drawView;
- id window;
- NSEvent* nextEvent;
- uint32_t mods;
-};
-
-@interface PuglWindow : NSWindow
-{
-@public
- PuglView* puglview;
-}
-
-- (void) setPuglview:(PuglView*)view;
-
-@end
-
@implementation PuglWindow
- (id) initWithContentRect:(NSRect)contentRect
@@ -103,19 +67,30 @@ struct PuglInternalsImpl {
@end
-@interface PuglWrapperView : NSView<NSTextInputClient>
+@implementation PuglWrapperView
+
+- (void) resizeWithOldSuperviewSize:(NSSize)oldSize
{
-@public
- PuglView* puglview;
- NSTrackingArea* trackingArea;
- NSMutableAttributedString* markedText;
- NSTimer* timer;
- NSTimer* urgentTimer;
+ [super resizeWithOldSuperviewSize:oldSize];
+
+ const NSRect bounds = [self bounds];
+ puglview->backend->resize(puglview, bounds.size.width, bounds.size.height);
}
-@end
+- (void) drawRect:(NSRect)rect
+{
+ const PuglEventExpose ev = {
+ PUGL_EXPOSE,
+ 0,
+ rect.origin.x,
+ rect.origin.y,
+ rect.size.width,
+ rect.size.height,
+ 0
+ };
-@implementation PuglWrapperView
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+}
- (BOOL) isFlipped
{
@@ -127,6 +102,20 @@ struct PuglInternalsImpl {
return YES;
}
+- (void) dispatchConfigure:(NSRect)bounds
+{
+ const PuglEventConfigure ev = {
+ PUGL_CONFIGURE,
+ 0,
+ bounds.origin.x,
+ bounds.origin.y,
+ bounds.size.width,
+ bounds.size.height,
+ };
+
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+}
+
static uint32_t
getModifiers(const NSEvent* const ev)
{
@@ -584,147 +573,6 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
@end
-@interface PuglOpenGLView : NSOpenGLView
-{
-@public
- PuglView* puglview;
-}
-
-@end
-
-@implementation PuglOpenGLView
-
-- (id) initWithFrame:(NSRect)frame
-{
- const int major = puglview->hints.context_version_major;
- const int profile = ((puglview->hints.use_compat_profile || major < 3)
- ? NSOpenGLProfileVersionLegacy
- : puglview->hints.context_version_major >= 4
- ? NSOpenGLProfileVersion4_1Core
- : NSOpenGLProfileVersion3_2Core);
-
- NSOpenGLPixelFormatAttribute pixelAttribs[16] = {
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAOpenGLProfile, profile,
- NSOpenGLPFAColorSize, 32,
- NSOpenGLPFADepthSize, 32,
- NSOpenGLPFAMultisample, puglview->hints.samples ? 1 : 0,
- NSOpenGLPFASampleBuffers, puglview->hints.samples ? 1 : 0,
- NSOpenGLPFASamples, puglview->hints.samples,
- 0};
-
- NSOpenGLPixelFormat* pixelFormat = [
- [NSOpenGLPixelFormat alloc] initWithAttributes:pixelAttribs];
-
- if (pixelFormat) {
- self = [super initWithFrame:frame pixelFormat:pixelFormat];
- [pixelFormat release];
- } else {
- self = [super initWithFrame:frame];
- }
-
- if (self) {
- [[self openGLContext] makeCurrentContext];
- [self reshape];
- }
- return self;
-}
-
-- (void) reshape
-{
- [super reshape];
- [[self openGLContext] update];
-
- if (!puglview) {
- return;
- }
-
- const NSRect bounds = [self bounds];
- const PuglEventConfigure ev = {
- PUGL_CONFIGURE,
- 0,
- bounds.origin.x,
- bounds.origin.y,
- bounds.size.width,
- bounds.size.height,
- };
-
- puglview->backend->resize(puglview, ev.width, ev.height);
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
-}
-
-- (void) drawRect:(NSRect)rect
-{
- const PuglEventExpose ev = {
- PUGL_EXPOSE,
- 0,
- rect.origin.x,
- rect.origin.y,
- rect.size.width,
- rect.size.height,
- 0
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
-}
-
-@end
-
-@interface PuglCairoView : NSView
-{
-@public
- PuglView* puglview;
- cairo_surface_t* surface;
- cairo_t* cr;
-}
-
-@end
-
-@implementation PuglCairoView
-
-- (id) initWithFrame:(NSRect)frame
-{
- return (self = [super initWithFrame:frame]);
-}
-
-- (void) resizeWithOldSuperviewSize:(NSSize)oldSize
-{
- [super resizeWithOldSuperviewSize:oldSize];
-
- const NSRect bounds = [self bounds];
- puglview->backend->resize(puglview, bounds.size.width, bounds.size.height);
-
- const PuglEventConfigure ev = {
- PUGL_CONFIGURE,
- 0,
- bounds.origin.x,
- bounds.origin.y,
- bounds.size.width,
- bounds.size.height,
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
-}
-
-- (void) drawRect:(NSRect)rect
-{
- const PuglEventExpose ev = {
- PUGL_EXPOSE,
- 0,
- rect.origin.x,
- rect.origin.y,
- rect.size.width,
- rect.size.height,
- 0
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
-}
-
-@end
-
@interface PuglWindowDelegate : NSObject<NSWindowDelegate>
{
PuglWindow* window;
@@ -997,7 +845,7 @@ puglGetTime(PuglView* view)
void
puglPostRedisplay(PuglView* view)
{
- [view->impl->drawView setNeedsDisplay: YES];
+ [view->impl->wrapperView setNeedsDisplay: YES];
}
PuglNativeWindow
@@ -1005,205 +853,3 @@ puglGetNativeWindow(PuglView* view)
{
return (PuglNativeWindow)view->impl->wrapperView;
}
-
-// Backend
-
-static int
-puglMacConfigure(PuglView* PUGL_UNUSED(view))
-{
- return 0;
-}
-
-static int
-puglMacGlCreate(PuglView* view)
-{
- PuglInternals* impl = view->impl;
- PuglOpenGLView* drawView = [PuglOpenGLView alloc];
-
- drawView->puglview = view;
- [drawView initWithFrame:NSMakeRect(0, 0, view->width, view->height)];
- if (view->hints.resizable) {
- [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- } else {
- [drawView setAutoresizingMask:NSViewNotSizable];
- }
-
- impl->drawView = drawView;
- return 0;
-}
-
-static int
-puglMacGlDestroy(PuglView* view)
-{
- PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
-
- [drawView removeFromSuperview];
- [drawView release];
-
- view->impl->drawView = nil;
- return 0;
-}
-
-static int
-puglMacGlEnter(PuglView* view, bool PUGL_UNUSED(drawing))
-{
- PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
-
- [[drawView openGLContext] makeCurrentContext];
- return 0;
-}
-
-static int
-puglMacGlLeave(PuglView* view, bool drawing)
-{
- PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
-
- if (drawing) {
- [[drawView openGLContext] flushBuffer];
- }
-
- [NSOpenGLContext clearCurrentContext];
-
- return 0;
-}
-
-static int
-puglMacGlResize(PuglView* PUGL_UNUSED(view),
- int PUGL_UNUSED(width),
- int PUGL_UNUSED(height))
-{
- return 0;
-}
-
-static void*
-puglMacGlGetContext(PuglView* PUGL_UNUSED(view))
-{
- return NULL;
-}
-
-const PuglBackend* puglGlBackend(void)
-{
- static const PuglBackend backend = {
- puglMacConfigure,
- puglMacGlCreate,
- puglMacGlDestroy,
- puglMacGlEnter,
- puglMacGlLeave,
- puglMacGlResize,
- puglMacGlGetContext
- };
-
- return &backend;
-}
-
-#ifdef PUGL_HAVE_CAIRO
-
-static int
-puglMacCairoCreate(PuglView* view)
-{
- PuglInternals* impl = view->impl;
- PuglCairoView* drawView = [PuglCairoView alloc];
-
- drawView->puglview = view;
- [drawView initWithFrame:NSMakeRect(0, 0, view->width, view->height)];
- if (view->hints.resizable) {
- [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- } else {
- [drawView setAutoresizingMask:NSViewNotSizable];
- }
-
- impl->drawView = drawView;
- return 0;
-}
-
-static int
-puglMacCairoDestroy(PuglView* view)
-{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
-
- [drawView removeFromSuperview];
- [drawView release];
-
- view->impl->drawView = nil;
- return 0;
-}
-
-static int
-puglMacCairoEnter(PuglView* view, bool drawing)
-{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
- if (!drawing) {
- return 0;
- }
-
- // Get Quartz context and transform to Cairo coordinates (TL origin)
- CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
- CGContextTranslateCTM(context, 0.0, view->height);
- CGContextScaleCTM(context, 1.0, -1.0);
-
- // Create a Cairo surface and context for drawing to Quartz
- assert(!drawView->surface);
- assert(!drawView->cr);
-
- drawView->surface = cairo_quartz_surface_create_for_cg_context(
- context, view->width, view->height);
-
- drawView->cr = cairo_create(drawView->surface);
-
- return 0;
-}
-
-static int
-puglMacCairoLeave(PuglView* view, bool drawing)
-{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
- if (!drawing) {
- return 0;
- }
-
- CGContextRef context = cairo_quartz_surface_get_cg_context(drawView->surface);
-
- cairo_destroy(drawView->cr);
- cairo_surface_destroy(drawView->surface);
-
- CGContextFlush(context);
-
- drawView->cr = NULL;
- drawView->surface = NULL;
-
- return 0;
-}
-
-static int
-puglMacCairoResize(PuglView* PUGL_UNUSED(view),
- int PUGL_UNUSED(width),
- int PUGL_UNUSED(height))
-{
- // No need to resize, the surface is created for the drawing context
- return 0;
-}
-
-static void*
-puglMacCairoGetContext(PuglView* view)
-{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
-
- return drawView->cr;
-}
-
-const PuglBackend* puglCairoBackend(void)
-{
- static const PuglBackend backend = {
- puglMacConfigure,
- puglMacCairoCreate,
- puglMacCairoDestroy,
- puglMacCairoEnter,
- puglMacCairoLeave,
- puglMacCairoResize,
- puglMacCairoGetContext
- };
-
- return &backend;
-}
-
-#endif
diff --git a/pugl/detail/mac_cairo.m b/pugl/detail/mac_cairo.m
new file mode 100644
index 0000000..b0a8db5
--- /dev/null
+++ b/pugl/detail/mac_cairo.m
@@ -0,0 +1,166 @@
+/*
+ Copyright 2019 David Robillard <http://drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/**
+ @file mac_cairo.m Cairo graphics backend for MacOS.
+*/
+
+#include "pugl/detail/implementation.h"
+#include "pugl/detail/mac.h"
+#include "pugl/pugl_cairo_backend.h"
+
+#include <cairo-quartz.h>
+
+#import <Cocoa/Cocoa.h>
+
+#include <assert.h>
+
+@interface PuglCairoView : NSView
+{
+@public
+ PuglView* puglview;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+}
+
+@end
+
+@implementation PuglCairoView
+
+- (id) initWithFrame:(NSRect)frame
+{
+ return (self = [super initWithFrame:frame]);
+}
+
+- (void) resizeWithOldSuperviewSize:(NSSize)oldSize
+{
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+
+ [super resizeWithOldSuperviewSize:oldSize];
+ [wrapper dispatchConfigure:[self bounds]];
+}
+
+@end
+
+static int
+puglMacCairoConfigure(PuglView* PUGL_UNUSED(view))
+{
+ return 0;
+}
+
+static int
+puglMacCairoCreate(PuglView* view)
+{
+ PuglInternals* impl = view->impl;
+ PuglCairoView* drawView = [PuglCairoView alloc];
+
+ drawView->puglview = view;
+ [drawView initWithFrame:NSMakeRect(0, 0, view->width, view->height)];
+ if (view->hints.resizable) {
+ [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ } else {
+ [drawView setAutoresizingMask:NSViewNotSizable];
+ }
+
+ impl->drawView = drawView;
+ return 0;
+}
+
+static int
+puglMacCairoDestroy(PuglView* view)
+{
+ PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
+
+ [drawView removeFromSuperview];
+ [drawView release];
+
+ view->impl->drawView = nil;
+ return 0;
+}
+
+static int
+puglMacCairoEnter(PuglView* view, bool drawing)
+{
+ PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
+ if (!drawing) {
+ return 0;
+ }
+
+ assert(!drawView->surface);
+ assert(!drawView->cr);
+
+ CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
+
+ drawView->surface = cairo_quartz_surface_create_for_cg_context(
+ context, view->width, view->height);
+
+ drawView->cr = cairo_create(drawView->surface);
+
+ return 0;
+}
+
+static int
+puglMacCairoLeave(PuglView* view, bool drawing)
+{
+ PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
+ if (!drawing) {
+ return 0;
+ }
+
+ assert(drawView->surface);
+ assert(drawView->cr);
+
+ CGContextRef context = cairo_quartz_surface_get_cg_context(drawView->surface);
+
+ cairo_destroy(drawView->cr);
+ cairo_surface_destroy(drawView->surface);
+ drawView->cr = NULL;
+ drawView->surface = NULL;
+
+ CGContextFlush(context);
+
+ return 0;
+}
+
+static int
+puglMacCairoResize(PuglView* PUGL_UNUSED(view),
+ int PUGL_UNUSED(width),
+ int PUGL_UNUSED(height))
+{
+ // No need to resize, the surface is created for the drawing context
+ return 0;
+}
+
+static void*
+puglMacCairoGetContext(PuglView* view)
+{
+ return ((PuglCairoView*)view->impl->drawView)->cr;
+}
+
+const PuglBackend* puglCairoBackend(void)
+{
+ static const PuglBackend backend = {
+ puglMacCairoConfigure,
+ puglMacCairoCreate,
+ puglMacCairoDestroy,
+ puglMacCairoEnter,
+ puglMacCairoLeave,
+ puglMacCairoResize,
+ puglMacCairoGetContext
+ };
+
+ return &backend;
+}
diff --git a/pugl/detail/mac_gl.m b/pugl/detail/mac_gl.m
new file mode 100644
index 0000000..4a6e39a
--- /dev/null
+++ b/pugl/detail/mac_gl.m
@@ -0,0 +1,184 @@
+/*
+ Copyright 2019 David Robillard <http://drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/**
+ @file mac_gl.m OpenGL graphics backend for MacOS.
+*/
+
+#include "pugl/detail/implementation.h"
+#include "pugl/detail/mac.h"
+#include "pugl/pugl_gl_backend.h"
+
+#ifndef __MAC_10_10
+#define NSOpenGLProfileVersion4_1Core NSOpenGLProfileVersion3_2Core
+typedef NSUInteger NSEventModifierFlags;
+typedef NSUInteger NSWindowStyleMask;
+#endif
+
+@interface PuglOpenGLView : NSOpenGLView
+{
+@public
+ PuglView* puglview;
+}
+
+@end
+
+@implementation PuglOpenGLView
+
+- (id) initWithFrame:(NSRect)frame
+{
+ const int major = puglview->hints.context_version_major;
+ const int profile = ((puglview->hints.use_compat_profile || major < 3)
+ ? NSOpenGLProfileVersionLegacy
+ : puglview->hints.context_version_major >= 4
+ ? NSOpenGLProfileVersion4_1Core
+ : NSOpenGLProfileVersion3_2Core);
+
+ NSOpenGLPixelFormatAttribute pixelAttribs[16] = {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFAOpenGLProfile, profile,
+ NSOpenGLPFAColorSize, 32,
+ NSOpenGLPFADepthSize, 32,
+ NSOpenGLPFAMultisample, puglview->hints.samples ? 1 : 0,
+ NSOpenGLPFASampleBuffers, puglview->hints.samples ? 1 : 0,
+ NSOpenGLPFASamples, puglview->hints.samples,
+ 0};
+
+ NSOpenGLPixelFormat* pixelFormat = [
+ [NSOpenGLPixelFormat alloc] initWithAttributes:pixelAttribs];
+
+ if (pixelFormat) {
+ self = [super initWithFrame:frame pixelFormat:pixelFormat];
+ [pixelFormat release];
+ } else {
+ self = [super initWithFrame:frame];
+ }
+
+ if (self) {
+ [[self openGLContext] makeCurrentContext];
+ [self reshape];
+ }
+ return self;
+}
+
+- (void) reshape
+{
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+
+ [super reshape];
+ [wrapper dispatchConfigure:[self bounds]];
+}
+
+- (void) update
+{
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+
+ [super update];
+ [wrapper dispatchConfigure:[self bounds]];
+}
+
+@end
+
+static int
+puglMacGlConfigure(PuglView* PUGL_UNUSED(view))
+{
+ return 0;
+}
+
+static int
+puglMacGlCreate(PuglView* view)
+{
+ PuglInternals* impl = view->impl;
+ PuglOpenGLView* drawView = [PuglOpenGLView alloc];
+
+ drawView->puglview = view;
+ [drawView initWithFrame:NSMakeRect(0, 0, view->width, view->height)];
+ if (view->hints.resizable) {
+ [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ } else {
+ [drawView setAutoresizingMask:NSViewNotSizable];
+ }
+
+ impl->drawView = drawView;
+ return 0;
+}
+
+static int
+puglMacGlDestroy(PuglView* view)
+{
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+
+ [drawView removeFromSuperview];
+ [drawView release];
+
+ view->impl->drawView = nil;
+ return 0;
+}
+
+static int
+puglMacGlEnter(PuglView* view, bool PUGL_UNUSED(drawing))
+{
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+
+ [[drawView openGLContext] makeCurrentContext];
+ return 0;
+}
+
+static int
+puglMacGlLeave(PuglView* view, bool drawing)
+{
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+
+ if (drawing) {
+ [[drawView openGLContext] flushBuffer];
+ }
+
+ [NSOpenGLContext clearCurrentContext];
+
+ return 0;
+}
+
+static int
+puglMacGlResize(PuglView* view, int PUGL_UNUSED(width), int PUGL_UNUSED(height))
+{
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+
+ [drawView reshape];
+
+ return 0;
+}
+
+static void*
+puglMacGlGetContext(PuglView* PUGL_UNUSED(view))
+{
+ return NULL;
+}
+
+const PuglBackend* puglGlBackend(void)
+{
+ static const PuglBackend backend = {
+ puglMacGlConfigure,
+ puglMacGlCreate,
+ puglMacGlDestroy,
+ puglMacGlEnter,
+ puglMacGlLeave,
+ puglMacGlResize,
+ puglMacGlGetContext
+ };
+
+ return &backend;
+}