llkeyboardmacosx.cpp

Go to the documentation of this file.
00001 
00032 #if LL_DARWIN
00033 
00034 #include "linden_common.h"
00035 #include "llkeyboardmacosx.h"
00036 #include "llwindow.h"
00037 
00038 #include <Carbon/Carbon.h>
00039 
00040 LLKeyboardMacOSX::LLKeyboardMacOSX()
00041 {
00042         // Virtual keycode mapping table.  Yes, this was as annoying to generate as it looks.
00043         mTranslateKeyMap[0x00] = 'A';
00044         mTranslateKeyMap[0x01] = 'S';
00045         mTranslateKeyMap[0x02] = 'D';
00046         mTranslateKeyMap[0x03] = 'F';
00047         mTranslateKeyMap[0x04] = 'H';
00048         mTranslateKeyMap[0x05] = 'G';
00049         mTranslateKeyMap[0x06] = 'Z';
00050         mTranslateKeyMap[0x07] = 'X';
00051         mTranslateKeyMap[0x08] = 'C';
00052         mTranslateKeyMap[0x09] = 'V';
00053         mTranslateKeyMap[0x0b] = 'B';
00054         mTranslateKeyMap[0x0c] = 'Q';
00055         mTranslateKeyMap[0x0d] = 'W';
00056         mTranslateKeyMap[0x0e] = 'E';
00057         mTranslateKeyMap[0x0f] = 'R';
00058         mTranslateKeyMap[0x10] = 'Y';
00059         mTranslateKeyMap[0x11] = 'T';
00060         mTranslateKeyMap[0x12] = '1';
00061         mTranslateKeyMap[0x13] = '2';
00062         mTranslateKeyMap[0x14] = '3';
00063         mTranslateKeyMap[0x15] = '4';
00064         mTranslateKeyMap[0x16] = '6';
00065         mTranslateKeyMap[0x17] = '5';
00066         mTranslateKeyMap[0x18] = '=';   // KEY_EQUALS
00067         mTranslateKeyMap[0x19] = '9';
00068         mTranslateKeyMap[0x1a] = '7';
00069         mTranslateKeyMap[0x1b] = '-';   // KEY_HYPHEN
00070         mTranslateKeyMap[0x1c] = '8';
00071         mTranslateKeyMap[0x1d] = '0';
00072         mTranslateKeyMap[0x1e] = ']';
00073         mTranslateKeyMap[0x1f] = 'O';
00074         mTranslateKeyMap[0x20] = 'U';
00075         mTranslateKeyMap[0x21] = '[';
00076         mTranslateKeyMap[0x22] = 'I';
00077         mTranslateKeyMap[0x23] = 'P';
00078         mTranslateKeyMap[0x24] = KEY_RETURN,
00079         mTranslateKeyMap[0x25] = 'L';
00080         mTranslateKeyMap[0x26] = 'J';
00081         mTranslateKeyMap[0x27] = '\'';
00082         mTranslateKeyMap[0x28] = 'K';
00083         mTranslateKeyMap[0x29] = ';';
00084         mTranslateKeyMap[0x2a] = '\\';
00085         mTranslateKeyMap[0x2b] = ',';
00086         mTranslateKeyMap[0x2c] = KEY_DIVIDE;
00087         mTranslateKeyMap[0x2d] = 'N';
00088         mTranslateKeyMap[0x2e] = 'M';
00089         mTranslateKeyMap[0x2f] = '.';
00090         mTranslateKeyMap[0x30] = KEY_TAB;
00091         mTranslateKeyMap[0x31] = ' ';   // space!
00092         mTranslateKeyMap[0x32] = '`';
00093         mTranslateKeyMap[0x33] = KEY_BACKSPACE;
00094         mTranslateKeyMap[0x35] = KEY_ESCAPE;
00095         //mTranslateKeyMap[0x37] = 0;   // Command key.  (not used yet)
00096         mTranslateKeyMap[0x38] = KEY_SHIFT;
00097         mTranslateKeyMap[0x39] = KEY_CAPSLOCK;
00098         mTranslateKeyMap[0x3a] = KEY_ALT;
00099         mTranslateKeyMap[0x3b] = KEY_CONTROL;
00100         mTranslateKeyMap[0x41] = '.';   // keypad
00101         mTranslateKeyMap[0x43] = '*';   // keypad
00102         mTranslateKeyMap[0x45] = '+';   // keypad
00103         mTranslateKeyMap[0x4b] = KEY_PAD_DIVIDE;        // keypad
00104         mTranslateKeyMap[0x4c] = KEY_RETURN;    // keypad enter
00105         mTranslateKeyMap[0x4e] = '-';   // keypad
00106         mTranslateKeyMap[0x51] = '=';   // keypad
00107         mTranslateKeyMap[0x52] = '0';   // keypad
00108         mTranslateKeyMap[0x53] = '1';   // keypad
00109         mTranslateKeyMap[0x54] = '2';   // keypad
00110         mTranslateKeyMap[0x55] = '3';   // keypad
00111         mTranslateKeyMap[0x56] = '4';   // keypad
00112         mTranslateKeyMap[0x57] = '5';   // keypad
00113         mTranslateKeyMap[0x58] = '6';   // keypad
00114         mTranslateKeyMap[0x59] = '7';   // keypad
00115         mTranslateKeyMap[0x5b] = '8';   // keypad
00116         mTranslateKeyMap[0x5c] = '9';   // keypad
00117         mTranslateKeyMap[0x60] = KEY_F5;
00118         mTranslateKeyMap[0x61] = KEY_F6;
00119         mTranslateKeyMap[0x62] = KEY_F7;
00120         mTranslateKeyMap[0x63] = KEY_F3;
00121         mTranslateKeyMap[0x64] = KEY_F8;
00122         mTranslateKeyMap[0x65] = KEY_F9;
00123         mTranslateKeyMap[0x67] = KEY_F11;
00124         mTranslateKeyMap[0x6d] = KEY_F10;
00125         mTranslateKeyMap[0x6f] = KEY_F12;
00126         mTranslateKeyMap[0x72] = KEY_INSERT;
00127         mTranslateKeyMap[0x73] = KEY_HOME;
00128         mTranslateKeyMap[0x74] = KEY_PAGE_UP;
00129         mTranslateKeyMap[0x75] = KEY_DELETE;
00130         mTranslateKeyMap[0x76] = KEY_F4;
00131         mTranslateKeyMap[0x77] = KEY_END;
00132         mTranslateKeyMap[0x78] = KEY_F2;
00133         mTranslateKeyMap[0x79] = KEY_PAGE_DOWN;
00134         mTranslateKeyMap[0x7a] = KEY_F1;
00135         mTranslateKeyMap[0x7b] = KEY_LEFT;
00136         mTranslateKeyMap[0x7c] = KEY_RIGHT;
00137         mTranslateKeyMap[0x7d] = KEY_DOWN;
00138         mTranslateKeyMap[0x7e] = KEY_UP;
00139 
00140         // Build inverse map
00141         std::map<U16, KEY>::iterator iter;
00142         for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
00143         {
00144                 mInvTranslateKeyMap[iter->second] = iter->first;
00145         }
00146         
00147         // build numpad maps
00148         mTranslateNumpadMap[0x52] = KEY_PAD_INS;    // keypad 0
00149         mTranslateNumpadMap[0x53] = KEY_PAD_END;   // keypad 1
00150         mTranslateNumpadMap[0x54] = KEY_PAD_DOWN;       // keypad 2
00151         mTranslateNumpadMap[0x55] = KEY_PAD_PGDN;       // keypad 3
00152         mTranslateNumpadMap[0x56] = KEY_PAD_LEFT;       // keypad 4
00153         mTranslateNumpadMap[0x57] = KEY_PAD_CENTER;     // keypad 5
00154         mTranslateNumpadMap[0x58] = KEY_PAD_RIGHT;      // keypad 6
00155         mTranslateNumpadMap[0x59] = KEY_PAD_HOME;       // keypad 7
00156         mTranslateNumpadMap[0x5b] = KEY_PAD_UP;         // keypad 8
00157         mTranslateNumpadMap[0x5c] = KEY_PAD_PGUP;       // keypad 9
00158         mTranslateNumpadMap[0x41] = KEY_PAD_DEL;        // keypad .
00159         mTranslateNumpadMap[0x4c] = KEY_PAD_RETURN;     // keypad enter
00160         
00161         // Build inverse numpad map
00162         for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++)
00163         {
00164                 mInvTranslateNumpadMap[iter->second] = iter->first;
00165         }
00166 }
00167 
00168 void LLKeyboardMacOSX::resetMaskKeys()
00169 {
00170         U32 mask = GetCurrentEventKeyModifiers();
00171 
00172         // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
00173         //    It looks a bit suspicious, as it won't correct for keys that have been released.
00174         //    Is this the way it's supposed to work?
00175 
00176         if(mask & shiftKey)
00177         {
00178                 mKeyLevel[KEY_SHIFT] = TRUE;
00179         }
00180 
00181         if(mask & (controlKey))
00182         {
00183                 mKeyLevel[KEY_CONTROL] = TRUE;
00184         }
00185 
00186         if(mask & optionKey)
00187         {
00188                 mKeyLevel[KEY_ALT] = TRUE;
00189         }
00190 }
00191 
00192 /*
00193 static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &outMask)
00194 {
00195         // Translate the virtual keycode into the keycodes the keyboard system expects.
00196         U16 virtualKey = (mask >> 24) & 0x0000007F;
00197         outKey = macKeyTransArray[virtualKey];
00198 
00199 
00200         return(outKey != 0);
00201 }
00202 */
00203 
00204 MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
00205 {
00206         // translate the mask
00207         MASK out_mask = 0;
00208 
00209         if(mask & shiftKey)
00210         {
00211                 out_mask |= MASK_SHIFT;
00212         }
00213 
00214         if(mask & (controlKey | cmdKey))
00215         {
00216                 out_mask |= MASK_CONTROL;
00217         }
00218 
00219         if(mask & optionKey)
00220         {
00221                 out_mask |= MASK_ALT;
00222         }
00223 
00224         return out_mask;
00225 }
00226 
00227 BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
00228 {
00229         KEY             translated_key = 0;
00230         U32             translated_mask = 0;
00231         BOOL    handled = FALSE;
00232 
00233         translated_mask = updateModifiers(mask);
00234 
00235         if(translateNumpadKey(key, &translated_key))
00236         {
00237                 handled = handleTranslatedKeyDown(translated_key, translated_mask);
00238         }
00239 
00240         return handled;
00241 }
00242 
00243 
00244 BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
00245 {
00246         KEY             translated_key = 0;
00247         U32             translated_mask = 0;
00248         BOOL    handled = FALSE;
00249 
00250         translated_mask = updateModifiers(mask);
00251 
00252         if(translateNumpadKey(key, &translated_key))
00253         {
00254                 handled = handleTranslatedKeyUp(translated_key, translated_mask);
00255         }
00256 
00257         return handled;
00258 }
00259 
00260 MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
00261 {
00262         MASK result = MASK_NONE;
00263         U32 mask = GetCurrentEventKeyModifiers();
00264 
00265         if (mask & shiftKey)                    result |= MASK_SHIFT;
00266         if (mask & controlKey)                  result |= MASK_CONTROL;
00267         if (mask & optionKey)                   result |= MASK_ALT;
00268 
00269         // For keyboard events, consider Command equivalent to Control
00270         if (!for_mouse_event)
00271         {
00272                 if (mask & cmdKey) result |= MASK_CONTROL;
00273         }
00274 
00275         return result;
00276 }
00277 
00278 void LLKeyboardMacOSX::scanKeyboard()
00279 {
00280         S32 key;
00281         for (key = 0; key < KEY_COUNT; key++)
00282         {
00283                 // Generate callback if any event has occurred on this key this frame.
00284                 // Can't just test mKeyLevel, because this could be a slow frame and
00285                 // key might have gone down then up. JC
00286                 if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key])
00287                 {
00288                         mCurScanKey = key;
00289                         mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
00290                 }
00291         }
00292 
00293         // Reset edges for next frame
00294         for (key = 0; key < KEY_COUNT; key++)
00295         {
00296                 mKeyUp[key] = FALSE;
00297                 mKeyDown[key] = FALSE;
00298                 if (mKeyLevel[key])
00299                 {
00300                         mKeyLevelFrameCount[key]++;
00301                 }
00302         }
00303 }
00304 
00305 BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key )
00306 {
00307         if(mNumpadDistinct == ND_NUMLOCK_ON)
00308         {
00309                 std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
00310                 if(iter != mTranslateNumpadMap.end())
00311                 {
00312                         *translated_key = iter->second;
00313                         return TRUE;
00314                 }
00315         }
00316         return translateKey(os_key, translated_key);
00317 }
00318 
00319 U16     LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key)
00320 {
00321         if(mNumpadDistinct == ND_NUMLOCK_ON)
00322         {
00323                 std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
00324                 if(iter != mInvTranslateNumpadMap.end())
00325                 {
00326                         return iter->second;
00327                 }
00328         }
00329         return inverseTranslateKey(translated_key);
00330 }
00331 
00332 #endif // LL_DARWIN

Generated on Fri May 16 08:33:02 2008 for SecondLife by  doxygen 1.5.5