/[dtapublic]/projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkwinkey.c
ViewVC logotype

Diff of /projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkwinkey.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.29  
changed lines
  Added in v.98

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25