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 "key_event_napi.h"
17 
18 #include "util_napi.h"
19 #include "util_napi_value.h"
20 
21 #undef MMI_LOG_TAG
22 #define MMI_LOG_TAG "KeyEventNapi"
23 
24 namespace OHOS {
25 namespace MMI {
CreateKeyEvent(napi_env env,const std::shared_ptr<KeyEvent> & in,napi_value & out)26 napi_status KeyEventNapi::CreateKeyEvent(napi_env env, const std::shared_ptr<KeyEvent> &in, napi_value &out)
27 {
28     CHKPR(in, napi_invalid_arg);
29     auto status = SetNameProperty(env, out, "action", in->GetKeyAction() - KeyEvent::KEY_ACTION_CANCEL);
30     CHKRR(status, "set action property", status);
31 
32     CHECK_RETURN(in->GetKeyItem(), "get key item", status);
33     auto keyItem = in->GetKeyItem();
34     status = SetNameProperty(env, out, "key", keyItem);
35     CHKRR(status, "set key property", status);
36 
37     status = SetNameProperty(env, out, "unicodeChar", in->GetKeyItem()->GetUnicode());
38     CHKRR(status, "set unicodeChar property", status);
39 
40     auto keyItems = in->GetKeyItems();
41     status = SetNameProperty(env, out, "keys", keyItems);
42     CHKRR(status, "set keys property", status);
43 
44     status = WriteKeyStatusToJs(env, in->GetPressedKeys(), out);
45     CHKRR(status, "set pressed key property", status);
46 
47     status = WriteFunctionKeyStatusToJs(env, in, out);
48     CHKRR(status, "set function key property", status);
49 
50     return napi_ok;
51 }
52 
GetKeyEvent(napi_env env,napi_value in,std::shared_ptr<KeyEvent> & out)53 napi_status KeyEventNapi::GetKeyEvent(napi_env env, napi_value in, std::shared_ptr<KeyEvent> &out)
54 {
55     napi_valuetype valueType = napi_undefined;
56     auto status = napi_typeof(env, in, &valueType);
57     CHECK_RETURN((status == napi_ok) && (valueType == napi_object), "object type invalid", status);
58 
59     KeyEvent::KeyItem item = GetNamePropertyKeyItem(env, in, "key");
60     out->SetKeyCode(item.GetKeyCode());
61 
62     uint32_t unicode = GetNamePropertyUint32(env, in, "unicodeChar");
63     out->GetKeyItem()->SetUnicode(unicode);
64 
65     int32_t keyAction = GetNamePropertyInt32(env, in, "action");
66     out->SetKeyAction(keyAction + KeyEvent::KEY_ACTION_CANCEL);
67 
68     std::vector<KeyEvent::KeyItem> keyItems = GetNamePropertyKeyItems(env, in, "keys");
69     for (const auto &keyItem : keyItems) {
70         out->AddKeyItem(keyItem);
71     }
72 
73     bool lock = GetNamePropertyBool(env, in, "capsLock");
74     out->SetFunctionKey(KeyEvent::CAPS_LOCK_FUNCTION_KEY, lock);
75     lock = GetNamePropertyBool(env, in, "numLock");
76     out->SetFunctionKey(KeyEvent::NUM_LOCK_FUNCTION_KEY, lock);
77     lock = GetNamePropertyBool(env, in, "scrollLock");
78     out->SetFunctionKey(KeyEvent::SCROLL_LOCK_FUNCTION_KEY, lock);
79 
80     return napi_ok;
81 }
82 
CreateKeyItem(napi_env env,const std::optional<KeyEvent::KeyItem> in,napi_value & out)83 napi_status KeyEventNapi::CreateKeyItem(napi_env env, const std::optional<KeyEvent::KeyItem> in, napi_value &out)
84 {
85     auto status = SetNameProperty(env, out, "code", in->GetKeyCode());
86     CHKRR(status, "set code property", status);
87 
88     status = SetNameProperty(env, out, "pressedTime", in->GetDownTime());
89     CHKRR(status, "set pressedTime property", status);
90 
91     status = SetNameProperty(env, out, "deviceId", in->GetDeviceId());
92     CHKRR(status, "set deviceId property", status);
93 
94     return napi_ok;
95 }
96 
GetKeyItem(napi_env env,napi_value in,KeyEvent::KeyItem & out)97 napi_status KeyEventNapi::GetKeyItem(napi_env env, napi_value in, KeyEvent::KeyItem &out)
98 {
99     int32_t keyCode = GetNamePropertyInt32(env, in, "code");
100     out.SetKeyCode(keyCode);
101     int64_t downTime = GetNamePropertyInt64(env, in, "pressedTime");
102     out.SetDownTime(downTime);
103     int32_t deviceId = GetNamePropertyInt32(env, in, "deviceId");
104     out.SetDeviceId(deviceId);
105     return napi_ok;
106 }
107 
WriteKeyStatusToJs(napi_env env,const std::vector<int32_t> & pressedKeys,napi_value & out)108 napi_status KeyEventNapi::WriteKeyStatusToJs(napi_env env, const std::vector<int32_t> &pressedKeys, napi_value &out)
109 {
110     bool isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_CTRL_LEFT)
111                     || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_CTRL_RIGHT);
112     auto status = SetNameProperty(env, out, "ctrlKey", isExists);
113     CHKRR(status, "set ctrlKey property", status);
114 
115     isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_ALT_LEFT)
116                || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_ALT_RIGHT);
117     status = SetNameProperty(env, out, "altKey", isExists);
118     CHKRR(status, "set altKey property", status);
119 
120     isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_SHIFT_LEFT)
121                || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_SHIFT_RIGHT);
122     status = SetNameProperty(env, out, "shiftKey", isExists);
123     CHKRR(status, "set shiftKey property", status);
124 
125     isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_META_LEFT)
126                || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_META_RIGHT);
127     status = SetNameProperty(env, out, "logoKey", isExists);
128     CHKRR(status, "set logoKey property", status);
129 
130     isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_FN);
131     status = SetNameProperty(env, out, "fnKey", isExists);
132     CHKRR(status, "set fnKey property", status);
133 
134     return napi_ok;
135 }
136 
WriteFunctionKeyStatusToJs(napi_env env,const std::shared_ptr<KeyEvent> & in,napi_value & out)137 napi_status KeyEventNapi::WriteFunctionKeyStatusToJs(napi_env env, const std::shared_ptr<KeyEvent> &in, napi_value &out)
138 {
139     auto status = SetNameProperty(env, out, "capsLock", in->GetFunctionKey(KeyEvent::CAPS_LOCK_FUNCTION_KEY));
140     CHKRR(status, "set capsLock property", status);
141 
142     status = SetNameProperty(env, out, "numLock", in->GetFunctionKey(KeyEvent::NUM_LOCK_FUNCTION_KEY));
143     CHKRR(status, "set numLock property", status);
144 
145     status = SetNameProperty(env, out, "scrollLock", in->GetFunctionKey(KeyEvent::SCROLL_LOCK_FUNCTION_KEY));
146     CHKRR(status, "set scrollLock property", status);
147 
148     return napi_ok;
149 }
150 
HasKeyCode(const std::vector<int32_t> & pressedKeys,int32_t keyCode)151 bool KeyEventNapi::HasKeyCode(const std::vector<int32_t> &pressedKeys, int32_t keyCode)
152 {
153     return std::find(pressedKeys.begin(), pressedKeys.end(), keyCode) != pressedKeys.end();
154 }
155 } // namespace MMI
156 } // namespace OHOS