home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xlib_KeyBind.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  23KB  |  769 lines

  1. /* $XConsortium: KeyBind.c /main/55 1996/02/02 14:08:55 kaleb $ */
  2. /* 
  3.  
  4. Copyright (c) 1985, 1987,  X Consortium
  5.  
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12.  
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15.  
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  19. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  20. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  
  23. Except as contained in this notice, the name of the X Consortium shall not be
  24. used in advertising or otherwise to promote the sale, use or other dealings
  25. in this Software without prior written authorization from the X Consortium.
  26.  
  27. */
  28.  
  29. /* Beware, here be monsters (still under construction... - JG */
  30.  
  31. #define NEED_EVENTS
  32. #include "Xlib_private.h"
  33. #include <X11/Xutil.h>
  34. #define XK_MISCELLANY
  35. #define XK_LATIN1
  36. #define XK_LATIN2
  37. #define XK_LATIN3
  38. #define XK_LATIN4
  39. #define XK_CYRILLIC
  40. #define XK_GREEK
  41. #define XK_XKB_KEYS
  42. #include <X11/keysymdef.h>
  43. #include <stdio.h>
  44.  
  45. #ifdef USE_OWN_COMPOSE
  46. #include "imComp.h"
  47. #endif
  48.  
  49. #ifdef XKB
  50. #define    XKeycodeToKeysym    _XKeycodeToKeysym
  51. #define    XKeysymToKeycode    _XKeysymToKeycode
  52. #define    XLookupKeysym        _XLookupKeysym
  53. #define    XRefreshKeyboardMapping    _XRefreshKeyboardMapping
  54. #define    XLookupString        _XLookupString
  55. #else
  56. #define    XkbKeysymToModifiers    _XKeysymToModifiers
  57. #endif
  58.  
  59. #define AllMods (ShiftMask|LockMask|ControlMask| \
  60.          Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
  61.  
  62. static void ComputeMaskFromKeytrans();
  63.  
  64. struct _XKeytrans {
  65.     struct _XKeytrans *next;/* next on list */
  66.     char *string;        /* string to return when the time comes */
  67.     int len;        /* length of string (since NULL is legit)*/
  68.     KeySym key;        /* keysym rebound */
  69.     unsigned int state;    /* modifier state */
  70.     KeySym *modifiers;    /* modifier keysyms you want */
  71.     int mlen;        /* length of modifier list */
  72. };
  73.  
  74. static KeySym
  75. #if NeedFunctionPrototypes
  76. KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col)
  77. #else
  78. KeyCodetoKeySym(dpy, keycode, col)
  79.     register Display *dpy;
  80.     KeyCode keycode;
  81.     int col;
  82. #endif
  83. {
  84.     DBUG_ENTER("KeyCodetoKeySym")
  85.     register int per = dpy->keysyms_per_keycode;
  86.     register KeySym *syms;
  87.     KeySym lsym, usym;
  88.  
  89.     if ((col < 0) || ((col >= per) && (col > 3)) ||
  90.     ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
  91.       DBUG_RETURN(NoSymbol);
  92.  
  93.     syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
  94.     if (col < 4) {
  95.     if (col > 1) {
  96.         while ((per > 2) && (syms[per - 1] == NoSymbol))
  97.         per--;
  98.         if (per < 3)
  99.         col -= 2;
  100.     }
  101.     if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
  102.         XConvertCase(syms[col&~1], &lsym, &usym);
  103.         if (!(col & 1))
  104.         DBUG_RETURN(lsym);
  105.         if (usym == lsym)
  106.         DBUG_RETURN(NoSymbol);
  107.         DBUG_RETURN(usym);
  108.     }
  109.     }
  110.     DBUG_RETURN(syms[col]);
  111. }
  112.  
  113. #if NeedFunctionPrototypes
  114. KeySym
  115. XKeycodeToKeysym(Display *dpy,
  116. #if NeedWidePrototypes
  117.          unsigned int kc,
  118. #else
  119.          KeyCode kc,
  120. #endif
  121.          int col)
  122. #else
  123. KeySym
  124. XKeycodeToKeysym(dpy, kc, col)
  125.     Display *dpy;
  126.     KeyCode kc;
  127.     int col;
  128. #endif
  129. {
  130.     DBUG_ENTER("XKeycodeToKeysym")
  131.     KeySym result;
  132.     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
  133.     DBUG_RETURN(NoSymbol);
  134.     result = KeyCodetoKeySym(dpy, kc, col);
  135.     DBUG_RETURN(result);
  136. }
  137.  
  138. KeyCode
  139. XKeysymToKeycode(dpy, ks)
  140.     Display *dpy;
  141.     KeySym ks;
  142. {
  143.     DBUG_ENTER("XKeysymToKeycode")
  144.     register int i, j;
  145.  
  146.     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
  147.     DBUG_RETURN((KeyCode) 0);
  148.     for (j = 0; j < dpy->keysyms_per_keycode; j++) {
  149.     for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
  150.         if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks)
  151.         DBUG_RETURN(i);
  152.     }
  153.     }
  154.     DBUG_RETURN(0);
  155. }
  156.  
  157. KeySym
  158. XLookupKeysym(event, col)
  159.     register XKeyEvent *event;
  160.     int col;
  161. {
  162.     DBUG_ENTER("XLookupKeysym")
  163.     KeySym result;
  164.     if ((! event->display->keysyms) && (! _XKeyInitialize(event->display)))
  165.     DBUG_RETURN(NoSymbol);
  166.     result = KeyCodetoKeySym(event->display, event->keycode, col);
  167.     DBUG_RETURN(result);
  168. }
  169.  
  170. static void
  171. ResetModMap(dpy)
  172.     Display *dpy;
  173. {
  174.     DBUG_ENTER("ResetModMap")
  175.     register XModifierKeymap *map;
  176.     register int i, j, n;
  177.     KeySym sym;
  178.     register struct _XKeytrans *p;
  179.  
  180.     map = dpy->modifiermap;
  181.     /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock,
  182.      * else if any contains Shift_Lock, then interpret as Shift_Lock,
  183.      * else ignore Lock altogether.
  184.      */
  185.     dpy->lock_meaning = NoSymbol;
  186.     /* Lock modifiers are in the second row of the matrix */
  187.     n = 2 * map->max_keypermod;
  188.     for (i = map->max_keypermod; i < n; i++) {
  189.     for (j = 0; j < dpy->keysyms_per_keycode; j++) {
  190.         sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
  191.         if (sym == XK_Caps_Lock) {
  192.         dpy->lock_meaning = XK_Caps_Lock;
  193.         break;
  194.         } else if (sym == XK_Shift_Lock) {
  195.         dpy->lock_meaning = XK_Shift_Lock;
  196.         }
  197.         else if (sym == XK_ISO_Lock) {
  198.         dpy->lock_meaning = XK_Caps_Lock;
  199.         break;
  200.         }
  201.     }
  202.     }
  203.     /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */
  204.     dpy->mode_switch = Mod1Mask;
  205.     dpy->num_lock = 0;
  206.     n *= 4;
  207.     for (i = 3*map->max_keypermod; i < n; i++) {
  208.     for (j = 0; j < dpy->keysyms_per_keycode; j++) {
  209.         sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
  210.         if (sym == XK_Mode_switch)
  211.         dpy->mode_switch |= 1 << (i / map->max_keypermod);
  212.         if (sym == XK_Num_Lock)
  213.         dpy->num_lock |= 1 << (i / map->max_keypermod);
  214.     }
  215.     }
  216.     for (p = dpy->key_bindings; p; p = p->next)
  217.     ComputeMaskFromKeytrans(dpy, p);
  218.     DBUG_VOID_RETURN;
  219. }
  220.  
  221. static int
  222. InitModMap(dpy)
  223.     Display *dpy;
  224. {
  225.     DBUG_ENTER("InitModMap")
  226.     register XModifierKeymap *map;
  227.  
  228.     if (! (map = XGetModifierMapping(dpy)))
  229.     DBUG_RETURN(0);
  230.     LockDisplay(dpy);
  231.     if (dpy->modifiermap)
  232.     XFreeModifiermap(dpy->modifiermap);
  233.     dpy->modifiermap = map;
  234.     dpy->free_funcs->modifiermap = XFreeModifiermap;
  235.     if (dpy->keysyms)
  236.     ResetModMap(dpy);
  237.     UnlockDisplay(dpy);
  238.     DBUG_RETURN(1);
  239. }
  240.  
  241. XRefreshKeyboardMapping(event)
  242.     register XMappingEvent *event;
  243. {
  244.     DBUG_ENTER("XRefreshKeyboardMapping")
  245.     if(event->request == MappingKeyboard) {
  246.     /* XXX should really only refresh what is necessary
  247.      * for now, make initialize test fail
  248.      */
  249.     LockDisplay(event->display);
  250.     if (event->display->keysyms) {
  251.          Xfree ((char *)event->display->keysyms);
  252.          event->display->keysyms = NULL;
  253.     }
  254.     UnlockDisplay(event->display);
  255.     }
  256.     if(event->request == MappingModifier) {
  257.     LockDisplay(event->display);
  258.     if (event->display->modifiermap) {
  259.         XFreeModifiermap(event->display->modifiermap);
  260.         event->display->modifiermap = NULL;
  261.     }
  262.     UnlockDisplay(event->display);
  263.     /* go ahead and get it now, since initialize test may not fail */
  264.     if (event->display->keysyms)
  265.         (void) InitModMap(event->display);
  266.     }
  267.     DBUG_RETURN(1);
  268. }
  269.  
  270. int
  271. _XKeyInitialize(dpy)
  272.     Display *dpy;
  273. {
  274.     DBUG_ENTER("_XKeyInitialize")
  275.     int per, n;
  276.     KeySym *keysyms;
  277.  
  278.     /* 
  279.      * lets go get the keysyms from the server.
  280.      */
  281.     if (!dpy->keysyms) {
  282.     n = dpy->max_keycode - dpy->min_keycode + 1;
  283.     keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode,
  284.                        n, &per);
  285.     /* keysyms may be NULL */
  286.     if (! keysyms) DBUG_RETURN(0);
  287.  
  288.     LockDisplay(dpy);
  289.     if (dpy->keysyms)
  290.         Xfree ((char *)dpy->keysyms);
  291.     dpy->keysyms = keysyms;
  292.     dpy->keysyms_per_keycode = per;
  293.     if (dpy->modifiermap)
  294.         ResetModMap(dpy);
  295.     UnlockDisplay(dpy);
  296.     }
  297.     if (!dpy->modifiermap) {
  298.     int result = InitModMap(dpy);
  299.     DBUG_RETURN(result);
  300.     }
  301.     DBUG_RETURN(1);
  302. }
  303.  
  304. void
  305. XConvertCase(sym, lower, upper)
  306.     register KeySym sym;
  307.     KeySym *lower;
  308.     KeySym *upper;
  309. {
  310.     DBUG_ENTER("XConvertCase")
  311.     *lower = sym;
  312.     *upper = sym;
  313.     switch(sym >> 8) {
  314.     case 0: /* Latin 1 */
  315.     if ((sym >= XK_A) && (sym <= XK_Z))
  316.         *lower += (XK_a - XK_A);
  317.     else if ((sym >= XK_a) && (sym <= XK_z))
  318.         *upper -= (XK_a - XK_A);
  319.     else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
  320.         *lower += (XK_agrave - XK_Agrave);
  321.     else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
  322.         *upper -= (XK_agrave - XK_Agrave);
  323.     else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
  324.         *lower += (XK_oslash - XK_Ooblique);
  325.     else if ((sym >= XK_oslash) && (sym <= XK_thorn))
  326.         *upper -= (XK_oslash - XK_Ooblique);
  327.     break;
  328.     case 1: /* Latin 2 */
  329.     /* Assume the KeySym is a legal value (ignore discontinuities) */
  330.     if (sym == XK_Aogonek)
  331.         *lower = XK_aogonek;
  332.     else if (sym >= XK_Lstroke && sym <= XK_Sacute)
  333.         *lower += (XK_lstroke - XK_Lstroke);
  334.     else if (sym >= XK_Scaron && sym <= XK_Zacute)
  335.         *lower += (XK_scaron - XK_Scaron);
  336.     else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
  337.         *lower += (XK_zcaron - XK_Zcaron);
  338.     else if (sym == XK_aogonek)
  339.         *upper = XK_Aogonek;
  340.     else if (sym >= XK_lstroke && sym <= XK_sacute)
  341.         *upper -= (XK_lstroke - XK_Lstroke);
  342.     else if (sym >= XK_scaron && sym <= XK_zacute)
  343.         *upper -= (XK_scaron - XK_Scaron);
  344.     else if (sym >= XK_zcaron && sym <= XK_zabovedot)
  345.         *upper -= (XK_zcaron - XK_Zcaron);
  346.     else if (sym >= XK_Racute && sym <= XK_Tcedilla)
  347.         *lower += (XK_racute - XK_Racute);
  348.     else if (sym >= XK_racute && sym <= XK_tcedilla)
  349.         *upper -= (XK_racute - XK_Racute);
  350.     break;
  351.     case 2: /* Latin 3 */
  352.     /* Assume the KeySym is a legal value (ignore discontinuities) */
  353.     if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
  354.         *lower += (XK_hstroke - XK_Hstroke);
  355.     else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
  356.         *lower += (XK_gbreve - XK_Gbreve);
  357.     else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
  358.         *upper -= (XK_hstroke - XK_Hstroke);
  359.     else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
  360.         *upper -= (XK_gbreve - XK_Gbreve);
  361.     else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
  362.         *lower += (XK_cabovedot - XK_Cabovedot);
  363.     else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
  364.         *upper -= (XK_cabovedot - XK_Cabovedot);
  365.     break;
  366.     case 3: /* Latin 4 */
  367.     /* Assume the KeySym is a legal value (ignore discontinuities) */
  368.     if (sym >= XK_Rcedilla && sym <= XK_Tslash)
  369.         *lower += (XK_rcedilla - XK_Rcedilla);
  370.     else if (sym >= XK_rcedilla && sym <= XK_tslash)
  371.         *upper -= (XK_rcedilla - XK_Rcedilla);
  372.     else if (sym == XK_ENG)
  373.         *lower = XK_eng;
  374.     else if (sym == XK_eng)
  375.         *upper = XK_ENG;
  376.     else if (sym >= XK_Amacron && sym <= XK_Umacron)
  377.         *lower += (XK_amacron - XK_Amacron);
  378.     else if (sym >= XK_amacron && sym <= XK_umacron)
  379.         *upper -= (XK_amacron - XK_Amacron);
  380.     break;
  381.     case 6: /* Cyrillic */
  382.     /* Assume the KeySym is a legal value (ignore discontinuities) */
  383.     if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
  384.         *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
  385.     else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
  386.         *upper += (XK_Serbian_DJE - XK_Serbian_dje);
  387.     else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
  388.         *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
  389.     else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
  390.         *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
  391.         break;
  392.     case 7: /* Greek */
  393.     /* Assume the KeySym is a legal value (ignore discontinuities) */
  394.     if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
  395.         *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
  396.     else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
  397.          sym != XK_Greek_iotaaccentdieresis &&
  398.          sym != XK_Greek_upsilonaccentdieresis)
  399.         *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
  400.     else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
  401.         *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
  402.     else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
  403.          sym != XK_Greek_finalsmallsigma)
  404.         *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
  405.         break;
  406.     }
  407.     DBUG_VOID_RETURN;
  408. }
  409.  
  410. int
  411. #if NeedFunctionPrototypes
  412. _XTranslateKey(    register Display *dpy,
  413.         KeyCode keycode,
  414.         register unsigned int modifiers,
  415.         unsigned int *modifiers_return,
  416.         KeySym *keysym_return)
  417. #else
  418. _XTranslateKey(dpy, keycode, modifiers, modifiers_return, keysym_return)
  419.     register Display *dpy;
  420.     KeyCode keycode;
  421.     register unsigned int modifiers;
  422.     unsigned int *modifiers_return;
  423.     KeySym *keysym_return;
  424. #endif
  425. {
  426.     DBUG_ENTER("_XTranslateKey")
  427.     int per;
  428.     register KeySym *syms;
  429.     KeySym sym, lsym, usym;
  430.  
  431.     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
  432.     DBUG_RETURN(0);
  433.     *modifiers_return = ((ShiftMask|LockMask)
  434.              | dpy->mode_switch | dpy->num_lock);
  435.     if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
  436.     {
  437.     *keysym_return = NoSymbol;
  438.     DBUG_RETURN(1);
  439.     }
  440.     per = dpy->keysyms_per_keycode;
  441.     syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
  442.     while ((per > 2) && (syms[per - 1] == NoSymbol))
  443.     per--;
  444.  
  445. #ifdef DEBUG
  446.     if (modifiers & dpy->mode_switch) 
  447.     fprintf(stderr,"_XTranslateKey: mode_switch\n");
  448.     else
  449.     fprintf(stderr,"_XTranslateKey: modifiers = %x, dpy->mode_switch = %x, per = %d,\n",
  450.         modifiers, dpy->mode_switch, per );
  451. #endif
  452.     
  453.     if ((per > 2) && (modifiers & dpy->mode_switch/*Mod1Mask*/)) {
  454.     syms += 2;
  455.     per -= 2;
  456.     }
  457.     if ((modifiers & dpy->num_lock) &&
  458.     (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
  459.     if ((modifiers & ShiftMask) ||
  460.         ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
  461.         *keysym_return = syms[0];
  462.     else
  463.         *keysym_return = syms[1];
  464.     } else if (!(modifiers & ShiftMask) &&
  465.     (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
  466.     if ((per == 1) || (syms[1] == NoSymbol))
  467.         XConvertCase(syms[0], keysym_return, &usym);
  468.     else
  469.         *keysym_return = syms[0];
  470.     } else if (!(modifiers & LockMask) ||
  471.            (dpy->lock_meaning != XK_Caps_Lock)) {
  472.     if ((per == 1) || ((usym = syms[1]) == NoSymbol))
  473.         XConvertCase(syms[0], &lsym, &usym);
  474.     *keysym_return = usym;
  475.     } else {
  476.     if ((per == 1) || ((sym = syms[1]) == NoSymbol))
  477.         sym = syms[0];
  478.     XConvertCase(sym, &lsym, &usym);
  479.     if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
  480.         ((sym != usym) || (lsym == usym)))
  481.         XConvertCase(syms[0], &lsym, &usym);
  482.     *keysym_return = usym;
  483.     }
  484.     if (*keysym_return == XK_VoidSymbol)
  485.     *keysym_return = NoSymbol;
  486.     DBUG_RETURN(1);
  487. }
  488.  
  489. int
  490. _XTranslateKeySym(dpy, symbol, modifiers, buffer, nbytes)
  491.     Display *dpy;
  492.     register KeySym symbol;
  493.     unsigned int modifiers;
  494.     char *buffer;
  495.     int nbytes;
  496. {
  497.     DBUG_ENTER("_XTranslateKeySym")
  498.     register struct _XKeytrans *p; 
  499.     int length;
  500.     unsigned long hiBytes;
  501.     register unsigned char c;
  502.  
  503.     if (!symbol)
  504.     DBUG_RETURN(0);
  505.     /* see if symbol rebound, if so, return that string. */
  506.     for (p = dpy->key_bindings; p; p = p->next) {
  507.     if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
  508.         length = p->len;
  509.         if (length > nbytes) length = nbytes;
  510.         memcpy (buffer, p->string, length);
  511.         DBUG_RETURN(length);
  512.     }
  513.     }
  514.     /* try to convert to Latin-1, handling control */
  515.     hiBytes = symbol >> 8;
  516.     if (!(nbytes &&
  517.       ((hiBytes == 0) ||
  518.        ((hiBytes == 0xFF) &&
  519.         (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
  520.          (symbol == XK_Return) ||
  521.          (symbol == XK_Escape) ||
  522.          (symbol == XK_KP_Space) ||
  523.          (symbol == XK_KP_Tab) ||
  524.          (symbol == XK_KP_Enter) ||
  525.          ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
  526.          (symbol == XK_KP_Equal) ||
  527.          (symbol == XK_Delete))))))
  528.     DBUG_RETURN(0);
  529.  
  530.     /* if X keysym, convert to ascii by grabbing low 7 bits */
  531.     if (symbol == XK_KP_Space)
  532.     c = XK_space & 0x7F; /* patch encoding botch */
  533.     else if (hiBytes == 0xFF)
  534.     c = symbol & 0x7F;
  535.     else
  536.     c = symbol & 0xFF;
  537.     /* only apply Control key if it makes sense, else ignore it */
  538.     if (modifiers & ControlMask) {
  539.     if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
  540.     else if (c == '2') c = '\000';
  541.     else if (c >= '3' && c <= '7') c -= ('3' - '\033');
  542.     else if (c == '8') c = '\177';
  543.     else if (c == '/') c = '_' & 0x1F;
  544.     }
  545.     buffer[0] = c;
  546.     DBUG_RETURN(1);
  547. }
  548.   
  549. /*ARGSUSED*/
  550. int
  551. XLookupString (event, buffer, nbytes, keysym, status)
  552.     register XKeyEvent *event;
  553.     char *buffer;    /* buffer */
  554.     int nbytes;    /* space in buffer for characters */
  555.     KeySym *keysym;
  556.     XComposeStatus *status;    /* not implemented */
  557. {
  558.     DBUG_ENTER("XLookupString")
  559.     unsigned int modifiers;
  560.     KeySym symbol;
  561.  
  562.     if (! _XTranslateKey(event->display, event->keycode, event->state,
  563.           &modifiers, &symbol))
  564.     DBUG_RETURN(0);
  565.  
  566. #ifdef USE_OWN_COMPOSE
  567.     if ( status ) {
  568.     static int been_here= 0;
  569.     if ( !been_here ) {
  570.         XimCompInitTables();
  571.         been_here = 1;
  572.     }
  573.     if ( !XimCompLegalStatus(status) ) {
  574.         status->compose_ptr = NULL;
  575.         status->chars_matched = 0;
  576.     }
  577.     if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) || 
  578.         XimCompIsComposeKey(symbol,event->keycode,status) ) {
  579.         XimCompRtrn rtrn;
  580.         switch (XimCompProcessSym(status,symbol,&rtrn)) {
  581.         case XIM_COMP_IGNORE:
  582.             break;
  583.         case XIM_COMP_IN_PROGRESS:
  584.             if ( keysym!=NULL )
  585.             *keysym = NoSymbol;
  586.             return 0;
  587.         case XIM_COMP_FAIL:
  588.         {
  589.             int n = 0, len= 0;
  590.             for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
  591.             if ( nbytes-len > 0 ) {
  592.                 len+= _XTranslateKeySym(event->display,rtrn.sym[n],
  593.                             event->state,
  594.                             buffer+len,nbytes-len);
  595.             }
  596.             }
  597.             if ( keysym!=NULL ) {
  598.             if ( n==1 )    *keysym = rtrn.sym[0];
  599.             else        *keysym = NoSymbol;
  600.             }
  601.             return len;
  602.         }
  603.         case XIM_COMP_SUCCEED:
  604.         {
  605.             int len,n = 0;
  606.  
  607.             symbol = rtrn.matchSym;
  608.             if ( keysym!=NULL )    *keysym = symbol;
  609.             if ( rtrn.str[0]!='\0' ) {
  610.             strncpy(buffer,rtrn.str,nbytes-1);
  611.             buffer[nbytes-1]= '\0';
  612.             len = strlen(buffer);
  613.             }
  614.             else {
  615.             len = _XTranslateKeySym(event->display,symbol,
  616.                             event->state,
  617.                             buffer,nbytes);
  618.             }
  619.             for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
  620.             if ( nbytes-len > 0 ) {
  621.                 len+= _XTranslateKeySym(event->display,rtrn.sym[n],
  622.                             event->state,
  623.                             buffer+len,nbytes-len);
  624.             }
  625.             }
  626.             DBUG_RETURN(len);
  627.         }
  628.         }
  629.     }
  630.     }
  631. #endif
  632.  
  633.     if (keysym)
  634.     *keysym = symbol;
  635.     /* arguable whether to use (event->state & ~modifiers) here */
  636.     {
  637.     int result = _XTranslateKeySym(event->display, symbol, event->state,
  638.                  buffer, nbytes);
  639.     DBUG_RETURN(result);
  640.     }
  641. }
  642.  
  643. static void
  644. _XFreeKeyBindings (dpy)
  645.     Display *dpy;
  646. {
  647.     DBUG_ENTER("_XFreeKeyBindings")
  648.     register struct _XKeytrans *p, *np;
  649.  
  650.     for (p = dpy->key_bindings; p; p = np) {
  651.     np = p->next;
  652.     Xfree(p->string);
  653.     Xfree((char *)p->modifiers);
  654.     Xfree((char *)p);
  655.     }   
  656.     DBUG_VOID_RETURN;
  657. }
  658.  
  659. #if NeedFunctionPrototypes
  660. XRebindKeysym (
  661.     Display *dpy,
  662.     KeySym keysym,
  663.     KeySym *mlist,
  664.     int nm,        /* number of modifiers in mlist */
  665.     _Xconst unsigned char *str,
  666.     int nbytes)
  667. #else
  668. XRebindKeysym (dpy, keysym, mlist, nm, str, nbytes)
  669.     Display *dpy;
  670.     KeySym keysym;
  671.     KeySym *mlist;
  672.     int nm;        /* number of modifiers in mlist */
  673.     unsigned char *str;
  674.     int nbytes;
  675. #endif
  676. {
  677.     DBUG_ENTER("XRebindKeysym")
  678.     register struct _XKeytrans *tmp, *p;
  679.     int nb;
  680.  
  681.     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
  682.     DBUG_RETURN(0);
  683.     LockDisplay(dpy);
  684.     tmp = dpy->key_bindings;
  685.     nb = sizeof(KeySym) * nm;
  686.  
  687.     if ((! (p = (struct _XKeytrans *) Xmalloc( sizeof(struct _XKeytrans)))) ||
  688.     ((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) && 
  689.      (nbytes > 0)) ||
  690.     ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) &&
  691.      (nb > 0))) {
  692.     if (p) {
  693.         if (p->string) Xfree(p->string);
  694.         if (p->modifiers) Xfree((char *) p->modifiers);
  695.         Xfree((char *) p);
  696.     }
  697.     UnlockDisplay(dpy);
  698.     DBUG_RETURN(0);
  699.     }
  700.  
  701.     dpy->key_bindings = p;
  702.     dpy->free_funcs->key_bindings = _XFreeKeyBindings;
  703.     p->next = tmp;    /* chain onto list */
  704.     memcpy (p->string, (char *) str, nbytes);
  705.     p->len = nbytes;
  706.     memcpy ((char *) p->modifiers, (char *) mlist, nb);
  707.     p->key = keysym;
  708.     p->mlen = nm;
  709.     ComputeMaskFromKeytrans(dpy, p);
  710.     UnlockDisplay(dpy);
  711.     DBUG_RETURN(0);
  712. }
  713.  
  714. unsigned
  715. _XKeysymToModifiers(dpy,ks)
  716.     Display *dpy;
  717.     KeySym ks;
  718. {
  719.     DBUG_ENTER("_XKeysymToModifiers")
  720.     CARD8 code,mods;
  721.     register KeySym *kmax;
  722.     register KeySym *k;
  723.     register XModifierKeymap *m;
  724.  
  725.     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
  726.     DBUG_RETURN(0);
  727.     kmax = dpy->keysyms + 
  728.        (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
  729.     k = dpy->keysyms;
  730.     m = dpy->modifiermap;
  731.     mods= 0;
  732.     while (k<kmax) {
  733.     if (*k == ks ) {
  734.         register int j = m->max_keypermod<<3;
  735.  
  736.         code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode);
  737.  
  738.         while (--j >= 0) {
  739.         if (code == m->modifiermap[j])
  740.             mods|= (1<<(j/m->max_keypermod));
  741.         }
  742.     }
  743.     k++;
  744.     }
  745.     DBUG_RETURN(mods);
  746. }
  747.     
  748. /*
  749.  * given a list of modifiers, computes the mask necessary for later matching.
  750.  * This routine must lookup the key in the Keymap and then search to see
  751.  * what modifier it is bound to, if any.  Sets the AnyModifier bit if it
  752.  * can't map some keysym to a modifier.
  753.  */
  754. static void
  755. ComputeMaskFromKeytrans(dpy, p)
  756.     Display *dpy;
  757.     register struct _XKeytrans *p;
  758. {
  759.     DBUG_ENTER("ComputeMaskFromKeytrans")
  760.     register int i;
  761.  
  762.     p->state = AnyModifier;
  763.     for (i = 0; i < p->mlen; i++) {
  764.     p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
  765.     }
  766.     p->state &= AllMods;
  767.     DBUG_VOID_RETURN;
  768. }
  769.