• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "adapter/preview/entrance/samples/event_adapter.h"
17 
18 #include <GLFW/glfw3.h>
19 #include <map>
20 #include <memory>
21 
22 #include "base/utils/utils.h"
23 #include "frameworks/base/log/log.h"
24 
25 namespace OHOS::Ace::Sample {
26 
27 namespace {
28 const std::map<int, KeyAction> ACTION_MAP = {
29     { GLFW_RELEASE, KeyAction::UP },
30     { GLFW_PRESS, KeyAction::DOWN },
31     { GLFW_REPEAT, KeyAction::LONG_PRESS },
32 };
33 
34 const std::map<int, KeyCode> CODE_MAP = {
35     { GLFW_KEY_BACKSPACE, KeyCode::KEY_FORWARD_DEL },
36     { GLFW_KEY_DELETE, KeyCode::KEY_DEL },
37     { GLFW_KEY_ESCAPE, KeyCode::KEY_ESCAPE },
38     { GLFW_KEY_ENTER, KeyCode::KEY_ENTER },
39     { GLFW_KEY_CAPS_LOCK, KeyCode::KEY_CAPS_LOCK },
40     { GLFW_KEY_UP, KeyCode::KEY_DPAD_UP },
41     { GLFW_KEY_DOWN, KeyCode::KEY_DPAD_DOWN },
42     { GLFW_KEY_LEFT, KeyCode::KEY_DPAD_LEFT },
43     { GLFW_KEY_RIGHT, KeyCode::KEY_DPAD_RIGHT },
44     { GLFW_KEY_GRAVE_ACCENT, KeyCode::KEY_GRAVE },
45     { GLFW_KEY_MINUS, KeyCode::KEY_MINUS },
46     { GLFW_KEY_EQUAL, KeyCode::KEY_EQUALS },
47     { GLFW_KEY_TAB, KeyCode::KEY_TAB },
48     { GLFW_KEY_LEFT_BRACKET, KeyCode::KEY_LEFT_BRACKET },
49     { GLFW_KEY_RIGHT_BRACKET, KeyCode::KEY_RIGHT_BRACKET },
50     { GLFW_KEY_BACKSLASH, KeyCode::KEY_BACKSLASH },
51     { GLFW_KEY_SEMICOLON, KeyCode::KEY_SEMICOLON },
52     { GLFW_KEY_APOSTROPHE, KeyCode::KEY_APOSTROPHE },
53     { GLFW_KEY_COMMA, KeyCode::KEY_COMMA },
54     { GLFW_KEY_PERIOD, KeyCode::KEY_PERIOD },
55     { GLFW_KEY_SLASH, KeyCode::KEY_SLASH },
56     { GLFW_KEY_SPACE, KeyCode::KEY_SPACE },
57     { GLFW_KEY_KP_DIVIDE, KeyCode::KEY_NUMPAD_DIVIDE },
58     { GLFW_KEY_KP_MULTIPLY, KeyCode::KEY_NUMPAD_MULTIPLY },
59     { GLFW_KEY_KP_SUBTRACT, KeyCode::KEY_NUMPAD_SUBTRACT },
60     { GLFW_KEY_KP_ADD, KeyCode::KEY_NUMPAD_ADD },
61     { GLFW_KEY_KP_ENTER, KeyCode::KEY_NUMPAD_ENTER },
62     { GLFW_KEY_KP_EQUAL, KeyCode::KEY_NUMPAD_EQUALS },
63     { GLFW_KEY_NUM_LOCK, KeyCode::KEY_NUM_LOCK },
64 };
65 } // namespace
66 
EventAdapter()67 EventAdapter::EventAdapter()
68 {
69     keyEvent_ = std::make_shared<KeyEvent>();
70     pointerEvent_ = std::make_shared<PointerEvent>();
71 }
72 
73 EventAdapter::~EventAdapter() = default;
74 
Initialize(std::shared_ptr<GlfwRenderContext> & glfwRenderContext)75 void EventAdapter::Initialize(std::shared_ptr<GlfwRenderContext>& glfwRenderContext)
76 {
77     // keyboard callback
78     auto&& keyboardCbk = [this](int key, int scancode, int action, int mods) {
79         if (RunSpecialOperations(key, action, mods)) {
80             LOGI("Some special shortcut keys are intercepted for performing specific operations.");
81             return;
82         }
83         if (keyEventCallback_ && RecognizeKeyEvent(key, action, mods)) {
84             keyEventCallback_(keyEvent_);
85         } else {
86             LOGW("Unrecognized key type.");
87         }
88     };
89     glfwRenderContext->OnKey(keyboardCbk);
90 
91     // mouse button callback
92     auto&& mouseButtonCbk = [this](int button, bool pressed, int mods) {
93         {
94             std::lock_guard lock(mouseMutex_);
95             isMousePressed_ = pressed;
96         }
97         if (pointerEventCallback_) {
98             RecognizePointerEvent(pressed ? TouchType::DOWN : TouchType::UP);
99             pointerEventCallback_(pointerEvent_);
100         }
101     };
102     glfwRenderContext->OnMouseButton(mouseButtonCbk);
103 
104     // cursor position callback
105     auto&& cursorPosCbk = [this](double x, double y) {
106         {
107             std::lock_guard lock(mouseMutex_);
108             posX_ = x;
109             posY_ = y;
110         }
111         if (isMousePressed_ && pointerEventCallback_) {
112             RecognizePointerEvent(TouchType::MOVE);
113             pointerEventCallback_(pointerEvent_);
114         }
115     };
116     glfwRenderContext->OnCursorPos(cursorPosCbk);
117 }
118 
RegisterKeyEventCallback(MMIKeyEventCallback && callback)119 void EventAdapter::RegisterKeyEventCallback(MMIKeyEventCallback&& callback)
120 {
121     keyEventCallback_ = std::move(callback);
122 }
123 
RegisterPointerEventCallback(MMIPointerEventCallback && callback)124 void EventAdapter::RegisterPointerEventCallback(MMIPointerEventCallback&& callback)
125 {
126     pointerEventCallback_ = std::move(callback);
127 }
128 
RegisterInspectorCallback(InspectorCallback && callback)129 void EventAdapter::RegisterInspectorCallback(InspectorCallback&& callback)
130 {
131     inspectorCallback_ = std::move(callback);
132 }
133 
RecognizeKeyEvent(int key,int action,int mods)134 bool EventAdapter::RecognizeKeyEvent(int key, int action, int mods)
135 {
136     auto iterAction = ACTION_MAP.find(action);
137     if (iterAction == ACTION_MAP.end()) {
138         return false;
139     }
140     keyEvent_->action = iterAction->second;
141 
142     keyEvent_->pressedCodes.clear();
143     if (mods & GLFW_MOD_CONTROL) {
144         keyEvent_->pressedCodes.push_back(KeyCode::KEY_CTRL_LEFT);
145     }
146     if (mods & GLFW_MOD_SUPER) {
147         keyEvent_->pressedCodes.push_back(KeyCode::KEY_META_LEFT);
148     }
149     if (mods & GLFW_MOD_SHIFT) {
150         keyEvent_->pressedCodes.push_back(KeyCode::KEY_SHIFT_LEFT);
151     }
152     if (mods & GLFW_MOD_ALT) {
153         keyEvent_->pressedCodes.push_back(KeyCode::KEY_ALT_LEFT);
154     }
155 
156     auto iterCode = CODE_MAP.find(key);
157     if (iterCode == CODE_MAP.end() && !(key >= GLFW_KEY_A && key <= GLFW_KEY_Z) &&
158         !(key >= GLFW_KEY_0 && key <= GLFW_KEY_9) && !(key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_9)) {
159         return false;
160     }
161     if (iterCode != CODE_MAP.end()) {
162         keyEvent_->code = iterCode->second;
163     }
164     if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
165         keyEvent_->code = static_cast<KeyCode>(static_cast<int32_t>(KeyCode::KEY_A) + key - GLFW_KEY_A);
166     }
167     if (key >= GLFW_KEY_0 && key <= GLFW_KEY_9) {
168         keyEvent_->code = static_cast<KeyCode>(static_cast<int32_t>(KeyCode::KEY_0) + key - GLFW_KEY_0);
169     }
170     if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_9) {
171         keyEvent_->code = static_cast<KeyCode>(static_cast<int32_t>(KeyCode::KEY_0) + key - GLFW_KEY_KP_0);
172     }
173     keyEvent_->key = "Test";
174     keyEvent_->pressedCodes.push_back(keyEvent_->code);
175 
176     return true;
177 }
178 
RecognizePointerEvent(const TouchType type)179 void EventAdapter::RecognizePointerEvent(const TouchType type)
180 {
181     std::lock_guard lock(mouseMutex_);
182     pointerEvent_->id = 1;
183     pointerEvent_->x = posX_;
184     pointerEvent_->y = posY_;
185     pointerEvent_->screenX = 0;
186     pointerEvent_->screenY = 0;
187     pointerEvent_->type = type;
188     pointerEvent_->time = std::chrono::high_resolution_clock::now();
189     pointerEvent_->size = sizeof(PointerEvent);
190     pointerEvent_->force = 0;
191     pointerEvent_->deviceId = 0;
192     pointerEvent_->sourceType = SourceType::TOUCH;
193     pointerEvent_->pointers = {};
194 }
195 
RunSpecialOperations(int key,int action,int mods)196 bool EventAdapter::RunSpecialOperations(int key, int action, int mods)
197 {
198     // Add specific operations which driven by some special shortcut keys.
199     if (inspectorCallback_ && (action == GLFW_PRESS) && (mods & GLFW_MOD_CONTROL) && (key == GLFW_KEY_I)) {
200         inspectorCallback_();
201         return true;
202     }
203     return false;
204 }
205 
206 } // namespace OHOS::Ace::Sample
207