00001
00032 #if LL_WINDOWS
00033
00034 #include "linden_common.h"
00035
00036 #include "llkeyboardwin32.h"
00037
00038 #include "llwindow.h"
00039
00040 #define WIN32_LEAN_AND_MEAN
00041 #include <winsock2.h>
00042 #include <windows.h>
00043
00044 LLKeyboardWin32::LLKeyboardWin32()
00045 {
00046
00047
00048
00049
00050
00051
00052 KEY cur_char;
00053 for (cur_char = 'A'; cur_char <= 'Z'; cur_char++)
00054 {
00055 mTranslateKeyMap[cur_char] = (KEY)cur_char;
00056 }
00057
00058 for (cur_char = '0'; cur_char <= '9'; cur_char++)
00059 {
00060 mTranslateKeyMap[cur_char] = (KEY)cur_char;
00061 }
00062
00063 for (cur_char = 0x60; cur_char <= 0x69; cur_char++)
00064 {
00065 mTranslateKeyMap[cur_char] = (KEY)('0' + (0x60 - cur_char));
00066 }
00067
00068
00069 mTranslateKeyMap[VK_SPACE] = ' ';
00070 mTranslateKeyMap[VK_OEM_1] = ';';
00071
00072
00073
00074
00075
00076 mTranslateKeyMap[VK_OEM_PLUS] = '=';
00077 mTranslateKeyMap[VK_OEM_COMMA] = ',';
00078 mTranslateKeyMap[VK_OEM_MINUS] = '-';
00079 mTranslateKeyMap[VK_OEM_PERIOD] = '.';
00080 mTranslateKeyMap[VK_OEM_2] = KEY_PAD_DIVIDE;
00081 mTranslateKeyMap[VK_OEM_3] = '`';
00082 mTranslateKeyMap[VK_OEM_4] = '[';
00083 mTranslateKeyMap[VK_OEM_5] = '\\';
00084 mTranslateKeyMap[VK_OEM_6] = ']';
00085 mTranslateKeyMap[VK_OEM_7] = '\'';
00086 mTranslateKeyMap[VK_ESCAPE] = KEY_ESCAPE;
00087 mTranslateKeyMap[VK_RETURN] = KEY_RETURN;
00088 mTranslateKeyMap[VK_LEFT] = KEY_LEFT;
00089 mTranslateKeyMap[VK_RIGHT] = KEY_RIGHT;
00090 mTranslateKeyMap[VK_UP] = KEY_UP;
00091 mTranslateKeyMap[VK_DOWN] = KEY_DOWN;
00092 mTranslateKeyMap[VK_BACK] = KEY_BACKSPACE;
00093 mTranslateKeyMap[VK_INSERT] = KEY_INSERT;
00094 mTranslateKeyMap[VK_DELETE] = KEY_DELETE;
00095 mTranslateKeyMap[VK_SHIFT] = KEY_SHIFT;
00096 mTranslateKeyMap[VK_CONTROL] = KEY_CONTROL;
00097 mTranslateKeyMap[VK_MENU] = KEY_ALT;
00098 mTranslateKeyMap[VK_CAPITAL] = KEY_CAPSLOCK;
00099 mTranslateKeyMap[VK_HOME] = KEY_HOME;
00100 mTranslateKeyMap[VK_END] = KEY_END;
00101 mTranslateKeyMap[VK_PRIOR] = KEY_PAGE_UP;
00102 mTranslateKeyMap[VK_NEXT] = KEY_PAGE_DOWN;
00103 mTranslateKeyMap[VK_TAB] = KEY_TAB;
00104 mTranslateKeyMap[VK_ADD] = KEY_ADD;
00105 mTranslateKeyMap[VK_SUBTRACT] = KEY_SUBTRACT;
00106 mTranslateKeyMap[VK_MULTIPLY] = KEY_MULTIPLY;
00107 mTranslateKeyMap[VK_DIVIDE] = KEY_DIVIDE;
00108 mTranslateKeyMap[VK_F1] = KEY_F1;
00109 mTranslateKeyMap[VK_F2] = KEY_F2;
00110 mTranslateKeyMap[VK_F3] = KEY_F3;
00111 mTranslateKeyMap[VK_F4] = KEY_F4;
00112 mTranslateKeyMap[VK_F5] = KEY_F5;
00113 mTranslateKeyMap[VK_F6] = KEY_F6;
00114 mTranslateKeyMap[VK_F7] = KEY_F7;
00115 mTranslateKeyMap[VK_F8] = KEY_F8;
00116 mTranslateKeyMap[VK_F9] = KEY_F9;
00117 mTranslateKeyMap[VK_F10] = KEY_F10;
00118 mTranslateKeyMap[VK_F11] = KEY_F11;
00119 mTranslateKeyMap[VK_F12] = KEY_F12;
00120 mTranslateKeyMap[VK_CLEAR] = KEY_PAD_CENTER;
00121
00122
00123 std::map<U16, KEY>::iterator iter;
00124 for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
00125 {
00126 mInvTranslateKeyMap[iter->second] = iter->first;
00127 }
00128
00129
00130 mTranslateNumpadMap[0x60] = KEY_PAD_INS;
00131 mTranslateNumpadMap[0x61] = KEY_PAD_END;
00132 mTranslateNumpadMap[0x62] = KEY_PAD_DOWN;
00133 mTranslateNumpadMap[0x63] = KEY_PAD_PGDN;
00134 mTranslateNumpadMap[0x64] = KEY_PAD_LEFT;
00135 mTranslateNumpadMap[0x65] = KEY_PAD_CENTER;
00136 mTranslateNumpadMap[0x66] = KEY_PAD_RIGHT;
00137 mTranslateNumpadMap[0x67] = KEY_PAD_HOME;
00138 mTranslateNumpadMap[0x68] = KEY_PAD_UP;
00139 mTranslateNumpadMap[0x69] = KEY_PAD_PGUP;
00140 mTranslateNumpadMap[0x6A] = KEY_PAD_MULTIPLY;
00141 mTranslateNumpadMap[0x6B] = KEY_PAD_ADD;
00142 mTranslateNumpadMap[0x6D] = KEY_PAD_SUBTRACT;
00143 mTranslateNumpadMap[0x6E] = KEY_PAD_DEL;
00144 mTranslateNumpadMap[0x6F] = KEY_PAD_DIVIDE;
00145
00146 for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++)
00147 {
00148 mInvTranslateNumpadMap[iter->second] = iter->first;
00149 }
00150 }
00151
00152
00153
00154
00155 void LLKeyboardWin32::resetMaskKeys()
00156 {
00157
00158
00159 if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
00160 {
00161 mKeyLevel[KEY_SHIFT] = TRUE;
00162 }
00163
00164 if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
00165 {
00166 mKeyLevel[KEY_CONTROL] = TRUE;
00167 }
00168
00169 if (GetAsyncKeyState(VK_MENU) & 0x8000)
00170 {
00171 mKeyLevel[KEY_ALT] = TRUE;
00172 }
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 MASK LLKeyboardWin32::updateModifiers()
00192 {
00193
00194
00195
00196
00197
00198 mKeyLevel[KEY_CAPSLOCK] = (GetKeyState(VK_CAPITAL) & 0x0001) != 0;
00199
00200 MASK mask = currentMask(FALSE);
00201 return mask;
00202 }
00203
00204
00205
00206 BOOL LLKeyboardWin32::handleKeyDown(const U16 key, MASK mask)
00207 {
00208 KEY translated_key;
00209 U32 translated_mask;
00210 BOOL handled = FALSE;
00211
00212 translated_mask = updateModifiers();
00213
00214 if (translateExtendedKey(key, mask, &translated_key))
00215 {
00216 handled = handleTranslatedKeyDown(translated_key, translated_mask);
00217 }
00218
00219 return handled;
00220 }
00221
00222
00223 BOOL LLKeyboardWin32::handleKeyUp(const U16 key, MASK mask)
00224 {
00225 KEY translated_key;
00226 U32 translated_mask;
00227 BOOL handled = FALSE;
00228
00229 translated_mask = updateModifiers();
00230
00231 if (translateExtendedKey(key, mask, &translated_key))
00232 {
00233 handled = handleTranslatedKeyUp(translated_key, translated_mask);
00234 }
00235
00236 return handled;
00237 }
00238
00239
00240 MASK LLKeyboardWin32::currentMask(BOOL)
00241 {
00242 MASK mask = MASK_NONE;
00243
00244 if (mKeyLevel[KEY_SHIFT]) mask |= MASK_SHIFT;
00245 if (mKeyLevel[KEY_CONTROL]) mask |= MASK_CONTROL;
00246 if (mKeyLevel[KEY_ALT]) mask |= MASK_ALT;
00247
00248 return mask;
00249 }
00250
00251
00252 void LLKeyboardWin32::scanKeyboard()
00253 {
00254 S32 key;
00255 MSG msg;
00256 BOOL pending_key_events = PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD);
00257 for (key = 0; key < KEY_COUNT; key++)
00258 {
00259
00260
00261
00262 if (!pending_key_events && mKeyLevel[key])
00263 {
00264
00265
00266
00267 if (key < KEY_BUTTON0)
00268 {
00269
00270
00271 U16 virtual_key = inverseTranslateExtendedKey(key);
00272
00273 if (!pending_key_events && !(GetAsyncKeyState(virtual_key) & 0x8000))
00274 {
00275
00276 mKeyLevel[key] = FALSE;
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284 if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key])
00285 {
00286 mCurScanKey = key;
00287 mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
00288 }
00289 }
00290
00291
00292 for (key = 0; key < KEY_COUNT; key++)
00293 {
00294 mKeyUp[key] = FALSE;
00295 mKeyDown[key] = FALSE;
00296 if (mKeyLevel[key])
00297 {
00298 mKeyLevelFrameCount[key]++;
00299 }
00300 }
00301 }
00302
00303 BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key)
00304 {
00305 if(mNumpadDistinct == ND_NUMLOCK_ON)
00306 {
00307 std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key);
00308 if (iter != mTranslateNumpadMap.end())
00309 {
00310 *translated_key = iter->second;
00311 return TRUE;
00312 }
00313 }
00314
00315 BOOL success = translateKey(os_key, translated_key);
00316 if(mNumpadDistinct != ND_NEVER) {
00317 if(!success) return success;
00318 if(mask & MASK_EXTENDED)
00319 {
00320
00321
00322
00323
00324
00325
00326 if(((mNumpadDistinct == ND_NUMLOCK_OFF &&
00327 !(GetKeyState(VK_NUMLOCK) & 1))
00328 || mNumpadDistinct == ND_NUMLOCK_ON) &&
00329 *translated_key == KEY_RETURN) {
00330 *translated_key = KEY_PAD_RETURN;
00331 }
00332 }
00333 else
00334 {
00335
00336 switch (*translated_key)
00337 {
00338 case KEY_LEFT:
00339 *translated_key = KEY_PAD_LEFT; break;
00340 case KEY_RIGHT:
00341 *translated_key = KEY_PAD_RIGHT; break;
00342 case KEY_UP:
00343 *translated_key = KEY_PAD_UP; break;
00344 case KEY_DOWN:
00345 *translated_key = KEY_PAD_DOWN; break;
00346 case KEY_HOME:
00347 *translated_key = KEY_PAD_HOME; break;
00348 case KEY_END:
00349 *translated_key = KEY_PAD_END; break;
00350 case KEY_PAGE_UP:
00351 *translated_key = KEY_PAD_PGUP; break;
00352 case KEY_PAGE_DOWN:
00353 *translated_key = KEY_PAD_PGDN; break;
00354 case KEY_INSERT:
00355 *translated_key = KEY_PAD_INS; break;
00356 case KEY_DELETE:
00357 *translated_key = KEY_PAD_DEL; break;
00358 }
00359 }
00360 }
00361 return success;
00362 }
00363
00364 U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key)
00365 {
00366
00367 if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1))
00368 {
00369 std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key);
00370 if (iter != mInvTranslateNumpadMap.end())
00371 {
00372 return iter->second;
00373 }
00374 }
00375
00376
00377
00378 KEY converted_key = translated_key;
00379 switch (converted_key)
00380 {
00381 case KEY_PAD_LEFT:
00382 converted_key = KEY_LEFT; break;
00383 case KEY_PAD_RIGHT:
00384 converted_key = KEY_RIGHT; break;
00385 case KEY_PAD_UP:
00386 converted_key = KEY_UP; break;
00387 case KEY_PAD_DOWN:
00388 converted_key = KEY_DOWN; break;
00389 case KEY_PAD_HOME:
00390 converted_key = KEY_HOME; break;
00391 case KEY_PAD_END:
00392 converted_key = KEY_END; break;
00393 case KEY_PAD_PGUP:
00394 converted_key = KEY_PAGE_UP; break;
00395 case KEY_PAD_PGDN:
00396 converted_key = KEY_PAGE_DOWN; break;
00397 case KEY_PAD_INS:
00398 converted_key = KEY_INSERT; break;
00399 case KEY_PAD_DEL:
00400 converted_key = KEY_DELETE; break;
00401 case KEY_PAD_RETURN:
00402 converted_key = KEY_RETURN; break;
00403 }
00404
00405 return inverseTranslateKey(converted_key);
00406 }
00407
00408 #endif