diff options
author | hobbs <hobbs@noemail.net> | 2007-04-21 19:06:37 (GMT) |
---|---|---|
committer | hobbs <hobbs@noemail.net> | 2007-04-21 19:06:37 (GMT) |
commit | ef77503b29e3733896c8d251b8935b3075f6fc5b (patch) | |
tree | 67b15fa8aaeefba792a30cace3d1ecf46d134365 /macosx/tkMacOSXKeyEvent.c | |
parent | 659bf053f562dfb0793d4dca0a39bcacfac2653c (diff) | |
download | tk-ef77503b29e3733896c8d251b8935b3075f6fc5b.zip tk-ef77503b29e3733896c8d251b8935b3075f6fc5b.tar.gz tk-ef77503b29e3733896c8d251b8935b3075f6fc5b.tar.bz2 |
* macosx/tkMacOSXBitmap.c, macosx/tkMacOSXButton.c:
* macosx/tkMacOSXCarbonEvents.c, macosx/tkMacOSXClipboard.c:
* macosx/tkMacOSXCursor.c, macosx/tkMacOSXDialog.c:
* macosx/tkMacOSXDraw.c, macosx/tkMacOSXEvent.c:
* macosx/tkMacOSXFont.c, macosx/tkMacOSXInit.c, macosx/tkMacOSXInt.h:
* macosx/tkMacOSXKeyEvent.c, macosx/tkMacOSXMenu.c:
* macosx/tkMacOSXMenubutton.c, macosx/tkMacOSXMouseEvent.c:
* macosx/tkMacOSXScale.c, macosx/tkMacOSXWindowEvent.c:
* macosx/tkMacOSXWm.c: Revert of commits from 2007-04-13 which
broke the OS X build.
FossilOrigin-Name: 888addf4ed50c4b8c88df0ef3df6b0408abd384c
Diffstat (limited to 'macosx/tkMacOSXKeyEvent.c')
-rw-r--r-- | macosx/tkMacOSXKeyEvent.c | 1418 |
1 files changed, 743 insertions, 675 deletions
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c index 27d6c7b..08d61a4 100644 --- a/macosx/tkMacOSXKeyEvent.c +++ b/macosx/tkMacOSXKeyEvent.c @@ -1,8 +1,8 @@ /* * tkMacOSXKeyEvent.c -- * - * This file implements functions that decode & handle keyboard events - * on MacOS X. + * This file implements functions that decode & handle keyboard events + * on MacOS X. * * Copyright 2001, Apple Computer, Inc. * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net> @@ -10,49 +10,51 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. - * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. - * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. - * - * RCS: @(#) $Id: tkMacOSXKeyEvent.c,v 1.19 2007/04/13 14:51:18 dkf Exp $ + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. + * + * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. + * + * + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXKeyEvent.c,v 1.20 2007/04/21 19:06:38 hobbs Exp $ */ #include "tkMacOSXInt.h" @@ -63,225 +65,252 @@ #define TK_MAC_DEBUG_KEYBOARD #endif */ -#ifdef TK_MAC_DEBUG_KEYBOARD -#define KDBG DBG_MSG -#else -#define KDBG(...) /* nothing */ -#endif typedef struct { - WindowRef whichWindow; - int global_x, global_y; - int local_x, local_y; + WindowRef whichWindow; + int global_x, global_y; + int local_x, local_y; unsigned int state; unsigned char ch; - UInt32 keyCode; - UInt32 keyModifiers; - UInt32 message; + UInt32 keyCode; + UInt32 keyModifiers; + UInt32 message; } KeyEventData; -static Tk_Window gGrabWinPtr = NULL; - /* Current grab window, NULL if no grab. */ -static Tk_Window gKeyboardWinPtr = NULL; - /* Current keyboard grab window. */ -static UInt32 deadKeyStateUp = 0; - /* The deadkey state for the current sequence - * of keyup events or 0 if not in a deadkey - * sequence */ -static UInt32 deadKeyStateDown = 0; - /* Ditto for keydown */ +static Tk_Window gGrabWinPtr = NULL; /* Current grab window, + * NULL if no grab. */ +static Tk_Window gKeyboardWinPtr = NULL; /* Current keyboard grab window. */ + +static UInt32 deadKeyStateUp = 0; /* The deadkey state for the current + * sequence of keyup events or 0 if + * not in a deadkey sequence */ +static UInt32 deadKeyStateDown = 0; /* Ditto for keydown */ /* * Declarations for functions used only in this file. */ - -static int InitKeyData(KeyEventData *keyEventDataPtr); -static int InitKeyEvent(XEvent *eventPtr, KeyEventData *e, - UInt32 savedKeyCode, UInt32 savedModifiers); -static int GenerateKeyEvent(UInt32 eKind, KeyEventData *e, - UInt32 savedKeyCode, UInt32 savedModifiers, - const UniChar *chars, int numChars); -static int GetKeyboardLayout(Ptr *resourcePtr, - TextEncoding *encodingPtr); -static TextEncoding GetKCHREncoding(ScriptCode script, SInt32 layoutid); -static int KeycodeToUnicodeViaUnicodeResource(UniChar *uniChars, - int maxChars, Ptr uchr, EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 *deadKeyStatePtr); -static int KeycodeToUnicodeViaKCHRResource(UniChar *uniChars, - int maxChars, Ptr kchr, TextEncoding encoding, - EventKind eKind, UInt32 keycode, UInt32 modifiers, - UInt32 *deadKeyStatePtr); + +static int InitKeyData( + KeyEventData * keyEventDataPtr); + +static int InitKeyEvent( + XEvent * eventPtr, + KeyEventData * e, + UInt32 savedKeyCode, + UInt32 savedModifiers); + +static int GenerateKeyEvent ( + UInt32 eKind, + KeyEventData * e, + UInt32 savedKeyCode, + UInt32 savedModifiers, + const UniChar * chars, int numChars); + +static int GetKeyboardLayout ( + Ptr * resourcePtr, TextEncoding * encodingPtr); +static TextEncoding GetKCHREncoding( + ScriptCode script, SInt32 layoutid); + +static int KeycodeToUnicodeViaUnicodeResource( + UniChar * uniChars, int maxChars, + Ptr uchr, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr); + +static int KeycodeToUnicodeViaKCHRResource( + UniChar * uniChars, int maxChars, + Ptr kchr, TextEncoding encoding, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr); /* *---------------------------------------------------------------------- * * TkMacOSXProcessKeyboardEvent -- * - * This routine processes the event in eventPtr, and generates the - * appropriate Tk events from it. + * This routine processes the event in eventPtr, and + * generates the appropriate Tk events from it. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TkMacOSXProcessKeyboardEvent( - TkMacOSXEvent *eventPtr, - MacEventStatus *statusPtr) + TkMacOSXEvent * eventPtr, + MacEventStatus * statusPtr) { static UInt32 savedKeyCode = 0; static UInt32 savedModifiers = 0; static UniChar savedChar = 0; - OSStatus status; + OSStatus status; KeyEventData keyEventData; - MenuRef menuRef; + MenuRef menuRef; MenuItemIndex menuItemIndex; int eventGenerated; UniChar uniChars[5]; /* make this larger, if needed */ UInt32 uniCharsLen = 0; if (!InitKeyData(&keyEventData)) { - statusPtr->err = 1; - return false; + statusPtr->err = 1; + return false; } - + /* * Because of the way that Tk operates, we can't in general funnel menu - * accelerators through IsMenuKeyEvent. Tk treats accelerators as mere + * accelerators through IsMenuKeyEvent. Tk treats accelerators as mere * decoration, and the user has to install bindings to get them to fire. * - * However, the only way to trigger the Hide & Hide Others functions is by - * invoking the Menu command for Hide. So there is no nice way to provide - * a Tk command to hide the app which would be available for a binding. So - * I am going to hijack Command-H and Command-Shift-H here, and run the - * menu commands. Since the HI Guidelines explicitly reserve these for - * Hide, this isn't such a bad thing. Also, if you do rebind Command-H to - * another menu item, Hide will lose its binding. - * - * Note that I don't really do anything at this point, I just mark - * stopProcessing as 0 and return, and then the RecieveAndProcessEvent - * code will dispatch the event to the default handler. + * However, the only way to trigger the Hide & Hide Others functions + * is by invoking the Menu command for Hide. So there is no nice way to + * provide a Tk command to hide the app which would be available for a + * binding. So I am going to hijack Command-H and Command-Shift-H + * here, and run the menu commands. Since the HI Guidelines explicitly + * reserve these for Hide, this isn't such a bad thing. Also, if you do + * rebind Command-H to another menu item, Hide will lose its binding. + * + * Note that I don't really do anything at this point, + * I just mark stopProcessing as 0 and return, and then the + * RecieveAndProcessEvent code will dispatch the event to the default + * handler. */ - if ((eventPtr->eKind == kEventRawKeyDown + if ((eventPtr->eKind == kEventRawKeyDown || eventPtr->eKind == kEventRawKeyRepeat) - && IsMenuKeyEvent(tkCurrentAppleMenu, eventPtr->eventRef, + && IsMenuKeyEvent(tkCurrentAppleMenu, eventPtr->eventRef, kMenuEventQueryOnly, &menuRef, &menuItemIndex)) { MenuCommand menuCmd; GetMenuItemCommandID (menuRef, menuItemIndex, &menuCmd); switch (menuCmd) { - case kHICommandHide: - case kHICommandHideOthers: - case kHICommandShowAll: - case kHICommandPreferences: - case kHICommandQuit: - statusPtr->stopProcessing = 0; - return 0; /* TODO: may not be on event on queue. */ - break; - default: - break; + case kHICommandHide: + case kHICommandHideOthers: + case kHICommandShowAll: + case kHICommandPreferences: + case kHICommandQuit: + statusPtr->stopProcessing = 0; + return 0; /* TODO: may not be on event on queue. */ + break; + default: + break; } } - status = GetEventParameter(eventPtr->eventRef, - kEventParamKeyMacCharCodes, typeChar, NULL, - sizeof(keyEventData.ch), NULL, &keyEventData.ch); + status = GetEventParameter(eventPtr->eventRef, + kEventParamKeyMacCharCodes, + typeChar, NULL, + sizeof(keyEventData.ch), NULL, + &keyEventData.ch); if (status != noErr) { - LOG_MSG("Failed to retrieve KeyMacCharCodes"); - statusPtr->err = 1; - return false; - } - status = GetEventParameter(eventPtr->eventRef, kEventParamKeyCode, - typeUInt32, NULL, sizeof(keyEventData.keyCode), NULL, - &keyEventData.keyCode); +#ifdef TK_MAC_DEBUG + fprintf (stderr, "Failed to retrieve KeyMacCharCodes\n"); +#endif + statusPtr->err = 1; + return false; + } + status = GetEventParameter(eventPtr->eventRef, + kEventParamKeyCode, + typeUInt32, NULL, + sizeof(keyEventData.keyCode), NULL, + &keyEventData.keyCode); if (status != noErr) { - LOG_MSG("Failed to retrieve KeyCode"); - statusPtr->err = 1; - return false; +#ifdef TK_MAC_DEBUG + fprintf (stderr, "Failed to retrieve KeyCode\n"); +#endif + statusPtr->err = 1; + return false; } - status = GetEventParameter(eventPtr->eventRef, kEventParamKeyModifiers, - typeUInt32, NULL, sizeof(keyEventData.keyModifiers), NULL, - &keyEventData.keyModifiers); + status = GetEventParameter(eventPtr->eventRef, + kEventParamKeyModifiers, + typeUInt32, NULL, + sizeof(keyEventData.keyModifiers), NULL, + &keyEventData.keyModifiers); if (status != noErr) { - LOG_MSG("Failed to retrieve KeyModifiers"); - statusPtr->err = 1; - return false; +#ifdef TK_MAC_DEBUG + fprintf (stderr, "Failed to retrieve KeyModifiers\n"); +#endif + statusPtr->err = 1; + return false; } switch (eventPtr->eKind) { - case kEventRawKeyUp: - case kEventRawKeyDown: - case kEventRawKeyRepeat: { - UInt32 *deadKeyStatePtr; - - if (kEventRawKeyDown == eventPtr->eKind) { - deadKeyStatePtr = &deadKeyStateDown; - } else { - deadKeyStatePtr = &deadKeyStateUp; - } - - uniCharsLen = TkMacOSXKeycodeToUnicode(uniChars, - sizeof(uniChars)/sizeof(*uniChars), eventPtr->eKind, - keyEventData.keyCode, keyEventData.keyModifiers, - deadKeyStatePtr); - } + case kEventRawKeyUp: + case kEventRawKeyDown: + case kEventRawKeyRepeat: + { + UInt32 *deadKeyStatePtr; + + if (kEventRawKeyDown == eventPtr->eKind) { + deadKeyStatePtr = &deadKeyStateDown; + } else { + deadKeyStatePtr = &deadKeyStateUp; + } + + uniCharsLen = TkMacOSXKeycodeToUnicode( + uniChars, sizeof(uniChars)/sizeof(*uniChars), + eventPtr->eKind, + keyEventData.keyCode, keyEventData.keyModifiers, + deadKeyStatePtr); + } } if (kEventRawKeyUp == eventPtr->eKind) { - /* - * For some reason the deadkey processing for KeyUp doesn't work - * sometimes, so we fudge and use the last detected KeyDown. - */ - - if ((0 == uniCharsLen) && (0 != savedChar)) { - uniChars[0] = savedChar; - uniCharsLen = 1; - } - - /* - * Suppress keyup events while we have a deadkey sequence on keydown. - * We still *do* want to collect deadkey state in this situation if - * the system provides it, that's why we do this only after - * TkMacOSXKeycodeToUnicode(). - */ - - if (0 != deadKeyStateDown) { - uniCharsLen = 0; - } + /* + * For some reason the deadkey processing for KeyUp doesn't work + * sometimes, so we fudge and use the last detected KeyDown. + */ + + if((0 == uniCharsLen) && (0 != savedChar)) { + uniChars[0] = savedChar; + uniCharsLen = 1; + } + + /* + * Suppress keyup events while we have a deadkey sequence on keydown. + * We still *do* want to collect deadkey state in this situation if + * the system provides it, that's why we do this only after + * TkMacOSXKeycodeToUnicode(). + */ + + if (0 != deadKeyStateDown) { + uniCharsLen = 0; + } } keyEventData.message = keyEventData.ch|(keyEventData.keyCode << 8); - eventGenerated = GenerateKeyEvent(eventPtr->eKind, &keyEventData, - savedKeyCode, savedModifiers, uniChars, uniCharsLen); + eventGenerated = GenerateKeyEvent( + eventPtr->eKind, &keyEventData, + savedKeyCode, savedModifiers, + uniChars, uniCharsLen); savedModifiers = keyEventData.keyModifiers; if ((kEventRawKeyDown == eventPtr->eKind) && (uniCharsLen > 0)) { - savedChar = uniChars[0]; + savedChar = uniChars[0]; } else { - savedChar = 0; + savedChar = 0; } - + statusPtr->stopProcessing = 1; if (eventGenerated == 0) { - savedKeyCode = keyEventData.message; - return false; + savedKeyCode = keyEventData.message; + return false; } else if (eventGenerated == -1) { - savedKeyCode = 0; - statusPtr->stopProcessing = 0; - return false; + savedKeyCode = 0; + statusPtr->stopProcessing = 0; + return false; } else { - savedKeyCode = 0; - return true; + savedKeyCode = 0; + return true; } } @@ -290,102 +319,107 @@ TkMacOSXProcessKeyboardEvent( * * GenerateKeyEvent -- * - * Given Macintosh keyUp, keyDown & autoKey events (in their "raw" form) - * and a list of unicode characters this function generates the - * appropriate X key events. + * Given Macintosh keyUp, keyDown & autoKey events (in their "raw" + * form) and a list of unicode characters this function generates the + * appropriate X key events. * - * Parameter eKind is a raw keyboard event. e contains the data sent with - * the event. savedKeyCode and savedModifiers contain the values from the - * last event that came before (see TkMacOSXProcessKeyboardEvent()). - * chars/numChars has the Unicode characters for which we want to create - * events. + * Parameter eKind is a raw keyboard event. e contains the data sent + * with the event. savedKeyCode and savedModifiers contain the values + * from the last event that came before (see + * TkMacOSXProcessKeyboardEvent()). chars/numChars has the Unicode + * characters for which we want to create events. * * Results: - * 1 if an event was generated, -1 for any error. + * 1 if an event was generated, -1 for any error. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ static int GenerateKeyEvent( - UInt32 eKind, - KeyEventData * e, - UInt32 savedKeyCode, - UInt32 savedModifiers, - const UniChar * chars, - int numChars) + UInt32 eKind, + KeyEventData * e, + UInt32 savedKeyCode, + UInt32 savedModifiers, + const UniChar * chars, int numChars) { XEvent event; int i; - + if (-1 == InitKeyEvent(&event, e, savedKeyCode, savedModifiers)) { - return -1; + return -1; } if (kEventRawKeyModifiersChanged == eKind) { - if (savedModifiers > e->keyModifiers) { - event.xany.type = KeyRelease; - } else { - event.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. - */ - - event.xany.send_event = -1; - /* - * Set keycode (which was zero) to the changed modifier - */ - - event.xkey.keycode = (e->keyModifiers ^ savedModifiers); - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + if (savedModifiers > e->keyModifiers) { + event.xany.type = KeyRelease; + } else { + event.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. + */ + + event.xany.send_event = -1; + + /* + * Set keycode (which was zero) to the changed modifier + */ + + event.xkey.keycode = (e->keyModifiers ^ savedModifiers); + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } else { - for (i = 0; i < numChars; ++i) { - /* - * Encode one char in the trans_chars array that was already - * introduced for MS Windows. Don't encode the string, if it is a - * control character but was not generated with a real control - * modifier. Such control characters get generated by KeyTrans() - * for special keys, but we rather want to identify those by their - * KeySyms. - */ - - event.xkey.trans_chars[0] = 0; - if ((controlKey & e->keyModifiers) || (chars[i] >= ' ')) { - int done; - done = Tcl_UniCharToUtf(chars[i],event.xkey.trans_chars); - event.xkey.trans_chars[done] = 0; - } - - switch(eKind) { - case kEventRawKeyDown: - event.xany.type = KeyPress; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - break; - case kEventRawKeyUp: - event.xany.type = KeyRelease; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - break; - case kEventRawKeyRepeat: - event.xany.type = KeyRelease; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - event.xany.type = KeyPress; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - break; - default: - LOG_MSG("GenerateKeyEvent(): Invalid parameter eKind %d", - (int) eKind); - return -1; - } - } + + for (i = 0; i < numChars; ++i) { + + /* + * Encode one char in the trans_chars array that was already + * introduced for MS Windows. Don't encode the string, if it is + * a control character but was not generated with a real control + * modifier. Such control characters get generated by KeyTrans() + * for special keys, but we rather want to identify those by + * their KeySyms. + */ + + event.xkey.trans_chars[0] = 0; + if ((controlKey & e->keyModifiers) || (chars[i] >= ' ')) { + int done; + done = Tcl_UniCharToUtf(chars[i],event.xkey.trans_chars); + event.xkey.trans_chars[done] = 0; + } + + switch(eKind) { + case kEventRawKeyDown: + event.xany.type = KeyPress; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + break; + case kEventRawKeyUp: + event.xany.type = KeyRelease; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + break; + case kEventRawKeyRepeat: + event.xany.type = KeyRelease; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.xany.type = KeyPress; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + break; + default: +#ifdef TK_MAC_DEBUG + fprintf (stderr, + "GenerateKeyEvent(): Invalid parameter eKind %d\n", + (int) eKind); +#endif + return -1; + } + } } return 1; @@ -396,33 +430,33 @@ GenerateKeyEvent( * * InitKeyData -- * - * This routine initializes a KeyEventData structure by asking the OS and - * Tk for all the global information needed here. + * This routine initializes a KeyEventData structure by asking the OS + * and Tk for all the global information needed here. * * Results: - * True if the current front window can be found in Tk data structures - - * false otherwise. + * True if the current front window can be found in Tk data structures + * - false otherwise. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ - -static int -InitKeyData( - KeyEventData *keyEventDataPtr) +static int +InitKeyData(KeyEventData * keyEventDataPtr) { - memset(keyEventDataPtr, 0, sizeof(*keyEventDataPtr)); + memset (keyEventDataPtr, 0, sizeof(*keyEventDataPtr)); keyEventDataPtr->whichWindow = ActiveNonFloatingWindow(); if (keyEventDataPtr->whichWindow == NULL) { - return false; + return false; } XQueryPointer(NULL, None, NULL, NULL, - &keyEventDataPtr->global_x, &keyEventDataPtr->global_y, - &keyEventDataPtr->local_x, &keyEventDataPtr->local_y, - &keyEventDataPtr->state); + &keyEventDataPtr->global_x, + &keyEventDataPtr->global_y, + &keyEventDataPtr->local_x, + &keyEventDataPtr->local_y, + &keyEventDataPtr->state); return true; } @@ -432,70 +466,75 @@ InitKeyData( * * InitKeyEvent -- * - * Initialize an XEvent structure by asking Tk for global information. - * Also uses a KeyEventData structure and other current state. + * Initialize an XEvent structure by asking Tk for global information. + * Also uses a KeyEventData structure and other current state. * * Results: - * 1 on success, -1 for any error. + * 1 on success, -1 for any error. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ -/* - * We have a general problem here. How do we handle 'Option-char' keypresses? - * The problem is that we might want to bind to some of these (e.g. Cmd-Opt-d - * is 'uncomment' in Alpha). OTOH Option-d actually produces a real character - * on MacOS, namely a mathematical delta. +/* + * We have a general problem here. How do we handle 'Option-char' + * keypresses? The problem is that we might want to bind to some of these + * (e.g. Cmd-Opt-d is 'uncomment' in Alpha). OTOH Option-d actually produces + * a real character on MacOS, namely a mathematical delta. * * The current behaviour is that a binding goes by the combinations of - * modifiers and base keysym, that is Option-d. The string value of the event - * is the mathematical delta character, so if no binding calls [break], the - * text widget will insert that character. + * modifiers and base keysym, that is Option-d. The string value of the + * event is the mathematical delta character, so if no binding calls + * [break], the text widget will insert that character. * - * Note that this is similar to control combinations on all platforms. They + * Note that this is similar to control combinations on all platforms. They * also generate events that have the base character as keysym and a real - * control character as character value. So Ctrl+C gets us the keysym XK_C, + * control character as character value. So Ctrl+C gets us the keysym XK_C, * the modifier Control (so you can bind <Control-C>) and a string value as * "\u0003". - * + * * For a different solutions we may want for the event to contain keysyms for - * *both* the 'Opt-d' side of things and the mathematical delta. Then a + * *both* the 'Opt-d' side of things and the mathematical delta. Then a * binding on Opt-d will trigger, but a binding on mathematical delta would - * also trigger. This would require changes in the core, though. + * also trigger. This would require changes in the core, though. */ static int InitKeyEvent( - XEvent * eventPtr, - KeyEventData * e, - UInt32 savedKeyCode, - UInt32 savedModifiers) + XEvent * eventPtr, + KeyEventData * e, + UInt32 savedKeyCode, + UInt32 savedModifiers) { Window window; Tk_Window tkwin; TkDisplay *dispPtr; - + /* - * The focus must be in the FrontWindow on the Macintosh. We then query Tk - * to determine the exact Tk window that owns the focus. + * The focus must be in the FrontWindow on the Macintosh. + * We then query Tk to determine the exact Tk window + * that owns the focus. */ window = TkMacOSXGetXWindow(e->whichWindow); dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); - + if (tkwin == NULL) { - LOG_MSG("tkwin == NULL, %d", __LINE__); - return -1; +#ifdef TK_MAC_DEBUG + fprintf(stderr,"tkwin == NULL, %d\n", __LINE__); +#endif + return -1; } - + tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; if (tkwin == NULL) { - LOG_MSG("tkwin == NULL, %d", __LINE__); - return -1; +#ifdef TK_MAC_DEBUG + fprintf(stderr,"tkwin == NULL, %d\n", __LINE__); +#endif + return -1; } eventPtr->xany.send_event = false; @@ -512,15 +551,17 @@ InitKeyEvent( eventPtr->xkey.state = e->state; eventPtr->xkey.trans_chars[0] = 0; - Tk_TopCoordsToWindow(tkwin, e->local_x, e->local_y, - &eventPtr->xkey.x, &eventPtr->xkey.y); + Tk_TopCoordsToWindow( + tkwin, e->local_x, e->local_y, + &eventPtr->xkey.x, &eventPtr->xkey.y); eventPtr->xkey.keycode = e->ch | - ((savedKeyCode & charCodeMask) << 8) | - ((e->message&keyCodeMask) << 8); + ((savedKeyCode & charCodeMask) << 8) | + ((e->message&keyCodeMask) << 8); return 1; } + /* * If we have old headers, we need to define these types and constants @@ -542,27 +583,25 @@ InitKeyEvent( * * GetKeyboardLayout -- * - * Queries the OS for a pointer to a keyboard resource. + * Queries the OS for a pointer to a keyboard resource. * - * This function works with the keyboard layout switch menu. It uses - * Keyboard Layout Services, where available. + * This function works with the keyboard layout switch menu. It uses + * Keyboard Layout Services, where available. * * Results: - * 1 if there is returned a Unicode 'uchr' resource in *resourcePtr, 0 if - * it is a classic 'KCHR' resource. A pointer to the actual resource data - * goes into *resourcePtr. If the resource is a 'KCHR' resource, the - * corresponding Mac encoding goes into *encodingPtr. + * 1 if there is returned a Unicode 'uchr' resource in *resourcePtr, 0 + * if it is a classic 'KCHR' resource. A pointer to the actual resource + * data goes into *resourcePtr. If the resource is a 'KCHR' resource, + * the corresponding Mac encoding goes into *encodingPtr. * * Side effects: - * Sets some internal static variables. + * Sets some internal static variables. * *---------------------------------------------------------------------- */ static int -GetKeyboardLayout( - Ptr *resourcePtr, - TextEncoding *encodingPtr) +GetKeyboardLayout (Ptr * resourcePtr, TextEncoding * encodingPtr) { static KeyboardLayoutRef lastLayout = NULL; static SInt32 lastLayoutId; @@ -583,260 +622,279 @@ GetKeyboardLayout( currentKeyScript = GetScriptManagerVariable(smKeyScript); TkMacOSXInitNamedSymbol(HIToolbox, OSStatus, KLGetCurrentKeyboardLayout, - KeyboardLayoutRef*); + KeyboardLayoutRef*); TkMacOSXInitNamedSymbol(HIToolbox, OSStatus, KLGetKeyboardLayoutProperty, - KeyboardLayoutRef, KeyboardLayoutPropertyTag, const void**); + KeyboardLayoutRef, KeyboardLayoutPropertyTag, const void**); if (KLGetCurrentKeyboardLayout && KLGetKeyboardLayoutProperty) { - /* - * Use the Keyboard Layout Services (these functions only exist since - * 10.2). - */ - - KLGetCurrentKeyboardLayout(¤tLayout); - - if (currentLayout != NULL) { - /* - * The layout pointer could in theory be the same for different - * layouts, only the id gives us the information that the keyboard - * has actually changed. OTOH the layout object can also change - * and it could still be the same layoutid. - */ - - KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, - (const void**)¤tLayoutId); - - if ((lastLayout != currentLayout) - || (lastLayoutId != currentLayoutId)) { - KDBG("GetKeyboardLayout(): Use KLS"); - hasLayoutChanged = true; - - /* - * Reinitialize all relevant variables. - */ - - lastLayout = currentLayout; - lastLayoutId = currentLayoutId; - uchr = NULL; - KCHR = NULL; - - if ((KLGetKeyboardLayoutProperty(currentLayout, kKLuchrData, - (const void**)&uchr) == noErr) && (uchr != NULL)) { - /* done */ - } else if ((KLGetKeyboardLayoutProperty(currentLayout, - kKLKCHRData, (const void**)&KCHR) == noErr) - && (KCHR != NULL)) { - /* done */ - } - } - } + + /* + * Use the Keyboard Layout Services (these functions only exist since + * 10.2). + */ + + KLGetCurrentKeyboardLayout(¤tLayout); + + if (currentLayout != NULL) { + + /* + * The layout pointer could in theory be the same for different + * layouts, only the id gives us the information that the + * keyboard has actually changed. OTOH the layout object can + * also change and it could still be the same layoutid. + */ + + KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, + (const void**)¤tLayoutId); + + if ((lastLayout != currentLayout) + || (lastLayoutId != currentLayoutId)) { + +#ifdef TK_MAC_DEBUG_KEYBOARD + fprintf (stderr, "GetKeyboardLayout(): Use KLS\n"); +#endif + + hasLayoutChanged = true; + + /* + * Reinitialize all relevant variables. + */ + + lastLayout = currentLayout; + lastLayoutId = currentLayoutId; + uchr = NULL; + KCHR = NULL; + + if ((KLGetKeyboardLayoutProperty(currentLayout, + kKLuchrData, (const void**)&uchr) + == noErr) + && (uchr != NULL)) { + /* done */ + } else if ((KLGetKeyboardLayoutProperty(currentLayout, + kKLKCHRData, (const void**)&KCHR) + == noErr) + && (KCHR != NULL)) { + /* done */ + } + } + } + } else { - /* - * Use the classic approach as shown in Apple code samples, loading - * the keyboard resources directly. This is broken for 10.3 and - * possibly already in 10.2. - */ - - currentLayoutId = GetScriptVariable(currentKeyScript,smScriptKeys); - - if ((lastLayout == NULL) || (lastLayoutId != currentLayoutId)) { - KDBG("GetKeyboardLayout(): Use GetResource()"); - - hasLayoutChanged = true; - - /* - * Reinitialize all relevant variables. - */ - - lastLayout = (KeyboardLayoutRef)-1; - lastLayoutId = currentLayoutId; - uchr = NULL; - KCHR = NULL; - - /* - * Get the new layout resource in the classic way. - */ - - if (handle != NULL) { - HUnlock(handle); - } - - if ((handle = GetResource('uchr',currentLayoutId)) != NULL) { - HLock(handle); - uchr = *handle; - } else if ((handle = GetResource('KCHR',currentLayoutId)) != NULL) { - HLock(handle); - KCHR = *handle; - } - } + + /* + * Use the classic approach as shown in Apple code samples, loading + * the keyboard resources directly. This is broken for 10.3 and + * possibly already in 10.2. + */ + + currentLayoutId = GetScriptVariable(currentKeyScript,smScriptKeys); + + if ((lastLayout == NULL) || (lastLayoutId != currentLayoutId)) { + +#ifdef TK_MAC_DEBUG_KEYBOARD + fprintf (stderr, "GetKeyboardLayout(): Use GetResource()\n"); +#endif + + hasLayoutChanged = true; + + /* + * Reinitialize all relevant variables. + */ + + lastLayout = (KeyboardLayoutRef)-1; + lastLayoutId = currentLayoutId; + uchr = NULL; + KCHR = NULL; + + /* + * Get the new layout resource in the classic way. + */ + + if (handle != NULL) { + HUnlock(handle); + } + + if ((handle = GetResource('uchr',currentLayoutId)) != NULL) { + HLock(handle); + uchr = *handle; + } else if ((handle = GetResource('KCHR',currentLayoutId)) != NULL) { + HLock(handle); + KCHR = *handle; + } + } } if (hasLayoutChanged) { + #ifdef TK_MAC_DEBUG_KEYBOARD - if (KCHR != NULL) { - KDBG("GetKeyboardLayout(): New 'KCHR' layout %d", - (int) (short) currentLayoutId); - } else if (uchr != NULL) { - KDBG("GetKeyboardLayout(): New 'uchr' layout %d", - (int) (short) currentLayoutId); - } else { - KDBG("GetKeyboardLayout(): Use cached layout " - "(should have been %d)", (int) (short) currentLayoutId); - } + if (KCHR != NULL) { + fprintf (stderr, "GetKeyboardLayout(): New 'KCHR' layout %d\n", + (int) (short) currentLayoutId); + } else if (uchr != NULL) { + fprintf (stderr, "GetKeyboardLayout(): New 'uchr' layout %d\n", + (int) (short) currentLayoutId); + } else { + fprintf (stderr, "GetKeyboardLayout(): Use cached layout " + "(should have been %d)\n", + (int) (short) currentLayoutId); + } #endif - deadKeyStateUp = deadKeyStateDown = 0; - - /* - * If we did get a new 'KCHR', compute its encoding and put it into - * lastEncoding. - * - * If we didn't get a new 'KCHR' and if we have no 'uchr' either, get - * some 'KCHR' from the OS cache and leave lastEncoding at its - * current value. This should better not happen, it doesn't really - * work. - */ - - if (KCHR != NULL) { - lastEncoding = GetKCHREncoding(currentKeyScript, currentLayoutId); - KDBG("GetKeyboardLayout(): New 'KCHR' encoding %lu (%lu + 0x%lX)", - lastEncoding, lastEncoding & 0xFFFFL, - lastEncoding & ~0xFFFFL); - } else if (uchr == NULL) { - KCHR = (Ptr) GetScriptManagerVariable(smKCHRCache); - } + deadKeyStateUp = deadKeyStateDown = 0; + + /* + * If we did get a new 'KCHR', compute its encoding and put it into + * lastEncoding. + * + * If we didn't get a new 'KCHR' and if we have no 'uchr' either, get + * some 'KCHR' from the OS cache and leave lastEncoding at its + * current value. This should better not happen, it doesn't really + * work. + */ + + if (KCHR != NULL) { + lastEncoding = GetKCHREncoding(currentKeyScript, currentLayoutId); +#ifdef TK_MAC_DEBUG_KEYBOARD + fprintf (stderr, "GetKeyboardLayout(): New 'KCHR' encoding %lu " + "(%lu + 0x%lX)\n", + lastEncoding, lastEncoding & 0xFFFFL, + lastEncoding & ~0xFFFFL); +#endif + } else if (uchr == NULL) { + KCHR = (Ptr) GetScriptManagerVariable(smKCHRCache); + } } if (uchr != NULL) { - *resourcePtr = uchr; - return 1; + *resourcePtr = uchr; + return 1; } else { - *resourcePtr = KCHR; - *encodingPtr = lastEncoding; - return 0; + *resourcePtr = KCHR; + *encodingPtr = lastEncoding; + return 0; } } + /* *---------------------------------------------------------------------- * * GetKCHREncoding -- * - * Upgrade a WorldScript code to a TEC encoding based on the keyboard - * layout id. + * Upgrade a WorldScript code to a TEC encoding based on the keyboard + * layout id. * * Results: - * The TEC code that corresponds best to the combination of WorldScript - * code and 'KCHR' id. + * The TEC code that corresponds best to the combination of WorldScript + * code and 'KCHR' id. * * Side effects: - * None. + * None. * * Rationale and Notes: - * WorldScript codes are sometimes not unique encodings. E.g. Icelandic - * uses script smRoman (0), but the actual encoding is - * kTextEncodingMacIcelandic (37). ftp://ftp.unicode.org/Public - * /MAPPINGS/VENDORS/APPLE/README.TXT has a good summary of these - * variants. So we need to upgrade the script to an encoding with - * GetTextEncodingFromScriptInfo(). + * WorldScript codes are sometimes not unique encodings. E.g. Icelandic + * uses script smRoman (0), but the actual encoding is + * kTextEncodingMacIcelandic (37). ftp://ftp.unicode.org/Public + * /MAPPINGS/VENDORS/APPLE/README.TXT has a good summary of these + * variants. So we need to upgrade the script to an encoding with + * GetTextEncodingFromScriptInfo(). * - * 'KCHR' ids are usually region codes (see the comments in Script.h). - * Where they are not, we get a paramErr from the OS function and have - * appropriate fallbacks. + * 'KCHR' ids are usually region codes (see the comments in Script.h). + * Where they are not, we get a paramErr from the OS function and have + * appropriate fallbacks. * *---------------------------------------------------------------------- */ static TextEncoding -GetKCHREncoding( - ScriptCode script, - SInt32 layoutid) +GetKCHREncoding(ScriptCode script, SInt32 layoutid) { RegionCode region = layoutid; TextEncoding encoding = script; if (GetTextEncodingFromScriptInfo(script, kTextLanguageDontCare, region, - &encoding) == noErr) { - return encoding; + &encoding) == noErr) { + return encoding; } /* - * GetTextEncodingFromScriptInfo() doesn't know about more exotic layouts. - * This provides a fallback for good measure. In an ideal world, exotic - * layouts would always provide a 'uchr' resource anyway, so we wouldn't - * need this. + * GetTextEncodingFromScriptInfo() doesn't know about more exotic + * layouts. This provides a fallback for good measure. In an ideal + * world, exotic layouts would always provide a 'uchr' resource anyway, + * so we wouldn't need this. * - * We can add more keyboard layouts, if we get actual complaints. Farsi or - * other Celtic/Gaelic layouts would be candidates. + * We can add more keyboard layouts, if we get actual complaints. Farsi + * or other Celtic/Gaelic layouts would be candidates. */ switch (layoutid) { - /* - * Icelandic and Faroese (planned). These layouts are sold by Apple - * Iceland for legacy applications. - */ - - case 1800: case 1821: - return kTextEncodingMacIcelandic; - - /* - * Irish and Welsh. These layouts are mentioned in <Script.h>. - * - * FIXME: This may have to be kTextEncodingMacGaelic instead, but I - * can't locate layouts of this type for testing. - */ - - case 581: case 779: - return kTextEncodingMacCeltic; - } + /* + * Icelandic and Faroese (planned). These layouts are sold by Apple + * Iceland for legacy applications. + */ + + case 1800: case 1821: + return kTextEncodingMacIcelandic; + + /* + * Irish and Welsh. These layouts are mentioned in <Script.h>. + * + * FIXME: This may have to be kTextEncodingMacGaelic instead, but I + * can't locate layouts of this type for testing. + */ + + case 581: case 779: + return kTextEncodingMacCeltic; + } + /* - * The valid script codes are also the valid default encoding codes, so if - * nothing else helps, fall back on those. + * The valid script codes are also the valid default encoding codes, so + * if nothing else helps, fall back on those. */ return script; } + /* *---------------------------------------------------------------------- * * KeycodeToUnicodeViaUnicodeResource -- * - * Given MacOS key event data this function generates the Unicode - * characters. It does this using a 'uchr' and the UCKeyTranslate API. + * Given MacOS key event data this function generates the Unicode + * characters. It does this using a 'uchr' and the UCKeyTranslate + * API. * - * The parameter deadKeyStatePtr can be NULL, if no deadkey handling is - * needed. + * The parameter deadKeyStatePtr can be NULL, if no deadkey handling + * is needed. * - * Tested and known to work with US, Hebrew, Greek and Russian layouts as - * well as "Unicode Hex Input". + * Tested and known to work with US, Hebrew, Greek and Russian layouts + * as well as "Unicode Hex Input". * * Results: - * The number of characters generated if any, 0 if we are waiting for - * another byte of a dead-key sequence. Fills in the uniChars array with - * a Unicode string. + * The number of characters generated if any, 0 if we are waiting for + * another byte of a dead-key sequence. Fills in the uniChars array + * with a Unicode string. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ static int KeycodeToUnicodeViaUnicodeResource( - UniChar *uniChars, - int maxChars, - Ptr uchr, - EventKind eKind, - UInt32 keycode, - UInt32 modifiers, - UInt32 *deadKeyStatePtr) + UniChar * uniChars, int maxChars, + Ptr uchr, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr) { int action; unsigned long keyboardType; OptionBits options = 0; UInt32 dummy_state; - UniCharCount actuallength; + UniCharCount actuallength; OSStatus status; keycode &= 0xFF; @@ -844,242 +902,260 @@ KeycodeToUnicodeViaUnicodeResource( keyboardType = LMGetKbdType(); if (NULL==deadKeyStatePtr) { - options = kUCKeyTranslateNoDeadKeysMask; - dummy_state = 0; - deadKeyStatePtr = &dummy_state; + options = kUCKeyTranslateNoDeadKeysMask; + dummy_state = 0; + deadKeyStatePtr = &dummy_state; } - switch(eKind) { - case kEventRawKeyDown: - action = kUCKeyActionDown; - break; - case kEventRawKeyUp: - action = kUCKeyActionUp; - break; - case kEventRawKeyRepeat: - action = kUCKeyActionAutoKey; - break; - default: - LOG_MSG("KeycodeToUnicodeViaUnicodeResource(): " - "Invalid parameter eKind %d", (int) eKind); - return 0; + switch(eKind) { + case kEventRawKeyDown: + action = kUCKeyActionDown; + break; + case kEventRawKeyUp: + action = kUCKeyActionUp; + break; + case kEventRawKeyRepeat: + action = kUCKeyActionAutoKey; + break; + default: +#ifdef TK_MAC_DEBUG + fprintf (stderr, + "KeycodeToUnicodeViaUnicodeResource(): " + "Invalid parameter eKind %d\n", + (int) eKind); +#endif + return 0; } - status = UCKeyTranslate((const UCKeyboardLayout *) uchr, keycode, action, - modifiers, keyboardType, options, deadKeyStatePtr, maxChars, - &actuallength, uniChars); + status = UCKeyTranslate( + (const UCKeyboardLayout *) uchr, + keycode, action, modifiers, keyboardType, + options, deadKeyStatePtr, + maxChars, &actuallength, uniChars); if ((0 == actuallength) && (0 != *deadKeyStatePtr)) { - /* - * More data later - */ - - return 0; + /* + * More data later + */ + + return 0; } - + /* * some IMEs leave residue :-( */ - - *deadKeyStatePtr = 0; + + *deadKeyStatePtr = 0; if (noErr != status) { - LOG_MSG("UCKeyTranslate failed: %d", (int) status); - actuallength = 0; +#ifdef TK_MAC_DEBUG + fprintf(stderr,"UCKeyTranslate failed: %d", (int) status); +#endif + actuallength = 0; } return actuallength; } + /* *---------------------------------------------------------------------- * * KeycodeToUnicodeViaKCHRResource -- * - * Given MacOS key event data this function generates the Unicode - * characters. It does this using a 'KCHR' and the KeyTranslate API. + * Given MacOS key event data this function generates the Unicode + * characters. It does this using a 'KCHR' and the KeyTranslate API. * - * The parameter deadKeyStatePtr can be NULL, if no deadkey handling is - * needed. + * The parameter deadKeyStatePtr can be NULL, if no deadkey handling + * is needed. * * Results: - * The number of characters generated if any, 0 if we are waiting for - * another byte of a dead-key sequence. Fills in the uniChars array with - * a Unicode string. + * The number of characters generated if any, 0 if we are waiting for + * another byte of a dead-key sequence. Fills in the uniChars array + * with a Unicode string. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ static int KeycodeToUnicodeViaKCHRResource( - UniChar *uniChars, - int maxChars, - Ptr kchr, - TextEncoding encoding, - EventKind eKind, - UInt32 keycode, - UInt32 modifiers, - UInt32 *deadKeyStatePtr) + UniChar * uniChars, int maxChars, + Ptr kchr, TextEncoding encoding, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr) { UInt32 result; char macBuff[3]; - char *macStr; + char * macStr; int macStrLen; UInt32 dummy_state = 0; + if (NULL == deadKeyStatePtr) { - deadKeyStatePtr = &dummy_state; + deadKeyStatePtr = &dummy_state; } keycode |= modifiers; result = KeyTranslate(kchr, keycode, deadKeyStatePtr); if ((0 == result) && (0 != dummy_state)) { - /* - * 'dummy_state' gets only filled if the caller did not want deadkey - * processing (deadKeyStatePtr was NULL originally), but we still - * have a deadkey. We just push the keycode for the space bar to get - * the real key value. - */ - - result = KeyTranslate(kchr, 0x31, deadKeyStatePtr); - *deadKeyStatePtr = 0; + /* + * 'dummy_state' gets only filled if the caller did not want deadkey + * processing (deadKeyStatePtr was NULL originally), but we still + * have a deadkey. We just push the keycode for the space bar to get + * the real key value. + */ + + result = KeyTranslate(kchr, 0x31, deadKeyStatePtr); + *deadKeyStatePtr = 0; } if ((0 == result) && (0 != *deadKeyStatePtr)) { - /* - * More data later - */ - - return 0; + /* + * More data later + */ + + return 0; } macBuff[0] = (char) (result >> 16); - macBuff[1] = (char) result; + macBuff[1] = (char) result; macBuff[2] = 0; if (0 != macBuff[0]) { - /* - * If the first byte is valid, the second is too - */ - - macStr = macBuff; - macStrLen = 2; + /* + * If the first byte is valid, the second is too + */ + + macStr = macBuff; + macStrLen = 2; } else if (0 != macBuff[1]) { - /* - * Only the second is valid - */ - - macStr = macBuff+1; - macStrLen = 1; + /* + * Only the second is valid + */ + + macStr = macBuff+1; + macStrLen = 1; } else { - /* - * No valid bytes at all -- shouldn't happen - */ - - macStr = NULL; - macStrLen = 0; + /* + * No valid bytes at all -- shouldn't happen + */ + + macStr = NULL; + macStrLen = 0; } if (macStrLen <= 0) { - return 0; + return 0; } else { - /* - * Use the CFString conversion routines. This is the easiest and most - * compatible way to get from an 8-bit string and a MacOS script code - * to a Unicode string. - * - * FIXME: The system ships with an Irish 'KCHR' but without the - * corresponding macCeltic encoding, which triggers the error below. - * Tcl doesn't have the macCeltic encoding either right now, so until - * we get that, we can just as well stick to this code. The right fix - * would be to use the Tcl encodings and add macCeltic and probably - * others there. Suitable Unicode data files for the missing encodings - * are available from www.evertype.com. - */ - - CFStringRef cfString; - int uniStrLen; - - cfString = CFStringCreateWithCStringNoCopy(NULL, macStr, encoding, - kCFAllocatorNull); - if (cfString == NULL) { - LOG_MSG("CFString: Can't convert with encoding %d", - (int) encoding); - return 0; - } - uniStrLen = CFStringGetLength(cfString); - if (uniStrLen > maxChars) { - uniStrLen = maxChars; - } - CFStringGetCharacters(cfString, CFRangeMake(0,uniStrLen), uniChars); - CFRelease(cfString); + /* + * Use the CFString conversion routines. This is the easiest and + * most compatible way to get from an 8-bit string and a MacOS script + * code to a Unicode string. + * + * FIXME: The system ships with an Irish 'KCHR' but without the + * corresponding macCeltic encoding, which triggers the error below. + * Tcl doesn't have the macCeltic encoding either right now, so until + * we get that, we can just as well stick to this code. The right + * fix would be to use the Tcl encodings and add macCeltic and + * probably others there. Suitable Unicode data files for the + * missing encodings are available from www.evertype.com. + */ + + CFStringRef cfString; + int uniStrLen; + + cfString = CFStringCreateWithCStringNoCopy( + NULL, macStr, encoding, kCFAllocatorNull); + if (cfString == NULL) { +#ifdef TK_MAC_DEBUG + fprintf(stderr, "CFString: Can't convert with encoding %d\n", + (int) encoding); +#endif + return 0; + } + + uniStrLen = CFStringGetLength(cfString); + if (uniStrLen > maxChars) { + uniStrLen = maxChars; + } + CFStringGetCharacters(cfString, CFRangeMake(0,uniStrLen), uniChars); + CFRelease(cfString); - return uniStrLen; + return uniStrLen; } } + /* *---------------------------------------------------------------------- * * TkMacOSXKeycodeToUnicode -- * - * Given MacOS key event data this function generates the Unicode - * characters. It does this using OS resources and APIs. + * Given MacOS key event data this function generates the Unicode + * characters. It does this using OS resources and APIs. * - * The parameter deadKeyStatePtr can be NULL, if no deadkey handling is - * needed. + * The parameter deadKeyStatePtr can be NULL, if no deadkey handling + * is needed. * - * This function is called from XKeycodeToKeysym() in tkMacOSKeyboard.c. + * This function is called from XKeycodeToKeysym() in + * tkMacOSKeyboard.c. * * Results: - * The number of characters generated if any, 0 if we are waiting for - * another byte of a dead-key sequence. Fills in the uniChars array with - * a Unicode string. + * The number of characters generated if any, 0 if we are waiting for + * another byte of a dead-key sequence. Fills in the uniChars array + * with a Unicode string. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ MODULE_SCOPE int TkMacOSXKeycodeToUnicode( - UniChar *uniChars, - int maxChars, - EventKind eKind, - UInt32 keycode, - UInt32 modifiers, - UInt32 *deadKeyStatePtr) + UniChar * uniChars, int maxChars, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr) { Ptr resource = NULL; TextEncoding encoding; + int len; + - if (GetKeyboardLayout(&resource, &encoding)) { - return KeycodeToUnicodeViaUnicodeResource(uniChars, maxChars, - resource, eKind, keycode, modifiers, deadKeyStatePtr); + if (GetKeyboardLayout(&resource,&encoding)) { + len = KeycodeToUnicodeViaUnicodeResource( + uniChars, maxChars, resource, eKind, + keycode, modifiers, deadKeyStatePtr); } else { - return KeycodeToUnicodeViaKCHRResource(uniChars, maxChars, resource, - encoding, eKind, keycode, modifiers, deadKeyStatePtr); + len = KeycodeToUnicodeViaKCHRResource( + uniChars, maxChars, resource, encoding, eKind, + keycode, modifiers, deadKeyStatePtr); } + + return len; } + + /* *---------------------------------------------------------------------- * * XGrabKeyboard -- * - * Simulates a keyboard grab by setting the focus. + * Simulates a keyboard grab by setting the focus. * * Results: - * Always returns GrabSuccess. + * Always returns GrabSuccess. * * Side effects: - * Sets the keyboard focus to the specified window. + * Sets the keyboard focus to the specified window. * *---------------------------------------------------------------------- */ @@ -1102,13 +1178,13 @@ XGrabKeyboard( * * XUngrabKeyboard -- * - * Releases the simulated keyboard grab. + * Releases the simulated keyboard grab. * * Results: - * None. + * None. * * Side effects: - * Sets the keyboard focus back to the value before the grab. + * Sets the keyboard focus back to the value before the grab. * *---------------------------------------------------------------------- */ @@ -1127,14 +1203,13 @@ XUngrabKeyboard( * TkMacOSXGetCapture -- * * Results: - * Returns the current grab window + * Returns the current grab window * Side effects: - * None. + * None. * */ - Tk_Window -TkMacOSXGetCapture(void) +TkMacOSXGetCapture() { return gGrabWinPtr; } @@ -1144,25 +1219,26 @@ TkMacOSXGetCapture(void) * * 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. + * 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. + * None. * * Side effects: - * Sets the capture flag and captures the mouse. + * Sets the capture flag and captures the mouse. * *---------------------------------------------------------------------- */ void TkpSetCapture( - TkWindow *winPtr) /* Capture window, or NULL. */ + TkWindow *winPtr) /* Capture window, or NULL. */ { while ((winPtr != NULL) && !Tk_IsTopLevel(winPtr)) { - winPtr = winPtr->parentPtr; + winPtr = winPtr->parentPtr; } gGrabWinPtr = (Tk_Window) winPtr; } @@ -1172,25 +1248,25 @@ TkpSetCapture( * * 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 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 + * None * * Side effects: - * None + * None * *---------------------------------------------------------------------- */ void -Tk_SetCaretPos( - Tk_Window tkwin, - int x, - int y, - int height) +Tk_SetCaretPos(tkwin, x, y, height) + Tk_Window tkwin; + int x; + int y; + int height; { } @@ -1199,31 +1275,23 @@ Tk_SetCaretPos( * * TkMacOSXInitKeyboard -- * - * This procedure initializes the keyboard layout. + * This procedure initializes the keyboard layout. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE void -TkMacOSXInitKeyboard( - Tcl_Interp *interp) +TkMacOSXInitKeyboard ( + Tcl_Interp *interp) { Ptr resource; TextEncoding encoding; - - GetKeyboardLayout(&resource, &encoding); + + GetKeyboardLayout(&resource,&encoding); } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |