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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * tkWinKey.c --
  3.  *
  4.  * This file contains X emulation routines for keyboard related
  5.  * functions.
  6.  *
  7.  * Copyright (c) 1995 Sun Microsystems, Inc.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * RCS: @(#) $Id: tkWinKey.c,v 1.14.4.1 2006/08/30 21:53:46 hobbs Exp $
  13.  */
  14. #include "tkWinInt.h"
  15. /*
  16.  * The keymap table holds mappings of Windows keycodes to X keysyms.
  17.  * If Windows ever comes along and changes the value of their keycodes,
  18.  * this will break all kinds of things.  However, this table lookup is much
  19.  * faster than the alternative, in which we walked a list of keycodes looking
  20.  * for a match.  Since this lookup is performed for every Windows keypress
  21.  * event, it seems like a worthwhile improvement to use the table.
  22.  */
  23. #define MAX_KEYCODE 145 /* VK_SCROLL is the last entry in our table below */
  24. static KeySym keymap[] = {
  25.     NoSymbol, NoSymbol, NoSymbol, XK_Cancel, NoSymbol,
  26. NoSymbol, NoSymbol, NoSymbol, XK_BackSpace, XK_Tab,
  27. NoSymbol, NoSymbol, XK_Clear, XK_Return, NoSymbol,
  28. NoSymbol, XK_Shift_L, XK_Control_L, XK_Alt_L, XK_Pause,
  29. XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  30. NoSymbol, NoSymbol, XK_Escape, NoSymbol, NoSymbol,
  31. NoSymbol, NoSymbol, XK_space, XK_Prior, XK_Next,
  32. XK_End, XK_Home, XK_Left, XK_Up, XK_Right,
  33. XK_Down, XK_Select, XK_Print, XK_Execute, NoSymbol,
  34. XK_Insert, XK_Delete, XK_Help, NoSymbol, NoSymbol,
  35. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  36. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  37. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  38. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  39. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  40. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  41. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  42. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  43. NoSymbol, XK_Win_L, XK_Win_R, XK_App, NoSymbol,
  44. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  45. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  46. NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  47. NoSymbol, NoSymbol, XK_F1, XK_F2, XK_F3,
  48. XK_F4, XK_F5, XK_F6, XK_F7, XK_F8,
  49. XK_F9, XK_F10, XK_F11, XK_F12, XK_F13,
  50. XK_F14, XK_F15, XK_F16, XK_F17, XK_F18,
  51. XK_F19, XK_F20, XK_F21, XK_F22, XK_F23,
  52. XK_F24, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
  53. NoSymbol, NoSymbol, NoSymbol, NoSymbol, XK_Num_Lock,
  54. XK_Scroll_Lock
  55. };
  56. /*
  57.  * Prototypes for local procedures defined in this file:
  58.  */
  59. static KeySym KeycodeToKeysym _ANSI_ARGS_((unsigned int keycode,
  60.     int state, int noascii));
  61. /*
  62.  *----------------------------------------------------------------------
  63.  *
  64.  * TkpGetString --
  65.  *
  66.  * Retrieve the UTF string equivalent for the given keyboard event.
  67.  *
  68.  * Results:
  69.  * Returns the UTF string.
  70.  *
  71.  * Side effects:
  72.  * None.
  73.  *
  74.  *----------------------------------------------------------------------
  75.  */
  76. char *
  77. TkpGetString(winPtr, eventPtr, dsPtr)
  78.     TkWindow *winPtr; /* Window where event occurred:  needed to
  79.  * get input context. */
  80.     XEvent *eventPtr; /* X keyboard event. */
  81.     Tcl_DString *dsPtr; /* Uninitialized or empty string to hold
  82.  * result. */
  83. {
  84.     KeySym keysym;
  85.     XKeyEvent* keyEv = &eventPtr->xkey;
  86.     Tcl_DStringInit(dsPtr);
  87.     if (eventPtr->xkey.send_event == -1) {
  88.         if (eventPtr->xkey.nbytes > 0) {
  89.     Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
  90.                     eventPtr->xkey.trans_chars, eventPtr->xkey.nbytes, dsPtr);
  91.         }
  92.     } else if (eventPtr->xkey.send_event == -2) {
  93.         /*
  94.          * Special case for win2000 multi-lingal IME input. 
  95.          * xkey.trans_chars[] already contains a UNICODE char.
  96.          */
  97.         int unichar;
  98.         char buf[TCL_UTF_MAX];
  99.         int len;
  100.         unichar = (eventPtr->xkey.trans_chars[1] & 0xff);
  101.         unichar <<= 8;
  102.         unichar |= (eventPtr->xkey.trans_chars[0] & 0xff);
  103.         len = Tcl_UniCharToUtf((Tcl_UniChar) unichar, buf);
  104.         Tcl_DStringAppend(dsPtr, buf, len);
  105.     } else if (eventPtr->xkey.send_event == -3) {
  106. /*
  107.  * Special case for WM_UNICHAR.
  108.  * xkey.trans_chars[] already contains a UTF-8 char.
  109.  */
  110. Tcl_DStringAppend(dsPtr, eventPtr->xkey.trans_chars,
  111. eventPtr->xkey.nbytes);
  112.     } else  {
  113. /*
  114.  * This is an event generated from generic code.  It has no
  115.  * nchars or trans_chars members. 
  116.  */
  117. keysym = KeycodeToKeysym(eventPtr->xkey.keycode,
  118. eventPtr->xkey.state, 0);
  119. if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256)) 
  120. || (keysym == XK_Return)
  121. || (keysym == XK_Tab)) {
  122.     char buf[TCL_UTF_MAX];
  123.     int len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf);
  124.     Tcl_DStringAppend(dsPtr, buf, len);
  125. }
  126.     }
  127.     return Tcl_DStringValue(dsPtr);
  128. }
  129. /*
  130.  *----------------------------------------------------------------------
  131.  *
  132.  * XKeycodeToKeysym --
  133.  *
  134.  * Translate from a system-dependent keycode to a
  135.  * system-independent keysym.
  136.  *
  137.  * Results:
  138.  * Returns the translated keysym, or NoSymbol on failure.
  139.  *
  140.  * Side effects:
  141.  * None.
  142.  *
  143.  *----------------------------------------------------------------------
  144.  */
  145. KeySym
  146. XKeycodeToKeysym(display, keycode, index)
  147.     Display* display;
  148.     unsigned int keycode;
  149.     int index;
  150. {
  151.     int state = 0;
  152.     if (index & 0x01) {
  153. state |= ShiftMask;
  154.     }
  155.     return KeycodeToKeysym(keycode, state, 0);
  156. }
  157. /*
  158.  *----------------------------------------------------------------------
  159.  *
  160.  * KeycodeToKeysym --
  161.  *
  162.  * Translate from a system-dependent keycode to a
  163.  * system-independent keysym.
  164.  *
  165.  * Results:
  166.  * Returns the translated keysym, or NoSymbol on failure.
  167.  *
  168.  * Side effects:
  169.  * It may affect the internal state of the keyboard, such as
  170.  *      remembered dead key or lock indicator lamps.
  171.  *
  172.  *----------------------------------------------------------------------
  173.  */
  174. static KeySym
  175. KeycodeToKeysym(keycode, state, noascii)
  176.     unsigned int keycode;
  177.     int state;
  178.     int noascii;
  179. {
  180.     BYTE keys[256];
  181.     int result, deadkey, shift;
  182.     char buf[4];
  183.     unsigned int scancode = MapVirtualKey(keycode, 0);
  184.     /*
  185.      * Do not run keycodes of lock keys through ToAscii().
  186.      * One of ToAscii()'s side effects is to handle the lights
  187.      * on the keyboard, and we don't want to mess that up.
  188.      */
  189.     if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL ||
  190.     keycode == VK_NUMLOCK)
  191.         goto skipToAscii;
  192.     /*
  193.      * Use MapVirtualKey() to detect some dead keys.
  194.      */
  195.     if (MapVirtualKey(keycode, 2) > 0x7fffUL)
  196.         return XK_Multi_key;
  197.     /*
  198.      * Set up a keyboard with correct modifiers
  199.      */
  200.     memset(keys, 0, 256);
  201.     if (state & ShiftMask)
  202.         keys[VK_SHIFT] = 0x80;
  203.     if (state & ControlMask)
  204. keys[VK_CONTROL] = 0x80;
  205.     if (state & Mod2Mask)
  206. keys[VK_MENU] = 0x80;
  207.     /* 
  208.      * Make sure all lock button info is correct so we don't mess up the
  209.      * lights
  210.      */
  211.     if (state & LockMask)
  212. keys[VK_CAPITAL] = 1;
  213.     if (state & Mod3Mask)
  214. keys[VK_SCROLL] = 1;
  215.     if (state & Mod1Mask)
  216. keys[VK_NUMLOCK] = 1;
  217.     result = ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
  218.     if (result < 0) {
  219.         /*
  220.          * Win95/98:
  221.          * This was a dead char, which is now remembered by the keyboard.
  222.          * Call ToAscii() again to forget it.
  223.          * WinNT:
  224.          * This was a dead char, overwriting any previously remembered
  225.          * key. Calling ToAscii() again does not affect anything.
  226.          */
  227.         ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
  228.         return XK_Multi_key;
  229.     }
  230.     if (result == 2) {
  231.         /*
  232.          * This was a dead char, and there were one previously remembered
  233.          * by the keyboard.
  234.          * Call ToAscii() again with proper parameters to restore it.
  235.          */
  236.         /* 
  237.  * Get information about the old char
  238.  */
  239.         deadkey = VkKeyScan(buf[0]);
  240.         shift = deadkey >> 8;
  241.         deadkey &= 255;
  242.         scancode = MapVirtualKey(deadkey, 0);
  243.         /*
  244.  * Set up a keyboard with proper modifier keys
  245.  */
  246.         memset(keys, 0, 256);
  247.         if (shift & 1)
  248.             keys[VK_SHIFT] = 0x80;
  249.         if (shift & 2)
  250.             keys[VK_CONTROL] = 0x80;
  251.         if (shift & 4)
  252.             keys[VK_MENU] = 0x80;
  253.         ToAscii(deadkey, scancode, keys, (LPWORD) buf, 0);
  254.         return XK_Multi_key;
  255.     }
  256.     /*
  257.      * Keycode mapped to a valid Latin-1 character.  Since the keysyms
  258.      * for alphanumeric characters map onto Latin-1, we just return it.
  259.      *
  260.      * We treat 0x7F as a special case mostly for backwards compatibility.
  261.      * In versions of Tk<=8.2, Control-Backspace returned "XK_BackSpace"
  262.      * as the X Keysym.  This was due to the fact that we did not
  263.      * initialize the keys array properly when we passed it to ToAscii, above.
  264.      * We had previously not been setting the state bit for the Control key.
  265.      * When we fixed that, we found that Control-Backspace on Windows is
  266.      * interpreted as ASCII-127 (0x7F), which corresponds to the Delete key.
  267.      *
  268.      * Upon discovering this, we realized we had two choices:  return XK_Delete
  269.      * or return XK_BackSpace.  If we returned XK_Delete, that could be
  270.      * considered "more correct" (although the correctness would be dependant
  271.      * on whether you believe that ToAscii is doing the right thing in that
  272.      * case); however, this would break backwards compatibility, and worse,
  273.      * it would limit application programmers -- they would effectively be
  274.      * unable to bind to <Control-Backspace> on Windows.  We therefore chose
  275.      * instead to return XK_BackSpace (handled here by letting the code
  276.      * "fall-through" to the return statement below, which works because the
  277.      * keycode for this event is VK_BACKSPACE, and the keymap table maps that
  278.      * keycode to XK_BackSpace).
  279.      */
  280.     if (result == 1 && UCHAR(buf[0]) >= 0x20 && UCHAR(buf[0]) != 0x7F) {
  281. return (KeySym) UCHAR(buf[0]);
  282.     }
  283.     /*
  284.      * Keycode is a non-alphanumeric key, so we have to do the lookup.
  285.      */
  286.     skipToAscii:
  287.     if (keycode < 0 || keycode > MAX_KEYCODE) {
  288. return NoSymbol;
  289.     }
  290.     switch (keycode) {
  291. /*
  292.  * Windows only gives us an undifferentiated VK_CONTROL
  293.  * code (for example) when either Control key is pressed.
  294.  * To distinguish between left and right, we have to query the
  295.  * state of one of the two to determine which was actually
  296.  * pressed.  So if the keycode indicates Control, Shift, or Menu
  297.  * (the key that everybody else calls Alt), do this extra test.
  298.  * If the right-side key was pressed, return the appropriate
  299.  * keycode.  Otherwise, we fall through and rely on the
  300.  * keymap table to hold the correct keysym value.
  301.  */
  302. case VK_CONTROL: {
  303.     if (GetKeyState(VK_RCONTROL) & 0x80) {
  304. return XK_Control_R;
  305.     }
  306.     break;
  307. }
  308. case VK_SHIFT: {
  309.     if (GetKeyState(VK_RSHIFT) & 0x80) {
  310. return XK_Shift_R;
  311.     }
  312.     break;
  313. }
  314. case VK_MENU: {
  315.     if (GetKeyState(VK_RMENU) & 0x80) {
  316. return XK_Alt_R;
  317.     }
  318.     break;
  319. }
  320.     }
  321.     return keymap[keycode];
  322. }
  323. /*
  324.  *----------------------------------------------------------------------
  325.  *
  326.  * TkpGetKeySym --
  327.  *
  328.  * Given an X KeyPress or KeyRelease event, map the
  329.  * keycode in the event into a KeySym.
  330.  *
  331.  * Results:
  332.  * The return value is the KeySym corresponding to
  333.  * eventPtr, or NoSymbol if no matching Keysym could be
  334.  * found.
  335.  *
  336.  * Side effects:
  337.  * In the first call for a given display, keycode-to-
  338.  * KeySym maps get loaded.
  339.  *
  340.  *----------------------------------------------------------------------
  341.  */
  342. KeySym
  343. TkpGetKeySym(dispPtr, eventPtr)
  344.     TkDisplay *dispPtr; /* Display in which to map keycode. */
  345.     XEvent *eventPtr; /* Description of X event. */
  346. {
  347.     KeySym sym;
  348.     int state = eventPtr->xkey.state;
  349.     /*
  350.      * Refresh the mapping information if it's stale
  351.      */
  352.     if (dispPtr->bindInfoStale) {
  353. TkpInitKeymapInfo(dispPtr);
  354.     }
  355.     sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0);
  356.     /*
  357.      * Special handling: if this is a ctrl-alt or shifted key, and there
  358.      * is no keysym defined, try without the modifiers.
  359.      */
  360.     if ((sym == NoSymbol) && ((state & ControlMask) || (state & Mod2Mask))) {
  361.         state &=  ~(ControlMask | Mod2Mask);
  362.         sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0);
  363.     }
  364.     if ((sym == NoSymbol) && (state & ShiftMask)) {
  365.         state &=  ~ShiftMask;
  366.         sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0);
  367.     }
  368.     return sym;
  369. }
  370. /*
  371.  *--------------------------------------------------------------
  372.  *
  373.  * TkpInitKeymapInfo --
  374.  *
  375.  * This procedure is invoked to scan keymap information
  376.  * to recompute stuff that's important for binding, such
  377.  * as the modifier key (if any) that corresponds to "mode
  378.  * switch".
  379.  *
  380.  * Results:
  381.  * None.
  382.  *
  383.  * Side effects:
  384.  * Keymap-related information in dispPtr is updated.
  385.  *
  386.  *--------------------------------------------------------------
  387.  */
  388. void
  389. TkpInitKeymapInfo(dispPtr)
  390.     TkDisplay *dispPtr; /* Display for which to recompute keymap
  391.  * information. */
  392. {
  393.     XModifierKeymap *modMapPtr;
  394.     KeyCode *codePtr;
  395.     KeySym keysym;
  396.     int count, i, j, max, arraySize;
  397. #define KEYCODE_ARRAY_SIZE 20
  398.     dispPtr->bindInfoStale = 0;
  399.     modMapPtr = XGetModifierMapping(dispPtr->display);
  400.     /*
  401.      * Check the keycodes associated with the Lock modifier.  If
  402.      * any of them is associated with the XK_Shift_Lock modifier,
  403.      * then Lock has to be interpreted as Shift Lock, not Caps Lock.
  404.      */
  405.     dispPtr->lockUsage = LU_IGNORE;
  406.     codePtr = modMapPtr->modifiermap + modMapPtr->max_keypermod*LockMapIndex;
  407.     for (count = modMapPtr->max_keypermod; count > 0; count--, codePtr++) {
  408. if (*codePtr == 0) {
  409.     continue;
  410. }
  411. keysym = KeycodeToKeysym(*codePtr, 0, 1);
  412. if (keysym == XK_Shift_Lock) {
  413.     dispPtr->lockUsage = LU_SHIFT;
  414.     break;
  415. }
  416. if (keysym == XK_Caps_Lock) {
  417.     dispPtr->lockUsage = LU_CAPS;
  418.     break;
  419. }
  420.     }
  421.     /*
  422.      * Look through the keycodes associated with modifiers to see if
  423.      * the the "mode switch", "meta", or "alt" keysyms are associated
  424.      * with any modifiers.  If so, remember their modifier mask bits.
  425.      */
  426.     dispPtr->modeModMask = 0;
  427.     dispPtr->metaModMask = 0;
  428.     dispPtr->altModMask = 0;
  429.     codePtr = modMapPtr->modifiermap;
  430.     max = 8*modMapPtr->max_keypermod;
  431.     for (i = 0; i < max; i++, codePtr++) {
  432. if (*codePtr == 0) {
  433.     continue;
  434. }
  435. keysym = KeycodeToKeysym(*codePtr, 0, 1);
  436. if (keysym == XK_Mode_switch) {
  437.     dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
  438. }
  439. if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) {
  440.     dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
  441. }
  442. if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) {
  443.     dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
  444. }
  445.     }
  446.     /*
  447.      * Create an array of the keycodes for all modifier keys.
  448.      */
  449.     if (dispPtr->modKeyCodes != NULL) {
  450. ckfree((char *) dispPtr->modKeyCodes);
  451.     }
  452.     dispPtr->numModKeyCodes = 0;
  453.     arraySize = KEYCODE_ARRAY_SIZE;
  454.     dispPtr->modKeyCodes = (KeyCode *) ckalloc((unsigned)
  455.     (KEYCODE_ARRAY_SIZE * sizeof(KeyCode)));
  456.     for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
  457. if (*codePtr == 0) {
  458.     continue;
  459. }
  460. /*
  461.  * Make sure that the keycode isn't already in the array.
  462.  */
  463. for (j = 0; j < dispPtr->numModKeyCodes; j++) {
  464.     if (dispPtr->modKeyCodes[j] == *codePtr) {
  465. goto nextModCode;
  466.     }
  467. }
  468. if (dispPtr->numModKeyCodes >= arraySize) {
  469.     KeyCode *new;
  470.     /*
  471.      * Ran out of space in the array;  grow it.
  472.      */
  473.     arraySize *= 2;
  474.     new = (KeyCode *) ckalloc((unsigned)
  475.     (arraySize * sizeof(KeyCode)));
  476.     memcpy((VOID *) new, (VOID *) dispPtr->modKeyCodes,
  477.     (dispPtr->numModKeyCodes * sizeof(KeyCode)));
  478.     ckfree((char *) dispPtr->modKeyCodes);
  479.     dispPtr->modKeyCodes = new;
  480. }
  481. dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
  482. dispPtr->numModKeyCodes++;
  483. nextModCode: continue;
  484.     }
  485.     XFreeModifiermap(modMapPtr);
  486. }
  487. /*
  488.  * When mapping from a keysym to a keycode, need
  489.  * information about the modifier state that should be used
  490.  * so that when they call XKeycodeToKeysym taking into
  491.  * account the xkey.state, they will get back the original
  492.  * keysym.
  493.  */
  494. void
  495. TkpSetKeycodeAndState(tkwin, keySym, eventPtr)
  496.     Tk_Window tkwin;
  497.     KeySym keySym;
  498.     XEvent *eventPtr;
  499. {
  500.     int i;
  501.     SHORT result;
  502.     int shift;
  503.     
  504.     eventPtr->xkey.keycode = 0;
  505.     if (keySym == NoSymbol) {
  506.         return;
  507.     }
  508.     /*
  509.      * We check our private map first for a virtual keycode,
  510.      * as VkKeyScan will return values that don't map to X
  511.      * for the "extended" Syms.  This may be due to just casting
  512.      * problems below, but this works.
  513.      */
  514.     for (i = 0; i <= MAX_KEYCODE; i++) {
  515. if (keymap[i] == keySym) {
  516.             eventPtr->xkey.keycode = i;
  517.             return;
  518. }
  519.     }
  520.     if (keySym >= 0x20) {
  521. result = VkKeyScan((char) keySym);
  522. if (result != -1) {
  523.             shift = result >> 8;
  524.             if (shift & 1)
  525.                 eventPtr->xkey.state |= ShiftMask;
  526.             if (shift & 2)
  527.                 eventPtr->xkey.state |= ControlMask;
  528.             if (shift & 4)
  529.                 eventPtr->xkey.state |= Mod2Mask;
  530.             eventPtr->xkey.keycode = (KeyCode) (result & 0xff);
  531. }
  532.     }
  533. }
  534. /*
  535.  *----------------------------------------------------------------------
  536.  *
  537.  * XKeysymToKeycode --
  538.  *
  539.  * Translate a keysym back into a keycode.
  540.  *
  541.  * Results:
  542.  * Returns the keycode that would generate the specified keysym.
  543.  *
  544.  * Side effects:
  545.  * None.
  546.  *
  547.  *----------------------------------------------------------------------
  548.  */
  549. KeyCode
  550. XKeysymToKeycode(display, keysym)
  551.     Display* display;
  552.     KeySym keysym;
  553. {
  554.     int i;
  555.     SHORT result;
  556.     /*
  557.      * We check our private map first for a virtual keycode,
  558.      * as VkKeyScan will return values that don't map to X
  559.      * for the "extended" Syms.  This may be due to just casting
  560.      * problems below, but this works.
  561.      */
  562.     if (keysym == NoSymbol) {
  563. return 0;
  564.     }
  565.     for (i = 0; i <= MAX_KEYCODE; i++) {
  566. if (keymap[i] == keysym) {
  567.     return ((KeyCode) i);
  568. }
  569.     }
  570.     if (keysym >= 0x20) {
  571. result = VkKeyScan((char) keysym);
  572. if (result != -1) {
  573.     return (KeyCode) (result & 0xff);
  574. }
  575.     }
  576.     return 0;
  577. }
  578. /*
  579.  *----------------------------------------------------------------------
  580.  *
  581.  * XGetModifierMapping --
  582.  *
  583.  * Fetch the current keycodes used as modifiers.
  584.  *
  585.  * Results:
  586.  * Returns a new modifier map.
  587.  *
  588.  * Side effects:
  589.  * Allocates a new modifier map data structure.
  590.  *
  591.  *----------------------------------------------------------------------
  592.  */
  593. XModifierKeymap *
  594. XGetModifierMapping(display)
  595.     Display* display;
  596. {
  597.     XModifierKeymap *map = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));
  598.     map->max_keypermod = 1;
  599.     map->modifiermap = (KeyCode *) ckalloc(sizeof(KeyCode)*8);
  600.     map->modifiermap[ShiftMapIndex] = VK_SHIFT;
  601.     map->modifiermap[LockMapIndex] = VK_CAPITAL;
  602.     map->modifiermap[ControlMapIndex] = VK_CONTROL;
  603.     map->modifiermap[Mod1MapIndex] = VK_NUMLOCK;
  604.     map->modifiermap[Mod2MapIndex] = VK_MENU;
  605.     map->modifiermap[Mod3MapIndex] = VK_SCROLL;
  606.     map->modifiermap[Mod4MapIndex] = 0;
  607.     map->modifiermap[Mod5MapIndex] = 0;
  608.     return map;
  609. }
  610. /*
  611.  *----------------------------------------------------------------------
  612.  *
  613.  * XFreeModifiermap --
  614.  *
  615.  * Deallocate a modifier map that was created by
  616.  * XGetModifierMapping.
  617.  *
  618.  * Results:
  619.  * None.
  620.  *
  621.  * Side effects:
  622.  * Frees the datastructure referenced by modmap.
  623.  *
  624.  *----------------------------------------------------------------------
  625.  */
  626. void
  627. XFreeModifiermap(modmap)
  628.     XModifierKeymap* modmap;
  629. {
  630.     ckfree((char *) modmap->modifiermap);
  631.     ckfree((char *) modmap);
  632. }
  633. /*
  634.  *----------------------------------------------------------------------
  635.  *
  636.  * XStringToKeysym --
  637.  *
  638.  * Translate a keysym name to the matching keysym. 
  639.  *
  640.  * Results:
  641.  * Returns the keysym.  Since this is already handled by
  642.  * Tk's StringToKeysym function, we just return NoSymbol.
  643.  *
  644.  * Side effects:
  645.  * None.
  646.  *
  647.  *----------------------------------------------------------------------
  648.  */
  649. KeySym
  650. XStringToKeysym(string)
  651.     _Xconst char *string;
  652. {
  653.     return NoSymbol;
  654. }
  655. /*
  656.  *----------------------------------------------------------------------
  657.  *
  658.  * XKeysymToString --
  659.  *
  660.  * Convert a keysym to character form.
  661.  *
  662.  * Results:
  663.  * Returns NULL, since Tk will have handled this already.
  664.  *
  665.  * Side effects:
  666.  * None.
  667.  *
  668.  *----------------------------------------------------------------------
  669.  */
  670. char *
  671. XKeysymToString(keysym)
  672.     KeySym keysym;
  673. {
  674.     return NULL;
  675. }