comparison src/video/cocoa/SDL_cocoakeyboard.m @ 2268:4baee598306d

Date: Thu, 05 Jul 2007 14:02:33 -0700 From: Sam Lantinga Subject: SDL 1.3 keyboard plan After lots of discussion with Christian, this is what we came up with: > So, to sum up... > SDLK_* become the physical keys, starting at > (1<<21) > We create a macro SDLK_INDEX(X) > We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName() > SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for non-printable characters > and does so based on the OS's current keyboard layout > SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and converting SDLK_* into our names, which are UTF-8 for printable characters. > WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*) Here is the patch he came up with, and his e-mail about it: Date: Fri, 17 Aug 2007 19:50:28 +0200 From: Christian Walther Subject: Re: SDL 1.3 keyboard plan > Sounds great, go ahead and send me a patch. Here goes! Thanks for having a look. Don't hesitate to comment if anything does not conform to your ideas. One caveat: Committing this now may break compilability of some video drivers - specifically, if they use any of the SDLK_* codes that were obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did break, but is already fixed) and X11 (which didn't, but then its key handling is #iffed out). If that's a problem, it may need to go into a branch. -Christian
author Sam Lantinga <slouken@libsdl.org>
date Sun, 19 Aug 2007 14:52:52 +0000
parents 243bc7ae5a21
children d5a11262f067
comparison
equal deleted inserted replaced
2267:c785543d1843 2268:4baee598306d
24 #include "SDL_cocoavideo.h" 24 #include "SDL_cocoavideo.h"
25 #include "SDL_cocoakeys.h" 25 #include "SDL_cocoakeys.h"
26 26
27 #include "../../events/SDL_keyboard_c.h" 27 #include "../../events/SDL_keyboard_c.h"
28 28
29 #include <Carbon/Carbon.h>
30
29 31
30 #ifndef NX_DEVICERCTLKEYMASK 32 #ifndef NX_DEVICERCTLKEYMASK
31 #define NX_DEVICELCTLKEYMASK 0x00000001 33 #define NX_DEVICELCTLKEYMASK 0x00000001
32 #endif 34 #endif
33 #ifndef NX_DEVICELSHIFTKEYMASK 35 #ifndef NX_DEVICELSHIFTKEYMASK
49 #define NX_DEVICERALTKEYMASK 0x00000040 51 #define NX_DEVICERALTKEYMASK 0x00000040
50 #endif 52 #endif
51 #ifndef NX_DEVICERCTLKEYMASK 53 #ifndef NX_DEVICERCTLKEYMASK
52 #define NX_DEVICERCTLKEYMASK 0x00002000 54 #define NX_DEVICERCTLKEYMASK 0x00002000
53 #endif 55 #endif
54
55 static void
56 InitKeymap (SDLKey *keymap)
57 {
58 const void *KCHRPtr;
59 UInt32 state;
60 UInt32 value;
61 int i;
62
63 for ( i=0; i<256; ++i )
64 keymap[i] = SDLK_UNKNOWN;
65
66 /* This keymap is almost exactly the same as the OS 9 one */
67 keymap[KEY_ESCAPE] = SDLK_ESCAPE;
68 keymap[KEY_F1] = SDLK_F1;
69 keymap[KEY_F2] = SDLK_F2;
70 keymap[KEY_F3] = SDLK_F3;
71 keymap[KEY_F4] = SDLK_F4;
72 keymap[KEY_F5] = SDLK_F5;
73 keymap[KEY_F6] = SDLK_F6;
74 keymap[KEY_F7] = SDLK_F7;
75 keymap[KEY_F8] = SDLK_F8;
76 keymap[KEY_F9] = SDLK_F9;
77 keymap[KEY_F10] = SDLK_F10;
78 keymap[KEY_F11] = SDLK_F11;
79 keymap[KEY_F12] = SDLK_F12;
80 keymap[KEY_F13] = SDLK_F13;
81 keymap[KEY_F14] = SDLK_F14;
82 keymap[KEY_F15] = SDLK_F15;
83 /*
84 keymap[KEY_PRINT] = SDLK_PRINT;
85 keymap[KEY_SCROLLOCK] = SDLK_SCROLLOCK;
86 keymap[KEY_PAUSE] = SDLK_PAUSE;
87 */
88 keymap[KEY_POWER] = SDLK_POWER;
89 keymap[KEY_BACKQUOTE] = SDLK_BACKQUOTE;
90 keymap[KEY_1] = SDLK_1;
91 keymap[KEY_2] = SDLK_2;
92 keymap[KEY_3] = SDLK_3;
93 keymap[KEY_4] = SDLK_4;
94 keymap[KEY_5] = SDLK_5;
95 keymap[KEY_6] = SDLK_6;
96 keymap[KEY_7] = SDLK_7;
97 keymap[KEY_8] = SDLK_8;
98 keymap[KEY_9] = SDLK_9;
99 keymap[KEY_0] = SDLK_0;
100 keymap[KEY_MINUS] = SDLK_MINUS;
101 keymap[KEY_EQUALS] = SDLK_EQUALS;
102 keymap[KEY_BACKSPACE] = SDLK_BACKSPACE;
103 keymap[KEY_INSERT] = SDLK_INSERT;
104 keymap[KEY_HOME] = SDLK_HOME;
105 keymap[KEY_PAGEUP] = SDLK_PAGEUP;
106 keymap[KEY_NUMLOCK] = SDLK_NUMLOCK;
107 keymap[KEY_KP_EQUALS] = SDLK_KP_EQUALS;
108 keymap[KEY_KP_DIVIDE] = SDLK_KP_DIVIDE;
109 keymap[KEY_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
110 keymap[KEY_TAB] = SDLK_TAB;
111 keymap[KEY_q] = SDLK_q;
112 keymap[KEY_w] = SDLK_w;
113 keymap[KEY_e] = SDLK_e;
114 keymap[KEY_r] = SDLK_r;
115 keymap[KEY_t] = SDLK_t;
116 keymap[KEY_y] = SDLK_y;
117 keymap[KEY_u] = SDLK_u;
118 keymap[KEY_i] = SDLK_i;
119 keymap[KEY_o] = SDLK_o;
120 keymap[KEY_p] = SDLK_p;
121 keymap[KEY_LEFTBRACKET] = SDLK_LEFTBRACKET;
122 keymap[KEY_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
123 keymap[KEY_BACKSLASH] = SDLK_BACKSLASH;
124 keymap[KEY_DELETE] = SDLK_DELETE;
125 keymap[KEY_END] = SDLK_END;
126 keymap[KEY_PAGEDOWN] = SDLK_PAGEDOWN;
127 keymap[KEY_KP7] = SDLK_KP7;
128 keymap[KEY_KP8] = SDLK_KP8;
129 keymap[KEY_KP9] = SDLK_KP9;
130 keymap[KEY_KP_MINUS] = SDLK_KP_MINUS;
131 keymap[KEY_CAPSLOCK] = SDLK_CAPSLOCK;
132 keymap[KEY_a] = SDLK_a;
133 keymap[KEY_s] = SDLK_s;
134 keymap[KEY_d] = SDLK_d;
135 keymap[KEY_f] = SDLK_f;
136 keymap[KEY_g] = SDLK_g;
137 keymap[KEY_h] = SDLK_h;
138 keymap[KEY_j] = SDLK_j;
139 keymap[KEY_k] = SDLK_k;
140 keymap[KEY_l] = SDLK_l;
141 keymap[KEY_SEMICOLON] = SDLK_SEMICOLON;
142 keymap[KEY_QUOTE] = SDLK_QUOTE;
143 keymap[KEY_RETURN] = SDLK_RETURN;
144 keymap[KEY_KP4] = SDLK_KP4;
145 keymap[KEY_KP5] = SDLK_KP5;
146 keymap[KEY_KP6] = SDLK_KP6;
147 keymap[KEY_KP_PLUS] = SDLK_KP_PLUS;
148 keymap[KEY_LSHIFT] = SDLK_LSHIFT;
149 keymap[KEY_RSHIFT] = SDLK_RSHIFT;
150 keymap[KEY_z] = SDLK_z;
151 keymap[KEY_x] = SDLK_x;
152 keymap[KEY_c] = SDLK_c;
153 keymap[KEY_v] = SDLK_v;
154 keymap[KEY_b] = SDLK_b;
155 keymap[KEY_n] = SDLK_n;
156 keymap[KEY_m] = SDLK_m;
157 keymap[KEY_COMMA] = SDLK_COMMA;
158 keymap[KEY_PERIOD] = SDLK_PERIOD;
159 keymap[KEY_SLASH] = SDLK_SLASH;
160 keymap[KEY_UP] = SDLK_UP;
161 keymap[KEY_KP1] = SDLK_KP1;
162 keymap[KEY_KP2] = SDLK_KP2;
163 keymap[KEY_KP3] = SDLK_KP3;
164 keymap[KEY_KP_ENTER] = SDLK_KP_ENTER;
165 keymap[KEY_LCTRL] = SDLK_LCTRL;
166 keymap[KEY_LALT] = SDLK_LALT;
167 keymap[KEY_LMETA] = SDLK_LMETA;
168 keymap[KEY_RCTRL] = SDLK_RCTRL;
169 keymap[KEY_RALT] = SDLK_RALT;
170 keymap[KEY_RMETA] = SDLK_RMETA;
171 keymap[KEY_SPACE] = SDLK_SPACE;
172 keymap[KEY_LEFT] = SDLK_LEFT;
173 keymap[KEY_DOWN] = SDLK_DOWN;
174 keymap[KEY_RIGHT] = SDLK_RIGHT;
175 keymap[KEY_KP0] = SDLK_KP0;
176 keymap[KEY_KP_PERIOD] = SDLK_KP_PERIOD;
177 keymap[KEY_IBOOK_ENTER] = SDLK_KP_ENTER;
178 keymap[KEY_IBOOK_RIGHT] = SDLK_RIGHT;
179 keymap[KEY_IBOOK_DOWN] = SDLK_DOWN;
180 keymap[KEY_IBOOK_UP] = SDLK_UP;
181 keymap[KEY_IBOOK_LEFT] = SDLK_LEFT;
182
183 /*
184 Up there we setup a static scancode->keysym map. However, it will not
185 work very well on international keyboard. Hence we now query Mac OS X
186 for its own keymap to adjust our own mapping table. However, this is
187 basically only useful for ascii char keys. This is also the reason
188 why we keep the static table, too.
189 */
190
191 /* Get a pointer to the systems cached KCHR */
192 KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
193 if (KCHRPtr) {
194 /* Loop over all 127 possible scan codes */
195 for (i = 0; i < 0x7F; i++) {
196 /* We pretend a clean start to begin with (i.e. no dead keys active */
197 state = 0;
198
199 /* Now translate the key code to a key value */
200 value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
201
202 /* If the state become 0, it was a dead key. We need to translate again,
203 passing in the new state, to get the actual key value */
204 if (state != 0)
205 value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
206
207 /* Now we should have a latin1 value, which are SDL keysyms */
208 if (value >= 32 && value <= 255) {
209 keymap[i] = value;
210 }
211 }
212 }
213
214 /*
215 The keypad codes are re-setup here, because the loop above cannot
216 distinguish between a key on the keypad and a regular key. We maybe
217 could get around this problem in another fashion: NSEvent's flags
218 include a "NSNumericPadKeyMask" bit; we could check that and modify
219 the symbol we return on the fly. However, this flag seems to exhibit
220 some weird behaviour related to the num lock key
221 */
222 keymap[KEY_KP0] = SDLK_KP0;
223 keymap[KEY_KP1] = SDLK_KP1;
224 keymap[KEY_KP2] = SDLK_KP2;
225 keymap[KEY_KP3] = SDLK_KP3;
226 keymap[KEY_KP4] = SDLK_KP4;
227 keymap[KEY_KP5] = SDLK_KP5;
228 keymap[KEY_KP6] = SDLK_KP6;
229 keymap[KEY_KP7] = SDLK_KP7;
230 keymap[KEY_KP8] = SDLK_KP8;
231 keymap[KEY_KP9] = SDLK_KP9;
232 keymap[KEY_KP_MINUS] = SDLK_KP_MINUS;
233 keymap[KEY_KP_PLUS] = SDLK_KP_PLUS;
234 keymap[KEY_KP_PERIOD] = SDLK_KP_PERIOD;
235 keymap[KEY_KP_EQUALS] = SDLK_KP_EQUALS;
236 keymap[KEY_KP_DIVIDE] = SDLK_KP_DIVIDE;
237 keymap[KEY_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
238 keymap[KEY_KP_ENTER] = SDLK_KP_ENTER;
239 }
240 56
241 /* This is the original behavior, before support was added for 57 /* This is the original behavior, before support was added for
242 * differentiating between left and right versions of the keys. 58 * differentiating between left and right versions of the keys.
243 */ 59 */
244 static void 60 static void
431 247
432 oldMask = oldMods & NSNumericPadKeyMask; 248 oldMask = oldMods & NSNumericPadKeyMask;
433 newMask = newMods & NSNumericPadKeyMask; 249 newMask = newMods & NSNumericPadKeyMask;
434 250
435 if (oldMask != newMask) { 251 if (oldMask != newMask) {
436 SDL_SendKeyboardKey(keyboard, SDL_PRESSED, (Uint8)scancode, SDLK_NUMLOCK); 252 SDL_SendKeyboardKey(keyboard, SDL_PRESSED, (Uint8)scancode, SDLK_KP_NUMLOCKCLEAR);
437 SDL_SendKeyboardKey(keyboard, SDL_RELEASED, (Uint8)scancode, SDLK_NUMLOCK); 253 SDL_SendKeyboardKey(keyboard, SDL_RELEASED, (Uint8)scancode, SDLK_KP_NUMLOCKCLEAR);
438 } 254 }
439 } 255 }
440 256
441 /* This function will handle the modifier keys and also determine the 257 /* This function will handle the modifier keys and also determine the
442 * correct side of the key. 258 * correct side of the key.
511 { 327 {
512 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 328 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
513 SDL_Keyboard keyboard; 329 SDL_Keyboard keyboard;
514 NSAutoreleasePool *pool; 330 NSAutoreleasePool *pool;
515 331
516 InitKeymap(data->keymap);
517
518 pool = [[NSAutoreleasePool alloc] init]; 332 pool = [[NSAutoreleasePool alloc] init];
519 data->fieldEdit = [[NSTextView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)]; 333 data->fieldEdit = [[NSTextView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)];
520 [pool release]; 334 [pool release];
521 335
522 SDL_zero(keyboard); 336 SDL_zero(keyboard);
523 data->keyboard = SDL_AddKeyboard(&keyboard, -1); 337 data->keyboard = SDL_AddKeyboard(&keyboard, -1);
338
339 /* Set our own names for the platform-dependent but layout-independent keys */
340 SDL_SetKeyName(SDLK_KP_NUMLOCKCLEAR, "clear");
341 SDL_SetKeyName(SDLK_LALT, "left option");
342 SDL_SetKeyName(SDLK_LMETA, "left command");
343 SDL_SetKeyName(SDLK_RALT, "right option");
344 SDL_SetKeyName(SDLK_RMETA, "right command");
524 } 345 }
525 346
526 void 347 void
527 Cocoa_HandleKeyEvent(_THIS, NSEvent *event) 348 Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
528 { 349 {
529 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 350 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
530 unsigned short scancode = [event keyCode]; 351 unsigned short scancode = [event keyCode];
352 SDLKey physicalKey;
531 const char *text; 353 const char *text;
532 354
533 if (scancode >= 256) { 355 if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
356 /* see comments in SDL_cocoakeys.h */
357 scancode = 60 - scancode;
358 }
359 if (scancode < SDL_arraysize(macToSDLKey)) {
360 physicalKey = macToSDLKey[scancode];
361 }
362 else {
534 /* Hmm, does this ever happen? If so, need to extend the keymap... */ 363 /* Hmm, does this ever happen? If so, need to extend the keymap... */
535 return; 364 physicalKey = SDLK_UNKNOWN;
536 } 365 }
537 366
538 switch ([event type]) { 367 switch ([event type]) {
539 case NSKeyDown: 368 case NSKeyDown:
540 if (![event isARepeat]) { 369 if (![event isARepeat]) {
541 SDL_SendKeyboardKey(data->keyboard, SDL_PRESSED, (Uint8)scancode, 370 SDL_SendKeyboardKey(data->keyboard, SDL_PRESSED, (Uint8)scancode, physicalKey);
542 data->keymap[scancode]); 371 #if 1
372 if (physicalKey == SDLK_UNKNOWN) {
373 fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
374 }
375 #endif
543 } 376 }
544 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { 377 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
378 /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */
545 [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; 379 [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
546 text = [[event characters] UTF8String]; 380 text = [[event characters] UTF8String];
547 if(text && *text) { 381 if(text && *text) {
548 SDL_SendKeyboardText(data->keyboard, text); 382 SDL_SendKeyboardText(data->keyboard, text);
549 } 383 }
550 } 384 }
551 break; 385 break;
552 case NSKeyUp: 386 case NSKeyUp:
553 SDL_SendKeyboardKey(data->keyboard, SDL_RELEASED, (Uint8)scancode, 387 SDL_SendKeyboardKey(data->keyboard, SDL_RELEASED, (Uint8)scancode, physicalKey);
554 data->keymap[scancode]);
555 break; 388 break;
556 case NSFlagsChanged: 389 case NSFlagsChanged:
390 /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
557 HandleModifiers(_this, scancode, [event modifierFlags]); 391 HandleModifiers(_this, scancode, [event modifierFlags]);
558 break; 392 break;
393 default: /* just to avoid compiler warnings */
394 break;
395 }
396 }
397
398 SDLKey
399 Cocoa_GetLayoutKey(_THIS, SDLKey physicalKey)
400 {
401 switch (physicalKey) {
402 /* Many of these keys would generate a character in the translation by keyboard layout, but an inappropriate one, so we catch them before. */
403 case SDLK_UNKNOWN:
404 case SDLK_RETURN:
405 case SDLK_ESCAPE:
406 case SDLK_BACKSPACE:
407 case SDLK_TAB:
408 case SDLK_SPACE:
409 case SDLK_CAPSLOCK:
410 case SDLK_F1:
411 case SDLK_F2:
412 case SDLK_F3:
413 case SDLK_F4:
414 case SDLK_F5:
415 case SDLK_F6:
416 case SDLK_F7:
417 case SDLK_F8:
418 case SDLK_F9:
419 case SDLK_F10:
420 case SDLK_F11:
421 case SDLK_F12:
422 case SDLK_PRINTSCREEN:
423 case SDLK_SCROLLLOCK:
424 case SDLK_PAUSE:
425 case SDLK_INSERT:
426 case SDLK_HOME:
427 case SDLK_PAGEUP:
428 case SDLK_DELETE:
429 case SDLK_END:
430 case SDLK_PAGEDOWN:
431 case SDLK_RIGHT:
432 case SDLK_LEFT:
433 case SDLK_DOWN:
434 case SDLK_UP:
435 case SDLK_KP_NUMLOCKCLEAR:
436 case SDLK_KP_ENTER:
437 case SDLK_APPLICATION:
438 case SDLK_POWER:
439 case SDLK_F13:
440 case SDLK_F14:
441 case SDLK_F15:
442 case SDLK_F16:
443 case SDLK_LCTRL:
444 case SDLK_LSHIFT:
445 case SDLK_LALT:
446 case SDLK_LMETA:
447 case SDLK_RCTRL:
448 case SDLK_RSHIFT:
449 case SDLK_RALT:
450 case SDLK_RMETA:
451 return physicalKey;
452
453 /* For the rest, we try the translation first. */
454 default: {
455 UInt16 vkey = 0;
456 KeyboardLayoutRef layout;
457 KeyboardLayoutKind kind;
458 UInt32 keyboardType = LMGetKbdType();
459
460 /* Look up pkey to get a Mac virtual key code - linear search isn't terribly efficient, this might have to be optimized. */
461 while (vkey < 128 && physicalKey != macToSDLKey[vkey]) vkey++;
462 if (vkey == 128) return physicalKey;
463 if ((vkey == 10 || vkey == 50) && KBGetLayoutType(keyboardType) == kKeyboardISO) vkey = 60 - vkey; /* see comments in SDL_cocoakeys.h */
464
465 if (KLGetCurrentKeyboardLayout(&layout) != noErr) return physicalKey;
466 if (KLGetKeyboardLayoutProperty(layout, kKLKind, (const void **)&kind) != noErr) return physicalKey;
467 if (kind == kKLKCHRuchrKind || kind == kKLuchrKind) {
468 UniChar utf16String[4];
469 UInt32 deadKeyState = 0;
470 UniCharCount actualStringLength;
471 const UCKeyboardLayout *uchrData;
472
473 if (KLGetKeyboardLayoutProperty(layout, kKLuchrData, (const void **)&uchrData) != noErr) return physicalKey;
474 if (UCKeyTranslate(uchrData, vkey, kUCKeyActionDisplay, 0, keyboardType, 0, &deadKeyState, 4, &actualStringLength, utf16String) != noErr) return physicalKey;
475 /* kUCKeyActionDisplay (instead of kUCKeyActionDown) seems to take care of dead keys, so no need to check for that case and simulate a second key press */
476
477 if (actualStringLength == 0) return physicalKey;
478
479 /* Decode the first character from UTF-16. I'm not sure if this is appropriate for keyboard layouts that generate more than 1 character, or if we would have to use SDL_KEY_LAYOUT_SPECIAL_BIT in that case. */
480 if (utf16String[0] < 0xD800 || utf16String[0] > 0xDFFF) {
481 return utf16String[0];
482 }
483 else if (utf16String[0] > 0xDBFF || utf16String[1] < 0xDC00 || utf16String[1] > 0xDFFF) {
484 /* invalid UTF-16 */
485 return physicalKey;
486 }
487 else {
488 return (((utf16String[0] & 0x3FF) << 10) | (utf16String[1] & 0x3FF)) + 0x10000;
489 }
490 }
491 else { /* kind == kKLKCHRKind */
492 const void *kchrData;
493 UInt32 state = 0;
494 UInt8 charCode;
495 SInt32 scriptCode;
496 TextEncoding keyboardEncoding;
497 CFStringRef conversionString;
498 UniChar codepoint;
499
500 if (KLGetKeyboardLayoutProperty(layout, kKLKCHRData, &kchrData) != noErr) return physicalKey;
501 charCode = KeyTranslate(kchrData, vkey, &state) & 0xFF; /* Actually returns a UInt32 containing two character codes (and two 'reserved' bytes), but we're only interested in the second (or only) one */
502 if (charCode == 0) {
503 /* It's a dead key, so simulate a second key press */
504 charCode = KeyTranslate(kchrData, vkey, &state) & 0xFF;
505 /* Still zero? Give up. */
506 if (charCode == 0) return physicalKey;
507 }
508 if (KLGetKeyboardLayoutProperty(layout, kKLGroupIdentifier, (const void **)&scriptCode) != noErr) return physicalKey; /* That the group identifier is actually a script code is not documented, but confirmed here: <http://lists.apple.com/archives/carbon-dev/2005/Jan/msg00533.html> */
509 if (UpgradeScriptInfoToTextEncoding(scriptCode, kTextLanguageDontCare, kTextRegionDontCare, NULL, &keyboardEncoding) != noErr) return physicalKey;
510
511 conversionString = CFStringCreateWithBytes(kCFAllocatorDefault, &charCode, 1, keyboardEncoding, FALSE);
512 codepoint = CFStringGetCharacterAtIndex(conversionString, 0);
513 CFRelease(conversionString);
514 return codepoint;
515 }
516 }
559 } 517 }
560 } 518 }
561 519
562 void 520 void
563 Cocoa_QuitKeyboard(_THIS) 521 Cocoa_QuitKeyboard(_THIS)