src/video/cocoa/SDL_cocoakeyboard.m
author Jiang Jiang
Mon, 25 May 2009 02:42:45 +0000
branchgsoc2009_IME
changeset 3127 da6cbfa5b5f2
parent 2859 99210400e8b9
child 3129 e42873b9c6f1
permissions -rw-r--r--
Get basic text input support working for Cocoa
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_cocoavideo.h"
    25 
    26 #include "../../events/SDL_keyboard_c.h"
    27 #include "../../events/scancodes_darwin.h"
    28 
    29 #include <Carbon/Carbon.h>
    30 
    31 
    32 #ifndef NX_DEVICERCTLKEYMASK
    33     #define NX_DEVICELCTLKEYMASK    0x00000001
    34 #endif
    35 #ifndef NX_DEVICELSHIFTKEYMASK
    36     #define NX_DEVICELSHIFTKEYMASK  0x00000002
    37 #endif
    38 #ifndef NX_DEVICERSHIFTKEYMASK
    39     #define NX_DEVICERSHIFTKEYMASK  0x00000004
    40 #endif
    41 #ifndef NX_DEVICELCMDKEYMASK
    42     #define NX_DEVICELCMDKEYMASK    0x00000008
    43 #endif
    44 #ifndef NX_DEVICERCMDKEYMASK
    45     #define NX_DEVICERCMDKEYMASK    0x00000010
    46 #endif
    47 #ifndef NX_DEVICELALTKEYMASK
    48     #define NX_DEVICELALTKEYMASK    0x00000020
    49 #endif
    50 #ifndef NX_DEVICERALTKEYMASK
    51     #define NX_DEVICERALTKEYMASK    0x00000040
    52 #endif
    53 #ifndef NX_DEVICERCTLKEYMASK
    54     #define NX_DEVICERCTLKEYMASK    0x00002000
    55 #endif
    56 
    57 @interface SDLTranslatorResponder : NSTextView
    58 {
    59 }
    60 - (void) doCommandBySelector:(SEL)myselector;
    61 @end
    62 
    63 @implementation SDLTranslatorResponder
    64 
    65 - (void) insertText:(id) aString
    66 {
    67     const char *str;
    68 
    69     NSLog(@"insertText: %@", aString);
    70 
    71     if ([aString isKindOfClass: [NSAttributedString class]])
    72         str = [[aString string] UTF8String];
    73     else
    74         str = [aString UTF8String];
    75 
    76     SDL_SendKeyboardText(0, str);
    77 }
    78 
    79 - (void) doCommandBySelector:(SEL) myselector
    80 {
    81     NSLog(@"doCommandBySelector, passed down");
    82     [super doCommandBySelector: myselector];
    83 }
    84 @end
    85 
    86 /* This is the original behavior, before support was added for 
    87  * differentiating between left and right versions of the keys.
    88  */
    89 static void
    90 DoUnsidedModifiers(int keyboard, unsigned short scancode,
    91                    unsigned int oldMods, unsigned int newMods)
    92 {
    93     const int mapping[] = {
    94         SDL_SCANCODE_CAPSLOCK,
    95         SDL_SCANCODE_LSHIFT,
    96         SDL_SCANCODE_LCTRL,
    97         SDL_SCANCODE_LALT,
    98         SDL_SCANCODE_LGUI
    99     };
   100     unsigned int i, bit;
   101 
   102     /* Iterate through the bits, testing each against the current modifiers */
   103     for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
   104         unsigned int oldMask, newMask;
   105 
   106         oldMask = oldMods & bit;
   107         newMask = newMods & bit;
   108 
   109         if (oldMask && oldMask != newMask) {        /* modifier up event */
   110             /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
   111             if (bit == NSAlphaShiftKeyMask) {
   112                 SDL_SendKeyboardKey(keyboard, SDL_PRESSED, mapping[i]);
   113             }
   114             SDL_SendKeyboardKey(keyboard, SDL_RELEASED, mapping[i]);
   115         } else if (newMask && oldMask != newMask) { /* modifier down event */
   116             SDL_SendKeyboardKey(keyboard, SDL_PRESSED, mapping[i]);
   117             /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
   118             if (bit == NSAlphaShiftKeyMask) {
   119                 SDL_SendKeyboardKey(keyboard, SDL_RELEASED, mapping[i]);
   120             }
   121         }
   122     }
   123 }
   124 
   125 /* This is a helper function for HandleModifierSide. This 
   126  * function reverts back to behavior before the distinction between
   127  * sides was made.
   128  */
   129 static void
   130 HandleNonDeviceModifier(int keyboard,
   131                         unsigned int device_independent_mask,
   132                         unsigned int oldMods,
   133                         unsigned int newMods,
   134                         SDL_scancode scancode)
   135 {
   136     unsigned int oldMask, newMask;
   137     
   138     /* Isolate just the bits we care about in the depedent bits so we can 
   139      * figure out what changed
   140      */ 
   141     oldMask = oldMods & device_independent_mask;
   142     newMask = newMods & device_independent_mask;
   143     
   144     if (oldMask && oldMask != newMask) {
   145         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, scancode);
   146     } else if (newMask && oldMask != newMask) {
   147         SDL_SendKeyboardKey(keyboard, SDL_PRESSED, scancode);
   148     }
   149 }
   150 
   151 /* This is a helper function for HandleModifierSide. 
   152  * This function sets the actual SDL_PrivateKeyboard event.
   153  */
   154 static void
   155 HandleModifierOneSide(int keyboard,
   156                       unsigned int oldMods, unsigned int newMods,
   157                       SDL_scancode scancode, 
   158                       unsigned int sided_device_dependent_mask)
   159 {
   160     unsigned int old_dep_mask, new_dep_mask;
   161 
   162     /* Isolate just the bits we care about in the depedent bits so we can 
   163      * figure out what changed
   164      */ 
   165     old_dep_mask = oldMods & sided_device_dependent_mask;
   166     new_dep_mask = newMods & sided_device_dependent_mask;
   167 
   168     /* We now know that this side bit flipped. But we don't know if
   169      * it went pressed to released or released to pressed, so we must 
   170      * find out which it is.
   171      */
   172     if (new_dep_mask && old_dep_mask != new_dep_mask) {
   173         SDL_SendKeyboardKey(keyboard, SDL_PRESSED, scancode);
   174     } else {
   175         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, scancode);
   176     }
   177 }
   178 
   179 /* This is a helper function for DoSidedModifiers.
   180  * This function will figure out if the modifier key is the left or right side, 
   181  * e.g. left-shift vs right-shift. 
   182  */
   183 static void
   184 HandleModifierSide(int keyboard,
   185                    int device_independent_mask, 
   186                    unsigned int oldMods, unsigned int newMods, 
   187                    SDL_scancode left_scancode, 
   188                    SDL_scancode right_scancode,
   189                    unsigned int left_device_dependent_mask, 
   190                    unsigned int right_device_dependent_mask)
   191 {
   192     unsigned int device_dependent_mask = (left_device_dependent_mask |
   193                                          right_device_dependent_mask);
   194     unsigned int diff_mod;
   195     
   196     /* On the basis that the device independent mask is set, but there are 
   197      * no device dependent flags set, we'll assume that we can't detect this 
   198      * keyboard and revert to the unsided behavior.
   199      */
   200     if ((device_dependent_mask & newMods) == 0) {
   201         /* Revert to the old behavior */
   202         HandleNonDeviceModifier(keyboard, device_independent_mask, oldMods, newMods, left_scancode);
   203         return;
   204     }
   205 
   206     /* XOR the previous state against the new state to see if there's a change */
   207     diff_mod = (device_dependent_mask & oldMods) ^
   208                (device_dependent_mask & newMods);
   209     if (diff_mod) {
   210         /* A change in state was found. Isolate the left and right bits 
   211          * to handle them separately just in case the values can simulataneously
   212          * change or if the bits don't both exist.
   213          */
   214         if (left_device_dependent_mask & diff_mod) {
   215             HandleModifierOneSide(keyboard, oldMods, newMods, left_scancode, left_device_dependent_mask);
   216         }
   217         if (right_device_dependent_mask & diff_mod) {
   218             HandleModifierOneSide(keyboard, oldMods, newMods, right_scancode, right_device_dependent_mask);
   219         }
   220     }
   221 }
   222    
   223 /* This is a helper function for DoSidedModifiers.
   224  * This function will release a key press in the case that 
   225  * it is clear that the modifier has been released (i.e. one side 
   226  * can't still be down).
   227  */
   228 static void
   229 ReleaseModifierSide(int keyboard,
   230                     unsigned int device_independent_mask, 
   231                     unsigned int oldMods, unsigned int newMods,
   232                     SDL_scancode left_scancode, 
   233                     SDL_scancode right_scancode,
   234                     unsigned int left_device_dependent_mask, 
   235                     unsigned int right_device_dependent_mask)
   236 {
   237     unsigned int device_dependent_mask = (left_device_dependent_mask |
   238                                           right_device_dependent_mask);
   239 
   240     /* On the basis that the device independent mask is set, but there are 
   241      * no device dependent flags set, we'll assume that we can't detect this 
   242      * keyboard and revert to the unsided behavior.
   243      */
   244     if ((device_dependent_mask & oldMods) == 0) {
   245         /* In this case, we can't detect the keyboard, so use the left side 
   246          * to represent both, and release it. 
   247          */
   248         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, left_scancode);
   249         return;
   250     }
   251 
   252     /* 
   253      * This could have been done in an if-else case because at this point,
   254      * we know that all keys have been released when calling this function. 
   255      * But I'm being paranoid so I want to handle each separately,
   256      * so I hope this doesn't cause other problems.
   257      */
   258     if ( left_device_dependent_mask & oldMods ) {
   259         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, left_scancode);
   260     }
   261     if ( right_device_dependent_mask & oldMods ) {
   262         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, right_scancode);
   263     }
   264 }
   265 
   266 /* This is a helper function for DoSidedModifiers.
   267  * This function handles the CapsLock case.
   268  */
   269 static void
   270 HandleCapsLock(int keyboard, unsigned short scancode,
   271                unsigned int oldMods, unsigned int newMods)
   272 {
   273     unsigned int oldMask, newMask;
   274     
   275     oldMask = oldMods & NSAlphaShiftKeyMask;
   276     newMask = newMods & NSAlphaShiftKeyMask;
   277 
   278     if (oldMask != newMask) {
   279         SDL_SendKeyboardKey(keyboard, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
   280         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
   281     }
   282 
   283     oldMask = oldMods & NSNumericPadKeyMask;
   284     newMask = newMods & NSNumericPadKeyMask;
   285 
   286     if (oldMask != newMask) {
   287         SDL_SendKeyboardKey(keyboard, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
   288         SDL_SendKeyboardKey(keyboard, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
   289     }
   290 }
   291 
   292 /* This function will handle the modifier keys and also determine the 
   293  * correct side of the key.
   294  */
   295 static void
   296 DoSidedModifiers(int keyboard, unsigned short scancode,
   297                  unsigned int oldMods, unsigned int newMods)
   298 {
   299 	/* Set up arrays for the key syms for the left and right side. */
   300     const SDL_scancode left_mapping[]  = {
   301         SDL_SCANCODE_LSHIFT,
   302         SDL_SCANCODE_LCTRL,
   303         SDL_SCANCODE_LALT,
   304         SDL_SCANCODE_LGUI
   305     };
   306     const SDL_scancode right_mapping[] = {
   307         SDL_SCANCODE_RSHIFT,
   308         SDL_SCANCODE_RCTRL,
   309         SDL_SCANCODE_RALT,
   310         SDL_SCANCODE_RGUI
   311     };
   312 	/* Set up arrays for the device dependent masks with indices that 
   313      * correspond to the _mapping arrays 
   314      */
   315     const unsigned int left_device_mapping[]  = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
   316     const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
   317 
   318     unsigned int i, bit;
   319 
   320     /* Handle CAPSLOCK separately because it doesn't have a left/right side */
   321     HandleCapsLock(keyboard, scancode, oldMods, newMods);
   322 
   323     /* Iterate through the bits, testing each against the old modifiers */
   324     for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
   325         unsigned int oldMask, newMask;
   326 		
   327         oldMask = oldMods & bit;
   328         newMask = newMods & bit;
   329 		
   330         /* If the bit is set, we must always examine it because the left
   331          * and right side keys may alternate or both may be pressed.
   332          */
   333         if (newMask) {
   334             HandleModifierSide(keyboard, bit, oldMods, newMods,
   335                                left_mapping[i], right_mapping[i],
   336                                left_device_mapping[i], right_device_mapping[i]);
   337         }
   338         /* If the state changed from pressed to unpressed, we must examine
   339             * the device dependent bits to release the correct keys.
   340             */
   341         else if (oldMask && oldMask != newMask) {
   342             ReleaseModifierSide(keyboard, bit, oldMods, newMods,
   343                               left_mapping[i], right_mapping[i],
   344                               left_device_mapping[i], right_device_mapping[i]);
   345         }
   346     }
   347 }
   348 
   349 static void
   350 HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
   351 {
   352     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   353 
   354     if (modifierFlags == data->modifierFlags) {
   355     	return;
   356     }
   357 
   358     /* 
   359      * Starting with Panther (10.3.0), the ability to distinguish between 
   360      * left side and right side modifiers is available.
   361      */
   362     if (data->osversion >= 0x1030) {
   363         DoSidedModifiers(data->keyboard, scancode, data->modifierFlags, modifierFlags);
   364     } else {
   365         DoUnsidedModifiers(data->keyboard, scancode, data->modifierFlags, modifierFlags);
   366     }
   367     data->modifierFlags = modifierFlags;
   368 }
   369 
   370 static void
   371 UpdateKeymap(SDL_VideoData *data)
   372 {
   373     KeyboardLayoutRef key_layout;
   374     const void *chr_data;
   375     int i;
   376     SDL_scancode scancode;
   377     SDLKey keymap[SDL_NUM_SCANCODES];
   378 
   379     /* See if the keymap needs to be updated */
   380     KLGetCurrentKeyboardLayout(&key_layout);
   381     if (key_layout == data->key_layout) {
   382         return;
   383     }
   384     data->key_layout = key_layout;
   385 
   386     SDL_GetDefaultKeymap(keymap);
   387 
   388     /* Try Unicode data first (preferred as of Mac OS X 10.5) */
   389     KLGetKeyboardLayoutProperty(key_layout, kKLuchrData, &chr_data);
   390     if (chr_data) {
   391         UInt32 keyboard_type = LMGetKbdType();
   392         OSStatus err;
   393 
   394         for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) {
   395             UniChar s[8];
   396             UniCharCount len;
   397             UInt32 dead_key_state;
   398 
   399             /* Make sure this scancode is a valid character scancode */
   400             scancode = darwin_scancode_table[i];
   401             if (scancode == SDL_SCANCODE_UNKNOWN ||
   402                 (keymap[scancode] & SDLK_SCANCODE_MASK)) {
   403                 continue;
   404             }
   405 
   406             dead_key_state = 0;
   407             err = UCKeyTranslate (chr_data, i, kUCKeyActionDown,
   408                                   0, keyboard_type,
   409                                   kUCKeyTranslateNoDeadKeysMask,
   410                                   &dead_key_state, 8, &len, s);
   411             if (err != noErr)
   412                 continue;
   413 
   414             if (len > 0 && s[0] != 0x10) {
   415                 keymap[scancode] = s[0];
   416             }
   417         }
   418         SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES);
   419         return;
   420     }
   421 
   422     /* Fall back to older style key map data */
   423     KLGetKeyboardLayoutProperty(key_layout, kKLKCHRData, &chr_data);
   424     if (chr_data) {
   425         for (i = 0; i < 128; i++) {
   426             UInt32 c, state = 0;
   427 
   428             /* Make sure this scancode is a valid character scancode */
   429             scancode = darwin_scancode_table[i];
   430             if (scancode == SDL_SCANCODE_UNKNOWN ||
   431                 (keymap[scancode] & SDLK_SCANCODE_MASK)) {
   432                 continue;
   433             }
   434 
   435             c = KeyTranslate (chr_data, i, &state) & 255;
   436             if (state) {
   437                 /* Dead key, process key up */
   438                 c = KeyTranslate (chr_data, i | 128, &state) & 255;
   439             }
   440 
   441             if (c != 0 && c != 0x10) {
   442                 /* MacRoman to Unicode table, taken from X.org sources */
   443                 static const unsigned short macroman_table[128] = {
   444                     0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
   445                     0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
   446                     0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
   447                     0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
   448                     0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf,
   449                     0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8,
   450                     0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211,
   451                     0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8,
   452                     0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab,
   453                     0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153,
   454                     0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca,
   455                     0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
   456                     0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1,
   457                     0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
   458                     0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc,
   459                     0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7,
   460                 };
   461 
   462                 if (c >= 128) {
   463                     c = macroman_table[c - 128];
   464                 }
   465                 keymap[scancode] = c;
   466             }
   467         }
   468         SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES);
   469         return;
   470     }
   471 }
   472 
   473 void
   474 Cocoa_InitKeyboard(_THIS)
   475 {
   476     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   477     SDL_Keyboard keyboard;
   478     NSAutoreleasePool *pool;
   479 
   480     pool = [[NSAutoreleasePool alloc] init];
   481     data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)];
   482     [pool release];
   483     
   484     SDL_zero(keyboard);
   485     data->keyboard = SDL_AddKeyboard(&keyboard, -1);
   486     UpdateKeymap(data);
   487     
   488     /* Set our own names for the platform-dependent but layout-independent keys */
   489     /* This key is NumLock on the MacBook keyboard. :) */
   490     /*SDL_SetScancodeName(SDL_SCANCODE_NUMLOCKCLEAR, "Clear");*/
   491     SDL_SetScancodeName(SDL_SCANCODE_LALT, "Left Option");
   492     SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Command");
   493     SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
   494     SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
   495 }
   496 
   497 void
   498 Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
   499 {
   500     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   501     unsigned short scancode = [event keyCode];
   502     SDL_scancode code;
   503     const char *text;
   504 
   505     if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
   506         /* see comments in SDL_cocoakeys.h */
   507         scancode = 60 - scancode;
   508     }
   509     if (scancode < SDL_arraysize(darwin_scancode_table)) {
   510         code = darwin_scancode_table[scancode];
   511     }
   512     else {
   513         /* Hmm, does this ever happen?  If so, need to extend the keymap... */
   514         code = SDL_SCANCODE_UNKNOWN;
   515     }
   516 
   517     switch ([event type]) {
   518     case NSKeyDown:
   519         if (![event isARepeat]) {
   520             /* See if we need to rebuild the keyboard layout */
   521             UpdateKeymap(data);
   522 
   523             SDL_SendKeyboardKey(data->keyboard, SDL_PRESSED, code);
   524 #if 1
   525             if (code == SDL_SCANCODE_UNKNOWN) {
   526                 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);
   527             }
   528 #endif
   529         }
   530         if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   531             /* 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. */
   532             NSLog(@"interpretKeyEvents");
   533             if (! [[data->fieldEdit superview] isEqual: [[event window] contentView]])
   534             {
   535                 NSLog(@"add fieldEdit to window contentView");
   536                 [data->fieldEdit removeFromSuperview];
   537                 [[[event window] contentView] addSubview: data->fieldEdit];
   538                 [[event window] makeFirstResponder: data->fieldEdit];
   539             }
   540             [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
   541 #if 0
   542             text = [[event characters] UTF8String];
   543             if(text && *text) {
   544                 SDL_SendKeyboardText(data->keyboard, text);
   545                 [data->fieldEdit setString:@""];
   546             }
   547 #endif
   548         }
   549         break;
   550     case NSKeyUp:
   551         SDL_SendKeyboardKey(data->keyboard, SDL_RELEASED, code);
   552         break;
   553     case NSFlagsChanged:
   554         /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
   555         HandleModifiers(_this, scancode, [event modifierFlags]);
   556         break;
   557     default: /* just to avoid compiler warnings */
   558         break;
   559     }
   560 }
   561 
   562 void
   563 Cocoa_QuitKeyboard(_THIS)
   564 {
   565     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   566     NSAutoreleasePool *pool;
   567 
   568     SDL_DelKeyboard(data->keyboard);
   569 
   570     pool = [[NSAutoreleasePool alloc] init];
   571     [data->fieldEdit release];
   572     [pool release];
   573 }
   574 
   575 /* vi: set ts=4 sw=4 expandtab: */