summaryrefslogtreecommitdiff
path: root/include/input/KeyLayoutMap.h
blob: b2bd535cbf71b6d417fc9856df771d78e4f11ac3 (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
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LIBINPUT_KEY_LAYOUT_MAP_H
#define _LIBINPUT_KEY_LAYOUT_MAP_H

#include <android-base/result.h>
#include <stdint.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/Tokenizer.h>

#include <input/InputDevice.h>

namespace android {

struct AxisInfo {
    enum Mode {
        // Axis value is reported directly.
        MODE_NORMAL = 0,
        // Axis value should be inverted before reporting.
        MODE_INVERT = 1,
        // Axis value should be split into two axes
        MODE_SPLIT = 2,
    };

    // Axis mode.
    Mode mode;

    // Axis id.
    // When split, this is the axis used for values smaller than the split position.
    int32_t axis;

    // When split, this is the axis used for values after higher than the split position.
    int32_t highAxis;

    // The split value, or 0 if not split.
    int32_t splitValue;

    // The flat value, or -1 if none.
    int32_t flatOverride;

    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
    }
};

/**
 * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
 *
 * This object is immutable after it has been loaded.
 */
class KeyLayoutMap {
public:
    static base::Result<std::shared_ptr<KeyLayoutMap>> load(const std::string& filename);
    static base::Result<std::shared_ptr<KeyLayoutMap>> load(Tokenizer* tokenizer);
    static base::Result<std::shared_ptr<KeyLayoutMap>> loadContents(const std::string& filename,
                                                                    const char* contents);

    status_t mapKey(int32_t scanCode, int32_t usageCode,
            int32_t* outKeyCode, uint32_t* outFlags) const;
    status_t findScanCodesForKey(int32_t keyCode, std::vector<int32_t>* outScanCodes) const;
    status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const;
    status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const;

    status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
    const std::string getLoadFileName() const;
    // Return pair of sensor type and sensor data index, for the input device abs code
    base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor(int32_t absCode);

    virtual ~KeyLayoutMap();

private:
    struct Key {
        int32_t keyCode;
        uint32_t flags;
    };

    struct Led {
        int32_t ledCode;
    };

    struct Sensor {
        InputDeviceSensorType sensorType;
        int32_t sensorDataIndex;
    };

    KeyedVector<int32_t, Key> mKeysByScanCode;
    KeyedVector<int32_t, Key> mKeysByUsageCode;
    KeyedVector<int32_t, AxisInfo> mAxes;
    KeyedVector<int32_t, Led> mLedsByScanCode;
    KeyedVector<int32_t, Led> mLedsByUsageCode;
    std::unordered_map<int32_t, Sensor> mSensorsByAbsCode;
    std::string mLoadFileName;

    KeyLayoutMap();

    const Key* getKey(int32_t scanCode, int32_t usageCode) const;

    class Parser {
        KeyLayoutMap* mMap;
        Tokenizer* mTokenizer;

    public:
        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
        ~Parser();
        status_t parse();

    private:
        status_t parseKey();
        status_t parseAxis();
        status_t parseLed();
        status_t parseSensor();
    };
};

} // namespace android

#endif // _LIBINPUT_KEY_LAYOUT_MAP_H