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