llkeyboardmacosx.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /**
  2. * @file llkeyboardmacosx.cpp
  3. * @brief Handler for assignable key bindings
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, 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_DARWIN
  33. #include "linden_common.h"
  34. #include "llkeyboardmacosx.h"
  35. #include "llwindow.h"
  36. #include "llwindowmacosx-objc.h"
  37. LLKeyboardMacOSX::LLKeyboardMacOSX()
  38. {
  39. // Virtual keycode mapping table. Yes, this was as annoying to generate as it looks.
  40. mTranslateKeyMap[0x00] = 'A';
  41. mTranslateKeyMap[0x01] = 'S';
  42. mTranslateKeyMap[0x02] = 'D';
  43. mTranslateKeyMap[0x03] = 'F';
  44. mTranslateKeyMap[0x04] = 'H';
  45. mTranslateKeyMap[0x05] = 'G';
  46. mTranslateKeyMap[0x06] = 'Z';
  47. mTranslateKeyMap[0x07] = 'X';
  48. mTranslateKeyMap[0x08] = 'C';
  49. mTranslateKeyMap[0x09] = 'V';
  50. mTranslateKeyMap[0x0b] = 'B';
  51. mTranslateKeyMap[0x0c] = 'Q';
  52. mTranslateKeyMap[0x0d] = 'W';
  53. mTranslateKeyMap[0x0e] = 'E';
  54. mTranslateKeyMap[0x0f] = 'R';
  55. mTranslateKeyMap[0x10] = 'Y';
  56. mTranslateKeyMap[0x11] = 'T';
  57. mTranslateKeyMap[0x12] = '1';
  58. mTranslateKeyMap[0x13] = '2';
  59. mTranslateKeyMap[0x14] = '3';
  60. mTranslateKeyMap[0x15] = '4';
  61. mTranslateKeyMap[0x16] = '6';
  62. mTranslateKeyMap[0x17] = '5';
  63. mTranslateKeyMap[0x18] = '='; // KEY_EQUALS
  64. mTranslateKeyMap[0x19] = '9';
  65. mTranslateKeyMap[0x1a] = '7';
  66. mTranslateKeyMap[0x1b] = '-'; // KEY_HYPHEN
  67. mTranslateKeyMap[0x1c] = '8';
  68. mTranslateKeyMap[0x1d] = '0';
  69. mTranslateKeyMap[0x1e] = ']';
  70. mTranslateKeyMap[0x1f] = 'O';
  71. mTranslateKeyMap[0x20] = 'U';
  72. mTranslateKeyMap[0x21] = '[';
  73. mTranslateKeyMap[0x22] = 'I';
  74. mTranslateKeyMap[0x23] = 'P';
  75. mTranslateKeyMap[0x24] = KEY_RETURN;
  76. mTranslateKeyMap[0x25] = 'L';
  77. mTranslateKeyMap[0x26] = 'J';
  78. mTranslateKeyMap[0x27] = '\'';
  79. mTranslateKeyMap[0x28] = 'K';
  80. mTranslateKeyMap[0x29] = ';';
  81. mTranslateKeyMap[0x2a] = '\\';
  82. mTranslateKeyMap[0x2b] = ',';
  83. mTranslateKeyMap[0x2c] = KEY_DIVIDE;
  84. mTranslateKeyMap[0x2d] = 'N';
  85. mTranslateKeyMap[0x2e] = 'M';
  86. mTranslateKeyMap[0x2f] = '.';
  87. mTranslateKeyMap[0x30] = KEY_TAB;
  88. mTranslateKeyMap[0x31] = ' '; // space!
  89. mTranslateKeyMap[0x32] = '`';
  90. mTranslateKeyMap[0x33] = KEY_BACKSPACE;
  91. mTranslateKeyMap[0x35] = KEY_ESCAPE;
  92. //mTranslateKeyMap[0x37] = 0; // Command key. (not used yet)
  93. mTranslateKeyMap[0x38] = KEY_SHIFT;
  94. mTranslateKeyMap[0x39] = KEY_CAPSLOCK;
  95. mTranslateKeyMap[0x3a] = KEY_ALT;
  96. mTranslateKeyMap[0x3b] = KEY_CONTROL;
  97. mTranslateKeyMap[0x41] = '.'; // keypad
  98. mTranslateKeyMap[0x43] = '*'; // keypad
  99. mTranslateKeyMap[0x45] = '+'; // keypad
  100. mTranslateKeyMap[0x4b] = KEY_PAD_DIVIDE; // keypad
  101. mTranslateKeyMap[0x4c] = KEY_RETURN; // keypad enter
  102. mTranslateKeyMap[0x4e] = '-'; // keypad
  103. mTranslateKeyMap[0x51] = '='; // keypad
  104. mTranslateKeyMap[0x52] = '0'; // keypad
  105. mTranslateKeyMap[0x53] = '1'; // keypad
  106. mTranslateKeyMap[0x54] = '2'; // keypad
  107. mTranslateKeyMap[0x55] = '3'; // keypad
  108. mTranslateKeyMap[0x56] = '4'; // keypad
  109. mTranslateKeyMap[0x57] = '5'; // keypad
  110. mTranslateKeyMap[0x58] = '6'; // keypad
  111. mTranslateKeyMap[0x59] = '7'; // keypad
  112. mTranslateKeyMap[0x5b] = '8'; // keypad
  113. mTranslateKeyMap[0x5c] = '9'; // keypad
  114. mTranslateKeyMap[0x60] = KEY_F5;
  115. mTranslateKeyMap[0x61] = KEY_F6;
  116. mTranslateKeyMap[0x62] = KEY_F7;
  117. mTranslateKeyMap[0x63] = KEY_F3;
  118. mTranslateKeyMap[0x64] = KEY_F8;
  119. mTranslateKeyMap[0x65] = KEY_F9;
  120. mTranslateKeyMap[0x67] = KEY_F11;
  121. mTranslateKeyMap[0x6d] = KEY_F10;
  122. mTranslateKeyMap[0x6f] = KEY_F12;
  123. mTranslateKeyMap[0x72] = KEY_INSERT;
  124. mTranslateKeyMap[0x73] = KEY_HOME;
  125. mTranslateKeyMap[0x74] = KEY_PAGE_UP;
  126. mTranslateKeyMap[0x75] = KEY_DELETE;
  127. mTranslateKeyMap[0x76] = KEY_F4;
  128. mTranslateKeyMap[0x77] = KEY_END;
  129. mTranslateKeyMap[0x78] = KEY_F2;
  130. mTranslateKeyMap[0x79] = KEY_PAGE_DOWN;
  131. mTranslateKeyMap[0x7a] = KEY_F1;
  132. mTranslateKeyMap[0x7b] = KEY_LEFT;
  133. mTranslateKeyMap[0x7c] = KEY_RIGHT;
  134. mTranslateKeyMap[0x7d] = KEY_DOWN;
  135. mTranslateKeyMap[0x7e] = KEY_UP;
  136. // Build inverse map
  137. std::map<U32, KEY>::iterator iter;
  138. for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
  139. {
  140. mInvTranslateKeyMap[iter->second] = iter->first;
  141. }
  142. // build numpad maps
  143. mTranslateNumpadMap[0x52] = KEY_PAD_INS; // keypad 0
  144. mTranslateNumpadMap[0x53] = KEY_PAD_END; // keypad 1
  145. mTranslateNumpadMap[0x54] = KEY_PAD_DOWN; // keypad 2
  146. mTranslateNumpadMap[0x55] = KEY_PAD_PGDN; // keypad 3
  147. mTranslateNumpadMap[0x56] = KEY_PAD_LEFT; // keypad 4
  148. mTranslateNumpadMap[0x57] = KEY_PAD_CENTER; // keypad 5
  149. mTranslateNumpadMap[0x58] = KEY_PAD_RIGHT; // keypad 6
  150. mTranslateNumpadMap[0x59] = KEY_PAD_HOME; // keypad 7
  151. mTranslateNumpadMap[0x5b] = KEY_PAD_UP; // keypad 8
  152. mTranslateNumpadMap[0x5c] = KEY_PAD_PGUP; // keypad 9
  153. mTranslateNumpadMap[0x41] = KEY_PAD_DEL; // keypad .
  154. mTranslateNumpadMap[0x4c] = KEY_PAD_RETURN; // keypad enter
  155. // Build inverse numpad map
  156. for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++)
  157. {
  158. mInvTranslateNumpadMap[iter->second] = iter->first;
  159. }
  160. }
  161. void LLKeyboardMacOSX::resetMaskKeys()
  162. {
  163. U32 mask = getModifiers();
  164. // MBW -- XXX -- This mirrors the operation of the Windows version of
  165. // resetMaskKeys(). It looks a bit suspicious, as it won't correct for keys
  166. // that have been released. Is this the way it's supposed to work ?
  167. if (mask & MAC_SHIFT_KEY)
  168. {
  169. mKeyLevel[KEY_SHIFT] = true;
  170. }
  171. if (mask & MAC_CTRL_KEY)
  172. {
  173. mKeyLevel[KEY_CONTROL] = true;
  174. }
  175. if (mask & MAC_ALT_KEY)
  176. {
  177. mKeyLevel[KEY_ALT] = true;
  178. }
  179. }
  180. #if 0
  181. static bool translateKeyMac(U32 key, U32 mask, KEY& out_key, U32& out_mask)
  182. {
  183. // Translate the virtual keycode into the keycodes the keyboard system
  184. // expects.
  185. U32 virtual_key = (mask >> 24) & 0x0000007F;
  186. outKey = macKeyTransArray[virtual_key];
  187. return outKey != 0;
  188. }
  189. #endif
  190. void LLKeyboardMacOSX::handleModifier(MASK mask)
  191. {
  192. updateModifiers(mask);
  193. }
  194. MASK LLKeyboardMacOSX::updateModifiers(U32 mask)
  195. {
  196. // translate the mask
  197. MASK out_mask = 0;
  198. if (mask & MAC_SHIFT_KEY)
  199. {
  200. out_mask |= MASK_SHIFT;
  201. }
  202. if (mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
  203. {
  204. out_mask |= MASK_CONTROL;
  205. }
  206. if (mask & MAC_ALT_KEY)
  207. {
  208. out_mask |= MASK_ALT;
  209. }
  210. return out_mask;
  211. }
  212. bool LLKeyboardMacOSX::handleKeyDown(U32 key, U32 mask)
  213. {
  214. U32 translated_mask = updateModifiers(mask);
  215. KEY translated_key = 0;
  216. if (translateNumpadKey(key, &translated_key, translated_mask))
  217. {
  218. return handleTranslatedKeyDown(translated_key, translated_mask);
  219. }
  220. return false;
  221. }
  222. bool LLKeyboardMacOSX::handleKeyUp(U32 key, U32 mask)
  223. {
  224. U32 translated_mask = updateModifiers(mask);
  225. KEY translated_key = 0;
  226. if (translateNumpadKey(key, &translated_key, translated_mask))
  227. {
  228. return handleTranslatedKeyUp(translated_key, translated_mask);
  229. }
  230. return false;
  231. }
  232. MASK LLKeyboardMacOSX::currentMask(bool for_mouse_event)
  233. {
  234. MASK result = MASK_NONE;
  235. U32 mask = getModifiers();
  236. if (mask & MAC_SHIFT_KEY)
  237. {
  238. result |= MASK_SHIFT;
  239. }
  240. if (mask & MAC_CTRL_KEY)
  241. {
  242. result |= MASK_CONTROL;
  243. }
  244. if (mask & MAC_ALT_KEY)
  245. {
  246. result |= MASK_ALT;
  247. }
  248. // For keyboard events, consider Command equivalent to Control
  249. if (!for_mouse_event && (mask & MAC_CMD_KEY))
  250. {
  251. result |= MASK_CONTROL;
  252. }
  253. return result;
  254. }
  255. void LLKeyboardMacOSX::scanKeyboard()
  256. {
  257. for (S32 key = 0; key < KEY_COUNT; ++key)
  258. {
  259. // Generate callback if any event has occurred on this key this frame.
  260. // Cannot just test mKeyLevel, because this could be a slow frame and
  261. // key might have gone down then up. JC
  262. if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key])
  263. {
  264. mCurScanKey = key;
  265. mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key],
  266. mKeyLevel[key]);
  267. }
  268. }
  269. // Reset edges for next frame
  270. for (S32 key = 0; key < KEY_COUNT; ++key)
  271. {
  272. mKeyUp[key] = false;
  273. mKeyDown[key] = false;
  274. if (mKeyLevel[key])
  275. {
  276. ++mKeyLevelFrameCount[key];
  277. }
  278. }
  279. }
  280. bool LLKeyboardMacOSX::translateNumpadKey(U32 os_key, KEY* translated_key,
  281. MASK mask)
  282. {
  283. if (mNumpadDistinct == ND_NUMLOCK_ON)
  284. {
  285. std::map<U32, KEY>::iterator iter = mTranslateNumpadMap.find(os_key);
  286. if (iter != mTranslateNumpadMap.end())
  287. {
  288. *translated_key = iter->second;
  289. return true;
  290. }
  291. }
  292. return translateKey(os_key, translated_key, mask);
  293. }
  294. U32 LLKeyboardMacOSX::inverseTranslateNumpadKey(KEY translated_key)
  295. {
  296. if (mNumpadDistinct == ND_NUMLOCK_ON)
  297. {
  298. std::map<KEY, U32>::iterator iter =
  299. mInvTranslateNumpadMap.find(translated_key);
  300. if (iter != mInvTranslateNumpadMap.end())
  301. {
  302. return iter->second;
  303. }
  304. }
  305. return inverseTranslateKey(translated_key);
  306. }
  307. #endif // LL_DARWIN