1 /*
2  * Copyright (c) 2022 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 "joystick_transform_processor.h"
17 
18 #include "mmi_log.h"
19 
20 #undef MMI_LOG_DOMAIN
21 #define MMI_LOG_DOMAIN MMI_LOG_DISPATCH
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "JoystickTransformProcessor"
24 
25 namespace OHOS {
26 namespace MMI {
JoystickTransformProcessor(int32_t deviceId)27 JoystickTransformProcessor::JoystickTransformProcessor(int32_t deviceId) : deviceId_(deviceId)
28 {
29     joystickType.emplace_back(
30         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_X, PointerEvent::AXIS_TYPE_ABS_X));
31     joystickType.emplace_back(
32         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_Y, PointerEvent::AXIS_TYPE_ABS_Y));
33     joystickType.emplace_back(
34         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_Z, PointerEvent::AXIS_TYPE_ABS_Z));
35     joystickType.emplace_back(
36         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_RZ, PointerEvent::AXIS_TYPE_ABS_RZ));
37     joystickType.emplace_back(
38         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_GAS, PointerEvent::AXIS_TYPE_ABS_GAS));
39     joystickType.emplace_back(
40         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_BRAKE, PointerEvent::AXIS_TYPE_ABS_BRAKE));
41     joystickType.emplace_back(
42         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_HAT0X, PointerEvent::AXIS_TYPE_ABS_HAT0X));
43     joystickType.emplace_back(
44         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_HAT0Y, PointerEvent::AXIS_TYPE_ABS_HAT0Y));
45     joystickType.emplace_back(
46         std::make_pair(LIBINPUT_JOYSTICK_AXIS_SOURCE_ABS_THROTTLE, PointerEvent::AXIS_TYPE_ABS_THROTTLE));
47 }
48 
OnEventJoystickButton(struct libinput_event * event)49 bool JoystickTransformProcessor::OnEventJoystickButton(struct libinput_event* event)
50 {
51     CALL_DEBUG_ENTER;
52     CHKPF(event);
53     auto data = libinput_event_get_joystick_button_event(event);
54     CHKPF(data);
55     int64_t time = GetSysClockTime();
56     pointerEvent_->SetActionTime(time);
57     pointerEvent_->SetActionStartTime(time);
58     pointerEvent_->SetDeviceId(deviceId_);
59     uint32_t button = libinput_event_joystick_button_get_key(data);
60     int32_t buttonId = LibinputButtonToPointer(button);
61     if (buttonId == PointerEvent::BUTTON_NONE) {
62         MMI_HILOGE("Unknown btn, btn:%{public}u", button);
63         return false;
64     }
65     pointerEvent_->SetButtonId(buttonId);
66     auto state = libinput_event_joystick_button_get_key_state(data);
67     if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
68         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP);
69         pointerEvent_->DeleteReleaseButton(buttonId);
70     } else if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
71         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN);
72         pointerEvent_->SetButtonPressed(buttonId);
73     } else {
74         MMI_HILOGE("Unknown state, state:%{public}u", state);
75         return false;
76     }
77     MMI_HILOGD("button:%{public}u, buttonId:%{public}d, state:%{public}d", button, buttonId, state);
78     return true;
79 }
80 
LibinputButtonToPointer(const uint32_t button)81 int32_t JoystickTransformProcessor::LibinputButtonToPointer(const uint32_t button)
82 {
83     auto iter = LibinputChangeToPointer.find(button);
84     return (iter == LibinputChangeToPointer.end() ? PointerEvent::BUTTON_NONE : iter->second);
85 }
86 
OnEventJoystickAxis(struct libinput_event * event)87 bool JoystickTransformProcessor::OnEventJoystickAxis(struct libinput_event *event)
88 {
89     CALL_DEBUG_ENTER;
90     CHKPF(event);
91     auto data = libinput_event_get_joystick_axis_event(event);
92     CHKPF(data);
93     int64_t time = GetSysClockTime();
94     pointerEvent_->SetActionTime(time);
95     pointerEvent_->SetActionStartTime(time);
96     pointerEvent_->SetDeviceId(deviceId_);
97     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
98     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_JOYSTICK);
99 
100     for (const auto &item : joystickType) {
101         if (libinput_event_get_joystick_axis_value_is_changed(data, item.first) != 0) {
102             struct libinput_event_joystick_axis_abs_info* axisInfo =
103                 libinput_event_get_joystick_axis_abs_info(data, item.first);
104             CHKPF(axisInfo);
105             pointerEvent_->SetAxisValue(item.second, axisInfo->value);
106         }
107     }
108     return true;
109 }
110 
OnEvent(struct libinput_event * event)111 std::shared_ptr<PointerEvent> JoystickTransformProcessor::OnEvent(struct libinput_event *event)
112 {
113     CALL_DEBUG_ENTER;
114     CHKPP(event);
115     if (pointerEvent_ == nullptr) {
116         pointerEvent_ = PointerEvent::Create();
117         CHKPP(pointerEvent_);
118     }
119     pointerEvent_->ClearAxisValue();
120     auto type = libinput_event_get_type(event);
121     switch (type) {
122         case LIBINPUT_EVENT_JOYSTICK_BUTTON: {
123             if (!OnEventJoystickButton(event)) {
124                 MMI_HILOGE("Get OnEventJoystickButton failed");
125                 return nullptr;
126             }
127             break;
128         }
129         case LIBINPUT_EVENT_JOYSTICK_AXIS: {
130             if (!OnEventJoystickAxis(event)) {
131                 MMI_HILOGE("Get OnEventJoystickAxis failed");
132                 return nullptr;
133             }
134             break;
135         }
136         default: {
137             MMI_HILOGE("Unknown event type, joystickType:%{public}d", type);
138             return nullptr;
139         }
140     }
141     WIN_MGR->UpdateTargetPointer(pointerEvent_);
142 
143     return pointerEvent_;
144 }
145 } // namespace MMI
146 } // namespace OHOS
147