summaryrefslogtreecommitdiff
path: root/indra/llwindow/llkeyboard.h
blob: 2c96df3b5b1a06c6b8fb4cdf07bf94f394b909ce (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
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
 * @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:
#ifndef LL_SDL
    typedef U16 NATIVE_KEY_TYPE;
#else
    typedef U32 NATIVE_KEY_TYPE;
#endif
	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 NATIVE_KEY_TYPE os_key, KEY *translated_key);
    NATIVE_KEY_TYPE		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 NATIVE_KEY_TYPE key, MASK mask) = 0;
	virtual BOOL	handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) = 0;

#ifdef LL_DARWIN
	// 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 stringFromMouse(EMouseClickType click, 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 );
    static std::string stringFromAccelerator(MASK accel_mask, EMouseClickType click);

	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<NATIVE_KEY_TYPE, KEY>	mTranslateKeyMap;		// Map of translations from OS keys to Linden KEYs
	std::map<KEY, NATIVE_KEY_TYPE>	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;
};

// Interface to get key from assigned command
class LLKeyBindingToStringHandler
{
public:
    virtual std::string getKeyBindingAsString(const std::string& mode, const std::string& control) const = 0;
};

extern LLKeyboard *gKeyboard;

#endif