diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llwindow/llkeyboardmacosx.cpp | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/linden/indra/llwindow/llkeyboardmacosx.cpp b/linden/indra/llwindow/llkeyboardmacosx.cpp new file mode 100644 index 0000000..961bb66 --- /dev/null +++ b/linden/indra/llwindow/llkeyboardmacosx.cpp | |||
@@ -0,0 +1,328 @@ | |||
1 | /** | ||
2 | * @file llkeyboardmacosx.cpp | ||
3 | * @brief Handler for assignable key bindings | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #if LL_DARWIN | ||
29 | |||
30 | #include "linden_common.h" | ||
31 | #include "llkeyboardmacosx.h" | ||
32 | #include "llwindow.h" | ||
33 | |||
34 | #include <Carbon/Carbon.h> | ||
35 | |||
36 | LLKeyboardMacOSX::LLKeyboardMacOSX() | ||
37 | { | ||
38 | // Virtual keycode mapping table. Yes, this was as annoying to generate as it looks. | ||
39 | mTranslateKeyMap[0x00] = 'A'; | ||
40 | mTranslateKeyMap[0x01] = 'S'; | ||
41 | mTranslateKeyMap[0x02] = 'D'; | ||
42 | mTranslateKeyMap[0x03] = 'F'; | ||
43 | mTranslateKeyMap[0x04] = 'H'; | ||
44 | mTranslateKeyMap[0x05] = 'G'; | ||
45 | mTranslateKeyMap[0x06] = 'Z'; | ||
46 | mTranslateKeyMap[0x07] = 'X'; | ||
47 | mTranslateKeyMap[0x08] = 'C'; | ||
48 | mTranslateKeyMap[0x09] = 'V'; | ||
49 | mTranslateKeyMap[0x0b] = 'B'; | ||
50 | mTranslateKeyMap[0x0c] = 'Q'; | ||
51 | mTranslateKeyMap[0x0d] = 'W'; | ||
52 | mTranslateKeyMap[0x0e] = 'E'; | ||
53 | mTranslateKeyMap[0x0f] = 'R'; | ||
54 | mTranslateKeyMap[0x10] = 'Y'; | ||
55 | mTranslateKeyMap[0x11] = 'T'; | ||
56 | mTranslateKeyMap[0x12] = '1'; | ||
57 | mTranslateKeyMap[0x13] = '2'; | ||
58 | mTranslateKeyMap[0x14] = '3'; | ||
59 | mTranslateKeyMap[0x15] = '4'; | ||
60 | mTranslateKeyMap[0x16] = '6'; | ||
61 | mTranslateKeyMap[0x17] = '5'; | ||
62 | mTranslateKeyMap[0x18] = '='; // KEY_EQUALS | ||
63 | mTranslateKeyMap[0x19] = '9'; | ||
64 | mTranslateKeyMap[0x1a] = '7'; | ||
65 | mTranslateKeyMap[0x1b] = '-'; // KEY_HYPHEN | ||
66 | mTranslateKeyMap[0x1c] = '8'; | ||
67 | mTranslateKeyMap[0x1d] = '0'; | ||
68 | mTranslateKeyMap[0x1e] = ']'; | ||
69 | mTranslateKeyMap[0x1f] = 'O'; | ||
70 | mTranslateKeyMap[0x20] = 'U'; | ||
71 | mTranslateKeyMap[0x21] = '['; | ||
72 | mTranslateKeyMap[0x22] = 'I'; | ||
73 | mTranslateKeyMap[0x23] = 'P'; | ||
74 | mTranslateKeyMap[0x24] = KEY_RETURN, | ||
75 | mTranslateKeyMap[0x25] = 'L'; | ||
76 | mTranslateKeyMap[0x26] = 'J'; | ||
77 | mTranslateKeyMap[0x27] = '\''; | ||
78 | mTranslateKeyMap[0x28] = 'K'; | ||
79 | mTranslateKeyMap[0x29] = ';'; | ||
80 | mTranslateKeyMap[0x2a] = '\\'; | ||
81 | mTranslateKeyMap[0x2b] = ','; | ||
82 | mTranslateKeyMap[0x2c] = '/'; | ||
83 | mTranslateKeyMap[0x2d] = 'N'; | ||
84 | mTranslateKeyMap[0x2e] = 'M'; | ||
85 | mTranslateKeyMap[0x2f] = '.'; | ||
86 | mTranslateKeyMap[0x30] = KEY_TAB; | ||
87 | mTranslateKeyMap[0x31] = ' '; // space! | ||
88 | mTranslateKeyMap[0x32] = '`'; | ||
89 | mTranslateKeyMap[0x33] = KEY_BACKSPACE; | ||
90 | mTranslateKeyMap[0x35] = KEY_ESCAPE; | ||
91 | //mTranslateKeyMap[0x37] = 0; // Command key. (not used yet) | ||
92 | mTranslateKeyMap[0x38] = KEY_SHIFT; | ||
93 | mTranslateKeyMap[0x39] = KEY_CAPSLOCK; | ||
94 | mTranslateKeyMap[0x3a] = KEY_ALT; | ||
95 | mTranslateKeyMap[0x3b] = KEY_CONTROL; | ||
96 | mTranslateKeyMap[0x41] = '.'; // keypad | ||
97 | mTranslateKeyMap[0x43] = '*'; // keypad | ||
98 | mTranslateKeyMap[0x45] = '+'; // keypad | ||
99 | mTranslateKeyMap[0x4b] = '/'; // keypad | ||
100 | mTranslateKeyMap[0x4c] = KEY_RETURN; // keypad enter | ||
101 | mTranslateKeyMap[0x4e] = '-'; // keypad | ||
102 | mTranslateKeyMap[0x51] = '='; // keypad | ||
103 | mTranslateKeyMap[0x52] = '0'; // keypad | ||
104 | mTranslateKeyMap[0x53] = '1'; // keypad | ||
105 | mTranslateKeyMap[0x54] = '2'; // keypad | ||
106 | mTranslateKeyMap[0x55] = '3'; // keypad | ||
107 | mTranslateKeyMap[0x56] = '4'; // keypad | ||
108 | mTranslateKeyMap[0x57] = '5'; // keypad | ||
109 | mTranslateKeyMap[0x58] = '6'; // keypad | ||
110 | mTranslateKeyMap[0x59] = '7'; // keypad | ||
111 | mTranslateKeyMap[0x5b] = '8'; // keypad | ||
112 | mTranslateKeyMap[0x5c] = '9'; // keypad | ||
113 | mTranslateKeyMap[0x60] = KEY_F5; | ||
114 | mTranslateKeyMap[0x61] = KEY_F6; | ||
115 | mTranslateKeyMap[0x62] = KEY_F7; | ||
116 | mTranslateKeyMap[0x63] = KEY_F3; | ||
117 | mTranslateKeyMap[0x64] = KEY_F8; | ||
118 | mTranslateKeyMap[0x65] = KEY_F9; | ||
119 | mTranslateKeyMap[0x67] = KEY_F11; | ||
120 | mTranslateKeyMap[0x6d] = KEY_F10; | ||
121 | mTranslateKeyMap[0x6f] = KEY_F12; | ||
122 | mTranslateKeyMap[0x72] = KEY_INSERT; | ||
123 | mTranslateKeyMap[0x73] = KEY_HOME; | ||
124 | mTranslateKeyMap[0x74] = KEY_PAGE_UP; | ||
125 | mTranslateKeyMap[0x75] = KEY_DELETE; | ||
126 | mTranslateKeyMap[0x76] = KEY_F4; | ||
127 | mTranslateKeyMap[0x77] = KEY_END; | ||
128 | mTranslateKeyMap[0x78] = KEY_F2; | ||
129 | mTranslateKeyMap[0x79] = KEY_PAGE_DOWN; | ||
130 | mTranslateKeyMap[0x7a] = KEY_F1; | ||
131 | mTranslateKeyMap[0x7b] = KEY_LEFT; | ||
132 | mTranslateKeyMap[0x7c] = KEY_RIGHT; | ||
133 | mTranslateKeyMap[0x7d] = KEY_DOWN; | ||
134 | mTranslateKeyMap[0x7e] = KEY_UP; | ||
135 | |||
136 | // Build inverse map | ||
137 | std::map<U16, KEY>::iterator iter; | ||
138 | for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) | ||
139 | { | ||
140 | mInvTranslateKeyMap[iter->second] = iter->first; | ||
141 | } | ||
142 | |||
143 | // build numpad maps | ||
144 | mTranslateNumpadMap[0x52] = KEY_PAD_INS; // keypad 0 | ||
145 | mTranslateNumpadMap[0x53] = KEY_PAD_END; // keypad 1 | ||
146 | mTranslateNumpadMap[0x54] = KEY_PAD_DOWN; // keypad 2 | ||
147 | mTranslateNumpadMap[0x55] = KEY_PAD_PGDN; // keypad 3 | ||
148 | mTranslateNumpadMap[0x56] = KEY_PAD_LEFT; // keypad 4 | ||
149 | mTranslateNumpadMap[0x57] = KEY_PAD_CENTER; // keypad 5 | ||
150 | mTranslateNumpadMap[0x58] = KEY_PAD_RIGHT; // keypad 6 | ||
151 | mTranslateNumpadMap[0x59] = KEY_PAD_HOME; // keypad 7 | ||
152 | mTranslateNumpadMap[0x5b] = KEY_PAD_UP; // keypad 8 | ||
153 | mTranslateNumpadMap[0x5c] = KEY_PAD_PGUP; // keypad 9 | ||
154 | mTranslateNumpadMap[0x41] = KEY_PAD_DEL; // keypad . | ||
155 | mTranslateNumpadMap[0x4c] = KEY_PAD_RETURN; // keypad enter | ||
156 | |||
157 | // Build inverse numpad map | ||
158 | for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) | ||
159 | { | ||
160 | mInvTranslateNumpadMap[iter->second] = iter->first; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | void LLKeyboardMacOSX::resetMaskKeys() | ||
165 | { | ||
166 | U32 mask = GetCurrentEventKeyModifiers(); | ||
167 | |||
168 | // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys(). | ||
169 | // It looks a bit suspicious, as it won't correct for keys that have been released. | ||
170 | // Is this the way it's supposed to work? | ||
171 | |||
172 | if(mask & shiftKey) | ||
173 | { | ||
174 | mKeyLevel[KEY_SHIFT] = TRUE; | ||
175 | } | ||
176 | |||
177 | if(mask & (controlKey)) | ||
178 | { | ||
179 | mKeyLevel[KEY_CONTROL] = TRUE; | ||
180 | } | ||
181 | |||
182 | if(mask & optionKey) | ||
183 | { | ||
184 | mKeyLevel[KEY_ALT] = TRUE; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &outMask) | ||
190 | { | ||
191 | // Translate the virtual keycode into the keycodes the keyboard system expects. | ||
192 | U16 virtualKey = (mask >> 24) & 0x0000007F; | ||
193 | outKey = macKeyTransArray[virtualKey]; | ||
194 | |||
195 | |||
196 | return(outKey != 0); | ||
197 | } | ||
198 | */ | ||
199 | |||
200 | MASK LLKeyboardMacOSX::updateModifiers(const U32 mask) | ||
201 | { | ||
202 | // translate the mask | ||
203 | MASK out_mask = 0; | ||
204 | |||
205 | if(mask & shiftKey) | ||
206 | { | ||
207 | out_mask |= MASK_SHIFT; | ||
208 | } | ||
209 | |||
210 | if(mask & (controlKey | cmdKey)) | ||
211 | { | ||
212 | out_mask |= MASK_CONTROL; | ||
213 | } | ||
214 | |||
215 | if(mask & optionKey) | ||
216 | { | ||
217 | out_mask |= MASK_ALT; | ||
218 | } | ||
219 | |||
220 | return out_mask; | ||
221 | } | ||
222 | |||
223 | BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask) | ||
224 | { | ||
225 | KEY translated_key = 0; | ||
226 | U32 translated_mask = 0; | ||
227 | BOOL handled = FALSE; | ||
228 | |||
229 | translated_mask = updateModifiers(mask); | ||
230 | |||
231 | if(translateNumpadKey(key, &translated_key)) | ||
232 | { | ||
233 | handled = handleTranslatedKeyDown(translated_key, translated_mask); | ||
234 | } | ||
235 | |||
236 | return handled; | ||
237 | } | ||
238 | |||
239 | |||
240 | BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask) | ||
241 | { | ||
242 | KEY translated_key = 0; | ||
243 | U32 translated_mask = 0; | ||
244 | BOOL handled = FALSE; | ||
245 | |||
246 | translated_mask = updateModifiers(mask); | ||
247 | |||
248 | if(translateNumpadKey(key, &translated_key)) | ||
249 | { | ||
250 | handled = handleTranslatedKeyUp(translated_key, translated_mask); | ||
251 | } | ||
252 | |||
253 | return handled; | ||
254 | } | ||
255 | |||
256 | MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event) | ||
257 | { | ||
258 | MASK result = MASK_NONE; | ||
259 | U32 mask = GetCurrentEventKeyModifiers(); | ||
260 | |||
261 | if (mask & shiftKey) result |= MASK_SHIFT; | ||
262 | if (mask & controlKey) result |= MASK_CONTROL; | ||
263 | if (mask & optionKey) result |= MASK_ALT; | ||
264 | |||
265 | // For keyboard events, consider Command equivalent to Control | ||
266 | if (!for_mouse_event) | ||
267 | { | ||
268 | if (mask & cmdKey) result |= MASK_CONTROL; | ||
269 | } | ||
270 | |||
271 | return result; | ||
272 | } | ||
273 | |||
274 | void LLKeyboardMacOSX::scanKeyboard() | ||
275 | { | ||
276 | S32 key; | ||
277 | for (key = 0; key < KEY_COUNT; key++) | ||
278 | { | ||
279 | // Generate callback if any event has occurred on this key this frame. | ||
280 | // Can't just test mKeyLevel, because this could be a slow frame and | ||
281 | // key might have gone down then up. JC | ||
282 | if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) | ||
283 | { | ||
284 | mCurScanKey = key; | ||
285 | mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | // Reset edges for next frame | ||
290 | for (key = 0; key < KEY_COUNT; key++) | ||
291 | { | ||
292 | mKeyUp[key] = FALSE; | ||
293 | mKeyDown[key] = FALSE; | ||
294 | if (mKeyLevel[key]) | ||
295 | { | ||
296 | mKeyLevelFrameCount[key]++; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | |||
301 | BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key ) | ||
302 | { | ||
303 | if(mNumpadDistinct == ND_NUMLOCK_ON) | ||
304 | { | ||
305 | std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); | ||
306 | if(iter != mTranslateNumpadMap.end()) | ||
307 | { | ||
308 | *translated_key = iter->second; | ||
309 | return TRUE; | ||
310 | } | ||
311 | } | ||
312 | return translateKey(os_key, translated_key); | ||
313 | } | ||
314 | |||
315 | U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key) | ||
316 | { | ||
317 | if(mNumpadDistinct == ND_NUMLOCK_ON) | ||
318 | { | ||
319 | std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key); | ||
320 | if(iter != mInvTranslateNumpadMap.end()) | ||
321 | { | ||
322 | return iter->second; | ||
323 | } | ||
324 | } | ||
325 | return inverseTranslateKey(translated_key); | ||
326 | } | ||
327 | |||
328 | #endif // LL_DARWIN | ||