From f49e2a7af5b517124a855a8ab6380a74ad898a7f Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 14 Sep 2008 19:09:13 +0000 Subject: Horribly hacked together Unicode keyboard support for OS X. But although this needs a lot of fixing and cleaning, we can now at least enter characters outside of the stricly ASCII range again. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6242 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_mac.cxx | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx index af58c2fe2..06ee599a0 100644 --- a/src/Fl_mac.cxx +++ b/src/Fl_mac.cxx @@ -1091,13 +1091,121 @@ static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned shor return deflt; } +/* + * + */ +static int keycodeToUnicode( + char * uniChars, int maxChars, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr) +{ + // first get the keyboard mapping in a post 10.2 way + + Ptr resource; + TextEncoding encoding; + static TextEncoding lastEncoding = kTextEncodingMacRoman; + int len = 0; + KeyboardLayoutRef currentLayout = NULL; + static KeyboardLayoutRef lastLayout = NULL; + SInt32 currentLayoutId = 0; + static SInt32 lastLayoutId; + int hasLayoutChanged = false; + static Ptr uchr = NULL; + static Ptr KCHR = NULL; + ScriptCode currentKeyScript; + + KLGetCurrentKeyboardLayout(¤tLayout); + if (currentLayout) { + KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, (const void**)¤tLayoutId); + if ( (lastLayout != currentLayout) || (lastLayoutId != currentLayoutId) ) { + lastLayout = currentLayout; + lastLayoutId = currentLayoutId; + uchr = NULL; + KCHR = NULL; + if ((KLGetKeyboardLayoutProperty(currentLayout, kKLuchrData, (const void**)&uchr) == noErr) && (uchr != NULL)) { + // done + } else if ((KLGetKeyboardLayoutProperty(currentLayout, kKLKCHRData, (const void**)&KCHR) == noErr) && (KCHR != NULL)) { + // done + } + // FIXME No Layout property found. Now we have a problem. + } + } + if (hasLayoutChanged) { + //deadKeyStateUp = deadKeyStateDown = 0; + if (KCHR != NULL) { + // FIXME this must not happen + } else if (uchr == NULL) { + KCHR = (Ptr) GetScriptManagerVariable(smKCHRCache); + } + } + if (uchr != NULL) { + // this is what I expect + resource = uchr; + } else { + resource = KCHR; + encoding = lastEncoding; + // this is actually not supported by the following code and will likely crash + } + + // now apply that keyboard mapping to our keycode + + int action; + //OptionBits options = 0; + OptionBits options = kUCKeyTranslateNoDeadKeysMask; + unsigned long keyboardType; + keycode &= 0xFF; + modifiers = (modifiers >> 8) & 0xFF; + keyboardType = LMGetKbdType(); + OSStatus status; + UniCharCount actuallength; + UniChar utext[10]; + + switch(eKind) { + case kEventRawKeyDown: action = kUCKeyActionDown; break; + case kEventRawKeyUp: action = kUCKeyActionUp; break; + case kEventRawKeyRepeat: action = kUCKeyActionAutoKey; break; + default: return 0; + } + + status = UCKeyTranslate( + (const UCKeyboardLayout *) uchr, + keycode, action, modifiers, keyboardType, + options, deadKeyStatePtr, + 10, &actuallength, utext); + + if ((0 == actuallength) && (0 != *deadKeyStatePtr)) { + /* + * More data later + */ + + return 0; + } + + *deadKeyStatePtr = 0; + + if (noErr != status) { + fprintf(stderr,"UCKeyTranslate failed: %d", (int) status); + actuallength = 0; + } + // FIXME no bounds check (see maxchars) + int i; + for (i=0; i= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) || sym == FL_Tab || sym == FL_Enter) { buffer[0] = key; @@ -1184,6 +1293,11 @@ pascal OSStatus carbonKeyboardHandler( buffer[0] = 0; Fl::e_length = 0; } +#else + // Matt: attempt to get the correct Unicode character(S) from our keycode + static UInt32 deadKeyState = 0; // must be cleared when losing focus + Fl::e_length = keycodeToUnicode(buffer, 31, kind, keyCode, mods, &deadKeyState); +#endif Fl::e_text = buffer; // insert UnicodeHandling here! break; -- cgit v1.2.3