Import Tk 8.5.15 (as of svn r89086)
This commit is contained in:
723
macosx/tkMacOSXKeyEvent.c
Normal file
723
macosx/tkMacOSXKeyEvent.c
Normal file
@@ -0,0 +1,723 @@
|
||||
/*
|
||||
* tkMacOSXKeyEvent.c --
|
||||
*
|
||||
* This file implements functions that decode & handle keyboard events on
|
||||
* MacOS X.
|
||||
*
|
||||
* Copyright 2001-2009, Apple Inc.
|
||||
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
|
||||
* Copyright (c) 2012 Adrian Robert.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include "tkMacOSXPrivate.h"
|
||||
#include "tkMacOSXEvent.h"
|
||||
|
||||
/*
|
||||
#ifdef TK_MAC_DEBUG
|
||||
#define TK_MAC_DEBUG_KEYBOARD
|
||||
#endif
|
||||
*/
|
||||
#define NS_KEYLOG 0
|
||||
|
||||
|
||||
static Tk_Window grabWinPtr = NULL;
|
||||
/* Current grab window, NULL if no grab. */
|
||||
static Tk_Window keyboardGrabWinPtr = NULL;
|
||||
/* Current keyboard grab window. */
|
||||
static NSModalSession modalSession = NULL;
|
||||
|
||||
static BOOL processingCompose = NO;
|
||||
static BOOL finishedCompose = NO;
|
||||
|
||||
static int caret_x = 0, caret_y = 0, caret_height = 0;
|
||||
|
||||
static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state);
|
||||
static unsigned isFunctionKey(unsigned int code);
|
||||
|
||||
|
||||
#pragma mark TKApplication(TKKeyEvent)
|
||||
|
||||
@implementation TKApplication(TKKeyEvent)
|
||||
|
||||
- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
|
||||
#endif
|
||||
NSWindow* w;
|
||||
NSEventType type = [theEvent type];
|
||||
NSUInteger modifiers, len = 0;
|
||||
BOOL repeat = NO;
|
||||
unsigned short keyCode;
|
||||
NSString *characters = nil, *charactersIgnoringModifiers = nil;
|
||||
static NSUInteger savedModifiers = 0;
|
||||
static NSMutableArray *nsEvArray;
|
||||
|
||||
if (nsEvArray == nil)
|
||||
{
|
||||
nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
processingCompose = NO;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case NSKeyUp:
|
||||
if (finishedCompose)
|
||||
{
|
||||
// if we were composing, swallow the last release since we already sent
|
||||
finishedCompose = NO;
|
||||
return theEvent;
|
||||
}
|
||||
case NSKeyDown:
|
||||
repeat = [theEvent isARepeat];
|
||||
characters = [theEvent characters];
|
||||
charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];
|
||||
len = [charactersIgnoringModifiers length];
|
||||
case NSFlagsChanged:
|
||||
modifiers = [theEvent modifierFlags];
|
||||
keyCode = [theEvent keyCode];
|
||||
w = [self windowWithWindowNumber:[theEvent windowNumber]];
|
||||
#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
|
||||
NSLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
return theEvent;
|
||||
}
|
||||
|
||||
if (!processingCompose) {
|
||||
unsigned int state = 0;
|
||||
|
||||
if (modifiers & NSAlphaShiftKeyMask) {
|
||||
state |= LockMask;
|
||||
}
|
||||
if (modifiers & NSShiftKeyMask) {
|
||||
state |= ShiftMask;
|
||||
}
|
||||
if (modifiers & NSControlKeyMask) {
|
||||
state |= ControlMask;
|
||||
}
|
||||
if (modifiers & NSCommandKeyMask) {
|
||||
state |= Mod1Mask; /* command key */
|
||||
}
|
||||
if (modifiers & NSAlternateKeyMask) {
|
||||
state |= Mod2Mask; /* option key */
|
||||
}
|
||||
if (modifiers & NSNumericPadKeyMask) {
|
||||
state |= Mod3Mask;
|
||||
}
|
||||
if (modifiers & NSFunctionKeyMask) {
|
||||
state |= Mod4Mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* The focus must be in the FrontWindow on the Macintosh. We then query Tk
|
||||
* to determine the exact Tk window that owns the focus.
|
||||
*/
|
||||
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
|
||||
if (!tkwin) {
|
||||
TkMacOSXDbgMsg("tkwin == NULL");
|
||||
return theEvent;
|
||||
}
|
||||
tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
if (!tkwin) {
|
||||
TkMacOSXDbgMsg("tkwin == NULL");
|
||||
return theEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's a function key, or we have modifiers other than Shift or Alt,
|
||||
* pass it straight to Tk. Otherwise we'll send for input processing.
|
||||
*/
|
||||
int code = (len == 0) ?
|
||||
0 : [charactersIgnoringModifiers characterAtIndex: 0];
|
||||
if (type != NSKeyDown || isFunctionKey(code)
|
||||
|| (len > 0 && state & (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask))) {
|
||||
|
||||
XEvent xEvent;
|
||||
setupXEvent(&xEvent, w, state);
|
||||
|
||||
if (type == NSFlagsChanged) {
|
||||
if (savedModifiers > modifiers) {
|
||||
xEvent.xany.type = KeyRelease;
|
||||
} else {
|
||||
xEvent.xany.type = KeyPress;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use special '-1' to signify a special keycode to our platform
|
||||
* specific code in tkMacOSXKeyboard.c. This is rather like what
|
||||
* happens on Windows.
|
||||
*/
|
||||
|
||||
xEvent.xany.send_event = -1;
|
||||
|
||||
/*
|
||||
* Set keycode (which was zero) to the changed modifier
|
||||
*/
|
||||
|
||||
xEvent.xkey.keycode = (modifiers ^ savedModifiers);
|
||||
} else {
|
||||
if (type == NSKeyUp || repeat) {
|
||||
xEvent.xany.type = KeyRelease;
|
||||
} else {
|
||||
xEvent.xany.type = KeyPress;
|
||||
}
|
||||
|
||||
/* For command key, take input manager's word so things
|
||||
like dvorak / qwerty layout work. */
|
||||
if ((modifiers & NSCommandKeyMask) == NSCommandKeyMask
|
||||
&& (modifiers & NSAlternateKeyMask) != NSAlternateKeyMask
|
||||
&& len > 0 && !isFunctionKey(code)) {
|
||||
// head off keycode-based translation in tkMacOSXKeyboard.c
|
||||
xEvent.xkey.nbytes = [characters length]; //len
|
||||
}
|
||||
|
||||
if ([characters length] > 0) {
|
||||
xEvent.xkey.keycode =
|
||||
(keyCode << 16) | (UInt16) [characters characterAtIndex:0];
|
||||
if (![characters getCString:xEvent.xkey.trans_chars
|
||||
maxLength:XMaxTransChars encoding:NSUTF8StringEncoding]) {
|
||||
/* prevent SF bug 2907388 (crash on some composite chars) */
|
||||
//PENDING: we might not need this anymore
|
||||
TkMacOSXDbgMsg("characters too long");
|
||||
return theEvent;
|
||||
}
|
||||
}
|
||||
|
||||
if (repeat) {
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
xEvent.xany.type = KeyPress;
|
||||
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
}
|
||||
}
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
savedModifiers = modifiers;
|
||||
return theEvent;
|
||||
} /* if send straight to TK */
|
||||
|
||||
} /* if not processing compose */
|
||||
|
||||
if (type == NSKeyDown) {
|
||||
if (NS_KEYLOG)
|
||||
fprintf (stderr, "keyDown: %s compose sequence.\n",
|
||||
processingCompose == YES ? "Continue" : "Begin");
|
||||
processingCompose = YES;
|
||||
[nsEvArray addObject: theEvent];
|
||||
[[w contentView] interpretKeyEvents: nsEvArray];
|
||||
[nsEvArray removeObject: theEvent];
|
||||
}
|
||||
|
||||
savedModifiers = modifiers;
|
||||
|
||||
return theEvent;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation TKContentView(TKKeyEvent)
|
||||
/* <NSTextInput> implementation (called through interpretKeyEvents:]). */
|
||||
|
||||
/* <NSTextInput>: called when done composing;
|
||||
NOTE: also called when we delete over working text, followed immed.
|
||||
by doCommandBySelector: deleteBackward: */
|
||||
- (void)insertText: (id)aString
|
||||
{
|
||||
int i, len = [(NSString *)aString length];
|
||||
XEvent xEvent;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"insertText '%@'\tlen = %d", aString, len);
|
||||
processingCompose = NO;
|
||||
finishedCompose = YES;
|
||||
|
||||
/* first, clear any working text */
|
||||
if (_workingText != nil)
|
||||
[self deleteWorkingText];
|
||||
|
||||
/* now insert the string as keystrokes */
|
||||
setupXEvent(&xEvent, [self window], 0);
|
||||
xEvent.xany.type = KeyPress;
|
||||
|
||||
for (i =0; i<len; i++)
|
||||
{
|
||||
xEvent.xkey.keycode = (UInt16) [aString characterAtIndex: i];
|
||||
[[aString substringWithRange: NSMakeRange(i,1)]
|
||||
getCString: xEvent.xkey.trans_chars
|
||||
maxLength: XMaxTransChars encoding: NSUTF8StringEncoding];
|
||||
xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);
|
||||
xEvent.xany.type = KeyPress;
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
|
||||
xEvent.xany.type = KeyRelease;
|
||||
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* <NSTextInput>: inserts display of composing characters */
|
||||
- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange
|
||||
{
|
||||
NSString *str = [aString respondsToSelector: @selector (string)] ?
|
||||
[aString string] : aString;
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"setMarkedText '%@' len =%d range %d from %d", str, [str length],
|
||||
selRange.length, selRange.location);
|
||||
|
||||
if (_workingText != nil)
|
||||
[self deleteWorkingText];
|
||||
if ([str length] == 0)
|
||||
return;
|
||||
|
||||
processingCompose = YES;
|
||||
_workingText = [str copy];
|
||||
|
||||
//PENDING: insert workingText underlined
|
||||
}
|
||||
|
||||
|
||||
/* delete display of composing characters [not in <NSTextInput>] */
|
||||
- (void)deleteWorkingText
|
||||
{
|
||||
if (_workingText == nil)
|
||||
return;
|
||||
if (NS_KEYLOG)
|
||||
NSLog(@"deleteWorkingText len = %d\n", [_workingText length]);
|
||||
[_workingText release];
|
||||
_workingText = nil;
|
||||
processingCompose = NO;
|
||||
|
||||
//PENDING: delete working text
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
return _workingText != nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
NSRange rng = _workingText != nil
|
||||
? NSMakeRange (0, [_workingText length]) : NSMakeRange (NSNotFound, 0);
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"markedRange request");
|
||||
return rng;
|
||||
}
|
||||
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"unmark (accept) text");
|
||||
[self deleteWorkingText];
|
||||
processingCompose = NO;
|
||||
}
|
||||
|
||||
|
||||
/* used to position char selection windows, etc. */
|
||||
- (NSRect)firstRectForCharacterRange: (NSRange)theRange
|
||||
{
|
||||
NSRect rect;
|
||||
NSPoint pt;
|
||||
|
||||
pt.x = caret_x;
|
||||
pt.y = caret_y;
|
||||
|
||||
pt = [self convertPoint: pt toView: nil];
|
||||
pt = [[self window] convertBaseToScreen: pt];
|
||||
pt.y -= caret_height;
|
||||
|
||||
rect.origin = pt;
|
||||
rect.size.width = caret_height;
|
||||
rect.size.height = caret_height;
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
- (NSInteger)conversationIdentifier
|
||||
{
|
||||
return (NSInteger)self;
|
||||
}
|
||||
|
||||
|
||||
- (void)doCommandBySelector: (SEL)aSelector
|
||||
{
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));
|
||||
processingCompose = NO;
|
||||
if (aSelector == @selector (deleteBackward:))
|
||||
{
|
||||
/* happens when user backspaces over an ongoing composition:
|
||||
throw a 'delete' into the event queue */
|
||||
XEvent xEvent;
|
||||
setupXEvent(&xEvent, [self window], 0);
|
||||
xEvent.xany.type = KeyPress;
|
||||
xEvent.xkey.nbytes = 1;
|
||||
xEvent.xkey.keycode = (0x33 << 16) | 0x7F;
|
||||
xEvent.xkey.trans_chars[0] = 0x7F;
|
||||
xEvent.xkey.trans_chars[1] = 0x0;
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *)validAttributesForMarkedText
|
||||
{
|
||||
static NSArray *arr = nil;
|
||||
if (arr == nil) arr = [NSArray new];
|
||||
/* [[NSArray arrayWithObject: NSUnderlineStyleAttributeName] retain]; */
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
- (NSRange)selectedRange
|
||||
{
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"selectedRange request");
|
||||
return NSMakeRange (NSNotFound, 0);
|
||||
}
|
||||
|
||||
|
||||
- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
|
||||
{
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"characterIndexForPoint request");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
|
||||
{
|
||||
static NSAttributedString *str = nil;
|
||||
if (str == nil) str = [NSAttributedString new];
|
||||
if (NS_KEYLOG)
|
||||
NSLog (@"attributedSubstringFromRange request");
|
||||
return str;
|
||||
}
|
||||
/* End <NSTextInput> impl. */
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set up basic fields in xevent for keyboard input.
|
||||
*/
|
||||
static void
|
||||
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
|
||||
{
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
|
||||
memset(xEvent, 0, sizeof(XEvent));
|
||||
xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
xEvent->xany.send_event = false;
|
||||
xEvent->xany.display = Tk_Display(tkwin);
|
||||
xEvent->xany.window = Tk_WindowId(tkwin);
|
||||
|
||||
xEvent->xkey.root = XRootWindow(Tk_Display(tkwin), 0);
|
||||
xEvent->xkey.subwindow = None;
|
||||
xEvent->xkey.time = TkpGetMS();
|
||||
xEvent->xkey.state = state;
|
||||
xEvent->xkey.same_screen = true;
|
||||
xEvent->xkey.trans_chars[0] = 0;
|
||||
xEvent->xkey.nbytes = 0;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* XGrabKeyboard --
|
||||
*
|
||||
* Simulates a keyboard grab by setting the focus.
|
||||
*
|
||||
* Results:
|
||||
* Always returns GrabSuccess.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets the keyboard focus to the specified window.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
XGrabKeyboard(
|
||||
Display* display,
|
||||
Window grab_window,
|
||||
Bool owner_events,
|
||||
int pointer_mode,
|
||||
int keyboard_mode,
|
||||
Time time)
|
||||
{
|
||||
keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
|
||||
if (keyboardGrabWinPtr && grabWinPtr) {
|
||||
NSWindow *w = TkMacOSXDrawableWindow(grab_window);
|
||||
MacDrawable *macWin = (MacDrawable *) grab_window;
|
||||
|
||||
if (w && macWin->toplevel->winPtr == (TkWindow*) grabWinPtr) {
|
||||
if (modalSession) {
|
||||
Tcl_Panic("XGrabKeyboard: already grabbed");
|
||||
}
|
||||
modalSession = [NSApp beginModalSessionForWindow:[w retain]];
|
||||
}
|
||||
}
|
||||
return GrabSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* XUngrabKeyboard --
|
||||
*
|
||||
* Releases the simulated keyboard grab.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets the keyboard focus back to the value before the grab.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
XUngrabKeyboard(
|
||||
Display* display,
|
||||
Time time)
|
||||
{
|
||||
if (modalSession) {
|
||||
NSWindow *w = keyboardGrabWinPtr ? TkMacOSXDrawableWindow(
|
||||
((TkWindow *) keyboardGrabWinPtr)->window) : nil;
|
||||
[NSApp endModalSession:modalSession];
|
||||
[w release];
|
||||
modalSession = NULL;
|
||||
}
|
||||
keyboardGrabWinPtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXGetCapture --
|
||||
*
|
||||
* Results:
|
||||
* Returns the current grab window
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tk_Window
|
||||
TkMacOSXGetCapture(void)
|
||||
{
|
||||
return grabWinPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXGetModalSession --
|
||||
*
|
||||
* Results:
|
||||
* Returns the current modal session
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE NSModalSession
|
||||
TkMacOSXGetModalSession(void)
|
||||
{
|
||||
return modalSession;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkpSetCapture --
|
||||
*
|
||||
* This function captures the mouse so that all future events will be
|
||||
* reported to this window, even if the mouse is outside the window. If
|
||||
* the specified window is NULL, then the mouse is released.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets the capture flag and captures the mouse.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkpSetCapture(
|
||||
TkWindow *winPtr) /* Capture window, or NULL. */
|
||||
{
|
||||
while (winPtr && !Tk_IsTopLevel(winPtr)) {
|
||||
winPtr = winPtr->parentPtr;
|
||||
}
|
||||
grabWinPtr = (Tk_Window) winPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Tk_SetCaretPos(
|
||||
Tk_Window tkwin,
|
||||
int x,
|
||||
int y,
|
||||
int height)
|
||||
{
|
||||
TkCaret *caretPtr = &(((TkWindow *) tkwin)->dispPtr->caret);
|
||||
|
||||
/*
|
||||
* Prevent processing anything if the values haven't changed. Windows only
|
||||
* has one display, so we can do this with statics.
|
||||
*/
|
||||
|
||||
if ((caretPtr->winPtr == ((TkWindow *) tkwin))
|
||||
&& (caretPtr->x == x) && (caretPtr->y == y)) {
|
||||
return;
|
||||
}
|
||||
|
||||
caretPtr->winPtr = ((TkWindow *) tkwin);
|
||||
caretPtr->x = x;
|
||||
caretPtr->y = y;
|
||||
caretPtr->height = height;
|
||||
|
||||
/*
|
||||
* As in Windows, adjust to the toplevel to get the coords right.
|
||||
*/
|
||||
|
||||
while (!Tk_IsTopLevel(tkwin)) {
|
||||
x += Tk_X(tkwin);
|
||||
y += Tk_Y(tkwin);
|
||||
tkwin = Tk_Parent(tkwin);
|
||||
if (tkwin == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 79
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user