PageRenderTime 25ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llwindow/llkeyboardmacosx.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 327 lines | 241 code | 36 blank | 50 comment | 31 complexity | 4d6e59db876ce34158a68956ed7d2787 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llkeyboardmacosx.cpp
  3. * @brief Handler for assignable key bindings
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #if LL_DARWIN
  27. #include "linden_common.h"
  28. #include "llkeyboardmacosx.h"
  29. #include "llwindowcallbacks.h"
  30. #include <Carbon/Carbon.h>
  31. LLKeyboardMacOSX::LLKeyboardMacOSX()
  32. {
  33. // Virtual keycode mapping table. Yes, this was as annoying to generate as it looks.
  34. mTranslateKeyMap[0x00] = 'A';
  35. mTranslateKeyMap[0x01] = 'S';
  36. mTranslateKeyMap[0x02] = 'D';
  37. mTranslateKeyMap[0x03] = 'F';
  38. mTranslateKeyMap[0x04] = 'H';
  39. mTranslateKeyMap[0x05] = 'G';
  40. mTranslateKeyMap[0x06] = 'Z';
  41. mTranslateKeyMap[0x07] = 'X';
  42. mTranslateKeyMap[0x08] = 'C';
  43. mTranslateKeyMap[0x09] = 'V';
  44. mTranslateKeyMap[0x0b] = 'B';
  45. mTranslateKeyMap[0x0c] = 'Q';
  46. mTranslateKeyMap[0x0d] = 'W';
  47. mTranslateKeyMap[0x0e] = 'E';
  48. mTranslateKeyMap[0x0f] = 'R';
  49. mTranslateKeyMap[0x10] = 'Y';
  50. mTranslateKeyMap[0x11] = 'T';
  51. mTranslateKeyMap[0x12] = '1';
  52. mTranslateKeyMap[0x13] = '2';
  53. mTranslateKeyMap[0x14] = '3';
  54. mTranslateKeyMap[0x15] = '4';
  55. mTranslateKeyMap[0x16] = '6';
  56. mTranslateKeyMap[0x17] = '5';
  57. mTranslateKeyMap[0x18] = '='; // KEY_EQUALS
  58. mTranslateKeyMap[0x19] = '9';
  59. mTranslateKeyMap[0x1a] = '7';
  60. mTranslateKeyMap[0x1b] = '-'; // KEY_HYPHEN
  61. mTranslateKeyMap[0x1c] = '8';
  62. mTranslateKeyMap[0x1d] = '0';
  63. mTranslateKeyMap[0x1e] = ']';
  64. mTranslateKeyMap[0x1f] = 'O';
  65. mTranslateKeyMap[0x20] = 'U';
  66. mTranslateKeyMap[0x21] = '[';
  67. mTranslateKeyMap[0x22] = 'I';
  68. mTranslateKeyMap[0x23] = 'P';
  69. mTranslateKeyMap[0x24] = KEY_RETURN,
  70. mTranslateKeyMap[0x25] = 'L';
  71. mTranslateKeyMap[0x26] = 'J';
  72. mTranslateKeyMap[0x27] = '\'';
  73. mTranslateKeyMap[0x28] = 'K';
  74. mTranslateKeyMap[0x29] = ';';
  75. mTranslateKeyMap[0x2a] = '\\';
  76. mTranslateKeyMap[0x2b] = ',';
  77. mTranslateKeyMap[0x2c] = KEY_DIVIDE;
  78. mTranslateKeyMap[0x2d] = 'N';
  79. mTranslateKeyMap[0x2e] = 'M';
  80. mTranslateKeyMap[0x2f] = '.';
  81. mTranslateKeyMap[0x30] = KEY_TAB;
  82. mTranslateKeyMap[0x31] = ' '; // space!
  83. mTranslateKeyMap[0x32] = '`';
  84. mTranslateKeyMap[0x33] = KEY_BACKSPACE;
  85. mTranslateKeyMap[0x35] = KEY_ESCAPE;
  86. //mTranslateKeyMap[0x37] = 0; // Command key. (not used yet)
  87. mTranslateKeyMap[0x38] = KEY_SHIFT;
  88. mTranslateKeyMap[0x39] = KEY_CAPSLOCK;
  89. mTranslateKeyMap[0x3a] = KEY_ALT;
  90. mTranslateKeyMap[0x3b] = KEY_CONTROL;
  91. mTranslateKeyMap[0x41] = '.'; // keypad
  92. mTranslateKeyMap[0x43] = '*'; // keypad
  93. mTranslateKeyMap[0x45] = '+'; // keypad
  94. mTranslateKeyMap[0x4b] = KEY_PAD_DIVIDE; // keypad
  95. mTranslateKeyMap[0x4c] = KEY_RETURN; // keypad enter
  96. mTranslateKeyMap[0x4e] = '-'; // keypad
  97. mTranslateKeyMap[0x51] = '='; // keypad
  98. mTranslateKeyMap[0x52] = '0'; // keypad
  99. mTranslateKeyMap[0x53] = '1'; // keypad
  100. mTranslateKeyMap[0x54] = '2'; // keypad
  101. mTranslateKeyMap[0x55] = '3'; // keypad
  102. mTranslateKeyMap[0x56] = '4'; // keypad
  103. mTranslateKeyMap[0x57] = '5'; // keypad
  104. mTranslateKeyMap[0x58] = '6'; // keypad
  105. mTranslateKeyMap[0x59] = '7'; // keypad
  106. mTranslateKeyMap[0x5b] = '8'; // keypad
  107. mTranslateKeyMap[0x5c] = '9'; // keypad
  108. mTranslateKeyMap[0x60] = KEY_F5;
  109. mTranslateKeyMap[0x61] = KEY_F6;
  110. mTranslateKeyMap[0x62] = KEY_F7;
  111. mTranslateKeyMap[0x63] = KEY_F3;
  112. mTranslateKeyMap[0x64] = KEY_F8;
  113. mTranslateKeyMap[0x65] = KEY_F9;
  114. mTranslateKeyMap[0x67] = KEY_F11;
  115. mTranslateKeyMap[0x6d] = KEY_F10;
  116. mTranslateKeyMap[0x6f] = KEY_F12;
  117. mTranslateKeyMap[0x72] = KEY_INSERT;
  118. mTranslateKeyMap[0x73] = KEY_HOME;
  119. mTranslateKeyMap[0x74] = KEY_PAGE_UP;
  120. mTranslateKeyMap[0x75] = KEY_DELETE;
  121. mTranslateKeyMap[0x76] = KEY_F4;
  122. mTranslateKeyMap[0x77] = KEY_END;
  123. mTranslateKeyMap[0x78] = KEY_F2;
  124. mTranslateKeyMap[0x79] = KEY_PAGE_DOWN;
  125. mTranslateKeyMap[0x7a] = KEY_F1;
  126. mTranslateKeyMap[0x7b] = KEY_LEFT;
  127. mTranslateKeyMap[0x7c] = KEY_RIGHT;
  128. mTranslateKeyMap[0x7d] = KEY_DOWN;
  129. mTranslateKeyMap[0x7e] = KEY_UP;
  130. // Build inverse map
  131. std::map<U16, KEY>::iterator iter;
  132. for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
  133. {
  134. mInvTranslateKeyMap[iter->second] = iter->first;
  135. }
  136. // build numpad maps
  137. mTranslateNumpadMap[0x52] = KEY_PAD_INS; // keypad 0
  138. mTranslateNumpadMap[0x53] = KEY_PAD_END; // keypad 1
  139. mTranslateNumpadMap[0x54] = KEY_PAD_DOWN; // keypad 2
  140. mTranslateNumpadMap[0x55] = KEY_PAD_PGDN; // keypad 3
  141. mTranslateNumpadMap[0x56] = KEY_PAD_LEFT; // keypad 4
  142. mTranslateNumpadMap[0x57] = KEY_PAD_CENTER; // keypad 5
  143. mTranslateNumpadMap[0x58] = KEY_PAD_RIGHT; // keypad 6
  144. mTranslateNumpadMap[0x59] = KEY_PAD_HOME; // keypad 7
  145. mTranslateNumpadMap[0x5b] = KEY_PAD_UP; // keypad 8
  146. mTranslateNumpadMap[0x5c] = KEY_PAD_PGUP; // keypad 9
  147. mTranslateNumpadMap[0x41] = KEY_PAD_DEL; // keypad .
  148. mTranslateNumpadMap[0x4c] = KEY_PAD_RETURN; // keypad enter
  149. // Build inverse numpad map
  150. for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++)
  151. {
  152. mInvTranslateNumpadMap[iter->second] = iter->first;
  153. }
  154. }
  155. void LLKeyboardMacOSX::resetMaskKeys()
  156. {
  157. U32 mask = GetCurrentEventKeyModifiers();
  158. // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
  159. // It looks a bit suspicious, as it won't correct for keys that have been released.
  160. // Is this the way it's supposed to work?
  161. if(mask & shiftKey)
  162. {
  163. mKeyLevel[KEY_SHIFT] = TRUE;
  164. }
  165. if(mask & (controlKey))
  166. {
  167. mKeyLevel[KEY_CONTROL] = TRUE;
  168. }
  169. if(mask & optionKey)
  170. {
  171. mKeyLevel[KEY_ALT] = TRUE;
  172. }
  173. }
  174. /*
  175. static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &outMask)
  176. {
  177. // Translate the virtual keycode into the keycodes the keyboard system expects.
  178. U16 virtualKey = (mask >> 24) & 0x0000007F;
  179. outKey = macKeyTransArray[virtualKey];
  180. return(outKey != 0);
  181. }
  182. */
  183. MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
  184. {
  185. // translate the mask
  186. MASK out_mask = 0;
  187. if(mask & shiftKey)
  188. {
  189. out_mask |= MASK_SHIFT;
  190. }
  191. if(mask & (controlKey | cmdKey))
  192. {
  193. out_mask |= MASK_CONTROL;
  194. }
  195. if(mask & optionKey)
  196. {
  197. out_mask |= MASK_ALT;
  198. }
  199. return out_mask;
  200. }
  201. BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
  202. {
  203. KEY translated_key = 0;
  204. U32 translated_mask = 0;
  205. BOOL handled = FALSE;
  206. translated_mask = updateModifiers(mask);
  207. if(translateNumpadKey(key, &translated_key))
  208. {
  209. handled = handleTranslatedKeyDown(translated_key, translated_mask);
  210. }
  211. return handled;
  212. }
  213. BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
  214. {
  215. KEY translated_key = 0;
  216. U32 translated_mask = 0;
  217. BOOL handled = FALSE;
  218. translated_mask = updateModifiers(mask);
  219. if(translateNumpadKey(key, &translated_key))
  220. {
  221. handled = handleTranslatedKeyUp(translated_key, translated_mask);
  222. }
  223. return handled;
  224. }
  225. MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
  226. {
  227. MASK result = MASK_NONE;
  228. U32 mask = GetCurrentEventKeyModifiers();
  229. if (mask & shiftKey) result |= MASK_SHIFT;
  230. if (mask & controlKey) result |= MASK_CONTROL;
  231. if (mask & optionKey) result |= MASK_ALT;
  232. // For keyboard events, consider Command equivalent to Control
  233. if (!for_mouse_event)
  234. {
  235. if (mask & cmdKey) result |= MASK_CONTROL;
  236. }
  237. return result;
  238. }
  239. void LLKeyboardMacOSX::scanKeyboard()
  240. {
  241. S32 key;
  242. for (key = 0; key < KEY_COUNT; key++)
  243. {
  244. // Generate callback if any event has occurred on this key this frame.
  245. // Can't just test mKeyLevel, because this could be a slow frame and
  246. // key might have gone down then up. JC
  247. if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key])
  248. {
  249. mCurScanKey = key;
  250. mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
  251. }
  252. }
  253. // Reset edges for next frame
  254. for (key = 0; key < KEY_COUNT; key++)
  255. {
  256. mKeyUp[key] = FALSE;
  257. mKeyDown[key] = FALSE;
  258. if (mKeyLevel[key])
  259. {
  260. mKeyLevelFrameCount[key]++;
  261. }
  262. }
  263. }
  264. BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key )
  265. {
  266. if(mNumpadDistinct == ND_NUMLOCK_ON)
  267. {
  268. std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
  269. if(iter != mTranslateNumpadMap.end())
  270. {
  271. *translated_key = iter->second;
  272. return TRUE;
  273. }
  274. }
  275. return translateKey(os_key, translated_key);
  276. }
  277. U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key)
  278. {
  279. if(mNumpadDistinct == ND_NUMLOCK_ON)
  280. {
  281. std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
  282. if(iter != mInvTranslateNumpadMap.end())
  283. {
  284. return iter->second;
  285. }
  286. }
  287. return inverseTranslateKey(translated_key);
  288. }
  289. #endif // LL_DARWIN