tkMacOSXKeyboard.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:20k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * tkMacOSXKeyboard.c --
  3.  *
  4.  * Routines to support keyboard events on the Macintosh.
  5.  *
  6.  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  7.  * Copyright 2001, Apple Computer, Inc.
  8.  * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net>
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  *
  13.  * RCS: @(#) $Id: tkMacOSXKeyboard.c,v 1.5.2.8 2007/06/04 09:28:45 das Exp $
  14.  */
  15. #include "tkMacOSXInt.h"
  16. #include "tkMacOSXEvent.h" /* for TkMacOSXKeycodeToUnicode()
  17.  * FIXME: That function should probably move
  18.  * here. */
  19. /*
  20.  * A couple of simple definitions to make code a bit more self-explaining.
  21.  *
  22.  * For the assignments of Mod1==meta==command and Mod2==alt==option, see also
  23.  * tkMacOSXMouseEvent.c.
  24.  */
  25. #define LATIN1_MAX  255
  26. #define MAC_KEYCODE_MAX  0x7F
  27. #define MAC_KEYCODE_MASK 0x7F
  28. #define COMMAND_MASK  Mod1Mask
  29. #define OPTION_MASK  Mod2Mask
  30. /*
  31.  * Tables enumerating the special keys defined on Mac keyboards. These are
  32.  * necessary for correct keysym mappings for all keys where the keysyms are
  33.  * not identical with their ASCII or Latin-1 code points.
  34.  */
  35. typedef struct {
  36.     int keycode; /* Macintosh keycode. */
  37.     KeySym keysym; /* X windows keysym. */
  38. } KeyInfo;
  39. /*
  40.  * Notes on keyArray:
  41.  *
  42.  * 0x34, XK_Return - Powerbooks use this and some keymaps define it.
  43.  *
  44.  * 0x4C, XK_Return - XFree86 and Apple's X11 call this one XK_KP_Enter.
  45.  *
  46.  * 0x47, XK_Clear - This key is NumLock when used on PCs, but Mac
  47.  * applications don't use it like that, nor does Apple's X11.
  48.  *
  49.  * All other keycodes are taken from the published ADB keyboard layouts.
  50.  */
  51. static KeyInfo keyArray[] = {
  52.     {0x24, XK_Return},
  53.     {0x30, XK_Tab},
  54.     {0x33, XK_BackSpace},
  55.     {0x34, XK_Return},
  56.     {0x35, XK_Escape},
  57.     {0x47, XK_Clear},
  58.     {0x4C, XK_KP_Enter},
  59.     {0x72, XK_Help},
  60.     {0x73, XK_Home},
  61.     {0x74, XK_Page_Up},
  62.     {0x75, XK_Delete},
  63.     {0x77, XK_End},
  64.     {0x79, XK_Page_Down},
  65.     {0x7B, XK_Left},
  66.     {0x7C, XK_Right},
  67.     {0x7D, XK_Down},
  68.     {0x7E, XK_Up},
  69.     {0, 0}
  70. };
  71. static KeyInfo virtualkeyArray[] = {
  72.     {122, XK_F1},
  73.     {120, XK_F2},
  74.     {99, XK_F3},
  75.     {118, XK_F4},
  76.     {96, XK_F5},
  77.     {97, XK_F6},
  78.     {98, XK_F7},
  79.     {100, XK_F8},
  80.     {101, XK_F9},
  81.     {109, XK_F10},
  82.     {103, XK_F11},
  83.     {111, XK_F12},
  84.     {105, XK_F13},
  85.     {107, XK_F14},
  86.     {113, XK_F15},
  87.     {0, 0}
  88. };
  89. static int initialized = 0;
  90. static Tcl_HashTable keycodeTable; /* keyArray hashed by keycode value. */
  91. static Tcl_HashTable vkeyTable; /* virtualkeyArray hashed by virtual
  92.  * keycode value. */
  93. static int latin1Table[LATIN1_MAX+1]; /* Reverse mapping table for
  94.  * controls, ASCII and Latin-1. */
  95. /*
  96.  * Prototypes for static functions used in this file.
  97.  */
  98. static void InitKeyMaps (void);
  99. static void InitLatin1Table(Display *display);
  100. static int XKeysymToMacKeycode(Display *display, KeySym keysym);
  101. /*
  102.  *----------------------------------------------------------------------
  103.  *
  104.  * InitKeyMaps --
  105.  *
  106.  * Creates hash tables used by some of the functions in this file.
  107.  *
  108.  * FIXME: As keycodes are defined to be in the limited range 0-127, it
  109.  * would be easier and more efficient to use directly initialized plain
  110.  * arrays and drop this function.
  111.  *
  112.  * Results:
  113.  * None.
  114.  *
  115.  * Side effects:
  116.  * Allocates memory & creates some hash tables.
  117.  *
  118.  *----------------------------------------------------------------------
  119.  */
  120. static void
  121. InitKeyMaps(void)
  122. {
  123.     Tcl_HashEntry *hPtr;
  124.     KeyInfo *kPtr;
  125.     int dummy;
  126.     Tcl_InitHashTable(&keycodeTable, TCL_ONE_WORD_KEYS);
  127.     for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) {
  128. hPtr = Tcl_CreateHashEntry(&keycodeTable, (char *) kPtr->keycode,
  129. &dummy);
  130. Tcl_SetHashValue(hPtr, kPtr->keysym);
  131.     }
  132.     Tcl_InitHashTable(&vkeyTable, TCL_ONE_WORD_KEYS);
  133.     for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) {
  134. hPtr = Tcl_CreateHashEntry(&vkeyTable, (char *) kPtr->keycode,
  135. &dummy);
  136. Tcl_SetHashValue(hPtr, kPtr->keysym);
  137.     }
  138.     initialized = 1;
  139. }
  140. /*
  141.  *----------------------------------------------------------------------
  142.  *
  143.  * InitLatin1Table --
  144.  *
  145.  * Creates a simple table to be used for mapping from keysyms to
  146.  * keycodes. Always needs to be called before using latin1Table,
  147.  * because the keyboard layout may have changed, and than the table must
  148.  * be re-computed.
  149.  *
  150.  * Results:
  151.  * None.
  152.  *
  153.  * Side effects:
  154.  * Sets the global latin1Table.
  155.  *
  156.  *----------------------------------------------------------------------
  157.  */
  158. static void
  159. InitLatin1Table(
  160.     Display *display)
  161. {
  162.     static Boolean latin1_initialized = false;
  163.     static SInt16 lastKeyLayoutID = -1;
  164.     SInt16 keyScript;
  165.     SInt16 keyLayoutID;
  166.     keyScript = GetScriptManagerVariable(smKeyScript);
  167.     keyLayoutID = GetScriptVariable(keyScript,smScriptKeys);
  168.     if (!latin1_initialized || (lastKeyLayoutID != keyLayoutID)) {
  169. int keycode;
  170. KeySym keysym;
  171. int state;
  172. int modifiers;
  173. latin1_initialized = true;
  174. lastKeyLayoutID = keyLayoutID;
  175. memset(latin1Table, 0, sizeof(latin1Table));
  176. /*
  177.  * In the common X11 implementations, a keymap has four columns
  178.  * "plain", "Shift", "Mode_switch" and "Mode_switch + Shift". We
  179.  * don't use "Mode_switch", but we use "Option" instead. (This is
  180.  * similar to Apple's X11 implementation, where "Mode_switch" is used
  181.  * as an alias for "Option".)
  182.  *
  183.  * So here we go through all 4 columns of the keymap and find all
  184.  * Latin-1 compatible keycodes. We go through the columns
  185.  * back-to-front from the more exotic columns to the more simple, so
  186.  * that simple keycode-modifier combinations are preferred in the
  187.  * resulting table.
  188.  */
  189. for (state = 3; state >= 0; state--) {
  190.     modifiers = 0;
  191.     if (state & 1) {
  192. modifiers |= shiftKey;
  193.     }
  194.     if (state & 2) {
  195. modifiers |= optionKey;
  196.     }
  197.     for (keycode = 0; keycode <= MAC_KEYCODE_MAX; keycode++) {
  198. keysym = XKeycodeToKeysym(display,keycode<<16,state);
  199. if (keysym <= LATIN1_MAX) {
  200.     latin1Table[keysym] = keycode | modifiers;
  201. }
  202.     }
  203. }
  204.     }
  205. }
  206. /*
  207.  *----------------------------------------------------------------------
  208.  *
  209.  * XKeycodeToKeysym --
  210.  *
  211.  * Translate from a system-dependent keycode to a system-independent
  212.  * keysym.
  213.  *
  214.  * Results:
  215.  * Returns the translated keysym, or NoSymbol on failure.
  216.  *
  217.  * Side effects:
  218.  * None.
  219.  *
  220.  *----------------------------------------------------------------------
  221.  */
  222. KeySym
  223. XKeycodeToKeysym(
  224.     Display* display,
  225.     KeyCode keycode,
  226.     int index)
  227. {
  228.     register Tcl_HashEntry *hPtr;
  229.     int newKeycode;
  230.     UniChar newChar;
  231.     (void) display; /*unused*/
  232.     if (!initialized) {
  233. InitKeyMaps();
  234.     }
  235.     /*
  236.      * When determining what keysym to produce we first check to see if the
  237.      * key is a function key. We then check to see if the character is
  238.      * another non-printing key. Finally, we return the key syms for all
  239.      * ASCII and Latin-1 chars.
  240.      */
  241.     newKeycode = keycode >> 16;
  242.     if ((keycode & 0xFFFF) == 0x10) {
  243. hPtr = Tcl_FindHashEntry(&vkeyTable, (char *) newKeycode);
  244. if (hPtr != NULL) {
  245.     return (KeySym) Tcl_GetHashValue(hPtr);
  246. }
  247.     }
  248.     hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) newKeycode);
  249.     if (hPtr != NULL) {
  250. return (KeySym) Tcl_GetHashValue(hPtr);
  251.     }
  252.     /*
  253.      * Add in the Mac modifier flags for shift and option.
  254.      */
  255.     if (index & 1) {
  256. newKeycode |= shiftKey;
  257.     }
  258.     if (index & 2) {
  259. newKeycode |= optionKey;
  260.     }
  261.     newChar = 0;
  262.     TkMacOSXKeycodeToUnicode(
  263. &newChar, 1, kEventRawKeyDown,
  264. newKeycode & 0x00FF, newKeycode & 0xFF00, NULL);
  265.     /*
  266.      * X11 keysyms are identical to Unicode for ASCII and Latin-1. Give up
  267.      * for other characters for now.
  268.      */
  269.     if ((newChar >= XK_space) && (newChar <= LATIN1_MAX)) {
  270. return newChar;
  271.     }
  272.     return NoSymbol;
  273. }
  274. /*
  275.  *----------------------------------------------------------------------
  276.  *
  277.  * TkpGetString --
  278.  *
  279.  * Retrieve the string equivalent for the given keyboard event.
  280.  *
  281.  * Results:
  282.  * Returns the UTF string.
  283.  *
  284.  * Side effects:
  285.  * None.
  286.  *
  287.  *----------------------------------------------------------------------
  288.  */
  289. char *
  290. TkpGetString(
  291.     TkWindow *winPtr, /* Window where event occurred: Needed to get
  292.  * input context. */
  293.     XEvent *eventPtr, /* X keyboard event. */
  294.     Tcl_DString *dsPtr) /* Uninitialized or empty string to hold
  295.  * result. */
  296. {
  297.     (void) winPtr; /*unused*/
  298.     Tcl_DStringInit(dsPtr);
  299.     return Tcl_DStringAppend(dsPtr, eventPtr->xkey.trans_chars, -1);
  300. }
  301. /*
  302.  *----------------------------------------------------------------------
  303.  *
  304.  * XGetModifierMapping --
  305.  *
  306.  * Fetch the current keycodes used as modifiers.
  307.  *
  308.  * Results:
  309.  * Returns a new modifier map.
  310.  *
  311.  * Side effects:
  312.  * Allocates a new modifier map data structure.
  313.  *
  314.  *----------------------------------------------------------------------
  315.  */
  316. XModifierKeymap *
  317. XGetModifierMapping(
  318.     Display* display)
  319. {
  320.     XModifierKeymap * modmap;
  321.     (void) display; /*unused*/
  322.     /*
  323.      * MacOSX doesn't use the key codes for the modifiers for anything, and
  324.      * we don't generate them either. So there is no modifier map.
  325.      */
  326.     modmap = (XModifierKeymap *) ckalloc(sizeof(XModifierKeymap));
  327.     modmap->max_keypermod = 0;
  328.     modmap->modifiermap = NULL;
  329.     return modmap;
  330. }
  331. /*
  332.  *----------------------------------------------------------------------
  333.  *
  334.  * XFreeModifiermap --
  335.  *
  336.  * Deallocate a modifier map that was created by XGetModifierMapping.
  337.  *
  338.  * Results:
  339.  * None.
  340.  *
  341.  * Side effects:
  342.  * Frees the datastructure referenced by modmap.
  343.  *
  344.  *----------------------------------------------------------------------
  345.  */
  346. void
  347. XFreeModifiermap(
  348.     XModifierKeymap *modmap)
  349. {
  350.     if (modmap->modifiermap != NULL) {
  351. ckfree((char *) modmap->modifiermap);
  352.     }
  353.     ckfree((char *) modmap);
  354. }
  355. /*
  356.  *----------------------------------------------------------------------
  357.  *
  358.  * XKeysymToString, XStringToKeysym --
  359.  *
  360.  * These X window functions map keysyms to strings & strings to keysyms.
  361.  * However, Tk already does this for the most common keysyms.
  362.  * Therefore, these functions only need to support keysyms that will be
  363.  * specific to the Macintosh. Currently, there are none.
  364.  *
  365.  * Results:
  366.  * None.
  367.  *
  368.  * Side effects:
  369.  * None.
  370.  *
  371.  *----------------------------------------------------------------------
  372.  */
  373. char *
  374. XKeysymToString(
  375.     KeySym keysym)
  376. {
  377.     return NULL;
  378. }
  379. KeySym
  380. XStringToKeysym(
  381.     const char* string)
  382. {
  383.     return NoSymbol;
  384. }
  385. /*
  386.  *----------------------------------------------------------------------
  387.  *
  388.  * XKeysymToMacKeycode --
  389.  *
  390.  * An internal function like XKeysymToKeycode but only generating the
  391.  * Mac specific keycode plus the modifiers Shift and Option.
  392.  *
  393.  * Results:
  394.  * A Mac keycode with the actual keycode in the low byte and Mac-style
  395.  * modifier bits in the high byte.
  396.  *
  397.  * Side effects:
  398.  * None.
  399.  *
  400.  *----------------------------------------------------------------------
  401.  */
  402. static int
  403. XKeysymToMacKeycode(
  404.     Display *display,
  405.     KeySym keysym)
  406. {
  407.     if (keysym <= LATIN1_MAX) {
  408. /*
  409.  * Handle keysyms in the Latin-1 range where keysym and Unicode
  410.  * character code point are the same.
  411.  */
  412. InitLatin1Table(display);
  413. return latin1Table[keysym];
  414.     } else {
  415. /*
  416.  * Handle special keys from our exception tables. Don't mind if this
  417.  * is slow, neither the test suite nor [event generate] need to be
  418.  * optimized (we hope).
  419.  */
  420. KeyInfo *kPtr;
  421. for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) {
  422.     if (kPtr->keysym == keysym) {
  423. return kPtr->keycode;
  424.     }
  425. }
  426. for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) {
  427.     if (kPtr->keysym == keysym) {
  428. return kPtr->keycode;
  429.     }
  430. }
  431. /*
  432.  * For other keysyms (not Latin-1 and not special keys), we'd need a
  433.  * generic keysym-to-unicode table. We don't have that, so we give
  434.  * up here.
  435.  */
  436. return 0;
  437.     }
  438. }
  439. /*
  440.  *----------------------------------------------------------------------
  441.  *
  442.  * XKeysymToKeycode --
  443.  *
  444.  * The function XKeysymToKeycode takes an X11 keysym and converts it
  445.  * into a Mac keycode. It is in the stubs table for compatibility but
  446.  * not used anywhere in the core.
  447.  *
  448.  * Results:
  449.  * A 32 bit keycode with the the mac keycode (without modifiers) in the
  450.  * higher 16 bits of the keycode and the ASCII or Latin-1 code in the
  451.  * lower 8 bits of the keycode.
  452.  *
  453.  * Side effects:
  454.  * None.
  455.  *
  456.  *----------------------------------------------------------------------
  457.  */
  458. KeyCode
  459. XKeysymToKeycode(
  460.     Display* display,
  461.     KeySym keysym)
  462. {
  463.     int macKeycode = XKeysymToMacKeycode(display, keysym);
  464.     KeyCode result;
  465.     /*
  466.      * See also TkpSetKeycodeAndState. The 0x0010 magic is used in
  467.      * XKeycodeToKeysym. For special keys like XK_Return the lower 8 bits of
  468.      * the keysym are usually a related ASCII control code.
  469.      */
  470.     if ((keysym >= XK_F1) && (keysym <= XK_F35)) {
  471. result = 0x0010;
  472.     } else {
  473. result = 0x00FF & keysym;
  474.     }
  475.     result |= (macKeycode & MAC_KEYCODE_MASK) << 16;
  476.     return result;
  477. }
  478. /*
  479. NB: Keep this commented code for a moment for reference.
  480.     if ((keysym >= XK_space) && (XK_asciitilde)) {
  481. if (keysym == 'a') {
  482.     virtualKeyCode = 0x00;
  483. } else if (keysym == 'b' || keysym == 'B') {
  484.     virtualKeyCode = 0x0B;
  485. } else if (keysym == 'c') {
  486.     virtualKeyCode = 0x08;
  487. } else if (keysym == 'x' || keysym == 'X') {
  488.     virtualKeyCode = 0x07;
  489. } else if (keysym == 'z') {
  490.     virtualKeyCode = 0x06;
  491. } else if (keysym == ' ') {
  492.     virtualKeyCode = 0x31;
  493. } else if (keysym == XK_Return) {
  494.     virtualKeyCode = 0x24;
  495.     keysym = 'r';
  496. }
  497. keycode = keysym + (virtualKeyCode <<16);
  498.     }
  499.     return keycode;
  500. */
  501. /*
  502.  *----------------------------------------------------------------------
  503.  *
  504.  * TkpSetKeycodeAndState --
  505.  *
  506.  * The function TkpSetKeycodeAndState takes a keysym and fills in the
  507.  * appropriate members of an XEvent. It is similar to XKeysymToKeycode,
  508.  * but it also sets the modifier mask in the XEvent. It is used by
  509.  * [event generate] and it is in the stubs table.
  510.  *
  511.  * Results:
  512.  * Fills an XEvent, sets the member xkey.keycode with a keycode
  513.  * formatted the same as XKeysymToKeycode and the member xkey.state with
  514.  * the modifiers implied by the keysym. Also fills in xkey.trans_chars,
  515.  * so that the actual characters can be retrieved later.
  516.  *
  517.  * Side effects:
  518.  * None.
  519.  *
  520.  *----------------------------------------------------------------------
  521.  */
  522. void
  523. TkpSetKeycodeAndState(
  524.     Tk_Window tkwin,
  525.     KeySym keysym,
  526.     XEvent *eventPtr)
  527. {
  528.     if (keysym == NoSymbol) {
  529. eventPtr->xkey.keycode = 0;
  530.     } else {
  531. Display *display = Tk_Display(tkwin);
  532. int macKeycode = XKeysymToMacKeycode(display, keysym);
  533. /*
  534.  * See also XKeysymToKeycode.
  535.  */
  536. if ((keysym >= XK_F1) && (keysym <= XK_F35)) {
  537.     eventPtr->xkey.keycode = 0x0010;
  538. } else {
  539.     eventPtr->xkey.keycode = 0x00FF & keysym;
  540. }
  541. eventPtr->xkey.keycode |= (macKeycode & MAC_KEYCODE_MASK) << 16;
  542. if (shiftKey & macKeycode) {
  543.     eventPtr->xkey.state |= ShiftMask;
  544. }
  545. if (optionKey & macKeycode) {
  546.     eventPtr->xkey.state |= OPTION_MASK;
  547. }
  548. if (keysym <= LATIN1_MAX) {
  549.     int done;
  550.     done = Tcl_UniCharToUtf(keysym,eventPtr->xkey.trans_chars);
  551.     eventPtr->xkey.trans_chars[done] = 0;
  552. } else {
  553.     eventPtr->xkey.trans_chars[0] = 0;
  554. }
  555.     }
  556. }
  557. /*
  558.  *----------------------------------------------------------------------
  559.  *
  560.  * TkpGetKeySym --
  561.  *
  562.  * Given an X KeyPress or KeyRelease event, map the keycode in the event
  563.  * into a keysym.
  564.  *
  565.  * Results:
  566.  * The return value is the keysym corresponding to eventPtr, or NoSymbol
  567.  * if no matching keysym could be found.
  568.  *
  569.  * Side effects:
  570.  * In the first call for a given display, keycode-to-keysym maps get
  571.  * loaded.
  572.  *
  573.  *----------------------------------------------------------------------
  574.  */
  575. KeySym
  576. TkpGetKeySym(
  577.     TkDisplay *dispPtr, /* Display in which to map keycode. */
  578.     XEvent *eventPtr) /* Description of X event. */
  579. {
  580.     KeySym sym;
  581.     int index;
  582.     /*
  583.      * Refresh the mapping information if it's stale.
  584.      */
  585.     if (dispPtr->bindInfoStale) {
  586. TkpInitKeymapInfo(dispPtr);
  587.     }
  588.     /*
  589.      * Handle pure modifier keys specially. We use -1 as a signal for
  590.      * this.
  591.      */
  592.     if (eventPtr->xany.send_event == -1) {
  593. int modifier = eventPtr->xkey.keycode;
  594. if (modifier == cmdKey) {
  595.     return XK_Meta_L;
  596. } else if (modifier == shiftKey) {
  597.     return XK_Shift_L;
  598. } else if (modifier == alphaLock) {
  599.     return XK_Caps_Lock;
  600. } else if (modifier == optionKey) {
  601.     return XK_Alt_L;
  602. } else if (modifier == controlKey) {
  603.     return XK_Control_L;
  604. } else if (modifier == kEventKeyModifierNumLockMask) {
  605.     return XK_Num_Lock;
  606. } else if (modifier == kEventKeyModifierFnMask) {
  607.     return XK_Super_L;
  608. } else if (modifier == rightShiftKey) {
  609.     return XK_Shift_R;
  610. } else if (modifier == rightOptionKey) {
  611.     return XK_Alt_R;
  612. } else if (modifier == rightControlKey) {
  613.     return XK_Control_R;
  614. } else {
  615.     /*
  616.      * If we get here, we probably need to implement something new.
  617.      */
  618.     return NoSymbol;
  619. }
  620.     }
  621.     /*
  622.      * Figure out which of the four slots in the keymap vector to use for
  623.      * this key. Refer to Xlib documentation for more info on how this
  624.      * computation works. (Note: We use "Option" in keymap columns 2 and 3
  625.      * where other implementations have "Mode_switch".)
  626.      */
  627.     index = 0;
  628.     /*
  629.      * We want Option key combinations to use their base chars as keysyms, so
  630.      * we ignore the option modifier here.
  631.      */
  632. #if 0
  633.     if (eventPtr->xkey.state & OPTION_MASK) {
  634. index |= 2;
  635.     }
  636. #endif
  637.     if ((eventPtr->xkey.state & ShiftMask)
  638.     || (/* (dispPtr->lockUsage != LU_IGNORE)
  639.    && */ (eventPtr->xkey.state & LockMask))) {
  640. index |= 1;
  641.     }
  642.     /*
  643.      * First try of the actual translation.
  644.      */
  645.     sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, index);
  646.     /*
  647.      * Special handling: If the key was shifted because of Lock, but lock is
  648.      * only caps lock, not shift lock, and the shifted keysym isn't
  649.      * upper-case alphabetic, then switch back to the unshifted keysym.
  650.      */
  651.     if ((index & 1) && !(eventPtr->xkey.state & ShiftMask)
  652.     /*&& (dispPtr->lockUsage == LU_CAPS)*/ ) {
  653. /*
  654.  * FIXME: Keysyms are only identical to Unicode for ASCII and
  655.  * Latin-1, so we can't use Tcl_UniCharIsUpper() for keysyms outside
  656.  * that range. This may be a serious problem here.
  657.  */
  658. if ((sym == NoSymbol) || (sym > LATIN1_MAX)
  659. || !Tcl_UniCharIsUpper(sym)) {
  660.     index &= ~1;
  661.     sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
  662.     index);
  663. }
  664.     }
  665.     /*
  666.      * Another bit of special handling: If this is a shifted key and there is
  667.      * no keysym defined, then use the keysym for the unshifted key.
  668.      */
  669.     if ((index & 1) && (sym == NoSymbol)) {
  670. sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
  671. index & ~1);
  672.     }
  673.     return sym;
  674. }
  675. /*
  676.  *--------------------------------------------------------------
  677.  *
  678.  * TkpInitKeymapInfo --
  679.  *
  680.  * This procedure is invoked to scan keymap information to recompute
  681.  * stuff that's important for binding, such as the modifier key (if any)
  682.  * that corresponds to the "Mode_switch" keysym.
  683.  *
  684.  * Results:
  685.  * None.
  686.  *
  687.  * Side effects:
  688.  * Keymap-related information in dispPtr is updated.
  689.  *
  690.  *--------------------------------------------------------------
  691.  */
  692. void
  693. TkpInitKeymapInfo(
  694.     TkDisplay *dispPtr) /* Display for which to recompute keymap
  695.  * information. */
  696. {
  697.     dispPtr->bindInfoStale = 0;
  698.     /*
  699.      * Behaviours that are variable on X11 are defined constant on MacOSX.
  700.      * lockUsage is only used above in TkpGetKeySym(), nowhere else
  701.      * currently. There is no offical "Mode_switch" key.
  702.      */
  703.     dispPtr->lockUsage = LU_CAPS;
  704.     dispPtr->modeModMask = 0;
  705. #if 0
  706.     /*
  707.      * With this, <Alt> and <Meta> become synonyms for <Command> and <Option>
  708.      * in bindings like they are (and always have been) in the keysyms that
  709.      * are reported by KeyPress events. But the init scripts like text.tcl
  710.      * have some disabling bindings for <Meta>, so we don't want this without
  711.      * some changes in those scripts. See also bug #700311.
  712.      */
  713.     dispPtr->altModMask = OPTION_MASK;
  714.     dispPtr->metaModMask = COMMAND_MASK;
  715. #else
  716.     dispPtr->altModMask = 0;
  717.     dispPtr->metaModMask = 0;
  718. #endif
  719.     /*
  720.      * MacOSX doesn't use the keycodes for the modifiers for anything, and we
  721.      * don't generate them either (the keycodes actually given in the
  722.      * simulated modifier events are bogus). So there is no modifier map.
  723.      * If we ever want to simulate real modifier keycodes, the list will be
  724.      * constant in the Carbon implementation.
  725.      */
  726.     if (dispPtr->modKeyCodes != NULL) {
  727. ckfree((char *) dispPtr->modKeyCodes);
  728.     }
  729.     dispPtr->numModKeyCodes = 0;
  730.     dispPtr->modKeyCodes = NULL;
  731. }