summaryrefslogtreecommitdiff
path: root/indra/llwindow/llkeyboard.h
blob: a5272276726f8ef23effb7f8a73719439090771e (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)(std::string_view);

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;

#if defined(LL_DARWIN) && !defined(LL_SDL)
    // We only actually use this for macOS.
    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