123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci#include "adapter/preview/entrance/samples/event_adapter.h"
1723b3eb3cSopenharmony_ci
1823b3eb3cSopenharmony_ci#include <GLFW/glfw3.h>
1923b3eb3cSopenharmony_ci#include <map>
2023b3eb3cSopenharmony_ci#include <memory>
2123b3eb3cSopenharmony_ci
2223b3eb3cSopenharmony_ci#include "base/utils/utils.h"
2323b3eb3cSopenharmony_ci#include "frameworks/base/log/log.h"
2423b3eb3cSopenharmony_ci
2523b3eb3cSopenharmony_cinamespace OHOS::Ace::Sample {
2623b3eb3cSopenharmony_ci
2723b3eb3cSopenharmony_cinamespace {
2823b3eb3cSopenharmony_ciconst std::map<int, KeyAction> ACTION_MAP = {
2923b3eb3cSopenharmony_ci    { GLFW_RELEASE, KeyAction::UP },
3023b3eb3cSopenharmony_ci    { GLFW_PRESS, KeyAction::DOWN },
3123b3eb3cSopenharmony_ci    { GLFW_REPEAT, KeyAction::LONG_PRESS },
3223b3eb3cSopenharmony_ci};
3323b3eb3cSopenharmony_ci
3423b3eb3cSopenharmony_ciconst std::map<int, KeyCode> CODE_MAP = {
3523b3eb3cSopenharmony_ci    { GLFW_KEY_BACKSPACE, KeyCode::KEY_FORWARD_DEL },
3623b3eb3cSopenharmony_ci    { GLFW_KEY_DELETE, KeyCode::KEY_DEL },
3723b3eb3cSopenharmony_ci    { GLFW_KEY_ESCAPE, KeyCode::KEY_ESCAPE },
3823b3eb3cSopenharmony_ci    { GLFW_KEY_ENTER, KeyCode::KEY_ENTER },
3923b3eb3cSopenharmony_ci    { GLFW_KEY_CAPS_LOCK, KeyCode::KEY_CAPS_LOCK },
4023b3eb3cSopenharmony_ci    { GLFW_KEY_UP, KeyCode::KEY_DPAD_UP },
4123b3eb3cSopenharmony_ci    { GLFW_KEY_DOWN, KeyCode::KEY_DPAD_DOWN },
4223b3eb3cSopenharmony_ci    { GLFW_KEY_LEFT, KeyCode::KEY_DPAD_LEFT },
4323b3eb3cSopenharmony_ci    { GLFW_KEY_RIGHT, KeyCode::KEY_DPAD_RIGHT },
4423b3eb3cSopenharmony_ci    { GLFW_KEY_GRAVE_ACCENT, KeyCode::KEY_GRAVE },
4523b3eb3cSopenharmony_ci    { GLFW_KEY_MINUS, KeyCode::KEY_MINUS },
4623b3eb3cSopenharmony_ci    { GLFW_KEY_EQUAL, KeyCode::KEY_EQUALS },
4723b3eb3cSopenharmony_ci    { GLFW_KEY_TAB, KeyCode::KEY_TAB },
4823b3eb3cSopenharmony_ci    { GLFW_KEY_LEFT_BRACKET, KeyCode::KEY_LEFT_BRACKET },
4923b3eb3cSopenharmony_ci    { GLFW_KEY_RIGHT_BRACKET, KeyCode::KEY_RIGHT_BRACKET },
5023b3eb3cSopenharmony_ci    { GLFW_KEY_BACKSLASH, KeyCode::KEY_BACKSLASH },
5123b3eb3cSopenharmony_ci    { GLFW_KEY_SEMICOLON, KeyCode::KEY_SEMICOLON },
5223b3eb3cSopenharmony_ci    { GLFW_KEY_APOSTROPHE, KeyCode::KEY_APOSTROPHE },
5323b3eb3cSopenharmony_ci    { GLFW_KEY_COMMA, KeyCode::KEY_COMMA },
5423b3eb3cSopenharmony_ci    { GLFW_KEY_PERIOD, KeyCode::KEY_PERIOD },
5523b3eb3cSopenharmony_ci    { GLFW_KEY_SLASH, KeyCode::KEY_SLASH },
5623b3eb3cSopenharmony_ci    { GLFW_KEY_SPACE, KeyCode::KEY_SPACE },
5723b3eb3cSopenharmony_ci    { GLFW_KEY_KP_DIVIDE, KeyCode::KEY_NUMPAD_DIVIDE },
5823b3eb3cSopenharmony_ci    { GLFW_KEY_KP_MULTIPLY, KeyCode::KEY_NUMPAD_MULTIPLY },
5923b3eb3cSopenharmony_ci    { GLFW_KEY_KP_SUBTRACT, KeyCode::KEY_NUMPAD_SUBTRACT },
6023b3eb3cSopenharmony_ci    { GLFW_KEY_KP_ADD, KeyCode::KEY_NUMPAD_ADD },
6123b3eb3cSopenharmony_ci    { GLFW_KEY_KP_ENTER, KeyCode::KEY_NUMPAD_ENTER },
6223b3eb3cSopenharmony_ci    { GLFW_KEY_KP_EQUAL, KeyCode::KEY_NUMPAD_EQUALS },
6323b3eb3cSopenharmony_ci    { GLFW_KEY_NUM_LOCK, KeyCode::KEY_NUM_LOCK },
6423b3eb3cSopenharmony_ci};
6523b3eb3cSopenharmony_ci} // namespace
6623b3eb3cSopenharmony_ci
6723b3eb3cSopenharmony_ciEventAdapter::EventAdapter()
6823b3eb3cSopenharmony_ci{
6923b3eb3cSopenharmony_ci    keyEvent_ = std::make_shared<KeyEvent>();
7023b3eb3cSopenharmony_ci    pointerEvent_ = std::make_shared<PointerEvent>();
7123b3eb3cSopenharmony_ci}
7223b3eb3cSopenharmony_ci
7323b3eb3cSopenharmony_ciEventAdapter::~EventAdapter() = default;
7423b3eb3cSopenharmony_ci
7523b3eb3cSopenharmony_civoid EventAdapter::Initialize(std::shared_ptr<GlfwRenderContext>& glfwRenderContext)
7623b3eb3cSopenharmony_ci{
7723b3eb3cSopenharmony_ci    // keyboard callback
7823b3eb3cSopenharmony_ci    auto&& keyboardCbk = [this](int key, int scancode, int action, int mods) {
7923b3eb3cSopenharmony_ci        if (RunSpecialOperations(key, action, mods)) {
8023b3eb3cSopenharmony_ci            return;
8123b3eb3cSopenharmony_ci        }
8223b3eb3cSopenharmony_ci        if (keyEventCallback_ && RecognizeKeyEvent(key, action, mods)) {
8323b3eb3cSopenharmony_ci            keyEventCallback_(keyEvent_);
8423b3eb3cSopenharmony_ci        } else {
8523b3eb3cSopenharmony_ci            LOGW("Unrecognized key type.");
8623b3eb3cSopenharmony_ci        }
8723b3eb3cSopenharmony_ci    };
8823b3eb3cSopenharmony_ci    glfwRenderContext->OnKey(keyboardCbk);
8923b3eb3cSopenharmony_ci
9023b3eb3cSopenharmony_ci    // mouse button callback
9123b3eb3cSopenharmony_ci    auto&& mouseButtonCbk = [this](int button, bool pressed, int mods) {
9223b3eb3cSopenharmony_ci        {
9323b3eb3cSopenharmony_ci            std::lock_guard lock(mouseMutex_);
9423b3eb3cSopenharmony_ci            isMousePressed_ = pressed;
9523b3eb3cSopenharmony_ci        }
9623b3eb3cSopenharmony_ci        if (pointerEventCallback_) {
9723b3eb3cSopenharmony_ci            RecognizePointerEvent(pressed ? TouchType::DOWN : TouchType::UP);
9823b3eb3cSopenharmony_ci            pointerEventCallback_(pointerEvent_);
9923b3eb3cSopenharmony_ci        }
10023b3eb3cSopenharmony_ci    };
10123b3eb3cSopenharmony_ci    glfwRenderContext->OnMouseButton(mouseButtonCbk);
10223b3eb3cSopenharmony_ci
10323b3eb3cSopenharmony_ci    // cursor position callback
10423b3eb3cSopenharmony_ci    auto&& cursorPosCbk = [this](double x, double y) {
10523b3eb3cSopenharmony_ci        {
10623b3eb3cSopenharmony_ci            std::lock_guard lock(mouseMutex_);
10723b3eb3cSopenharmony_ci            posX_ = x;
10823b3eb3cSopenharmony_ci            posY_ = y;
10923b3eb3cSopenharmony_ci        }
11023b3eb3cSopenharmony_ci        if (isMousePressed_ && pointerEventCallback_) {
11123b3eb3cSopenharmony_ci            RecognizePointerEvent(TouchType::MOVE);
11223b3eb3cSopenharmony_ci            pointerEventCallback_(pointerEvent_);
11323b3eb3cSopenharmony_ci        }
11423b3eb3cSopenharmony_ci    };
11523b3eb3cSopenharmony_ci    glfwRenderContext->OnCursorPos(cursorPosCbk);
11623b3eb3cSopenharmony_ci}
11723b3eb3cSopenharmony_ci
11823b3eb3cSopenharmony_civoid EventAdapter::RegisterKeyEventCallback(MMIKeyEventCallback&& callback)
11923b3eb3cSopenharmony_ci{
12023b3eb3cSopenharmony_ci    keyEventCallback_ = std::move(callback);
12123b3eb3cSopenharmony_ci}
12223b3eb3cSopenharmony_ci
12323b3eb3cSopenharmony_civoid EventAdapter::RegisterPointerEventCallback(MMIPointerEventCallback&& callback)
12423b3eb3cSopenharmony_ci{
12523b3eb3cSopenharmony_ci    pointerEventCallback_ = std::move(callback);
12623b3eb3cSopenharmony_ci}
12723b3eb3cSopenharmony_ci
12823b3eb3cSopenharmony_civoid EventAdapter::RegisterInspectorCallback(InspectorCallback&& callback)
12923b3eb3cSopenharmony_ci{
13023b3eb3cSopenharmony_ci    inspectorCallback_ = std::move(callback);
13123b3eb3cSopenharmony_ci}
13223b3eb3cSopenharmony_ci
13323b3eb3cSopenharmony_cibool EventAdapter::RecognizeKeyEvent(int key, int action, int mods)
13423b3eb3cSopenharmony_ci{
13523b3eb3cSopenharmony_ci    auto iterAction = ACTION_MAP.find(action);
13623b3eb3cSopenharmony_ci    if (iterAction == ACTION_MAP.end()) {
13723b3eb3cSopenharmony_ci        return false;
13823b3eb3cSopenharmony_ci    }
13923b3eb3cSopenharmony_ci    keyEvent_->action = iterAction->second;
14023b3eb3cSopenharmony_ci
14123b3eb3cSopenharmony_ci    keyEvent_->pressedCodes.clear();
14223b3eb3cSopenharmony_ci    if (mods & GLFW_MOD_CONTROL) {
14323b3eb3cSopenharmony_ci        keyEvent_->pressedCodes.push_back(KeyCode::KEY_CTRL_LEFT);
14423b3eb3cSopenharmony_ci    }
14523b3eb3cSopenharmony_ci    if (mods & GLFW_MOD_SUPER) {
14623b3eb3cSopenharmony_ci        keyEvent_->pressedCodes.push_back(KeyCode::KEY_META_LEFT);
14723b3eb3cSopenharmony_ci    }
14823b3eb3cSopenharmony_ci    if (mods & GLFW_MOD_SHIFT) {
14923b3eb3cSopenharmony_ci        keyEvent_->pressedCodes.push_back(KeyCode::KEY_SHIFT_LEFT);
15023b3eb3cSopenharmony_ci    }
15123b3eb3cSopenharmony_ci    if (mods & GLFW_MOD_ALT) {
15223b3eb3cSopenharmony_ci        keyEvent_->pressedCodes.push_back(KeyCode::KEY_ALT_LEFT);
15323b3eb3cSopenharmony_ci    }
15423b3eb3cSopenharmony_ci
15523b3eb3cSopenharmony_ci    auto iterCode = CODE_MAP.find(key);
15623b3eb3cSopenharmony_ci    if (iterCode == CODE_MAP.end() && !(key >= GLFW_KEY_A && key <= GLFW_KEY_Z) &&
15723b3eb3cSopenharmony_ci        !(key >= GLFW_KEY_0 && key <= GLFW_KEY_9) && !(key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_9)) {
15823b3eb3cSopenharmony_ci        return false;
15923b3eb3cSopenharmony_ci    }
16023b3eb3cSopenharmony_ci    if (iterCode != CODE_MAP.end()) {
16123b3eb3cSopenharmony_ci        keyEvent_->code = iterCode->second;
16223b3eb3cSopenharmony_ci    }
16323b3eb3cSopenharmony_ci    if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
16423b3eb3cSopenharmony_ci        keyEvent_->code = static_cast<KeyCode>(static_cast<int32_t>(KeyCode::KEY_A) + key - GLFW_KEY_A);
16523b3eb3cSopenharmony_ci    }
16623b3eb3cSopenharmony_ci    if (key >= GLFW_KEY_0 && key <= GLFW_KEY_9) {
16723b3eb3cSopenharmony_ci        keyEvent_->code = static_cast<KeyCode>(static_cast<int32_t>(KeyCode::KEY_0) + key - GLFW_KEY_0);
16823b3eb3cSopenharmony_ci    }
16923b3eb3cSopenharmony_ci    if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_9) {
17023b3eb3cSopenharmony_ci        keyEvent_->code = static_cast<KeyCode>(static_cast<int32_t>(KeyCode::KEY_0) + key - GLFW_KEY_KP_0);
17123b3eb3cSopenharmony_ci    }
17223b3eb3cSopenharmony_ci    keyEvent_->key = "Test";
17323b3eb3cSopenharmony_ci    keyEvent_->pressedCodes.push_back(keyEvent_->code);
17423b3eb3cSopenharmony_ci
17523b3eb3cSopenharmony_ci    return true;
17623b3eb3cSopenharmony_ci}
17723b3eb3cSopenharmony_ci
17823b3eb3cSopenharmony_civoid EventAdapter::RecognizePointerEvent(const TouchType type)
17923b3eb3cSopenharmony_ci{
18023b3eb3cSopenharmony_ci    std::lock_guard lock(mouseMutex_);
18123b3eb3cSopenharmony_ci    pointerEvent_->id = 1;
18223b3eb3cSopenharmony_ci    pointerEvent_->x = posX_;
18323b3eb3cSopenharmony_ci    pointerEvent_->y = posY_;
18423b3eb3cSopenharmony_ci    pointerEvent_->screenX = 0;
18523b3eb3cSopenharmony_ci    pointerEvent_->screenY = 0;
18623b3eb3cSopenharmony_ci    pointerEvent_->type = type;
18723b3eb3cSopenharmony_ci    pointerEvent_->time = std::chrono::high_resolution_clock::now();
18823b3eb3cSopenharmony_ci    pointerEvent_->size = sizeof(PointerEvent);
18923b3eb3cSopenharmony_ci    pointerEvent_->force = 0;
19023b3eb3cSopenharmony_ci    pointerEvent_->deviceId = 0;
19123b3eb3cSopenharmony_ci    pointerEvent_->sourceType = static_cast<int32_t>(OHOS::MMI::SourceType::TOUCH);
19223b3eb3cSopenharmony_ci    pointerEvent_->pointers = {};
19323b3eb3cSopenharmony_ci}
19423b3eb3cSopenharmony_ci
19523b3eb3cSopenharmony_cibool EventAdapter::RunSpecialOperations(int key, int action, int mods)
19623b3eb3cSopenharmony_ci{
19723b3eb3cSopenharmony_ci    // Add specific operations which driven by some special shortcut keys.
19823b3eb3cSopenharmony_ci    if (inspectorCallback_ && (action == GLFW_PRESS) && (mods & GLFW_MOD_CONTROL) && (key == GLFW_KEY_I)) {
19923b3eb3cSopenharmony_ci        inspectorCallback_();
20023b3eb3cSopenharmony_ci        return true;
20123b3eb3cSopenharmony_ci    }
20223b3eb3cSopenharmony_ci    return false;
20323b3eb3cSopenharmony_ci}
20423b3eb3cSopenharmony_ci
20523b3eb3cSopenharmony_ci} // namespace OHOS::Ace::Sample
206