Brian P. Hinz 4a11567
diff -ur fltk-1.3.0r9619.org/configure.in fltk-1.3.0r9619/configure.in
Brian P. Hinz 4a11567
--- fltk-1.3.0r9619.org/configure.in	2012-04-22 04:45:09.000000000 +0200
Brian P. Hinz 4a11567
+++ fltk-1.3.0r9619/configure.in	2012-06-18 13:47:33.290447462 +0200
Brian P. Hinz 4a11567
@@ -865,6 +865,8 @@
Brian P. Hinz 4a11567
     Darwin*)
Brian P. Hinz 4a11567
         # MacOS X uses Cocoa for graphics.
Brian P. Hinz 4a11567
         LIBS="$LIBS -framework Cocoa"
Brian P. Hinz 4a11567
+        # And some Carbon for keyboard handling
Brian P. Hinz 4a11567
+        LIBS="$LIBS -framework Carbon"
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
 	if test x$have_pthread = xyes; then
Brian P. Hinz 4a11567
 	    AC_DEFINE(HAVE_PTHREAD)
Brian P. Hinz 4a11567
diff -ur fltk-1.3.0r9619.org/src/Fl_cocoa.mm fltk-1.3.0r9619/src/Fl_cocoa.mm
Brian P. Hinz 4a11567
--- fltk-1.3.0r9619.org/src/Fl_cocoa.mm	2012-06-16 10:49:52.000000000 +0200
Brian P. Hinz 4a11567
+++ fltk-1.3.0r9619/src/Fl_cocoa.mm	2012-06-18 13:47:42.944910782 +0200
Brian P. Hinz 4a11567
@@ -53,6 +53,7 @@
Brian P. Hinz 4a11567
 #include <math.h>
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
 #import <Cocoa/Cocoa.h>
Brian P. Hinz 4a11567
+#import <Carbon/Carbon.h>
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
 #ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h
Brian P. Hinz 4a11567
 #if defined(__LP64__) && __LP64__
Brian P. Hinz 4a11567
@@ -114,6 +115,8 @@
Brian P. Hinz 4a11567
 extern Fl_Window* fl_xmousewin;
Brian P. Hinz 4a11567
 #endif
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
+bool use_simple_keyboard = false;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
 enum { FLTKTimerEvent = 1, FLTKDataReadyEvent };
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
@@ -130,6 +133,39 @@
Brian P. Hinz 4a11567
 {
Brian P. Hinz 4a11567
 }
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
+// Undocumented voodoo. Taken from Mozilla.
Brian P. Hinz 4a11567
+#define ENABLE_ROMAN_KYBDS_ONLY -23
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+void fl_update_focus(void)
Brian P. Hinz 4a11567
+{
Brian P. Hinz 4a11567
+  Fl_Widget *focus;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  focus = Fl::grab();
Brian P. Hinz 4a11567
+  if (!focus)
Brian P. Hinz 4a11567
+    focus = Fl::focus();
Brian P. Hinz 4a11567
+  if (!focus)
Brian P. Hinz 4a11567
+    return;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  if (focus->simple_keyboard())
Brian P. Hinz 4a11567
+    use_simple_keyboard = true;
Brian P. Hinz 4a11567
+  else
Brian P. Hinz 4a11567
+    use_simple_keyboard = false;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  // Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
Brian P. Hinz 4a11567
+  // Safari people seem to think implies turning off advanced IME stuff
Brian P. Hinz 4a11567
+  // (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
Brian P. Hinz 4a11567
+  // in Safari/Webcore). Should be good enough for us then...
Brian P. Hinz 4a11567
+#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
Brian P. Hinz 4a11567
+  CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
Brian P. Hinz 4a11567
+  TSMSetDocumentProperty(TSMGetActiveDocument(),
Brian P. Hinz 4a11567
+                         kTSMDocumentEnabledInputSourcesPropertyTag,
Brian P. Hinz 4a11567
+                         sizeof(CFArrayRef), &inputSources);
Brian P. Hinz 4a11567
+  CFRelease(inputSources);
Brian P. Hinz 4a11567
+#else
Brian P. Hinz 4a11567
+  KeyScript(use_simple_keyboard ? ENABLE_ROMAN_KYBDS_ONLY : smKeyEnableKybds);
Brian P. Hinz 4a11567
+#endif  
Brian P. Hinz 4a11567
+}
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
 /*
Brian P. Hinz 4a11567
  * Mac keyboard lookup table
Brian P. Hinz 4a11567
  */
Brian P. Hinz 4a11567
@@ -908,6 +944,25 @@
Brian P. Hinz 4a11567
 }
Brian P. Hinz 4a11567
 @end
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
+static const char* cocoaDead2FLTK(const char *in)
Brian P. Hinz 4a11567
+{
Brian P. Hinz 4a11567
+  if (strcmp(in, "\140") == 0)      // GRAVE ACCENT
Brian P. Hinz 4a11567
+    return "\314\200";              // COMBINING GRAVE ACCENT
Brian P. Hinz 4a11567
+  if (strcmp(in, "\302\264") == 0)  // ACUTE ACCENT
Brian P. Hinz 4a11567
+    return "\314\201";              // COMBINING ACUTE ACCENT
Brian P. Hinz 4a11567
+  if (strcmp(in, "\136") == 0)      // CIRCUMFLEX ACCENT
Brian P. Hinz 4a11567
+    return "\314\202";              // COMBINING CIRCUMFLEX ACCENT
Brian P. Hinz 4a11567
+  if (strcmp(in, "\176") == 0)      // TILDE
Brian P. Hinz 4a11567
+    return "\314\203";              // COMBINING TILDE
Brian P. Hinz 4a11567
+  if (strcmp(in, "\302\250") == 0)  // DIAERESIS
Brian P. Hinz 4a11567
+    return "\314\210";              // COMBINING DIAERESIS
Brian P. Hinz 4a11567
+  // FIXME: OS X dead key behaviour isn't documented and I don't have
Brian P. Hinz 4a11567
+  //        any more keyboards to test with...
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  // hope that OS X gave us something proper to begin with
Brian P. Hinz 4a11567
+  return in;
Brian P. Hinz 4a11567
+}
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
 /*
Brian P. Hinz 4a11567
 Handle cocoa keyboard events
Brian P. Hinz 4a11567
 Events during a character composition sequence:
Brian P. Hinz 4a11567
@@ -1648,6 +1703,7 @@
Brian P. Hinz 4a11567
 - (void)rightMouseDragged:(NSEvent *)theEvent;
Brian P. Hinz 4a11567
 - (void)otherMouseDragged:(NSEvent *)theEvent;
Brian P. Hinz 4a11567
 - (void)scrollWheel:(NSEvent *)theEvent;
Brian P. Hinz 4a11567
++ (NSString *)keyTranslate:(UInt16)keyCode withModifierFlags:(UInt32)modifierFlags;
Brian P. Hinz 4a11567
 - (BOOL)handleKeyDown:(NSEvent *)theEvent;
Brian P. Hinz 4a11567
 - (void)keyDown:(NSEvent *)theEvent;
Brian P. Hinz 4a11567
 - (void)keyUp:(NSEvent *)theEvent;
Brian P. Hinz 4a11567
@@ -1726,6 +1782,130 @@
Brian P. Hinz 4a11567
 - (void)scrollWheel:(NSEvent *)theEvent {
Brian P. Hinz 4a11567
   cocoaMouseWheelHandler(theEvent);
Brian P. Hinz 4a11567
 }
Brian P. Hinz 4a11567
++ (NSString *)keyTranslate:(UInt16)keyCode withModifierFlags:(UInt32)modifierFlags {
Brian P. Hinz 4a11567
+  const UCKeyboardLayout *layout;
Brian P. Hinz 4a11567
+  OSStatus err;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  layout = NULL;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
Brian P. Hinz 4a11567
+  TISInputSourceRef keyboard;
Brian P. Hinz 4a11567
+  CFDataRef uchr;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  keyboard = TISCopyCurrentKeyboardInputSource();
Brian P. Hinz 4a11567
+  uchr = (CFDataRef)TISGetInputSourceProperty(keyboard,
Brian P. Hinz 4a11567
+                                              kTISPropertyUnicodeKeyLayoutData);
Brian P. Hinz 4a11567
+  if (uchr == NULL)
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  layout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);
Brian P. Hinz 4a11567
+#else
Brian P. Hinz 4a11567
+  KeyboardLayoutRef old_layout;
Brian P. Hinz 4a11567
+  int kind;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  err = KLGetCurrentKeyboardLayout(&old_layout);
Brian P. Hinz 4a11567
+  if (err != noErr)
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  err = KLGetKeyboardLayoutProperty(old_layout, kKLKind,
Brian P. Hinz 4a11567
+                                    (const void**)&kind);
Brian P. Hinz 4a11567
+  if (err != noErr)
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  // Old, crufty layout format?
Brian P. Hinz 4a11567
+  if (kind == kKLKCHRKind) {
Brian P. Hinz 4a11567
+    void *kchr_layout;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    UInt32 chars, state;
Brian P. Hinz 4a11567
+    char buf[3];
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    unichar result[16];
Brian P. Hinz 4a11567
+    ByteCount in_len, out_len;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    err = KLGetKeyboardLayoutProperty(old_layout, kKLKCHRData,
Brian P. Hinz 4a11567
+                                      (const void**)&kchr_layout);
Brian P. Hinz 4a11567
+    if (err != noErr)
Brian P. Hinz 4a11567
+      return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    state = 0;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    keyCode &= 0x7f;
Brian P. Hinz 4a11567
+    modifierFlags &= 0xff00;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    chars = KeyTranslate(kchr_layout, keyCode | modifierFlags, &state);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    buf[0] = (chars >> 16) & 0xff;
Brian P. Hinz 4a11567
+    buf[1] = chars & 0xff;
Brian P. Hinz 4a11567
+    buf[2] = '\0';
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    if (buf[0] == '\0') {
Brian P. Hinz 4a11567
+      buf[0] = buf[1];
Brian P. Hinz 4a11567
+      buf[1] = '\0';
Brian P. Hinz 4a11567
+    }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    // The data is now in some layout specific encoding. Need to convert
Brian P. Hinz 4a11567
+    // this to unicode.
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    ScriptCode script;
Brian P. Hinz 4a11567
+    TextEncoding encoding;
Brian P. Hinz 4a11567
+    TECObjectRef converter;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    script = (ScriptCode)GetScriptManagerVariable(smKeyScript);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    err = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare,
Brian P. Hinz 4a11567
+                                          kTextRegionDontCare, NULL,
Brian P. Hinz 4a11567
+                                          &encoding);
Brian P. Hinz 4a11567
+    if (err != noErr)
Brian P. Hinz 4a11567
+      return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    err = TECCreateConverter(&converter, encoding, kTextEncodingUnicodeV4_0);
Brian P. Hinz 4a11567
+    if (err != noErr)
Brian P. Hinz 4a11567
+      return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    in_len = strlen(buf);
Brian P. Hinz 4a11567
+    out_len = sizeof(result);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    err = TECConvertText(converter, (ConstTextPtr)buf, in_len, &in_len,
Brian P. Hinz 4a11567
+                         (TextPtr)result, out_len, &out_len);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    TECDisposeConverter(converter);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    if (err != noErr)
Brian P. Hinz 4a11567
+      return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    return [NSString stringWithCharacters:result
Brian P. Hinz 4a11567
+                     length:(out_len / sizeof(unichar))];
Brian P. Hinz 4a11567
+  }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  if ((kind != kKLKCHRuchrKind) && (kind != kKLuchrKind))
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  err = KLGetKeyboardLayoutProperty(old_layout, kKLuchrData,
Brian P. Hinz 4a11567
+                                    (const void**)&layout);
Brian P. Hinz 4a11567
+  if (err != noErr)
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+#endif
Brian P. Hinz 4a11567
+ 
Brian P. Hinz 4a11567
+  if (layout == NULL)
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  UInt32 dead_state;
Brian P. Hinz 4a11567
+  UniCharCount max_len, actual_len;
Brian P. Hinz 4a11567
+  UniChar string[255];
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  dead_state = 0;
Brian P. Hinz 4a11567
+  max_len = sizeof(string)/sizeof(*string);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  modifierFlags = (modifierFlags >> 8) & 0xff;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  err = UCKeyTranslate(layout, keyCode, kUCKeyActionDown, modifierFlags,
Brian P. Hinz 4a11567
+                       LMGetKbdType(), 0, &dead_state, max_len, &actual_len,
Brian P. Hinz 4a11567
+                       string);
Brian P. Hinz 4a11567
+  if (err != noErr)
Brian P. Hinz 4a11567
+    return nil;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  return [NSString stringWithCharacters:string length:actual_len];
Brian P. Hinz 4a11567
+}
Brian P. Hinz 4a11567
 - (BOOL)handleKeyDown:(NSEvent *)theEvent {
Brian P. Hinz 4a11567
   //NSLog(@"handleKeyDown");
Brian P. Hinz 4a11567
   fl_lock_function();
Brian P. Hinz 4a11567
@@ -1752,14 +1932,47 @@
Brian P. Hinz 4a11567
       break;
Brian P. Hinz 4a11567
     }
Brian P. Hinz 4a11567
   }
Brian P. Hinz 4a11567
-  if (!no_text_key && !(Fl::e_state & FL_META) ) {
Brian P. Hinz 4a11567
-    // Don't send cmd-<key> to interpretKeyEvents because it beeps.
Brian P. Hinz 4a11567
+  if (!no_text_key) {
Brian P. Hinz 4a11567
+    // The simple keyboard model will ignore insertText, so we need to grab
Brian P. Hinz 4a11567
+    // the symbol directly from the event. Note that we still use setMarkedText.
Brian P. Hinz 4a11567
+    if (use_simple_keyboard) {
Brian P. Hinz 4a11567
+      NSString *simple_chars;
Brian P. Hinz 4a11567
+      UInt32 modifiers;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+      // We want a "normal" symbol out of the event, which basically means
Brian P. Hinz 4a11567
+      // we only respect the shift and alt/altgr modifiers. Cocoa can help
Brian P. Hinz 4a11567
+      // us if we only wanted shift, but as we also want alt/altgr, we'll
Brian P. Hinz 4a11567
+      // have to do some lookup ourselves. This matches our behaviour on
Brian P. Hinz 4a11567
+      // other platforms.
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+      modifiers = 0;
Brian P. Hinz 4a11567
+      if ([theEvent modifierFlags] & NSAlphaShiftKeyMask)
Brian P. Hinz 4a11567
+        modifiers |= alphaLock;
Brian P. Hinz 4a11567
+      if ([theEvent modifierFlags] & NSShiftKeyMask)
Brian P. Hinz 4a11567
+        modifiers |= shiftKey;
Brian P. Hinz 4a11567
+      if ([theEvent modifierFlags] & NSAlternateKeyMask)
Brian P. Hinz 4a11567
+        modifiers |= optionKey;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+      simple_chars = [FLView keyTranslate:[theEvent keyCode]
Brian P. Hinz 4a11567
+                             withModifierFlags:modifiers];
Brian P. Hinz 4a11567
+      if (simple_chars == nil) {
Brian P. Hinz 4a11567
+        // Something went wrong. Fall back to what Cocoa gave us...
Brian P. Hinz 4a11567
+        simple_chars = [theEvent charactersIgnoringModifiers];
Brian P. Hinz 4a11567
+      }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+      [FLView prepareEtext:simple_chars];
Brian P. Hinz 4a11567
+    }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
     // Then we can let the OS have a stab at it and see if it thinks it
Brian P. Hinz 4a11567
     // should result in some text
Brian P. Hinz 4a11567
-    NSText *edit = [[theEvent window]  fieldEditor:YES forObject:nil];
Brian P. Hinz 4a11567
-    in_key_event = true;
Brian P. Hinz 4a11567
-    [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
Brian P. Hinz 4a11567
-    in_key_event = false;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+    // Don't send cmd-<key> to interpretKeyEvents because it beeps.
Brian P. Hinz 4a11567
+    if (!(Fl::e_state & FL_META)) {
Brian P. Hinz 4a11567
+      NSText *edit = [[theEvent window]  fieldEditor:YES forObject:nil];
Brian P. Hinz 4a11567
+      in_key_event = true;
Brian P. Hinz 4a11567
+      [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
Brian P. Hinz 4a11567
+      in_key_event = false;
Brian P. Hinz 4a11567
+    }
Brian P. Hinz 4a11567
   }
Brian P. Hinz 4a11567
   //NSLog(@"to text=%@ l=%d", [NSString stringWithUTF8String:Fl::e_text], Fl::e_length);
Brian P. Hinz 4a11567
   int handled = Fl::handle(FL_KEYDOWN, window);
Brian P. Hinz 4a11567
@@ -1937,21 +2150,30 @@
Brian P. Hinz 4a11567
   //NSLog(@"insertText: received=%@",received);
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
   if (!in_key_event) fl_lock_function();
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  // Simple keyboard widgets do not want these side channel inputs.
Brian P. Hinz 4a11567
+  if (use_simple_keyboard)
Brian P. Hinz 4a11567
+    goto end;
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
   [FLView prepareEtext:received];
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
   // We can get called outside of key events (e.g. from the character
Brian P. Hinz 4a11567
-  // palette). Transform such actions to FL_PASTE events.
Brian P. Hinz 4a11567
+  // palette). We need to fake our own key event at that point.
Brian P. Hinz 4a11567
   if (!in_key_event) {
Brian P. Hinz 4a11567
     Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
Brian P. Hinz 4a11567
-    Fl::handle(FL_PASTE, target);
Brian P. Hinz 4a11567
+    Fl::e_keysym = Fl::e_original_keysym = 0;
Brian P. Hinz 4a11567
+    Fl::handle(FL_KEYDOWN, target);
Brian P. Hinz 4a11567
     // for some reason, the window does not redraw until the next mouse move or button push
Brian P. Hinz 4a11567
     // sending a 'redraw()' or 'awake()' does not solve the issue!
Brian P. Hinz 4a11567
     Fl::flush();
Brian P. Hinz 4a11567
   }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+end:
Brian P. Hinz 4a11567
   if (!in_key_event) fl_unlock_function();
Brian P. Hinz 4a11567
 }
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection  {
Brian P. Hinz 4a11567
-  NSString *received;
Brian P. Hinz 4a11567
+  NSString *received, *current, *aggregate;
Brian P. Hinz 4a11567
   if (newSelection.location == 0) {
Brian P. Hinz 4a11567
     [self unmarkText];
Brian P. Hinz 4a11567
     return;
Brian P. Hinz 4a11567
@@ -1962,11 +2184,47 @@
Brian P. Hinz 4a11567
     received = (NSString*)aString;
Brian P. Hinz 4a11567
   }
Brian P. Hinz 4a11567
   //NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  fl_lock_function();
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  // Simple keyboard widgets generally do not want these side channel
Brian P. Hinz 4a11567
+  // inputs, but we have no other way of getting dead keys so we make
Brian P. Hinz 4a11567
+  // an exception in that case.
Brian P. Hinz 4a11567
+  if (use_simple_keyboard) {
Brian P. Hinz 4a11567
+    if (in_key_event && (Fl::e_length == 0)) {
Brian P. Hinz 4a11567
+      [FLView prepareEtext:received];
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+      Fl::e_text = (char*)cocoaDead2FLTK(Fl::e_text);
Brian P. Hinz 4a11567
+      Fl::e_length = strlen(Fl::e_text);
Brian P. Hinz 4a11567
+    }
Brian P. Hinz 4a11567
+    goto end;
Brian P. Hinz 4a11567
+  }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
   // This code creates the OS X behaviour of seeing dead keys as things
Brian P. Hinz 4a11567
   // are being composed.
Brian P. Hinz 4a11567
+  //
Brian P. Hinz 4a11567
+  // Note: The concatenation thing is because of how OS X deals with
Brian P. Hinz 4a11567
+  //       invalid sequences. At that point it will spit out one call
Brian P. Hinz 4a11567
+  //       to insertText with the now aborted sequence, and one new
Brian P. Hinz 4a11567
+  //       call to setMarkedText with the new sequence. Since we want
Brian P. Hinz 4a11567
+  //       both to be visible, we need to concatenate.
Brian P. Hinz 4a11567
   next_compose_length = newSelection.location;
Brian P. Hinz 4a11567
-  [FLView prepareEtext:received];
Brian P. Hinz 4a11567
-  //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", received, Fl::e_length, next_compose_length);
Brian P. Hinz 4a11567
+  current = [NSString stringWithUTF8String:Fl::e_text];
Brian P. Hinz 4a11567
+  aggregate = [current stringByAppendingString:received];
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  [FLView prepareEtext:aggregate];
Brian P. Hinz 4a11567
+  //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", aggregate, Fl::e_length, next_compose_length);
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+  // We can get called outside of key events (e.g. from the character
Brian P. Hinz 4a11567
+  // palette). We need to fake our own key event at that point.
Brian P. Hinz 4a11567
+  if (!in_key_event) {
Brian P. Hinz 4a11567
+    Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
Brian P. Hinz 4a11567
+    Fl::e_keysym = Fl::e_original_keysym = 0;
Brian P. Hinz 4a11567
+    Fl::handle(FL_KEYDOWN, target);
Brian P. Hinz 4a11567
+  }
Brian P. Hinz 4a11567
+
Brian P. Hinz 4a11567
+end:
Brian P. Hinz 4a11567
+  fl_unlock_function();
Brian P. Hinz 4a11567
 }
Brian P. Hinz 4a11567
 
Brian P. Hinz 4a11567
 - (void)unmarkText {