00001
00032 #if LL_SDL
00033
00034 #include "linden_common.h"
00035 #include "llkeyboardsdl.h"
00036 #include "llwindow.h"
00037 #include "SDL/SDL.h"
00038
00039 LLKeyboardSDL::LLKeyboardSDL()
00040 {
00041
00042
00043
00044
00045
00046
00047
00048 U16 cur_char;
00049 for (cur_char = 'A'; cur_char <= 'Z'; cur_char++)
00050 {
00051 mTranslateKeyMap[cur_char] = cur_char;
00052 }
00053 for (cur_char = 'a'; cur_char <= 'z'; cur_char++)
00054 {
00055 mTranslateKeyMap[cur_char] = (cur_char - 'a') + 'A';
00056 }
00057
00058 for (cur_char = '0'; cur_char <= '9'; cur_char++)
00059 {
00060 mTranslateKeyMap[cur_char] = cur_char;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 mTranslateKeyMap[SDLK_SPACE] = ' ';
00077 mTranslateKeyMap[SDLK_RETURN] = KEY_RETURN;
00078 mTranslateKeyMap[SDLK_LEFT] = KEY_LEFT;
00079 mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT;
00080 mTranslateKeyMap[SDLK_UP] = KEY_UP;
00081 mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN;
00082 mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;
00083 mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN;
00084 mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;
00085 mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE;
00086 mTranslateKeyMap[SDLK_DELETE] = KEY_DELETE;
00087 mTranslateKeyMap[SDLK_LSHIFT] = KEY_SHIFT;
00088 mTranslateKeyMap[SDLK_RSHIFT] = KEY_SHIFT;
00089 mTranslateKeyMap[SDLK_LCTRL] = KEY_CONTROL;
00090 mTranslateKeyMap[SDLK_RCTRL] = KEY_CONTROL;
00091 mTranslateKeyMap[SDLK_LALT] = KEY_ALT;
00092 mTranslateKeyMap[SDLK_RALT] = KEY_ALT;
00093 mTranslateKeyMap[SDLK_HOME] = KEY_HOME;
00094 mTranslateKeyMap[SDLK_END] = KEY_END;
00095 mTranslateKeyMap[SDLK_PAGEUP] = KEY_PAGE_UP;
00096 mTranslateKeyMap[SDLK_PAGEDOWN] = KEY_PAGE_DOWN;
00097 mTranslateKeyMap[SDLK_MINUS] = KEY_HYPHEN;
00098 mTranslateKeyMap[SDLK_EQUALS] = KEY_EQUALS;
00099 mTranslateKeyMap[SDLK_KP_EQUALS] = KEY_EQUALS;
00100 mTranslateKeyMap[SDLK_INSERT] = KEY_INSERT;
00101 mTranslateKeyMap[SDLK_CAPSLOCK] = KEY_CAPSLOCK;
00102 mTranslateKeyMap[SDLK_TAB] = KEY_TAB;
00103 mTranslateKeyMap[SDLK_KP_PLUS] = KEY_ADD;
00104 mTranslateKeyMap[SDLK_KP_MINUS] = KEY_SUBTRACT;
00105 mTranslateKeyMap[SDLK_KP_MULTIPLY] = KEY_MULTIPLY;
00106 mTranslateKeyMap[SDLK_KP_DIVIDE] = KEY_DIVIDE;
00107 mTranslateKeyMap[SDLK_F1] = KEY_F1;
00108 mTranslateKeyMap[SDLK_F2] = KEY_F2;
00109 mTranslateKeyMap[SDLK_F3] = KEY_F3;
00110 mTranslateKeyMap[SDLK_F4] = KEY_F4;
00111 mTranslateKeyMap[SDLK_F5] = KEY_F5;
00112 mTranslateKeyMap[SDLK_F6] = KEY_F6;
00113 mTranslateKeyMap[SDLK_F7] = KEY_F7;
00114 mTranslateKeyMap[SDLK_F8] = KEY_F8;
00115 mTranslateKeyMap[SDLK_F9] = KEY_F9;
00116 mTranslateKeyMap[SDLK_F10] = KEY_F10;
00117 mTranslateKeyMap[SDLK_F11] = KEY_F11;
00118 mTranslateKeyMap[SDLK_F12] = KEY_F12;
00119 mTranslateKeyMap[SDLK_PLUS] = '=';
00120 mTranslateKeyMap[SDLK_COMMA] = ',';
00121 mTranslateKeyMap[SDLK_MINUS] = '-';
00122 mTranslateKeyMap[SDLK_PERIOD] = '.';
00123 mTranslateKeyMap[SDLK_BACKQUOTE] = '`';
00124 mTranslateKeyMap[SDLK_SLASH] = '/';
00125 mTranslateKeyMap[SDLK_SEMICOLON] = ';';
00126 mTranslateKeyMap[SDLK_LEFTBRACKET] = '[';
00127 mTranslateKeyMap[SDLK_BACKSLASH] = '\\';
00128 mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']';
00129 mTranslateKeyMap[SDLK_QUOTE] = '\'';
00130
00131
00132 std::map<U16, KEY>::iterator iter;
00133 for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
00134 {
00135 mInvTranslateKeyMap[iter->second] = iter->first;
00136 }
00137
00138
00139 mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS;
00140 mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END;
00141 mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN;
00142 mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN;
00143 mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT;
00144 mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER;
00145 mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT;
00146 mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME;
00147 mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP;
00148 mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP;
00149 mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL;
00150
00151
00152 for (iter = mTranslateNumpadMap.begin();
00153 iter != mTranslateNumpadMap.end();
00154 iter++)
00155 {
00156 mInvTranslateNumpadMap[iter->second] = iter->first;
00157 }
00158 }
00159
00160 void LLKeyboardSDL::resetMaskKeys()
00161 {
00162 SDLMod mask = SDL_GetModState();
00163
00164
00165
00166
00167
00168 if(mask & KMOD_SHIFT)
00169 {
00170 mKeyLevel[KEY_SHIFT] = TRUE;
00171 }
00172
00173 if(mask & KMOD_CTRL)
00174 {
00175 mKeyLevel[KEY_CONTROL] = TRUE;
00176 }
00177
00178 if(mask & KMOD_ALT)
00179 {
00180 mKeyLevel[KEY_ALT] = TRUE;
00181 }
00182 }
00183
00184
00185 MASK LLKeyboardSDL::updateModifiers(const U32 mask)
00186 {
00187
00188 MASK out_mask = MASK_NONE;
00189
00190 if(mask & KMOD_SHIFT)
00191 {
00192 out_mask |= MASK_SHIFT;
00193 }
00194
00195 if(mask & KMOD_CTRL)
00196 {
00197 out_mask |= MASK_CONTROL;
00198 }
00199
00200 if(mask & KMOD_ALT)
00201 {
00202 out_mask |= MASK_ALT;
00203 }
00204
00205 return out_mask;
00206 }
00207
00208
00209 static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask)
00210 {
00211
00212
00213 U16 rtn = key;
00214 if (!(mask & KMOD_NUM))
00215 {
00216 switch (key)
00217 {
00218 case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break;
00219 case SDLK_KP0: rtn = SDLK_INSERT; break;
00220 case SDLK_KP1: rtn = SDLK_END; break;
00221 case SDLK_KP2: rtn = SDLK_DOWN; break;
00222 case SDLK_KP3: rtn = SDLK_PAGEDOWN; break;
00223 case SDLK_KP4: rtn = SDLK_LEFT; break;
00224 case SDLK_KP6: rtn = SDLK_RIGHT; break;
00225 case SDLK_KP7: rtn = SDLK_HOME; break;
00226 case SDLK_KP8: rtn = SDLK_UP; break;
00227 case SDLK_KP9: rtn = SDLK_PAGEUP; break;
00228 }
00229 }
00230 return rtn;
00231 }
00232
00233
00234 BOOL LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask)
00235 {
00236 U16 adjusted_nativekey;
00237 KEY translated_key = 0;
00238 U32 translated_mask = MASK_NONE;
00239 BOOL handled = FALSE;
00240
00241 adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
00242
00243 translated_mask = updateModifiers(mask);
00244
00245 if(translateNumpadKey(adjusted_nativekey, &translated_key))
00246 {
00247 handled = handleTranslatedKeyDown(translated_key, translated_mask);
00248 }
00249
00250 return handled;
00251 }
00252
00253
00254 BOOL LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask)
00255 {
00256 U16 adjusted_nativekey;
00257 KEY translated_key = 0;
00258 U32 translated_mask = MASK_NONE;
00259 BOOL handled = FALSE;
00260
00261 adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
00262
00263 translated_mask = updateModifiers(mask);
00264
00265 if(translateNumpadKey(adjusted_nativekey, &translated_key))
00266 {
00267 handled = handleTranslatedKeyUp(translated_key, translated_mask);
00268 }
00269
00270 return handled;
00271 }
00272
00273 MASK LLKeyboardSDL::currentMask(BOOL for_mouse_event)
00274 {
00275 MASK result = MASK_NONE;
00276 SDLMod mask = SDL_GetModState();
00277
00278 if (mask & KMOD_SHIFT) result |= MASK_SHIFT;
00279 if (mask & KMOD_CTRL) result |= MASK_CONTROL;
00280 if (mask & KMOD_ALT) result |= MASK_ALT;
00281
00282
00283 if (!for_mouse_event)
00284 {
00285 if (mask & KMOD_META) result |= MASK_CONTROL;
00286 }
00287
00288 return result;
00289 }
00290
00291 void LLKeyboardSDL::scanKeyboard()
00292 {
00293 for (S32 key = 0; key < KEY_COUNT; key++)
00294 {
00295
00296
00297
00298 if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key])
00299 {
00300 mCurScanKey = key;
00301 mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
00302 }
00303 }
00304
00305
00306 for (S32 key = 0; key < KEY_COUNT; key++)
00307 {
00308 mKeyUp[key] = FALSE;
00309 mKeyDown[key] = FALSE;
00310 if (mKeyLevel[key])
00311 {
00312 mKeyLevelFrameCount[key]++;
00313 }
00314 }
00315 }
00316
00317
00318 BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
00319 {
00320 if(mNumpadDistinct == ND_NUMLOCK_ON)
00321 {
00322 std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
00323 if(iter != mTranslateNumpadMap.end())
00324 {
00325 *translated_key = iter->second;
00326 return TRUE;
00327 }
00328 }
00329 BOOL success = translateKey(os_key, translated_key);
00330 return success;
00331 }
00332
00333 U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
00334 {
00335 if(mNumpadDistinct == ND_NUMLOCK_ON)
00336 {
00337 std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
00338 if(iter != mInvTranslateNumpadMap.end())
00339 {
00340 return iter->second;
00341 }
00342 }
00343 return inverseTranslateKey(translated_key);
00344 }
00345
00346 #endif
00347