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