diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llwindow/llkeyboardsdl.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llwindow/llkeyboardsdl.cpp')
-rw-r--r-- | linden/indra/llwindow/llkeyboardsdl.cpp | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/linden/indra/llwindow/llkeyboardsdl.cpp b/linden/indra/llwindow/llkeyboardsdl.cpp new file mode 100644 index 0000000..07db986 --- /dev/null +++ b/linden/indra/llwindow/llkeyboardsdl.cpp | |||
@@ -0,0 +1,343 @@ | |||
1 | /** | ||
2 | * @file llkeyboardsdl.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_SDL | ||
29 | |||
30 | #include "linden_common.h" | ||
31 | #include "llkeyboardsdl.h" | ||
32 | #include "llwindow.h" | ||
33 | #include "SDL/SDL.h" | ||
34 | |||
35 | LLKeyboardSDL::LLKeyboardSDL() | ||
36 | { | ||
37 | // Set up key mapping for SDL - eventually can read this from a file? | ||
38 | // Anything not in the key map gets dropped | ||
39 | // Add default A-Z | ||
40 | |||
41 | // Virtual key mappings from SDL_keysym.h ... | ||
42 | |||
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 | |||
54 | for (cur_char = '0'; cur_char <= '9'; cur_char++) | ||
55 | { | ||
56 | mTranslateKeyMap[cur_char] = cur_char; | ||
57 | } | ||
58 | |||
59 | // These ones are translated manually upon keydown/keyup because | ||
60 | // SDL doesn't handle their numlock transition. | ||
61 | //mTranslateKeyMap[SDLK_KP4] = KEY_PAD_LEFT; | ||
62 | //mTranslateKeyMap[SDLK_KP6] = KEY_PAD_RIGHT; | ||
63 | //mTranslateKeyMap[SDLK_KP8] = KEY_PAD_UP; | ||
64 | //mTranslateKeyMap[SDLK_KP2] = KEY_PAD_DOWN; | ||
65 | //mTranslateKeyMap[SDLK_KP_PERIOD] = KEY_DELETE; | ||
66 | //mTranslateKeyMap[SDLK_KP7] = KEY_HOME; | ||
67 | //mTranslateKeyMap[SDLK_KP1] = KEY_END; | ||
68 | //mTranslateKeyMap[SDLK_KP9] = KEY_PAGE_UP; | ||
69 | //mTranslateKeyMap[SDLK_KP3] = KEY_PAGE_DOWN; | ||
70 | //mTranslateKeyMap[SDLK_KP0] = KEY_INSERT; | ||
71 | |||
72 | mTranslateKeyMap[SDLK_SPACE] = ' '; | ||
73 | mTranslateKeyMap[SDLK_RETURN] = KEY_RETURN; | ||
74 | mTranslateKeyMap[SDLK_LEFT] = KEY_LEFT; | ||
75 | mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT; | ||
76 | mTranslateKeyMap[SDLK_UP] = KEY_UP; | ||
77 | mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN; | ||
78 | mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE; | ||
79 | mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN; | ||
80 | mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE; | ||
81 | mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE; | ||
82 | mTranslateKeyMap[SDLK_DELETE] = KEY_DELETE; | ||
83 | mTranslateKeyMap[SDLK_LSHIFT] = KEY_SHIFT; | ||
84 | mTranslateKeyMap[SDLK_RSHIFT] = KEY_SHIFT; | ||
85 | mTranslateKeyMap[SDLK_LCTRL] = KEY_CONTROL; | ||
86 | mTranslateKeyMap[SDLK_RCTRL] = KEY_CONTROL; | ||
87 | mTranslateKeyMap[SDLK_LALT] = KEY_ALT; | ||
88 | mTranslateKeyMap[SDLK_RALT] = KEY_ALT; | ||
89 | mTranslateKeyMap[SDLK_HOME] = KEY_HOME; | ||
90 | mTranslateKeyMap[SDLK_END] = KEY_END; | ||
91 | mTranslateKeyMap[SDLK_PAGEUP] = KEY_PAGE_UP; | ||
92 | mTranslateKeyMap[SDLK_PAGEDOWN] = KEY_PAGE_DOWN; | ||
93 | mTranslateKeyMap[SDLK_MINUS] = KEY_HYPHEN; | ||
94 | mTranslateKeyMap[SDLK_EQUALS] = KEY_EQUALS; | ||
95 | mTranslateKeyMap[SDLK_KP_EQUALS] = KEY_EQUALS; | ||
96 | mTranslateKeyMap[SDLK_INSERT] = KEY_INSERT; | ||
97 | mTranslateKeyMap[SDLK_CAPSLOCK] = KEY_CAPSLOCK; | ||
98 | mTranslateKeyMap[SDLK_TAB] = KEY_TAB; | ||
99 | mTranslateKeyMap[SDLK_KP_PLUS] = KEY_ADD; | ||
100 | mTranslateKeyMap[SDLK_KP_MINUS] = KEY_SUBTRACT; | ||
101 | mTranslateKeyMap[SDLK_KP_MULTIPLY] = KEY_MULTIPLY; | ||
102 | mTranslateKeyMap[SDLK_KP_DIVIDE] = KEY_DIVIDE; | ||
103 | mTranslateKeyMap[SDLK_F1] = KEY_F1; | ||
104 | mTranslateKeyMap[SDLK_F2] = KEY_F2; | ||
105 | mTranslateKeyMap[SDLK_F3] = KEY_F3; | ||
106 | mTranslateKeyMap[SDLK_F4] = KEY_F4; | ||
107 | mTranslateKeyMap[SDLK_F5] = KEY_F5; | ||
108 | mTranslateKeyMap[SDLK_F6] = KEY_F6; | ||
109 | mTranslateKeyMap[SDLK_F7] = KEY_F7; | ||
110 | mTranslateKeyMap[SDLK_F8] = KEY_F8; | ||
111 | mTranslateKeyMap[SDLK_F9] = KEY_F9; | ||
112 | mTranslateKeyMap[SDLK_F10] = KEY_F10; | ||
113 | mTranslateKeyMap[SDLK_F11] = KEY_F11; | ||
114 | mTranslateKeyMap[SDLK_F12] = KEY_F12; | ||
115 | mTranslateKeyMap[SDLK_PLUS] = '='; | ||
116 | mTranslateKeyMap[SDLK_COMMA] = ','; | ||
117 | mTranslateKeyMap[SDLK_MINUS] = '-'; | ||
118 | mTranslateKeyMap[SDLK_PERIOD] = '.'; | ||
119 | mTranslateKeyMap[SDLK_BACKQUOTE] = '`'; | ||
120 | mTranslateKeyMap[SDLK_SLASH] = '/'; | ||
121 | mTranslateKeyMap[SDLK_SEMICOLON] = ';'; | ||
122 | mTranslateKeyMap[SDLK_LEFTBRACKET] = '['; | ||
123 | mTranslateKeyMap[SDLK_BACKSLASH] = '\\'; | ||
124 | mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']'; | ||
125 | mTranslateKeyMap[SDLK_QUOTE] = '\''; | ||
126 | |||
127 | // Build inverse map | ||
128 | std::map<U16, KEY>::iterator iter; | ||
129 | for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) | ||
130 | { | ||
131 | mInvTranslateKeyMap[iter->second] = iter->first; | ||
132 | } | ||
133 | |||
134 | // numpad map | ||
135 | mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS; | ||
136 | mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END; | ||
137 | mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN; | ||
138 | mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN; | ||
139 | mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT; | ||
140 | mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER; | ||
141 | mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT; | ||
142 | mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME; | ||
143 | mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP; | ||
144 | mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP; | ||
145 | mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL; | ||
146 | |||
147 | // build inverse numpad map | ||
148 | for (iter = mTranslateNumpadMap.begin(); | ||
149 | iter != mTranslateNumpadMap.end(); | ||
150 | iter++) | ||
151 | { | ||
152 | mInvTranslateNumpadMap[iter->second] = iter->first; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | void LLKeyboardSDL::resetMaskKeys() | ||
157 | { | ||
158 | SDLMod mask = SDL_GetModState(); | ||
159 | |||
160 | // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys(). | ||
161 | // It looks a bit suspicious, as it won't correct for keys that have been released. | ||
162 | // Is this the way it's supposed to work? | ||
163 | |||
164 | if(mask & KMOD_SHIFT) | ||
165 | { | ||
166 | mKeyLevel[KEY_SHIFT] = TRUE; | ||
167 | } | ||
168 | |||
169 | if(mask & KMOD_CTRL) | ||
170 | { | ||
171 | mKeyLevel[KEY_CONTROL] = TRUE; | ||
172 | } | ||
173 | |||
174 | if(mask & KMOD_ALT) | ||
175 | { | ||
176 | mKeyLevel[KEY_ALT] = TRUE; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | |||
181 | MASK LLKeyboardSDL::updateModifiers(const U32 mask) | ||
182 | { | ||
183 | // translate the mask | ||
184 | MASK out_mask = MASK_NONE; | ||
185 | |||
186 | if(mask & KMOD_SHIFT) | ||
187 | { | ||
188 | out_mask |= MASK_SHIFT; | ||
189 | } | ||
190 | |||
191 | if(mask & KMOD_CTRL) | ||
192 | { | ||
193 | out_mask |= MASK_CONTROL; | ||
194 | } | ||
195 | |||
196 | if(mask & KMOD_ALT) | ||
197 | { | ||
198 | out_mask |= MASK_ALT; | ||
199 | } | ||
200 | |||
201 | return out_mask; | ||
202 | } | ||
203 | |||
204 | |||
205 | static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask) | ||
206 | { | ||
207 | // SDL doesn't automatically adjust the keysym according to | ||
208 | // whether NUMLOCK is engaged, so we massage the keysym manually. | ||
209 | U16 rtn = key; | ||
210 | if (!(mask & KMOD_NUM)) | ||
211 | { | ||
212 | switch (key) | ||
213 | { | ||
214 | case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; | ||
215 | case SDLK_KP0: rtn = SDLK_INSERT; break; | ||
216 | case SDLK_KP1: rtn = SDLK_END; break; | ||
217 | case SDLK_KP2: rtn = SDLK_DOWN; break; | ||
218 | case SDLK_KP3: rtn = SDLK_PAGEDOWN; break; | ||
219 | case SDLK_KP4: rtn = SDLK_LEFT; break; | ||
220 | case SDLK_KP6: rtn = SDLK_RIGHT; break; | ||
221 | case SDLK_KP7: rtn = SDLK_HOME; break; | ||
222 | case SDLK_KP8: rtn = SDLK_UP; break; | ||
223 | case SDLK_KP9: rtn = SDLK_PAGEUP; break; | ||
224 | } | ||
225 | } | ||
226 | return rtn; | ||
227 | } | ||
228 | |||
229 | |||
230 | BOOL LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) | ||
231 | { | ||
232 | U16 adjusted_nativekey; | ||
233 | KEY translated_key = 0; | ||
234 | U32 translated_mask = MASK_NONE; | ||
235 | BOOL handled = FALSE; | ||
236 | |||
237 | adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); | ||
238 | |||
239 | translated_mask = updateModifiers(mask); | ||
240 | |||
241 | if(translateNumpadKey(adjusted_nativekey, &translated_key)) | ||
242 | { | ||
243 | handled = handleTranslatedKeyDown(translated_key, translated_mask); | ||
244 | } | ||
245 | |||
246 | return handled; | ||
247 | } | ||
248 | |||
249 | |||
250 | BOOL LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask) | ||
251 | { | ||
252 | U16 adjusted_nativekey; | ||
253 | KEY translated_key = 0; | ||
254 | U32 translated_mask = MASK_NONE; | ||
255 | BOOL handled = FALSE; | ||
256 | |||
257 | adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); | ||
258 | |||
259 | translated_mask = updateModifiers(mask); | ||
260 | |||
261 | if(translateNumpadKey(adjusted_nativekey, &translated_key)) | ||
262 | { | ||
263 | handled = handleTranslatedKeyUp(translated_key, translated_mask); | ||
264 | } | ||
265 | |||
266 | return handled; | ||
267 | } | ||
268 | |||
269 | MASK LLKeyboardSDL::currentMask(BOOL for_mouse_event) | ||
270 | { | ||
271 | MASK result = MASK_NONE; | ||
272 | SDLMod mask = SDL_GetModState(); | ||
273 | |||
274 | if (mask & KMOD_SHIFT) result |= MASK_SHIFT; | ||
275 | if (mask & KMOD_CTRL) result |= MASK_CONTROL; | ||
276 | if (mask & KMOD_ALT) result |= MASK_ALT; | ||
277 | |||
278 | // For keyboard events, consider Meta keys equivalent to Control | ||
279 | if (!for_mouse_event) | ||
280 | { | ||
281 | if (mask & KMOD_META) result |= MASK_CONTROL; | ||
282 | } | ||
283 | |||
284 | return result; | ||
285 | } | ||
286 | |||
287 | void LLKeyboardSDL::scanKeyboard() | ||
288 | { | ||
289 | for (S32 key = 0; key < KEY_COUNT; key++) | ||
290 | { | ||
291 | // Generate callback if any event has occurred on this key this frame. | ||
292 | // Can't just test mKeyLevel, because this could be a slow frame and | ||
293 | // key might have gone down then up. JC | ||
294 | if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) | ||
295 | { | ||
296 | mCurScanKey = key; | ||
297 | mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | // Reset edges for next frame | ||
302 | for (S32 key = 0; key < KEY_COUNT; key++) | ||
303 | { | ||
304 | mKeyUp[key] = FALSE; | ||
305 | mKeyDown[key] = FALSE; | ||
306 | if (mKeyLevel[key]) | ||
307 | { | ||
308 | mKeyLevelFrameCount[key]++; | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | |||
314 | BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key) | ||
315 | { | ||
316 | if(mNumpadDistinct == ND_NUMLOCK_ON) | ||
317 | { | ||
318 | std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); | ||
319 | if(iter != mTranslateNumpadMap.end()) | ||
320 | { | ||
321 | *translated_key = iter->second; | ||
322 | return TRUE; | ||
323 | } | ||
324 | } | ||
325 | BOOL success = translateKey(os_key, translated_key); | ||
326 | return success; | ||
327 | } | ||
328 | |||
329 | U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) | ||
330 | { | ||
331 | if(mNumpadDistinct == ND_NUMLOCK_ON) | ||
332 | { | ||
333 | std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key); | ||
334 | if(iter != mInvTranslateNumpadMap.end()) | ||
335 | { | ||
336 | return iter->second; | ||
337 | } | ||
338 | } | ||
339 | return inverseTranslateKey(translated_key); | ||
340 | } | ||
341 | |||
342 | #endif | ||
343 | |||