diff options
Diffstat (limited to 'macosx/tkMacOSXKeyEvent.c')
-rw-r--r-- | macosx/tkMacOSXKeyEvent.c | 555 |
1 files changed, 308 insertions, 247 deletions
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c index f69a531..9b866f6 100644 --- a/macosx/tkMacOSXKeyEvent.c +++ b/macosx/tkMacOSXKeyEvent.c @@ -16,25 +16,29 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXInt.h" #include "tkMacOSXConstants.h" +#include "tkMacOSXWm.h" + +/* + * See tkMacOSXPrivate.h for macros related to key event processing. + */ /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_KEYBOARD #endif */ -#define NS_KEYLOG 0 +#define NS_KEYLOG 0 +#define XEVENT_MOD_MASK (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask) static Tk_Window keyboardGrabWinPtr = NULL; /* Current keyboard grab window. */ static NSWindow *keyboardGrabNSWindow = nil; /* Its underlying NSWindow.*/ static NSModalSession modalSession = nil; static BOOL processingCompose = NO; static Tk_Window composeWin = NULL; static int caret_x = 0, caret_y = 0, caret_height = 0; -static TkWindow *caret_win = NULL; - static void setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers); -static unsigned isFunctionKey(unsigned int code); - +static void setXEventPoint(XEvent *xEvent, Tk_Window tkwin, NSWindow *w); +static NSUInteger textInputModifiers; #pragma mark TKApplication(TKKeyEvent) @@ -45,33 +49,24 @@ static unsigned isFunctionKey(unsigned int code); #ifdef TK_MAC_DEBUG_EVENTS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent); #endif - unsigned short keyCode = [theEvent keyCode]; NSWindow *w = [theEvent window]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); + TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr; + Tk_Window tkwin = (Tk_Window) winPtr; + NSEventType type = [theEvent type]; + NSUInteger virtual = [theEvent keyCode]; NSUInteger modifiers = ([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask); - NSString *characters = nil; - NSString *charactersIgnoringModifiers = nil; - NSUInteger len = 0; - int code = 0; + XEvent xEvent; + MacKeycode macKC; + UniChar keychar = 0; + Bool can_input_text, has_modifiers = NO, use_text_input = NO; static NSUInteger savedModifiers = 0; - static NSMutableArray *nsEvArray; + static NSMutableArray *nsEvArray = nil; if (nsEvArray == nil) { nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1]; processingCompose = NO; } - - /* - * Control-Tab and Control-Shift-Tab are used to switch tabs in a tabbed - * window. We do not want to generate an Xevent for these since that might - * cause the deselected tab to be reactivated. - */ - - if (keyCode == 48 && (modifiers & NSControlKeyMask) == NSControlKeyMask) { - return theEvent; - } - if (!winPtr) { return theEvent; } @@ -83,136 +78,199 @@ static unsigned isFunctionKey(unsigned int code); * grab is in effect all key events are redirected to the grabber. */ - Tk_Window tkwin = (Tk_Window) winPtr; - TkWindow *grabWinPtr = winPtr->dispPtr->grabWinPtr; + grabWinPtr = winPtr->dispPtr->grabWinPtr; if (grabWinPtr) { if (winPtr->dispPtr->grabFlags || /* global grab */ grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */ - tkwin = (Tk_Window) winPtr->dispPtr->focusPtr; + winPtr =winPtr->dispPtr->focusPtr; + tkwin = (Tk_Window) winPtr; } } - NSEventType type = [theEvent type]; - BOOL has_modifiers = NO; - XEvent xEvent; - /* - * Check whether this key event belongs to the caret window. + * Extract the unicode character from KeyUp and KeyDown events. */ - setupXEvent(&xEvent, tkwin, modifiers); - Bool has_caret = (TkFocusKeyEvent(winPtr, &xEvent) == caret_win); + if (type == NSKeyUp || type == NSKeyDown) { + if ([[theEvent characters] length] > 0) { + keychar = [[theEvent characters] characterAtIndex:0]; - /* - * A KeyDown event received for the caret window which is not a function key - * and has no modifiers other than Shift or Alt will be processed with the - * TextInputClient protocol below. All other key events are handled here - * by queueing the XEvent created above. - */ + /* + * Currently, real keys always send BMP characters, but who knows? + */ - if (!processingCompose || !has_caret) { - switch (type) { - case NSFlagsChanged: - if (savedModifiers > modifiers) { - xEvent.xany.type = KeyRelease; - } else { - xEvent.xany.type = KeyPress; + if (CFStringIsSurrogateHighCharacter(keychar)) { + UniChar lowChar = [[theEvent characters] characterAtIndex:1]; + keychar = CFStringGetLongCharacterForSurrogatePair( + keychar, lowChar); } + } else { /* - * The value -1 indicates a special keycode to the platform - * specific code in tkMacOSXKeyboard.c. + * This is a dead key, such as Option-e, so it should go to the + * TextInputClient. */ - xEvent.xany.send_event = -1; - xEvent.xkey.keycode = (modifiers ^ savedModifiers); - break; - case NSKeyUp: - characters = [theEvent characters]; - xEvent.xany.type = KeyRelease; - xEvent.xkey.keycode = (keyCode << 16) | (UInt16) [characters characterAtIndex:0]; - break; - case NSKeyDown: - characters = [theEvent characters]; - charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers]; - xEvent.xany.type = KeyPress; - xEvent.xkey.keycode = (keyCode << 16) | (UInt16) [characters characterAtIndex:0]; - len = [charactersIgnoringModifiers length]; - if (len > 0) { - code = [charactersIgnoringModifiers characterAtIndex:0]; - has_modifiers = xEvent.xkey.state & - (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask); - } - break; - default: - return theEvent; /* Unrecognized key event. */ + use_text_input = YES; + } + + /* + * Apple uses 0x10 for unrecognized keys. + */ + + if (keychar == 0x10) { + keychar = UNKNOWN_KEYCHAR; } #if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1 - TKLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", - [self class], self, _cmd, (type == NSKeyDown) && [theEvent isARepeat], - modifiers, characters, charactersIgnoringModifiers, keyCode, - ([charactersIgnoringModifiers length] == 0) ? 0 : - [charactersIgnoringModifiers characterAtIndex: 0], w, type); + TKLog(@"-[%@(%p) %s] repeat=%d mods=%x char=%x code=%lu c=%d type=%d", + [self class], self, _cmd, + (type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar, + virtual, w, type); #endif - if (type != NSKeyDown || !has_caret || isFunctionKey(code) || has_modifiers) { - if (type == NSKeyDown && [theEvent isARepeat]) { + } - /* - * Insert a KeyRelease XEvent before a repeated KeyPress. - */ + /* + * Build a skeleton XEvent. We need to build it here, even if we will not + * send it, so we can pass it to TkFocusKeyEvent to determine whether the + * target widget can input text. + */ - xEvent.xany.type = KeyRelease; - Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); - xEvent.xany.type = KeyPress; - } + setupXEvent(&xEvent, tkwin, modifiers); + has_modifiers = xEvent.xkey.state & XEVENT_MOD_MASK; + focusWinPtr = TkFocusKeyEvent(winPtr, &xEvent); + if (focusWinPtr == NULL) { + TKContentView *contentView = [w contentView]; - /* - * Queue the XEvent and return. - */ + /* + * This NSEvent is being sent to a window which does not have focus. + * This could mean, for example, that the user deactivated the Tk app + * while the NSTextInputClient's popup character selection window was + * still open. We attempt to abandon any ongoing composition operation + * and discard the event. + */ - Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); - savedModifiers = modifiers; - return theEvent; - } + [contentView cancelComposingText]; + return theEvent; } + can_input_text = ((focusWinPtr->flags & TK_CAN_INPUT_TEXT) != 0); + +#if (NS_KEYLOG) + TKLog(@"keyDown: %s compose sequence.\n", + processingCompose == YES ? "Continue" : "Begin"); +#endif /* - * Either we are processing a composition or this is a normal KeyDown event - * for the caret window. Either way the event should be passed to - * interpretKeyEvents. But we only need to send KeyDown events. + * Decide whether this event should be processed with the NSTextInputClient + * protocol. */ - if (type == NSKeyDown) { - if (NS_KEYLOG) { - TKLog(@"keyDown: %s compose sequence.\n", - processingCompose == YES ? "Continue" : "Begin"); - } + if (processingCompose || + (type == NSKeyDown && can_input_text && !has_modifiers && + IS_PRINTABLE(keychar)) + ) { + use_text_input = YES; + } + + /* + * If we are processing this KeyDown event as an NSTextInputClient we do + * not queue an XEvent. We pass the NSEvent to our interpretKeyEvents + * method. When the composition sequence is complete, the callback method + * insertText: replacementRange will be called. That method generates a + * keyPress XEvent with the selected character. + */ + + if (use_text_input) { + textInputModifiers = modifiers; /* - * Call the interpretKeyEvents method to handle the event as a - * TextInputClient. When the composition sequence is complete, our - * implementation of insertText: replacementRange will be called. that - * method generates a key down XEvent with the selected character. In - * IME when multiple characters have the same composition sequence and - * the selected character is not the default it may be necessary to hit - * the Enter key multiple times before the character is accepted and - * rendered. So we repeatedly send Enter key events until inputText has - * cleared the processingCompose flag. + * In IME the Enter key is used to terminate a composition sequence. + * When there are multiple choices of input text available, and the + * user's selected choice is not the default, it may be necessary to + * hit the Enter key multiple times before the text is accepted and + * rendered (See ticket 39de9677aa]). So when sending an Enter key + * during composition, we continue sending Enter keys until the + * inputText method has cleared the processingCompose flag. */ - processingCompose = YES; - while(processingCompose) { + if (processingCompose && [theEvent keyCode] == 36) { + [nsEvArray addObject: theEvent]; + while(processingCompose) { + [[w contentView] interpretKeyEvents: nsEvArray]; + } + [nsEvArray removeObject: theEvent]; + } else { [nsEvArray addObject: theEvent]; [[w contentView] interpretKeyEvents: nsEvArray]; [nsEvArray removeObject: theEvent]; - if ([theEvent keyCode] != 36) { - break; - } } + return theEvent; + } + + /* + * We are not handling this event as an NSTextInputClient, so we need to + * finish constructing the XEvent and queue it. + */ + + macKC.v.o_s = ((modifiers & NSShiftKeyMask ? INDEX_SHIFT : 0) | + (modifiers & NSAlternateKeyMask ? INDEX_OPTION : 0)); + macKC.v.virtual = virtual; + switch (type) { + case NSFlagsChanged: + + /* + * This XEvent is a simulated KeyPress or KeyRelease event for a + * modifier key. To determine the type, note that the highest bit + * where the flags differ is 1 if and only if it is a KeyPress. The + * modifiers are saved so we can detect the next flag change. + */ + + xEvent.xany.type = modifiers > savedModifiers ? KeyPress : KeyRelease; + savedModifiers = modifiers; + + /* + * Set the keychar to MOD_KEYCHAR as a signal to TkpGetKeySym (see + * tkMacOSXKeyboard.c) that this is a modifier key event. + */ + + keychar = MOD_KEYCHAR; + break; + case NSKeyUp: + xEvent.xany.type = KeyRelease; + break; + case NSKeyDown: + xEvent.xany.type = KeyPress; + break; + default: + return theEvent; /* Unrecognized key event. */ + } + macKC.v.keychar = keychar; + xEvent.xkey.keycode = macKC.uint; + + /* + * Set the trans_chars for keychars outside of the private-use range. + */ + + setXEventPoint(&xEvent, tkwin, w); + if (IS_PRINTABLE(keychar)) { + int length = TkUniCharToUtf(keychar, xEvent.xkey.trans_chars); + xEvent.xkey.trans_chars[length] = 0; + } + + /* + * Finally we can queue the XEvent, inserting a KeyRelease before a + * repeated KeyPress. + */ + + if (type == NSKeyDown && [theEvent isARepeat]) { + xEvent.xany.type = KeyRelease; + Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + xEvent.xany.type = KeyPress; + } + if (xEvent.xany.type == KeyPress) { } - savedModifiers = modifiers; + Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); return theEvent; } @end @@ -240,11 +298,12 @@ static unsigned isFunctionKey(unsigned int code); - (void)insertText: (id)aString replacementRange: (NSRange)repRange { - int i, len; + int i, len, state; XEvent xEvent; - NSString *str; + NSString *str, *keystr, *lower; TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); Tk_Window tkwin = (Tk_Window) winPtr; + Bool sendingIMEText = NO; str = ([aString isKindOfClass: [NSAttributedString class]]) ? [aString string] : aString; @@ -254,13 +313,12 @@ static unsigned isFunctionKey(unsigned int code); TKLog(@"insertText '%@'\tlen = %d", aString, len); } - processingCompose = NO; - /* * Clear any working text. */ if (privateWorkingText != nil) { + sendingIMEText = YES; [self deleteWorkingText]; } @@ -268,7 +326,8 @@ static unsigned isFunctionKey(unsigned int code); * Insert the string as a sequence of keystrokes. */ - setupXEvent(&xEvent, tkwin, 0); + setupXEvent(&xEvent, tkwin, textInputModifiers); + setXEventPoint(&xEvent, tkwin, [self window]); xEvent.xany.type = KeyPress; /* @@ -285,28 +344,59 @@ static unsigned isFunctionKey(unsigned int code); /* * Next we generate an XEvent for each unicode character in our string. + * This string could contain non-BMP characters, for example if the + * emoji palette was used. * * NSString uses UTF-16 internally, which means that a non-BMP character is - * represented by a sequence of two 16-bit "surrogates". In principle we - * could record this in the XEvent by setting the keycode to the 32-bit - * unicode code point and setting the trans_chars string to the 4-byte - * UTF-8 string for the non-BMP character. However, that will not work - * when TCL_UTF_MAX is set to 3, as is the case for Tcl 8.6. A workaround - * used internally by Tcl 8.6 is to encode each surrogate as a 3-byte - * sequence using the UTF-8 algorithm (ignoring the fact that the UTF-8 - * encoding specification does not allow encoding UTF-16 surrogates). - * This gives a 6-byte encoding of the non-BMP character which we write into - * the trans_chars field of the XEvent. + * represented by a sequence of two 16-bit "surrogates". We record this in + * the XEvent by setting the low order 21-bits of the keycode to the UCS-32 + * value value of the character and the virtual keycode in the high order + * byte to the special value NON_BMP. In principle we could set the + * trans_chars string to the UTF-8 string for the non-BMP character. + * However, that will not work when TCL_UTF_MAX is set to 3, as is the case + * for Tcl 8.6. A workaround used internally by Tcl 8.6 is to encode each + * surrogate as a 3-byte sequence using the UTF-8 algorithm (ignoring the + * fact that the UTF-8 encoding specification does not allow encoding + * UTF-16 surrogates). This gives a 6-byte encoding of the non-BMP + * character which we write into the trans_chars field of the XEvent. */ + state = xEvent.xkey.state; for (i = 0; i < len; i++) { - xEvent.xkey.nbytes = TkUtfAtIndex(str, i, xEvent.xkey.trans_chars, - &xEvent.xkey.keycode); - if (xEvent.xkey.keycode > 0xffff){ + unsigned int code; + UniChar keychar; + MacKeycode macKC = {0}; + + keychar = [str characterAtIndex:i]; + macKC.v.keychar = keychar; + if (CFStringIsSurrogateHighCharacter(keychar)) { + UniChar lowChar = [str characterAtIndex:i+1]; + macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair( + (UniChar)keychar, lowChar); + macKC.v.virtual = NON_BMP_VIRTUAL; + } else if (repRange.location == 0 || sendingIMEText) { + macKC.v.virtual = REPLACEMENT_VIRTUAL; + } else { + macKC.uint = TkMacOSXAddVirtual(macKC.uint); + xEvent.xkey.state |= INDEX2STATE(macKC.x.xvirtual); + } + keystr = [[NSString alloc] initWithCharacters:&keychar length:1]; + lower = [keystr lowercaseString]; + if (![keystr isEqual: lower]) { + macKC.v.o_s |= INDEX_SHIFT; + xEvent.xkey.state |= ShiftMask; + } + if (xEvent.xkey.state & Mod2Mask) { + macKC.v.o_s |= INDEX_OPTION; + } + TkUtfAtIndex(str, i, xEvent.xkey.trans_chars, &code); + if (code > 0xFFFF){ i++; } + xEvent.xkey.keycode = macKC.uint; xEvent.xany.type = KeyPress; Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + xEvent.xkey.state = state; } } @@ -337,7 +427,6 @@ static unsigned isFunctionKey(unsigned int code); str = ([aString isKindOfClass: [NSAttributedString class]]) ? [aString string] : aString; - if (focusWin) { /* @@ -368,10 +457,10 @@ static unsigned isFunctionKey(unsigned int code); */ TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL); + processingCompose = YES; temp = [str copy]; [self insertText: temp replacementRange:repRange]; privateWorkingText = temp; - processingCompose = YES; TkSendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL); } @@ -380,7 +469,6 @@ static unsigned isFunctionKey(unsigned int code); return privateWorkingText != nil; } - - (NSRange)markedRange { NSRange rng = privateWorkingText != nil @@ -393,15 +481,6 @@ static unsigned isFunctionKey(unsigned int code); return rng; } -- (void)cancelComposingText -{ - if (NS_KEYLOG) { - TKLog(@"cancelComposingText"); - } - [self deleteWorkingText]; - processingCompose = NO; -} - - (void)unmarkText { if (NS_KEYLOG) { @@ -411,7 +490,6 @@ static unsigned isFunctionKey(unsigned int code); processingCompose = NO; } - /* * Called by the system to get a position for popup character selection windows * such as a Character Palette, or a selection menu for IME. @@ -525,6 +603,16 @@ static unsigned isFunctionKey(unsigned int code); } } } + +- (void)cancelComposingText +{ + if (NS_KEYLOG) { + TKLog(@"cancelComposingText"); + } + [self deleteWorkingText]; + processingCompose = NO; +} + @end /* @@ -535,6 +623,11 @@ static void setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers) { unsigned int state = 0; + Display *display = Tk_Display(tkwin); + + if (tkwin == NULL) { + return; + } if (modifiers) { state = (modifiers & NSAlphaShiftKeyMask ? LockMask : 0) | (modifiers & NSShiftKeyMask ? ShiftMask : 0) | @@ -545,11 +638,11 @@ setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers) (modifiers & NSFunctionKeyMask ? Mod4Mask : 0) ; } memset(xEvent, 0, sizeof(XEvent)); - xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + xEvent->xany.serial = LastKnownRequestProcessed(display); xEvent->xany.display = Tk_Display(tkwin); xEvent->xany.window = Tk_WindowId(tkwin); - xEvent->xkey.root = XRootWindow(Tk_Display(tkwin), 0); + xEvent->xkey.root = XRootWindow(display, 0); xEvent->xkey.time = TkpGetMS(); xEvent->xkey.state = state; xEvent->xkey.same_screen = true; @@ -557,6 +650,41 @@ setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers) * because of the memset() above. */ } +static void +setXEventPoint( + XEvent *xEvent, + Tk_Window tkwin, + NSWindow *w) +{ + TkWindow *winPtr = (TkWindow *) tkwin; + NSPoint local = [w mouseLocationOutsideOfEventStream]; + NSPoint global = [w tkConvertPointToScreen: local]; + int win_x, win_y; + + if (Tk_IsEmbedded(winPtr)) { + TkWindow *contPtr = TkpGetOtherWindow(winPtr); + if (Tk_IsTopLevel(contPtr)) { + local.x -= contPtr->wmInfoPtr->xInParent; + local.y -= contPtr->wmInfoPtr->yInParent; + } else { + TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr; + local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x); + local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y); + } + } else if (winPtr->wmInfoPtr != NULL) { + local.x -= winPtr->wmInfoPtr->xInParent; + local.y -= winPtr->wmInfoPtr->yInParent; + } + tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y); + local.x = win_x; + local.y = win_y; + global.y = TkMacOSXZeroScreenHeight() - global.y; + xEvent->xbutton.x = local.x; + xEvent->xbutton.y = local.y; + xEvent->xbutton.x_root = global.x; + xEvent->xbutton.y_root = global.y; +} + #pragma mark - /* @@ -661,15 +789,22 @@ TkMacOSXGetModalSession(void) * * Tk_SetCaretPos -- * - * This enables correct placement of the XIM caret. This is called by - * widgets to indicate their cursor placement, and the caret location is - * used by TkpGetString to place the XIM caret. + * This enables correct placement of the popups used for character + * selection by the NSTextInputClient. It gets called by text entry + * widgets whenever the cursor is drawn. It does nothing if the widget's + * NSWindow is not the current KeyWindow. Otherwise it udpates the + * display's caret structure and records the caret geometry in static + * variables for use by the NSTextInputClient implementation. Any + * widget passed to this function will be marked as being able to input + * text by setting the TK_CAN_INPUT_TEXT flag. * * Results: * None * * Side effects: - * None + * Sets the CAN_INPUT_TEXT flag on the widget passed as tkwin. May update + * the display's caret structure as well as the static variables caret_x, + * caret_y and caret_height. * *---------------------------------------------------------------------- */ @@ -681,28 +816,41 @@ Tk_SetCaretPos( int y, int height) { - TkCaret *caretPtr = &(((TkWindow *) tkwin)->dispPtr->caret); + TkWindow *winPtr = (TkWindow *) tkwin; + TkCaret *caretPtr = &(winPtr->dispPtr->caret); + NSWindow *w = TkMacOSXDrawableWindow(Tk_WindowId(tkwin)); /* - * Prevent processing anything if the values haven't changed. Windows only - * has one display, so we can do this with statics. + * Register this widget as being capable of text input, so we know we + * should process (appropriate) key events for this window with the + * NSTextInputClient protocol. */ - if ((caretPtr->winPtr == ((TkWindow *) tkwin)) - && (caretPtr->x == x) && (caretPtr->y == y)) { + winPtr->flags |= TK_CAN_INPUT_TEXT; + if (w && ![w isKeyWindow]) { return; } + if ((caretPtr->winPtr == winPtr + && caretPtr->x == x) && (caretPtr->y == y)) { + return; + } + + /* + * Update the display's caret information. + */ - caret_win = (TkWindow*) tkwin; - caretPtr->winPtr = ((TkWindow *) tkwin); + caretPtr->winPtr = winPtr; caretPtr->x = x; caretPtr->y = y; caretPtr->height = height; /* - * As in Windows, adjust to the toplevel to get the coords right. + * Record the caret geometry in static variables for use when processing + * key events. We use the TKContextView coordinate system for this. */ + caret_x = x; + caret_height = height; while (!Tk_IsTopLevel(tkwin)) { x += Tk_X(tkwin); y += Tk_Y(tkwin); @@ -711,94 +859,7 @@ Tk_SetCaretPos( return; } } - - /* - * But adjust for fact that NS uses flipped view. - */ - - y = Tk_Height(tkwin) - y; - - caret_x = x; - caret_y = y; - caret_height = height; -} - - -static unsigned convert_ns_to_X_keysym[] = -{ - NSHomeFunctionKey, 0x50, - NSLeftArrowFunctionKey, 0x51, - NSUpArrowFunctionKey, 0x52, - NSRightArrowFunctionKey, 0x53, - NSDownArrowFunctionKey, 0x54, - NSPageUpFunctionKey, 0x55, - NSPageDownFunctionKey, 0x56, - NSEndFunctionKey, 0x57, - NSBeginFunctionKey, 0x58, - NSSelectFunctionKey, 0x60, - NSPrintFunctionKey, 0x61, - NSExecuteFunctionKey, 0x62, - NSInsertFunctionKey, 0x63, - NSUndoFunctionKey, 0x65, - NSRedoFunctionKey, 0x66, - NSMenuFunctionKey, 0x67, - NSFindFunctionKey, 0x68, - NSHelpFunctionKey, 0x6A, - NSBreakFunctionKey, 0x6B, - - NSF1FunctionKey, 0xBE, - NSF2FunctionKey, 0xBF, - NSF3FunctionKey, 0xC0, - NSF4FunctionKey, 0xC1, - NSF5FunctionKey, 0xC2, - NSF6FunctionKey, 0xC3, - NSF7FunctionKey, 0xC4, - NSF8FunctionKey, 0xC5, - NSF9FunctionKey, 0xC6, - NSF10FunctionKey, 0xC7, - NSF11FunctionKey, 0xC8, - NSF12FunctionKey, 0xC9, - NSF13FunctionKey, 0xCA, - NSF14FunctionKey, 0xCB, - NSF15FunctionKey, 0xCC, - NSF16FunctionKey, 0xCD, - NSF17FunctionKey, 0xCE, - NSF18FunctionKey, 0xCF, - NSF19FunctionKey, 0xD0, - NSF20FunctionKey, 0xD1, - NSF21FunctionKey, 0xD2, - NSF22FunctionKey, 0xD3, - NSF23FunctionKey, 0xD4, - NSF24FunctionKey, 0xD5, - - NSBackspaceCharacter, 0x08, /* 8: Not on some KBs. */ - NSDeleteCharacter, 0xFF, /* 127: Big 'delete' key upper right. */ - NSDeleteFunctionKey, 0x9F, /* 63272: Del forw key off main array. */ - - NSTabCharacter, 0x09, - 0x19, 0x09, /* left tab->regular since pass shift */ - NSCarriageReturnCharacter, 0x0D, - NSNewlineCharacter, 0x0D, - NSEnterCharacter, 0x8D, - - 0x1B, 0x1B /* escape */ -}; - - -static unsigned -isFunctionKey( - unsigned code) -{ - const unsigned last_keysym = (sizeof(convert_ns_to_X_keysym) - / sizeof(convert_ns_to_X_keysym[0])); - unsigned keysym; - - for (keysym = 0; keysym < last_keysym; keysym += 2) { - if (code == convert_ns_to_X_keysym[keysym]) { - return 0xFF00 | convert_ns_to_X_keysym[keysym + 1]; - } - } - return 0; + caret_y = Tk_Height(tkwin) - y; } /* |