1 /*
2 * Copyright (c) 2021-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 "key_event_normalize.h"
17
18 #include "input_device_manager.h"
19 #include "key_map_manager.h"
20 #include "key_unicode_transformation.h"
21
22 namespace OHOS {
23 namespace MMI {
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeyEventNormalize" };
26 constexpr uint32_t KEYSTATUS = 0;
27 } // namespace
28
KeyEventNormalize()29 KeyEventNormalize::KeyEventNormalize() {}
30
~KeyEventNormalize()31 KeyEventNormalize::~KeyEventNormalize() {}
32
GetKeyEvent()33 std::shared_ptr<KeyEvent> KeyEventNormalize::GetKeyEvent()
34 {
35 if (keyEvent_ == nullptr) {
36 keyEvent_ = KeyEvent::Create();
37 }
38 return keyEvent_;
39 }
40
Normalize(struct libinput_event * event,std::shared_ptr<KeyEvent> keyEvent)41 int32_t KeyEventNormalize::Normalize(struct libinput_event *event, std::shared_ptr<KeyEvent> keyEvent)
42 {
43 CALL_DEBUG_ENTER;
44 CHKPR(event, PARAM_INPUT_INVALID);
45 CHKPR(keyEvent, ERROR_NULL_POINTER);
46 keyEvent->UpdateId();
47 auto data = libinput_event_get_keyboard_event(event);
48 CHKPR(data, ERROR_NULL_POINTER);
49
50 auto device = libinput_event_get_device(event);
51 CHKPR(device, ERROR_NULL_POINTER);
52 int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
53 int32_t keyCode = static_cast<int32_t>(libinput_event_keyboard_get_key(data));
54 MMI_HILOGD("The linux input keyCode:%{public}d", keyCode);
55 keyCode = KeyMapMgr->TransferDeviceKeyValue(device, keyCode);
56 int32_t keyAction = (libinput_event_keyboard_get_key_state(data) == 0) ?
57 (KeyEvent::KEY_ACTION_UP) : (KeyEvent::KEY_ACTION_DOWN);
58 auto preAction = keyEvent->GetAction();
59 if (preAction == KeyEvent::KEY_ACTION_UP) {
60 auto preUpKeyItem = keyEvent->GetKeyItem();
61 if (preUpKeyItem != nullptr) {
62 keyEvent->RemoveReleasedKeyItems(*preUpKeyItem);
63 } else {
64 MMI_HILOGE("The preUpKeyItem is null");
65 }
66 }
67 int64_t time = GetSysClockTime();
68 keyEvent->SetActionTime(time);
69 keyEvent->SetAction(keyAction);
70 keyEvent->SetDeviceId(deviceId);
71 keyEvent->SetKeyCode(keyCode);
72 keyEvent->SetKeyAction(keyAction);
73 if (keyEvent->GetPressedKeys().empty()) {
74 keyEvent->SetActionStartTime(time);
75 }
76
77 KeyEvent::KeyItem item;
78 bool isKeyPressed = (libinput_event_keyboard_get_key_state(data) != KEYSTATUS);
79 item.SetDownTime(time);
80 item.SetKeyCode(keyCode);
81 item.SetDeviceId(deviceId);
82 item.SetPressed(isKeyPressed);
83 item.SetUnicode(KeyCodeToUnicode(keyCode, keyEvent));
84
85 if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
86 keyEvent->AddPressedKeyItems(item);
87 }
88 if (keyAction == KeyEvent::KEY_ACTION_UP) {
89 int32_t funcKey = keyEvent->TransitionFunctionKey(keyCode);
90 if (funcKey != KeyEvent::UNKOWN_FUNCTION_KEY) {
91 int32_t ret = keyEvent->SetFunctionKey(funcKey, libinput_get_funckey_state(device, funcKey));
92 if (ret == funcKey) {
93 MMI_HILOGD("Set function key:%{public}d to state:%{public}d succeed",
94 funcKey, keyEvent->GetFunctionKey(funcKey));
95 }
96 }
97 auto pressedKeyItem = keyEvent->GetKeyItem(keyCode);
98 if (pressedKeyItem != nullptr) {
99 item.SetDownTime(pressedKeyItem->GetDownTime());
100 } else {
101 MMI_HILOGE("Find pressed key failed, keyCode:%{public}d", keyCode);
102 }
103 keyEvent->RemoveReleasedKeyItems(item);
104 keyEvent->AddPressedKeyItems(item);
105 }
106 return RET_OK;
107 }
108
ResetKeyEvent(struct libinput_device * device)109 void KeyEventNormalize::ResetKeyEvent(struct libinput_device* device)
110 {
111 if (InputDevMgr->IsKeyboardDevice(device) || InputDevMgr->IsPointerDevice(device)) {
112 if (keyEvent_ == nullptr) {
113 keyEvent_ = KeyEvent::Create();
114 }
115 if (libinput_has_event_led_type(device)) {
116 CHKPV(keyEvent_);
117 const std::vector<int32_t> funcKeys = {
118 KeyEvent::NUM_LOCK_FUNCTION_KEY,
119 KeyEvent::CAPS_LOCK_FUNCTION_KEY,
120 KeyEvent::SCROLL_LOCK_FUNCTION_KEY
121 };
122 for (const auto &funcKey : funcKeys) {
123 keyEvent_->SetFunctionKey(funcKey, libinput_get_funckey_state(device, funcKey));
124 }
125 }
126 }
127 }
128 } // namespace MMI
129 } // namespace OHOS
130