From c4c99727c52db828d662dd9632d6d9f79b97c1ff Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 23 May 2016 12:46:57 +0200 Subject: [PATCH] Add dynamic loading of HIToolbox.framework Fixes #717. --- CMakeLists.txt | 9 +++---- src/cocoa_init.m | 62 +++++++++++++++++++++++++++++++++++++------- src/cocoa_platform.h | 17 ++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02040dd0..4f274f5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -299,20 +299,17 @@ if (_GLFW_COCOA) find_library(IOKIT_FRAMEWORK IOKit) find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) find_library(CORE_VIDEO_FRAMEWORK CoreVideo) - find_library(CARBON_FRAMEWORK Carbon) mark_as_advanced(COCOA_FRAMEWORK IOKIT_FRAMEWORK CORE_FOUNDATION_FRAMEWORK - CORE_VIDEO_FRAMEWORK - CARBON_FRAMEWORK) + CORE_VIDEO_FRAMEWORK) list(APPEND glfw_LIBRARIES "${COCOA_FRAMEWORK}" "${IOKIT_FRAMEWORK}" "${CORE_FOUNDATION_FRAMEWORK}" - "${CORE_VIDEO_FRAMEWORK}" - "${CARBON_FRAMEWORK}") + "${CORE_VIDEO_FRAMEWORK}") set(glfw_PKG_DEPS "") - set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo -framework Carbon") + set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo") endif() #-------------------------------------------------------------------- diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 9b6434d5..a2337414 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -200,6 +200,58 @@ static void createKeyTables(void) } } +// Load HIToolbox.framework and the TIS symbols we need from it +// This works only because Cocoa has already loaded it properly +// +static GLFWbool initializeTIS(void) +{ + _glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox")); + if (!_glfw.ns.tis.bundle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to load HIToolbox.framework"); + return GLFW_FALSE; + } + + CFStringRef* kPropertyUnicodeKeyLayoutData = + CFBundleGetDataPointerForName(_glfw.ns.tis.bundle, + CFSTR("kTISPropertyUnicodeKeyLayoutData")); + _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource = + CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle, + CFSTR("TISCopyCurrentKeyboardLayoutInputSource")); + _glfw.ns.tis.GetInputSourceProperty = + CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle, + CFSTR("TISGetInputSourceProperty")); + _glfw.ns.tis.GetKbdType = + CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle, + CFSTR("LMGetKbdType")); + + if (!kPropertyUnicodeKeyLayoutData || + !TISCopyCurrentKeyboardLayoutInputSource || + !TISGetInputSourceProperty || + !LMGetKbdType) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to load TIS API symbols"); + return GLFW_FALSE; + } + + _glfw.ns.tis.kPropertyUnicodeKeyLayoutData = *kPropertyUnicodeKeyLayoutData; + + // TODO: Catch kTISNotifySelectedKeyboardInputSourceChanged and update + + _glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource(); + if (!_glfw.ns.inputSource) + return GLFW_FALSE; + + _glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource, + kTISPropertyUnicodeKeyLayoutData); + if (!_glfw.ns.unicodeData) + return GLFW_FALSE; + + return GLFW_TRUE; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -221,15 +273,7 @@ int _glfwPlatformInit(void) CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); - // TODO: Catch kTISNotifySelectedKeyboardInputSourceChanged and update - - _glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource(); - if (!_glfw.ns.inputSource) - return GLFW_FALSE; - - _glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource, - kTISPropertyUnicodeKeyLayoutData); - if (!_glfw.ns.unicodeData) + if (!initializeTIS()) return GLFW_FALSE; if (!_glfwInitThreadLocalStoragePOSIX()) diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 95eae62b..134c423c 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -56,6 +56,15 @@ typedef void* id; #define _GLFW_EGL_CONTEXT_STATE #define _GLFW_EGL_LIBRARY_CONTEXT_STATE +// HIToolbox.framework pointer typedefs +#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData +typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void); +#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource +typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef); +#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty +typedef UInt8 (*PFN_LMGetKbdType)(void); +#define LMGetKbdType _glfw.ns.tis.GetKbdType + // Cocoa-specific per-window data // @@ -89,6 +98,14 @@ typedef struct _GLFWlibraryNS short int nativeKeys[GLFW_KEY_LAST + 1]; char* clipboardString; + struct { + CFBundleRef bundle; + PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource; + PFN_TISGetInputSourceProperty GetInputSourceProperty; + PFN_LMGetKbdType GetKbdType; + CFStringRef kPropertyUnicodeKeyLayoutData; + } tis; + } _GLFWlibraryNS;