From 8101d7a7b67fc3414769b25944dc7c02b58d53d0 Mon Sep 17 00:00:00 2001 From: Matthew Henry Date: Sat, 14 Dec 2013 01:03:39 +1000 Subject: [PATCH 1/3] Replace CGDisplayIOServicePort with a workaround implementation This could be cleaned up and refined a bit by comparing more display attributes when available, but it gets the job done. --- src/cocoa_monitor.m | 97 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 13 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index caddde403..3965f21ef 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -36,6 +36,68 @@ #include +// Returns the io_service_t corresponding to a CG display ID, or 0 on failure. +// The io_service_t should be released with IOObjectRelease when not needed. +// +static io_service_t IOServicePortFromCGDisplayID(CGDirectDisplayID displayID) +{ + io_iterator_t iter; + io_service_t serv, servicePort = 0; + + CFMutableDictionaryRef matching = IOServiceMatching("IODisplayConnect"); + + // releases matching for us + kern_return_t err = IOServiceGetMatchingServices(kIOMasterPortDefault, + matching, + &iter); + if (err) + { + return 0; + } + + while ((serv = IOIteratorNext(iter)) != 0) + { + CFDictionaryRef info; + CFIndex vendorID, productID; + CFNumberRef vendorIDRef, productIDRef; + Boolean success; + + info = IODisplayCreateInfoDictionary(serv, + kIODisplayOnlyPreferredName); + + vendorIDRef = CFDictionaryGetValue(info, + CFSTR(kDisplayVendorID)); + productIDRef = CFDictionaryGetValue(info, + CFSTR(kDisplayProductID)); + + success = CFNumberGetValue(vendorIDRef, kCFNumberCFIndexType, + &vendorID); + success &= CFNumberGetValue(productIDRef, kCFNumberCFIndexType, + &productID); + + if (!success) + { + CFRelease(info); + continue; + } + + if (CGDisplayVendorNumber(displayID) != vendorID || + CGDisplayModelNumber(displayID) != productID) + { + CFRelease(info); + continue; + } + + // we're a match + servicePort = serv; + CFRelease(info); + break; + } + + IOObjectRelease(iter); + return servicePort; +} + // Get the name of the specified display // static const char* getDisplayName(CGDirectDisplayID displayID) @@ -44,30 +106,39 @@ static const char* getDisplayName(CGDirectDisplayID displayID) CFDictionaryRef info, names; CFStringRef value; CFIndex size; - - info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), - kIODisplayOnlyPreferredName); - names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); - - if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), - (const void**) &value)) + + io_service_t serv = IOServicePortFromCGDisplayID(displayID); + if (!serv) { - _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name"); - + return strdup("Unknown"); + } + + info = IODisplayCreateInfoDictionary(serv, + kIODisplayOnlyPreferredName); + + IOObjectRelease(serv); + + names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); + + if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), + (const void**) &value)) + { + CFRelease(info); return strdup("Unknown"); } - + size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), - kCFStringEncodingUTF8); + kCFStringEncodingUTF8); name = calloc(size + 1, sizeof(char)); CFStringGetCString(value, name, size, kCFStringEncodingUTF8); - + CFRelease(info); - + return name; } + // Check whether the display mode should be included in enumeration // static GLboolean modeIsGood(CGDisplayModeRef mode) From 139803fd07cf461a69cfe0d3f7eebcf514807627 Mon Sep 17 00:00:00 2001 From: Matthew Henry Date: Sat, 14 Dec 2013 01:31:46 +1000 Subject: [PATCH 2/3] Replace an input error call I accidentally removed --- src/cocoa_monitor.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 3965f21ef..e5499d034 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -123,7 +123,7 @@ static const char* getDisplayName(CGDirectDisplayID displayID) if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), (const void**) &value)) { - + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name"); CFRelease(info); return strdup("Unknown"); } From 2d1a98136ef876ba6548cf9acb3fea3aae695718 Mon Sep 17 00:00:00 2001 From: Matthew Henry Date: Sun, 12 Jan 2014 12:16:36 +1000 Subject: [PATCH 3/3] Added support for CGL context access in glfw3native.h This allows access to the underlying context on OSX without dropping into ObjC as CGL is an entirely C-based API --- .gitignore | 1 + include/GLFW/glfw3native.h | 13 ++++++++++++- src/nsgl_context.m | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4f8ddbc96..9e330a9b6 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ src/glfw_config.h src/glfw3.pc src/glfwConfig.cmake src/glfwConfigVersion.cmake +install_manifest.txt # Compiled binaries src/libglfw.so diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index d570f5876..5117d4cc1 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -55,7 +55,8 @@ extern "C" { * * The available context API macros are: * * `GLFW_EXPOSE_NATIVE_WGL` - * * `GLFW_EXPOSE_NATIVE_NSGL` + * * `GLFW_EXPOSE_NATIVE_NSGL` (OSX, ObjC required to do anything useful) + * * `GLFW_EXPOSE_NATIVE_CGL` * * `GLFW_EXPOSE_NATIVE_GLX` * * `GLFW_EXPOSE_NATIVE_EGL` * @@ -88,6 +89,8 @@ extern "C" { /* WGL is declared by windows.h */ #elif defined(GLFW_EXPOSE_NATIVE_NSGL) /* NSGL is declared by Cocoa.h */ +#elif defined(GLFW_EXPOSE_NATIVE_CGL) + #include #elif defined(GLFW_EXPOSE_NATIVE_GLX) #include #elif defined(GLFW_EXPOSE_NATIVE_EGL) @@ -133,6 +136,14 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); #endif +#if defined(GLFW_EXPOSE_NATIVE_CGL) +/*! @brief Returns the `CGLContextObj` of the specified window. + * @return The `CGLContextObj` of the specified window. + * @ingroup native + */ +GLFWAPI CGLContextObj glfwGetCGLContext(GLFWwindow* window); +#endif + #if defined(GLFW_EXPOSE_NATIVE_X11) /*! @brief Returns the `Display` used by GLFW. * @return The `Display` used by GLFW. diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 71638ad19..3a6b75c03 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -289,3 +289,9 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) return window->nsgl.context; } +GLFWAPI CGLContextObj glfwGetCGLContext(GLFWwindow* handle) +{ + NSOpenGLContext* ctx = glfwGetNSGLContext(handle); + return [ctx CGLContextObj]; +} +