Browse Source

OS X: Add keyboard layout detection and fix build

Rhody Lugo 10 years ago
parent
commit
d046bd88ad
4 changed files with 100 additions and 2 deletions
  1. 1 1
      drivers/theoraplayer/SCsub
  2. 1 1
      platform/osx/detect.py
  3. 2 0
      platform/osx/os_osx.h
  4. 96 0
      platform/osx/os_osx.mm

+ 1 - 1
drivers/theoraplayer/SCsub

@@ -70,7 +70,7 @@ if env["platform"] == "iphone":
 		env_theora.Append(CPPFLAGS=["-D_IOS", "-D__ARM_NEON__", "-fstrict-aliasing", "-fmessage-length=210", "-fdiagnostics-show-note-include-stack", "-fmacro-backtrace-limit=0", "-fcolor-diagnostics", "-Wno-trigraphs", "-fpascal-strings", "-fvisibility=hidden", "-fvisibility-inlines-hidden"])
 
 env_theora.Append(CPPFLAGS=["-D_LIB", "-D__THEORA"]) # removed -D_YUV_C
-env_theora.Append(CPPFLAGS=["-D_YUV_LIBYUV", "-DLIBYUV_NEON"])
+env_theora.Append(CPPFLAGS=["-D_YUV_LIBYUV"])
 #env_theora.Append(CPPFLAGS=["-D_YUV_C"])
 
 if env["platform"] == "iphone":

+ 1 - 1
platform/osx/detect.py

@@ -78,7 +78,7 @@ def configure(env):
 	env.Append(LIBS=['pthread'])
 	#env.Append(CPPFLAGS=['-F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks', '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk', '-mmacosx-version-min=10.4'])
 	#env.Append(LINKFLAGS=['-mmacosx-version-min=10.4', '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk', '-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk'])
-	env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit','-lz'])
+	env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit','-lz'])
 
 	if (env["CXX"]=="clang++"):
 		env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])

+ 2 - 0
platform/osx/os_osx.h

@@ -156,6 +156,8 @@ public:
 
 	virtual String get_executable_path() const;
 
+	virtual LatinKeyboardVariant get_latin_keyboard_variant() const;
+
 	virtual void move_window_to_foreground();
 
 	void run();

+ 96 - 0
platform/osx/os_osx.mm

@@ -27,6 +27,8 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #import <Cocoa/Cocoa.h>
+
+#include <Carbon/Carbon.h>
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOCFPlugIn.h>
 #include <IOKit/hid/IOHIDLib.h>
@@ -835,11 +837,24 @@ void OS_OSX::initialize_core() {
 
 }
 
+static bool keyboard_layout_dirty = true;
+static void keyboardLayoutChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
+	keyboard_layout_dirty = true;
+}
+
 void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
 
 	/*** OSX INITIALIZATION ***/
 	/*** OSX INITIALIZATION ***/
 	/*** OSX INITIALIZATION ***/
+
+	keyboard_layout_dirty = true;
+
+	// Register to be notified on keyboard layout changes
+	CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
+									NULL, keyboardLayoutChanged,
+									kTISNotifySelectedKeyboardInputSourceChanged, NULL,
+									CFNotificationSuspensionBehaviorDeliverImmediately);
     
 	window_delegate = [[GodotWindowDelegate alloc] init];
 
@@ -1007,6 +1022,8 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
 }
 void OS_OSX::finalize() {
 
+	CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
+
 }
 
 void OS_OSX::set_main_loop( MainLoop * p_main_loop ) {
@@ -1241,6 +1258,85 @@ String OS_OSX::get_executable_path() const {
 
 }
 
+// Returns string representation of keys, if they are printable.
+//
+static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
+
+	TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+	if (!currentKeyboard)
+		return nil;
+
+	CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
+	if (!layoutData)
+		return nil;
+
+	const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+
+	OSStatus err;
+	CFMutableStringRef output = CFStringCreateMutable(NULL, 0);
+
+	for (int i=0; i<length; ++i) {
+
+		UInt32 keysDown = 0;
+		UniChar chars[4];
+		UniCharCount realLength;
+
+		err = UCKeyTranslate(keyboardLayout,
+					   keyCode[i],
+					   kUCKeyActionDisplay,
+					   0,
+					   LMGetKbdType(),
+					   kUCKeyTranslateNoDeadKeysBit,
+					   &keysDown,
+					   sizeof(chars) / sizeof(chars[0]),
+					   &realLength,
+					   chars);
+
+		if (err != noErr) {
+			CFRelease(output);
+			return nil;
+		}
+
+		CFStringRef chararter = CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+		CFStringAppend(output, chararter);
+		CFRelease(chararter);
+	}
+
+	//CFStringUppercase(output, NULL);
+
+	return (NSString *)output;
+}
+OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const {
+
+	static LatinKeyboardVariant layout = LATIN_KEYBOARD_QWERTY;
+
+	if (keyboard_layout_dirty) {
+
+		layout = LATIN_KEYBOARD_QWERTY;
+
+		CGKeyCode keys[] = {kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y};
+		NSString *test = createStringForKeys(keys, 6);
+
+		if ([test isEqualToString:@"qwertz"]) {
+			layout = LATIN_KEYBOARD_QWERTZ;
+		} else if ([test isEqualToString:@"azerty"]) {
+			layout = LATIN_KEYBOARD_AZERTY;
+		} else if ([test isEqualToString:@"qzerty"]) {
+			layout = LATIN_KEYBOARD_QZERTY;
+		} else if ([test isEqualToString:@"',.pyf"]) {
+			layout = LATIN_KEYBOARD_DVORAK;
+		} else if ([test isEqualToString:@"xvlcwk"]) {
+			layout = LATIN_KEYBOARD_NEO;
+		}
+
+		[test release];
+
+		keyboard_layout_dirty = false;
+		return layout;
+	}
+
+	return layout;
+}
 
 void OS_OSX::process_events() {