|
|
|
|
@ -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,12 +837,25 @@ 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];
|
|
|
|
|
|
|
|
|
|
// Don't use accumulation buffer support; it's not accelerated
|
|
|
|
|
@ -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() {
|
|
|
|
|
|
|
|
|
|
|