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