mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-19 18:47:26 +03:00
fb98aa650d
This only changes some formatting, whitespace, etc.. There are no changes to the functionality. Let me know if you don't like some of those changes.
331 lines
10 KiB
Objective-C
331 lines
10 KiB
Objective-C
//========================================================================
|
|
// GLFW 3.3 macOS - www.glfw.org
|
|
//------------------------------------------------------------------------
|
|
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
//
|
|
// This software is provided 'as-is', without any express or implied
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
// arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it
|
|
// freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software. If you use this software
|
|
// in a product, an acknowledgment in the product documentation would
|
|
// be appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such, and must not
|
|
// be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source
|
|
// distribution.
|
|
//
|
|
//========================================================================
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
|
{
|
|
if (window)
|
|
[window->context.nsgl.object makeCurrentContext];
|
|
else
|
|
[NSOpenGLContext clearCurrentContext];
|
|
|
|
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
|
}
|
|
|
|
static void swapBuffersNSGL(_GLFWwindow* window)
|
|
{
|
|
// ARP appears to be unnecessary, but this is future-proof
|
|
[window->context.nsgl.object flushBuffer];
|
|
}
|
|
|
|
static void swapIntervalNSGL(int interval)
|
|
{
|
|
// As of Mojave this does not work so we use CVDisplayLink instead
|
|
(void)(interval);
|
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
"NSGL: Swap intervals do not work on macOS");
|
|
}
|
|
|
|
static int extensionSupportedNSGL(const char* extension)
|
|
{
|
|
// There are no NSGL extensions
|
|
return false;
|
|
}
|
|
|
|
static GLFWglproc getProcAddressNSGL(const char* procname)
|
|
{
|
|
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
|
|
procname,
|
|
kCFStringEncodingASCII);
|
|
|
|
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
|
symbolName);
|
|
|
|
CFRelease(symbolName);
|
|
|
|
return symbol;
|
|
}
|
|
|
|
static void destroyContextNSGL(_GLFWwindow* window)
|
|
{
|
|
[window->context.nsgl.pixelFormat release];
|
|
window->context.nsgl.pixelFormat = nil;
|
|
|
|
[window->context.nsgl.object release];
|
|
window->context.nsgl.object = nil;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
////// GLFW internal API //////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize OpenGL support
|
|
//
|
|
bool _glfwInitNSGL(void)
|
|
{
|
|
if (_glfw.nsgl.framework)
|
|
return true;
|
|
|
|
_glfw.nsgl.framework =
|
|
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
|
if (_glfw.nsgl.framework == NULL)
|
|
{
|
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
"NSGL: Failed to locate OpenGL framework");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Terminate OpenGL support
|
|
//
|
|
void _glfwTerminateNSGL(void)
|
|
{
|
|
}
|
|
|
|
// Create the OpenGL context
|
|
//
|
|
bool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|
const _GLFWctxconfig* ctxconfig,
|
|
const _GLFWfbconfig* fbconfig)
|
|
{
|
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
|
{
|
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
"NSGL: OpenGL ES is not available on macOS");
|
|
return false;
|
|
}
|
|
|
|
if (ctxconfig->major > 2)
|
|
{
|
|
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
|
|
{
|
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Context robustness modes (GL_KHR_robustness) are not yet supported by
|
|
// macOS but are not a hard constraint, so ignore and continue
|
|
|
|
// Context release behaviors (GL_KHR_context_flush_control) are not yet
|
|
// supported by macOS but are not a hard constraint, so ignore and continue
|
|
|
|
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
|
|
// a hard constraint, so ignore and continue
|
|
|
|
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
|
// are not a hard constraint, so ignore and continue
|
|
|
|
#define addAttrib(a) \
|
|
{ \
|
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
|
attribs[index++] = a; \
|
|
}
|
|
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
|
|
|
|
NSOpenGLPixelFormatAttribute attribs[40];
|
|
int index = 0;
|
|
|
|
addAttrib(NSOpenGLPFAAccelerated);
|
|
addAttrib(NSOpenGLPFAClosestPolicy);
|
|
|
|
if (ctxconfig->nsgl.offline)
|
|
{
|
|
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
|
|
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
|
|
// Info.plist for unbundled applications
|
|
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
|
// a straightforward wrapper of its CGL counterpart
|
|
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
|
|
}
|
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
|
if (ctxconfig->major >= 4)
|
|
{
|
|
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
|
}
|
|
else
|
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
|
if (ctxconfig->major >= 3)
|
|
{
|
|
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
|
}
|
|
|
|
if (ctxconfig->major <= 2)
|
|
{
|
|
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
|
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
|
|
|
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
|
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
|
fbconfig->accumBlueBits != GLFW_DONT_CARE &&
|
|
fbconfig->accumAlphaBits != GLFW_DONT_CARE)
|
|
{
|
|
const int accumBits = fbconfig->accumRedBits +
|
|
fbconfig->accumGreenBits +
|
|
fbconfig->accumBlueBits +
|
|
fbconfig->accumAlphaBits;
|
|
|
|
setAttrib(NSOpenGLPFAAccumSize, accumBits);
|
|
}
|
|
}
|
|
|
|
if (fbconfig->redBits != GLFW_DONT_CARE &&
|
|
fbconfig->greenBits != GLFW_DONT_CARE &&
|
|
fbconfig->blueBits != GLFW_DONT_CARE)
|
|
{
|
|
int colorBits = fbconfig->redBits +
|
|
fbconfig->greenBits +
|
|
fbconfig->blueBits;
|
|
|
|
// macOS needs non-zero color size, so set reasonable values
|
|
if (colorBits == 0)
|
|
colorBits = 24;
|
|
else if (colorBits < 15)
|
|
colorBits = 15;
|
|
|
|
setAttrib(NSOpenGLPFAColorSize, colorBits);
|
|
}
|
|
|
|
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
|
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
|
|
|
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
|
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
|
|
|
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
|
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
|
|
|
if (fbconfig->stereo)
|
|
{
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
"NSGL: Stereo rendering is deprecated");
|
|
return false;
|
|
#else
|
|
addAttrib(NSOpenGLPFAStereo);
|
|
#endif
|
|
}
|
|
|
|
if (fbconfig->doublebuffer)
|
|
addAttrib(NSOpenGLPFADoubleBuffer);
|
|
|
|
if (fbconfig->samples != GLFW_DONT_CARE)
|
|
{
|
|
if (fbconfig->samples == 0)
|
|
{
|
|
setAttrib(NSOpenGLPFASampleBuffers, 0);
|
|
}
|
|
else
|
|
{
|
|
setAttrib(NSOpenGLPFASampleBuffers, 1);
|
|
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
|
|
}
|
|
}
|
|
|
|
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
|
// framebuffer, so there's no need (and no way) to request it
|
|
|
|
addAttrib(0);
|
|
|
|
#undef addAttrib
|
|
#undef setAttrib
|
|
|
|
window->context.nsgl.pixelFormat =
|
|
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
|
if (window->context.nsgl.pixelFormat == nil)
|
|
{
|
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
"NSGL: Failed to find a suitable pixel format");
|
|
return false;
|
|
}
|
|
|
|
NSOpenGLContext* share = NULL;
|
|
|
|
if (ctxconfig->share)
|
|
share = ctxconfig->share->context.nsgl.object;
|
|
|
|
window->context.nsgl.object =
|
|
[[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
|
|
shareContext:share];
|
|
if (window->context.nsgl.object == nil)
|
|
{
|
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
"NSGL: Failed to create OpenGL context");
|
|
return false;
|
|
}
|
|
|
|
if (fbconfig->transparent)
|
|
{
|
|
GLint opaque = 0;
|
|
[window->context.nsgl.object setValues:&opaque
|
|
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
|
}
|
|
|
|
if (window->ns.retina)
|
|
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
|
|
|
GLint interval = 0;
|
|
[window->context.nsgl.object setValues:&interval
|
|
forParameter:NSOpenGLContextParameterSwapInterval];
|
|
|
|
[window->context.nsgl.object setView:window->ns.view];
|
|
|
|
window->context.makeCurrent = makeContextCurrentNSGL;
|
|
window->context.swapBuffers = swapBuffersNSGL;
|
|
window->context.swapInterval = swapIntervalNSGL;
|
|
window->context.extensionSupported = extensionSupportedNSGL;
|
|
window->context.getProcAddress = getProcAddressNSGL;
|
|
window->context.destroy = destroyContextNSGL;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
////// GLFW native API //////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
|
|
{
|
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
|
|
|
|
if (window->context.client == GLFW_NO_API)
|
|
{
|
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
return window->context.nsgl.object;
|
|
}
|