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#include "pointers_input_device.h"
16#include <unistd.h>
17#include "log/log.h"
18#include "common/input_device_manager.h"
19#include "ui_rotation.h"
20
21namespace Updater {
22void AddInputDevice()
23{
24    OHOS::InputDeviceManager::GetInstance()->Add(&PointersInputDevice::GetInstance());
25}
26
27void HandlePointersEvent(const input_event &ev, uint32_t type)
28{
29    PointersInputDevice::GetInstance().HandlePointEvent(ev, type);
30}
31
32PointersInputDevice &PointersInputDevice::GetInstance()
33{
34    static PointersInputDevice instance;
35    return instance;
36}
37
38bool PointersInputDevice::Read(OHOS::DeviceData& data)
39{
40    ReadTouch(data);
41    return false;
42}
43
44bool PointersInputDevice::ReadPoint(OHOS::DeviceData& data, OHOS::Point pos, bool fingerPressDown)
45{
46    auto [x, y] = UiRotation::GetInstance().RotateXY(pos.x, pos.y);
47    data.point.x = x;
48    data.point.y = y;
49    data.state = fingerPressDown ? OHOS::InputDevice::STATE_PRESS : OHOS::InputDevice::STATE_RELEASE;
50    return false;
51}
52
53bool PointersInputDevice::ReadTouch(OHOS::DeviceData &data)
54{
55    ReadPoint(data, reportAbsMt_, touchFingerDown_);
56    return false;
57}
58
59void PointersInputDevice::SetFingerDown(bool isPressed)
60{
61    touchFingerDown_ = isPressed;
62}
63
64void PointersInputDevice::HandleEvAbsMt(const input_event &ev)
65{
66    const static std::unordered_map<int, std::function<void(int)>> evMap {
67        {ABS_MT_POSITION_X, [this] (int value) {
68            reportAbsMt_.x = value;
69            SetFingerDown(true);
70        }},
71        {ABS_MT_POSITION_Y, [this] (int value) {
72            reportAbsMt_.y = value;
73            SetFingerDown(true);
74        }},
75        {ABS_MT_TRACKING_ID, [this] (int value) {
76            // Protocol B: -1 marks lifting the contact.
77            if (value < 0) {
78                SetFingerDown(false);
79            }
80        }}
81    };
82    if (auto it = evMap.find(ev.code); it != evMap.end()) {
83        it->second(ev.value);
84    }
85}
86
87int PointersInputDevice::HandlePointEvent(const input_event &ev, uint32_t type)
88{
89    if (ev.type == EV_ABS) {
90        HandleEvAbsMt(ev);
91        return 0;
92    }
93    if (ev.type == EV_KEY && ev.code == BTN_TOUCH) {
94        SetFingerDown(ev.value == 1);
95    }
96    return 0;
97}
98} // namespace Updater
99