1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _LIBINPUT_DISPLAY_VIEWPORT_H
18 #define _LIBINPUT_DISPLAY_VIEWPORT_H
19 
20 #include <cinttypes>
21 #include <optional>
22 
23 #include <android-base/stringprintf.h>
24 #include <input/Input.h>
25 
26 using android::base::StringPrintf;
27 
28 namespace android {
29 
30 enum {
31     DISPLAY_ORIENTATION_0 = 0,
32     DISPLAY_ORIENTATION_90 = 1,
33     DISPLAY_ORIENTATION_180 = 2,
34     DISPLAY_ORIENTATION_270 = 3
35 };
36 
37 /**
38  * Describes the different type of viewports supported by input flinger.
39  * Keep in sync with values in InputManagerService.java.
40  */
41 enum class ViewportType : int32_t {
42     VIEWPORT_INTERNAL = 1,
43     VIEWPORT_EXTERNAL = 2,
44     VIEWPORT_VIRTUAL = 3,
45 };
46 
viewportTypeToString(ViewportType type)47 static const char* viewportTypeToString(ViewportType type) {
48     switch(type) {
49         case ViewportType::VIEWPORT_INTERNAL:
50             return "INTERNAL";
51         case ViewportType::VIEWPORT_EXTERNAL:
52             return "EXTERNAL";
53         case ViewportType::VIEWPORT_VIRTUAL:
54             return "VIRTUAL";
55         default:
56             return "UNKNOWN";
57     }
58 }
59 
60 /*
61  * Describes how coordinates are mapped on a physical display.
62  * See com.android.server.display.DisplayViewport.
63  */
64 struct DisplayViewport {
65     int32_t displayId; // -1 if invalid
66     int32_t orientation;
67     int32_t logicalLeft;
68     int32_t logicalTop;
69     int32_t logicalRight;
70     int32_t logicalBottom;
71     int32_t physicalLeft;
72     int32_t physicalTop;
73     int32_t physicalRight;
74     int32_t physicalBottom;
75     int32_t deviceWidth;
76     int32_t deviceHeight;
77     bool isActive;
78     std::string uniqueId;
79     // The actual (hardware) port that the associated display is connected to.
80     // Not all viewports will have this specified.
81     std::optional<uint8_t> physicalPort;
82     ViewportType type;
83 
DisplayViewportDisplayViewport84     DisplayViewport()
85           : displayId(ADISPLAY_ID_NONE),
86             orientation(DISPLAY_ORIENTATION_0),
87             logicalLeft(0),
88             logicalTop(0),
89             logicalRight(0),
90             logicalBottom(0),
91             physicalLeft(0),
92             physicalTop(0),
93             physicalRight(0),
94             physicalBottom(0),
95             deviceWidth(0),
96             deviceHeight(0),
97             isActive(false),
98             uniqueId(),
99             physicalPort(std::nullopt),
100             type(ViewportType::VIEWPORT_INTERNAL) {}
101 
102     bool operator==(const DisplayViewport& other) const {
103         return displayId == other.displayId && orientation == other.orientation &&
104                 logicalLeft == other.logicalLeft && logicalTop == other.logicalTop &&
105                 logicalRight == other.logicalRight && logicalBottom == other.logicalBottom &&
106                 physicalLeft == other.physicalLeft && physicalTop == other.physicalTop &&
107                 physicalRight == other.physicalRight && physicalBottom == other.physicalBottom &&
108                 deviceWidth == other.deviceWidth && deviceHeight == other.deviceHeight &&
109                 isActive == other.isActive && uniqueId == other.uniqueId &&
110                 physicalPort == other.physicalPort && type == other.type;
111     }
112 
113     bool operator!=(const DisplayViewport& other) const {
114         return !(*this == other);
115     }
116 
isValidDisplayViewport117     inline bool isValid() const {
118         return displayId >= 0;
119     }
120 
setNonDisplayViewportDisplayViewport121     void setNonDisplayViewport(int32_t width, int32_t height) {
122         displayId = ADISPLAY_ID_NONE;
123         orientation = DISPLAY_ORIENTATION_0;
124         logicalLeft = 0;
125         logicalTop = 0;
126         logicalRight = width;
127         logicalBottom = height;
128         physicalLeft = 0;
129         physicalTop = 0;
130         physicalRight = width;
131         physicalBottom = height;
132         deviceWidth = width;
133         deviceHeight = height;
134         isActive = false;
135         uniqueId.clear();
136         physicalPort = std::nullopt;
137         type = ViewportType::VIEWPORT_INTERNAL;
138     }
139 
toStringDisplayViewport140     std::string toString() const {
141         return StringPrintf("Viewport %s: displayId=%d, uniqueId=%s, port=%s, orientation=%d, "
142                             "logicalFrame=[%d, %d, %d, %d], "
143                             "physicalFrame=[%d, %d, %d, %d], "
144                             "deviceSize=[%d, %d], "
145                             "isActive=[%d]",
146                             viewportTypeToString(type), displayId, uniqueId.c_str(),
147                             physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str()
148                                          : "<none>",
149                             orientation, logicalLeft, logicalTop, logicalRight, logicalBottom,
150                             physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth,
151                             deviceHeight, isActive);
152     }
153 };
154 
155 } // namespace android
156 
157 #endif // _LIBINPUT_DISPLAY_VIEWPORT_H
158