aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llwindow/llkeyboardsdl.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llwindow/llkeyboardsdl.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp343
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
35LLKeyboardSDL::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
156void 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
181MASK 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
205static 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
230BOOL 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
250BOOL 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
269MASK 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
287void 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
314BOOL 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
329U16 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