DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2599
Version: 1.3-feature


Attached file "fltk-1_v4.3.x-dead-chars-mac.patch"...


Link: http://www.fltk.org/str.php?L2599
Version: 1.3-feature
Index: src/Fl_cocoa.mm
===================================================================
--- src/Fl_cocoa.mm     (revision 8608)
+++ src/Fl_cocoa.mm     (working copy)
@@ -848,34 +848,26 @@
   return;
 }
 
+static const char* cocoaDead2FLTK(const char *in)
+{
+  if (strcmp(in, "\140") == 0)      // GRAVE ACCENT
+    return "\314\200";              // COMBINING GRAVE ACCENT
+  if (strcmp(in, "\302\264") == 0)  // ACUTE ACCENT
+    return "\314\201";              // COMBINING ACUTE ACCENT
+  if (strcmp(in, "\136") == 0)      // CIRCUMFLEX ACCENT
+    return "\314\202";              // COMBINING CIRCUMFLEX ACCENT
+  if (strcmp(in, "\176") == 0)      // TILDE
+    return "\314\203";              // COMBINING TILDE
+  if (strcmp(in, "\302\250") == 0)  // DIAERESIS
+    return "\314\210";              // COMBINING DIAERESIS
+  // FIXME: OS X dead key behaviour isn't documented and I don't have
+  //        any more keyboards to test with...
 
-static void calc_e_text(CFStringRef s, char *buffer, size_t len, unsigned sym)
-{
-  int i, no_text_key = false;
-  static unsigned notext[] = { // keys that don't emit text
-    FL_BackSpace, FL_Print, FL_Scroll_Lock, FL_Pause,
-    FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down,
-    FL_Left, FL_Up, FL_Right, FL_Down, 
-    FL_Menu, FL_Num_Lock, FL_Help 
-  };
-  int count = sizeof(notext)/sizeof(int);
-   
-  if (sym > FL_F && sym <= FL_F_Last) no_text_key = true;
-  else for (i=0; i < count; i++) {
-    if (notext[i] == sym) {
-      no_text_key = true;
-      break;
-      }
-  }
-  
-  if (no_text_key) {
-    buffer[0] = 0;
-  } else {
-    CFStringGetCString(s, buffer, len, kCFStringEncodingUTF8);
-  }
+  // hope that OS X gave us something proper to begin with
+  return in;
 }
 
-static int cocoaKeyboardHandler(NSEvent *theEvent);
+static void cocoaKeyboardHandler(NSEvent *theEvent);
 
 @interface FLTextView : NSTextView 
 // this subclass is needed under OS X <= 10.4 but not under >= 10.5 where the 
base class is enough
@@ -885,11 +877,13 @@
 @implementation FLTextView
 - (void)insertText:(id)aString
 {
-  cocoaKeyboardHandler([NSApp currentEvent]);
+  //NSLog(@"FLTextView:insertText:");
+  [[[NSApp keyWindow] contentView] insertText:aString];
 }
 - (void)doCommandBySelector:(SEL)aSelector
 {
-  cocoaKeyboardHandler([NSApp currentEvent]);
+  //NSLog(@"FLTextView:doCommandBySelector:");
+  [[[NSApp keyWindow] contentView] doCommandBySelector:aSelector];
 }
 @end
 
@@ -902,15 +896,11 @@
     replace the temporary character by this one
  - keyup -> [theEvent characters] contains the standard character
  */
-static int cocoaKeyboardHandler(NSEvent *theEvent)
+static void cocoaKeyboardHandler(NSEvent *theEvent)
 {
-  static char buffer[32];
-  int sendEvent = 0, retval = 0;
-  Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window];
-  Fl::first_window(window);
   NSUInteger mods;
   
-  fl_lock_function();
+ fl_lock_function();
   // get the modifiers
   mods = [theEvent modifierFlags];
   // get the key code
@@ -926,40 +916,33 @@
   // In this mode, there seem to be no key-down codes
   // printf("%08x %08x %08x\n", keyCode, mods, key);
   maskedKeyCode = keyCode & 0x7f;
-  switch([theEvent type]) {
-    case NSKeyDown:
-      sendEvent = FL_KEYBOARD;
-      // fall through
-    case NSKeyUp:
-      if ( !sendEvent ) {
-        sendEvent = FL_KEYUP;
-        Fl::e_state &= 0xbfffffff; // clear the deadkey flag
-      }
-      mods_to_e_state( mods ); // process modifier keys
-      sym = macKeyLookUp[maskedKeyCode];
-      if (sym < 0xff00) { // a "simple" key
-       // find the result of this key without modifier
-       NSString *sim = [theEvent charactersIgnoringModifiers];
-       UniChar one;
-       CFStringGetCharacters((CFStringRef)sim, CFRangeMake(0, 1), &one);
-       // charactersIgnoringModifiers doesn't ignore shift, remove it when 
it's on
-       if(one >= 'A' && one <= 'Z') one += 32;
-       if (one > 0 && one <= 0x7f && (sym<'0' || sym>'9') ) sym = one;
-      }
-      Fl::e_keysym = Fl::e_original_keysym = sym;
-      // Handle FL_KP_Enter on regular keyboards and on Powerbooks
-      if ( maskedKeyCode==0x4c || maskedKeyCode==0x34) s = @"\r";    
-      calc_e_text((CFStringRef)s, buffer, sizeof(buffer), sym);
-      Fl::e_length = strlen(buffer);
-      Fl::e_text = buffer;
-    default:                   // prevent 'not handled in switch' warnings
-      break;
+
+  if ([theEvent type] == NSKeyUp) {
+    Fl::e_state &= 0xbfffffff; // clear the deadkey flag
   }
-  if (sendEvent) {
-    retval = Fl::handle(sendEvent,window);
+
+  mods_to_e_state( mods ); // process modifier keys
+  sym = macKeyLookUp[maskedKeyCode];
+  if (sym < 0xff00) { // a "simple" key
+    // find the result of this key without modifier
+    NSString *sim = [theEvent charactersIgnoringModifiers];
+    UniChar one;
+    CFStringGetCharacters((CFStringRef)sim, CFRangeMake(0, 1), &one);
+    // charactersIgnoringModifiers doesn't ignore shift, remove it when it's on
+    if(one >= 'A' && one <= 'Z') one += 32;
+    if (one > 0 && one <= 0x7f && (sym<'0' || sym>'9') ) sym = one;
   }
-  fl_unlock_function();  
-  return retval;
+  Fl::e_keysym = Fl::e_original_keysym = sym;
+
+  //NSLog(@"cocoaKeyboardHandler: keycode=%08x keysym=%08x mods=%08x symbol=%@ 
(%@)",
+  //  keyCode, sym, mods, [theEvent characters], [theEvent 
charactersIgnoringModifiers]);
+
+  // If there is text associated with this key, it will be filled
+  // in later.
+  Fl::e_length = 0;
+  Fl::e_text = (char*)"";
+  Fl::e_compose_symbol = (char*)[[theEvent charactersIgnoringModifiers] 
UTF8String];
+  fl_unlock_function();
 }
 
 
@@ -1637,7 +1620,10 @@
 
 
 @interface FLView : NSView <NSTextInput> {
+  int next_compose_length;
+  bool in_key_event;
 }
++ (void)prepareEtext:(NSString*)aString;
 - (void)drawRect:(NSRect)rect;
 - (BOOL)acceptsFirstResponder;
 - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
@@ -1653,6 +1639,7 @@
 - (void)rightMouseDragged:(NSEvent *)theEvent;
 - (void)otherMouseDragged:(NSEvent *)theEvent;
 - (void)scrollWheel:(NSEvent *)theEvent;
+- (BOOL)handleKeyDown:(NSEvent *)theEvent;
 - (void)keyDown:(NSEvent *)theEvent;
 - (void)keyUp:(NSEvent *)theEvent;
 - (void)flagsChanged:(NSEvent *)theEvent;
@@ -1679,8 +1666,8 @@
 }
 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent
 {   
-  int retval = cocoaKeyboardHandler(theEvent);
-  return (retval ? YES : NO);
+  //NSLog(@"performKeyEquivalent:");
+  return [self handleKeyDown:theEvent];
 }
 - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent
 {   
@@ -1721,14 +1708,53 @@
 - (void)scrollWheel:(NSEvent *)theEvent {
   cocoaMouseWheelHandler(theEvent);
 }
-- (void)keyDown:(NSEvent *)theEvent {
+- (BOOL)handleKeyDown:(NSEvent *)theEvent {
+  //NSLog(@"handleKeyDown");
+  fl_lock_function();
+
+  Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window];
+
+  next_compose_length = -1;
+  in_key_event = true;
+
+  // First let's process the raw key press
+  cocoaKeyboardHandler(theEvent);
+
+  // Then we can let the OS have a stab at it and see if it thinks it
+  // should result in some text
   NSText *edit = [[theEvent window]  fieldEditor:YES forObject:nil];
   [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
+
+  in_key_event = false;
+
+  Fl::first_window(window);
+  //NSLog(@"to text=%@ l=%d", [NSString stringWithUTF8String:Fl::e_text], 
Fl::e_length);
+  int handled = Fl::handle(FL_KEYDOWN,window);
+
+  // We have to update this after Fl::handle as it says what to do on the
+  // _next_ input
+  if (next_compose_length != -1)
+    Fl::compose_state = next_compose_length;
+
+  fl_unlock_function();
+
+  return (handled ? YES : NO);
 }
+- (void)keyDown:(NSEvent *)theEvent {
+  //NSLog(@"keyDown: ");
+  [self handleKeyDown:theEvent];
+}
 - (void)keyUp:(NSEvent *)theEvent {
+  //NSLog(@"keyUp: ");
+  fl_lock_function();
+  Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window];
   cocoaKeyboardHandler(theEvent);
+  Fl::first_window(window);
+  Fl::handle(FL_KEYUP,window);
+  fl_unlock_function();
 }
 - (void)flagsChanged:(NSEvent *)theEvent {
+  //NSLog(@"flagsChanged: ");
   fl_lock_function();
   static UInt32 prevMods = 0;
   NSUInteger mods = [theEvent modifierFlags];
@@ -1836,6 +1862,27 @@
   return NSDragOperationGeneric;
 }
 
++ (void)prepareEtext:(NSString*)aString {
+  // fills Fl::e_text with UTF-8 encoded aString using an adequate memory 
allocation
+  static char *received_utf8 = NULL;
+  static int lreceived = 0;
+  char *p = (char*)[aString UTF8String];
+  int l = strlen(p);
+  if (l > 0) {
+    if (lreceived == 0) {
+      received_utf8 = (char*)malloc(l + 1);
+      lreceived = l;
+    }
+    else if (l > lreceived) {
+      received_utf8 = (char*)realloc(received_utf8, l + 1);
+      lreceived = l;
+    }
+    strcpy(received_utf8, p);
+    Fl::e_text = received_utf8;
+  }
+  Fl::e_length = l;
+}
+
 // These functions implement text input.
 // Only two-stroke character composition works at this point.
 // Needs much elaboration to fully support CJK text input,
@@ -1843,49 +1890,75 @@
 - (void)doCommandBySelector:(SEL)aSelector {
 }
 
+
 - (void)insertText:(id)aString {
-  NSEvent *event = [NSApp currentEvent];
-  NSEventType type = [event type];
-  NSString *str = @"";
   NSString *received;
   if ([aString isKindOfClass:[NSAttributedString class]]) {
     received = [(NSAttributedString*)aString string];
   } else {
     received = (NSString*)aString;
   }
-  if (type == NSKeyDown ) {
-    str = [event characters];
+  //NSLog(@"insertText: received=%@",received);
+
+  fl_lock_function();
+
+  //Fl::e_text = (char*)[received UTF8String];
+  //Fl::e_length = strlen(Fl::e_text);
+  [FLView prepareEtext:received];
+
+  // We can get called outside of key events (e.g. from the character
+  // palette). Transform such actions to FL_PASTE events.
+  if (in_key_event) {
+    if (Fl::e_compose_state == FL_COMPOSE_INTERMEDIATE) {
+      Fl::e_compose_state = FL_COMPOSE_FINAL;
+    } else {
+      Fl::e_compose_state = FL_COMPOSE_NONE;
     }
-  if ([received isEqualToString:@"\b"] || [str isEqualToString:received]) {
-    if (type == NSKeyDown ) cocoaKeyboardHandler(event);
   } else {
-    fl_lock_function();
-    Fl_Window *window = [(FLWindow*)[NSApp keyWindow] getFl_Window];
-    Fl::e_text = (char*)[received UTF8String];
-    Fl::e_length = strlen(Fl::e_text);
-    if (type == NSKeyDown ) {
-      Fl::e_keysym = macKeyLookUp[ [event keyCode] & 0x7f] ;
-      Fl::handle(FL_KEYBOARD, window);
-      }
-    else {
-      Fl::handle(FL_PASTE, window);
-      // for some reason, the window does not redraw until the next mouse move 
or button push
-      // sending a 'redraw()' or 'awake()' does not solve the issue!
-      Fl::flush();
-    }
-    fl_unlock_function();
+    Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+    Fl::handle(FL_PASTE, target);
   }
+
+  fl_unlock_function();
 }
 
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection  {
-  // NSLog(@"setMarkedText: %@ %d %d Fl::compose_state=%d",
-  //  aString,newSelection.location,newSelection.length,newSelection.location);
-  [self insertText:aString];
-  Fl::compose_state = newSelection.location;
+  NSString *received;
+
+  if (newSelection.location == 0) {
+    [self unmarkText];
+    return;
+  }
+  if ([aString isKindOfClass:[NSAttributedString class]]) {
+    received = [(NSAttributedString*)aString string];
+  } else {
+    received = (NSString*)aString;
+  }
+
+  fl_lock_function();
+  //NSLog(@"setMarkedText: %@ %d 
%d",received,newSelection.location,newSelection.length);
+
+  //Fl::e_compose_symbol = cocoaDead2FLTK((char*)[received UTF8String]);
+  //Fl::e_compose_state = FL_COMPOSE_INTERMEDIATE;
+
+  // This code creates the OS X behaviour of seeing dead keys as things
+  // are being composed.
+  next_compose_length = newSelection.location;
+  //NSString *current = [NSString stringWithUTF8String:Fl::e_text];
+  //NSString *aggregate = [current stringByAppendingString:received];
+  //Fl::e_text = (char*)[aggregate UTF8String];
+  [FLView prepareEtext:received];
+  Fl::e_compose_symbol = Fl::e_text; // cocoaDead2FLTK(Fl::e_text);
+  Fl::e_compose_state = FL_COMPOSE_INTERMEDIATE;
+  //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", received, 
Fl::e_length, next_compose_length);
+  fl_unlock_function();
 }
 
 - (void)unmarkText {
+  fl_lock_function();
   Fl::compose_state = 0;
+  Fl::e_compose_state = FL_COMPOSE_NONE;
+  fl_unlock_function();
   //NSLog(@"unmarkText");
 }
 
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to