summaryrefslogtreecommitdiff
path: root/indra/llwindow/llkeyboard.h
blob: 0cfba78c5b31401cf113428efe832657b203efb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/** 
 * @file llkeyboard.h
 * @brief Handler for assignable key bindings
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLKEYBOARD_H
#define LL_LLKEYBOARD_H

#include <map>
#include <boost/function.hpp>

#include "llstringtable.h"
#include "lltimer.h"
#include "indra_constants.h"

enum EKeystate 
{
	KEYSTATE_DOWN,
	KEYSTATE_LEVEL,
	KEYSTATE_UP
};

typedef boost::function<bool(EKeystate keystate)> LLKeyFunc;
typedef std::string (LLKeyStringTranslatorFunc)(const char *label);
	
enum EKeyboardInsertMode
{
	LL_KIM_INSERT,
	LL_KIM_OVERWRITE
};

class LLWindowCallbacks;

class LLKeyboard
{
public:
	LLKeyboard();
	virtual ~LLKeyboard();

    void			resetKeyDownAndHandle();
    void			resetKeys();


	F32				getCurKeyElapsedTime()	{ return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; }
	F32				getCurKeyElapsedFrameCount()	{ return getKeyDown(mCurScanKey) ? (F32)getKeyElapsedFrameCount( mCurScanKey ) : 0.f; }
	BOOL			getKeyDown(const KEY key) { return mKeyLevel[key]; }
	BOOL			getKeyRepeated(const KEY key) { return mKeyRepeated[key]; }

	BOOL			translateKey(const U32 os_key, KEY *translated_key);
	U32				inverseTranslateKey(const KEY translated_key);
	BOOL			handleTranslatedKeyUp(KEY translated_key, U32 translated_mask);		// Translated into "Linden" keycodes
	BOOL			handleTranslatedKeyDown(KEY translated_key, U32 translated_mask);	// Translated into "Linden" keycodes


	virtual BOOL	handleKeyUp(const U32 key, MASK mask) = 0;
	virtual BOOL	handleKeyDown(const U32 key, MASK mask) = 0;
	
#if defined(LL_DARWIN) && !defined(LL_SDL)
	// We only actually use this for OS X.
	virtual void	handleModifier(MASK mask) = 0;
#endif // LL_DARWIN

	// Asynchronously poll the control, alt, and shift keys and set the
	// appropriate internal key masks.
	virtual void	resetMaskKeys() = 0;
	virtual void	scanKeyboard() = 0;															// scans keyboard, calls functions as necessary
	// Mac must differentiate between Command = Control for keyboard events
	// and Command != Control for mouse events.
	virtual MASK	currentMask(BOOL for_mouse_event) = 0;
	virtual KEY		currentKey() { return mCurTranslatedKey; }

	EKeyboardInsertMode getInsertMode()	{ return mInsertMode; }
	void toggleInsertMode();

	static BOOL		maskFromString(const std::string& str, MASK *mask);		// False on failure
	static BOOL		keyFromString(const std::string& str, KEY *key);			// False on failure
	static std::string stringFromKey(KEY key, bool translate = true);
	static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"...
	static std::string stringFromAccelerator( MASK accel_mask, KEY key );

	void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
	F32				getKeyElapsedTime( KEY key );  // Returns time in seconds since key was pressed.
	S32				getKeyElapsedFrameCount( KEY key );  // Returns time in frames since key was pressed.

	static void		setStringTranslatorFunc( LLKeyStringTranslatorFunc *trans_func );
	
protected:
	void 			addKeyName(KEY key, const std::string& name);

protected:
	std::map<U32, KEY>	mTranslateKeyMap;		// Map of translations from OS keys to Linden KEYs
	std::map<KEY, U32>	mInvTranslateKeyMap;	// Map of translations from Linden KEYs to OS keys
	LLWindowCallbacks *mCallbacks;

	LLTimer			mKeyLevelTimer[KEY_COUNT];	// Time since level was set
	S32				mKeyLevelFrameCount[KEY_COUNT];	// Frames since level was set
	BOOL			mKeyLevel[KEY_COUNT];		// Levels
	BOOL			mKeyRepeated[KEY_COUNT];	// Key was repeated
	BOOL			mKeyUp[KEY_COUNT];			// Up edge
	BOOL			mKeyDown[KEY_COUNT];		// Down edge
	KEY				mCurTranslatedKey;
	KEY				mCurScanKey;		// Used during the scanKeyboard()

	static LLKeyStringTranslatorFunc*	mStringTranslator;	// Used for l10n + PC/Mac/Linux accelerator labeling
	
	EKeyboardInsertMode mInsertMode;

	static std::map<KEY,std::string> sKeysToNames;
	static std::map<std::string,KEY> sNamesToKeys;
};

extern LLKeyboard *gKeyboard;

#endif