llkeyboardsdl.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llkeyboardsdl.cpp
  3.  * @brief Handler for assignable key bindings
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #if LL_SDL
  33. #include "linden_common.h"
  34. #include "llkeyboardsdl.h"
  35. #include "llwindowcallbacks.h"
  36. #include "SDL/SDL.h"
  37. LLKeyboardSDL::LLKeyboardSDL()
  38. {
  39. // Set up key mapping for SDL - eventually can read this from a file?
  40. // Anything not in the key map gets dropped
  41. // Add default A-Z
  42. // Virtual key mappings from SDL_keysym.h ...
  43. // SDL maps the letter keys to the ASCII you'd expect, but it's lowercase...
  44. U16 cur_char;
  45. for (cur_char = 'A'; cur_char <= 'Z'; cur_char++)
  46. {
  47. mTranslateKeyMap[cur_char] = cur_char;
  48. }
  49. for (cur_char = 'a'; cur_char <= 'z'; cur_char++)
  50. {
  51. mTranslateKeyMap[cur_char] = (cur_char - 'a') + 'A';
  52. }
  53. for (cur_char = '0'; cur_char <= '9'; cur_char++)
  54. {
  55. mTranslateKeyMap[cur_char] = cur_char;
  56. }
  57. // These ones are translated manually upon keydown/keyup because
  58. // SDL doesn't handle their numlock transition.
  59. //mTranslateKeyMap[SDLK_KP4] = KEY_PAD_LEFT;
  60. //mTranslateKeyMap[SDLK_KP6] = KEY_PAD_RIGHT;
  61. //mTranslateKeyMap[SDLK_KP8] = KEY_PAD_UP;
  62. //mTranslateKeyMap[SDLK_KP2] = KEY_PAD_DOWN;
  63. //mTranslateKeyMap[SDLK_KP_PERIOD] = KEY_DELETE;
  64. //mTranslateKeyMap[SDLK_KP7] = KEY_HOME;
  65. //mTranslateKeyMap[SDLK_KP1] = KEY_END;
  66. //mTranslateKeyMap[SDLK_KP9] = KEY_PAGE_UP;
  67. //mTranslateKeyMap[SDLK_KP3] = KEY_PAGE_DOWN;
  68. //mTranslateKeyMap[SDLK_KP0] = KEY_INSERT;
  69. mTranslateKeyMap[SDLK_SPACE] = ' ';
  70. mTranslateKeyMap[SDLK_RETURN] = KEY_RETURN;
  71. mTranslateKeyMap[SDLK_LEFT] = KEY_LEFT;
  72. mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT;
  73. mTranslateKeyMap[SDLK_UP] = KEY_UP;
  74. mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN;
  75. mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;
  76. mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN;
  77. mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;
  78. mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE;
  79. mTranslateKeyMap[SDLK_DELETE] = KEY_DELETE;
  80. mTranslateKeyMap[SDLK_LSHIFT] = KEY_SHIFT;
  81. mTranslateKeyMap[SDLK_RSHIFT] = KEY_SHIFT;
  82. mTranslateKeyMap[SDLK_LCTRL] = KEY_CONTROL;
  83. mTranslateKeyMap[SDLK_RCTRL] = KEY_CONTROL;
  84. mTranslateKeyMap[SDLK_LALT] = KEY_ALT;
  85. mTranslateKeyMap[SDLK_RALT] = KEY_ALT;
  86. mTranslateKeyMap[SDLK_HOME] = KEY_HOME;
  87. mTranslateKeyMap[SDLK_END] = KEY_END;
  88. mTranslateKeyMap[SDLK_PAGEUP] = KEY_PAGE_UP;
  89. mTranslateKeyMap[SDLK_PAGEDOWN] = KEY_PAGE_DOWN;
  90. mTranslateKeyMap[SDLK_MINUS] = KEY_HYPHEN;
  91. mTranslateKeyMap[SDLK_EQUALS] = KEY_EQUALS;
  92. mTranslateKeyMap[SDLK_KP_EQUALS] = KEY_EQUALS;
  93. mTranslateKeyMap[SDLK_INSERT] = KEY_INSERT;
  94. mTranslateKeyMap[SDLK_CAPSLOCK] = KEY_CAPSLOCK;
  95. mTranslateKeyMap[SDLK_TAB] = KEY_TAB;
  96. mTranslateKeyMap[SDLK_KP_PLUS] = KEY_ADD;
  97. mTranslateKeyMap[SDLK_KP_MINUS] = KEY_SUBTRACT;
  98. mTranslateKeyMap[SDLK_KP_MULTIPLY] = KEY_MULTIPLY;
  99. mTranslateKeyMap[SDLK_KP_DIVIDE] = KEY_PAD_DIVIDE;
  100. mTranslateKeyMap[SDLK_F1] = KEY_F1;
  101. mTranslateKeyMap[SDLK_F2] = KEY_F2;
  102. mTranslateKeyMap[SDLK_F3] = KEY_F3;
  103. mTranslateKeyMap[SDLK_F4] = KEY_F4;
  104. mTranslateKeyMap[SDLK_F5] = KEY_F5;
  105. mTranslateKeyMap[SDLK_F6] = KEY_F6;
  106. mTranslateKeyMap[SDLK_F7] = KEY_F7;
  107. mTranslateKeyMap[SDLK_F8] = KEY_F8;
  108. mTranslateKeyMap[SDLK_F9] = KEY_F9;
  109. mTranslateKeyMap[SDLK_F10] = KEY_F10;
  110. mTranslateKeyMap[SDLK_F11] = KEY_F11;
  111. mTranslateKeyMap[SDLK_F12] = KEY_F12;
  112. mTranslateKeyMap[SDLK_PLUS]   = '=';
  113. mTranslateKeyMap[SDLK_COMMA]  = ',';
  114. mTranslateKeyMap[SDLK_MINUS]  = '-';
  115. mTranslateKeyMap[SDLK_PERIOD] = '.';
  116. mTranslateKeyMap[SDLK_BACKQUOTE] = '`';
  117. mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE;
  118. mTranslateKeyMap[SDLK_SEMICOLON] = ';';
  119. mTranslateKeyMap[SDLK_LEFTBRACKET] = '[';
  120. mTranslateKeyMap[SDLK_BACKSLASH] = '\';
  121. mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']';
  122. mTranslateKeyMap[SDLK_QUOTE] = ''';
  123. // Build inverse map
  124. std::map<U16, KEY>::iterator iter;
  125. for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
  126. {
  127. mInvTranslateKeyMap[iter->second] = iter->first;
  128. }
  129. // numpad map
  130. mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS;
  131. mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END;
  132. mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN;
  133. mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN;
  134. mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT;
  135. mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER;
  136. mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT;
  137. mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME;
  138. mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP;
  139. mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP;
  140. mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL;
  141. // build inverse numpad map
  142. for (iter = mTranslateNumpadMap.begin();
  143.      iter != mTranslateNumpadMap.end();
  144.      iter++)
  145. {
  146. mInvTranslateNumpadMap[iter->second] = iter->first;
  147. }
  148. }
  149. void LLKeyboardSDL::resetMaskKeys()
  150. {
  151. SDLMod mask = SDL_GetModState();
  152. // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
  153. //    It looks a bit suspicious, as it won't correct for keys that have been released.
  154. //    Is this the way it's supposed to work?
  155. if(mask & KMOD_SHIFT)
  156. {
  157. mKeyLevel[KEY_SHIFT] = TRUE;
  158. }
  159. if(mask & KMOD_CTRL)
  160. {
  161. mKeyLevel[KEY_CONTROL] = TRUE;
  162. }
  163. if(mask & KMOD_ALT)
  164. {
  165. mKeyLevel[KEY_ALT] = TRUE;
  166. }
  167. }
  168. MASK LLKeyboardSDL::updateModifiers(const U32 mask)
  169. {
  170. // translate the mask
  171. MASK out_mask = MASK_NONE;
  172. if(mask & KMOD_SHIFT)
  173. {
  174. out_mask |= MASK_SHIFT;
  175. }
  176. if(mask & KMOD_CTRL)
  177. {
  178. out_mask |= MASK_CONTROL;
  179. }
  180. if(mask & KMOD_ALT)
  181. {
  182. out_mask |= MASK_ALT;
  183. }
  184. return out_mask;
  185. }
  186. static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask)
  187. {
  188. // SDL doesn't automatically adjust the keysym according to
  189. // whether NUMLOCK is engaged, so we massage the keysym manually.
  190. U16 rtn = key;
  191. if (!(mask & KMOD_NUM))
  192. {
  193. switch (key)
  194. {
  195. case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break;
  196. case SDLK_KP0: rtn = SDLK_INSERT; break;
  197. case SDLK_KP1: rtn = SDLK_END; break;
  198. case SDLK_KP2: rtn = SDLK_DOWN; break;
  199. case SDLK_KP3: rtn = SDLK_PAGEDOWN; break;
  200. case SDLK_KP4: rtn = SDLK_LEFT; break;
  201. case SDLK_KP6: rtn = SDLK_RIGHT; break;
  202. case SDLK_KP7: rtn = SDLK_HOME; break;
  203. case SDLK_KP8: rtn = SDLK_UP; break;
  204. case SDLK_KP9: rtn = SDLK_PAGEUP; break;
  205. }
  206. }
  207. return rtn;
  208. }
  209. BOOL LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask)
  210. {
  211. U16     adjusted_nativekey;
  212. KEY translated_key = 0;
  213. U32 translated_mask = MASK_NONE;
  214. BOOL handled = FALSE;
  215. adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
  216. translated_mask = updateModifiers(mask);
  217. if(translateNumpadKey(adjusted_nativekey, &translated_key))
  218. {
  219. handled = handleTranslatedKeyDown(translated_key, translated_mask);
  220. }
  221. return handled;
  222. }
  223. BOOL LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask)
  224. {
  225. U16     adjusted_nativekey;
  226. KEY translated_key = 0;
  227. U32 translated_mask = MASK_NONE;
  228. BOOL handled = FALSE;
  229. adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
  230. translated_mask = updateModifiers(mask);
  231. if(translateNumpadKey(adjusted_nativekey, &translated_key))
  232. {
  233. handled = handleTranslatedKeyUp(translated_key, translated_mask);
  234. }
  235. return handled;
  236. }
  237. MASK LLKeyboardSDL::currentMask(BOOL for_mouse_event)
  238. {
  239. MASK result = MASK_NONE;
  240. SDLMod mask = SDL_GetModState();
  241. if (mask & KMOD_SHIFT) result |= MASK_SHIFT;
  242. if (mask & KMOD_CTRL) result |= MASK_CONTROL;
  243. if (mask & KMOD_ALT) result |= MASK_ALT;
  244. // For keyboard events, consider Meta keys equivalent to Control
  245. if (!for_mouse_event)
  246. {
  247. if (mask & KMOD_META) result |= MASK_CONTROL;
  248. }
  249. return result;
  250. }
  251. void LLKeyboardSDL::scanKeyboard()
  252. {
  253. for (S32 key = 0; key < KEY_COUNT; key++)
  254. {
  255. // Generate callback if any event has occurred on this key this frame.
  256. // Can't just test mKeyLevel, because this could be a slow frame and
  257. // key might have gone down then up. JC
  258. if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key])
  259. {
  260. mCurScanKey = key;
  261. mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
  262. }
  263. }
  264. // Reset edges for next frame
  265. for (S32 key = 0; key < KEY_COUNT; key++)
  266. {
  267. mKeyUp[key] = FALSE;
  268. mKeyDown[key] = FALSE;
  269. if (mKeyLevel[key])
  270. {
  271. mKeyLevelFrameCount[key]++;
  272. }
  273. }
  274. }
  275.  
  276. BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
  277. {
  278. if(mNumpadDistinct == ND_NUMLOCK_ON)
  279. {
  280. std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
  281. if(iter != mTranslateNumpadMap.end())
  282. {
  283. *translated_key = iter->second;
  284. return TRUE;
  285. }
  286. }
  287. BOOL success = translateKey(os_key, translated_key);
  288. return success;
  289. }
  290. U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
  291. {
  292. if(mNumpadDistinct == ND_NUMLOCK_ON)
  293. {
  294. std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
  295. if(iter != mInvTranslateNumpadMap.end())
  296. {
  297. return iter->second;
  298. }
  299. }
  300. return inverseTranslateKey(translated_key);
  301. }
  302. #endif