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