1 /*
2 * Copyright (c) 2020-2021 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 "lite_wm.h"
17
18 #include "gfx_utils/color.h"
19 #include "gfx_utils/graphic_log.h"
20 #include "gfx_utils/pixel_format_utils.h"
21
22 namespace OHOS {
23 namespace {
24 #define EXPAND_RECT(x) x.GetLeft(), x.GetTop(), x.GetRight(), x.GetBottom()
25 const uint16_t CURSOR_WIDTH = 24;
26 const uint16_t CURSOR_HEIGHT = 25;
27 const uint8_t CURSOR_MAP[] = {
28 /* Pixel format: ARGB1555 */
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80,
37 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00,
40 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80,
51 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
60 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80,
61 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
73 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
74 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00,
78 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00,
84 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00,
93 };
94
95 const uint8_t MAX_WINDOW_NUMBLE = 32;
96 const uint32_t WINDOW_ID_FULL_STORAGE = 0xFFFFFFFF;
97 }
98
LiteWM()99 LiteWM::LiteWM()
100 : updates_({}), layerData_(nullptr), cursorInfo_({}), mousePosition_({}), deviceData_({}),
101 needScreenshot_(false), screenshotSurface_(nullptr), winIdStorage(0)
102 {
103 InitMutex(stackLock_, PTHREAD_MUTEX_RECURSIVE);
104 pthread_mutex_init(&mouseLock_, nullptr);
105 pthread_mutex_init(&eventLock_, nullptr);
106 pthread_mutex_init(&screenshotMutex_, nullptr);
107
108 InputManagerService::GetInstance()->GetDistributer()->AddRawEventListener(this);
109 InitMouseCursor();
110
111 layerData_ = GetDevSurfaceData();
112 if (layerData_ != nullptr) {
113 if (layerData_->virAddr == nullptr) {
114 GRAPHIC_LOGE("LayerInfo addr is null!");
115 }
116 GRAPHIC_LOGI("LayerInfo, width=%d, height=%d, stride=%d",
117 layerData_->width, layerData_->height, layerData_->stride);
118 } else {
119 GRAPHIC_LOGE("LayerInfo is null!");
120 }
121 }
122
~LiteWM()123 LiteWM::~LiteWM()
124 {
125 }
126
GetInstance()127 LiteWM* LiteWM::GetInstance()
128 {
129 static LiteWM liteWm;
130 return &liteWm;
131 }
132
MainTaskHandler()133 void LiteWM::MainTaskHandler()
134 {
135 if (layerData_ == nullptr || layerData_->virAddr == nullptr) {
136 return;
137 }
138
139 if (needScreenshot_) {
140 Screenshot();
141 needScreenshot_ = false;
142 }
143
144 if (cursorInfo_.enableCursor) {
145 UpdateMouseCursor();
146 }
147
148 ProcessUpdates();
149 }
150
UpdateMouseCursor()151 void LiteWM::UpdateMouseCursor()
152 {
153 Rect& rect = cursorInfo_.rect;
154 Point point = GetMousePosition();
155 if (rect.GetLeft() == point.x && rect.GetTop() == point.y) {
156 return;
157 }
158 cursorInfo_.needRedraw = true;
159 AddUpdateRegion(rect);
160 rect.SetPosition(point.x, point.y);
161 }
162
GetLayerInfo(LiteLayerInfo & layerInfo)163 void LiteWM::GetLayerInfo(LiteLayerInfo& layerInfo)
164 {
165 if (layerData_ == nullptr) {
166 return;
167 }
168 layerInfo.pixelFormat = layerData_->pixelFormat;
169 layerInfo.width = layerData_->width;
170 layerInfo.height = layerData_->height;
171 }
172
GetSurface(int32_t id)173 Surface* LiteWM::GetSurface(int32_t id)
174 {
175 LiteWindow* window = GetWindowById(id);
176 if (window != nullptr) {
177 return window->GetSurface();
178 }
179 return nullptr;
180 }
181
Show(int32_t id)182 void LiteWM::Show(int32_t id)
183 {
184 GraphicLocker lock(stackLock_);
185 LiteWindow* window = GetWindowById(id);
186 if (window != nullptr) {
187 window->SetIsShow(true);
188 UpdateWindowRegion(window, window->config_.rect);
189 }
190 }
191
Hide(int32_t id)192 void LiteWM::Hide(int32_t id)
193 {
194 GraphicLocker lock(stackLock_);
195 LiteWindow* window = GetWindowById(id);
196 if (window != nullptr) {
197 window->SetIsShow(false);
198 UpdateWindowRegion(window, window->config_.rect);
199 }
200 }
201
RaiseToTop(int32_t id)202 void LiteWM::RaiseToTop(int32_t id)
203 {
204 GraphicLocker lock(stackLock_);
205 auto node = GetWindowNodeById(id);
206 if (node != nullptr) {
207 node->prev_->next_ = node->next_;
208 node->next_->prev_ = node->prev_;
209 auto head = winList_.Begin()->prev_;
210 node->next_ = head->next_;
211 node->prev_ = head;
212 head->next_->prev_ = node;
213 head->next_ = node;
214
215 if (node->data_ != nullptr) {
216 UpdateWindowRegion(winList_.Begin()->data_, node->data_->config_.rect);
217 }
218 }
219 }
220
LowerToBottom(int32_t id)221 void LiteWM::LowerToBottom(int32_t id)
222 {
223 GraphicLocker lock(stackLock_);
224 auto node = GetWindowNodeById(id);
225 if (node != nullptr) {
226 node->prev_->next_ = node->next_;
227 node->next_->prev_ = node->prev_;
228 auto head = winList_.Begin()->prev_;
229 node->prev_ = head->prev_;
230 node->next_ = head;
231 head->prev_->next_ = node;
232 head->prev_ = node;
233
234 if (node->data_ != nullptr) {
235 UpdateWindowRegion(winList_.Begin()->data_, node->data_->config_.rect);
236 }
237 }
238 }
239
MoveTo(int32_t id,int16_t x,int16_t y)240 void LiteWM::MoveTo(int32_t id, int16_t x, int16_t y)
241 {
242 GraphicLocker lock(stackLock_);
243 LiteWindow* window = GetWindowById(id);
244 if (window != nullptr) {
245 window->MoveTo(x, y);
246 }
247 }
248
Resize(int32_t id,int16_t width,int16_t height)249 void LiteWM::Resize(int32_t id, int16_t width, int16_t height)
250 {
251 GraphicLocker lock(stackLock_);
252 LiteWindow* window = GetWindowById(id);
253 if (window == nullptr) {
254 return;
255 }
256 Rect rectBefore = window->config_.rect;
257 window->Resize(width, height);
258 Rect rectAfter = window->config_.rect;
259 Rect mask;
260 if (mask.Intersect(rectBefore, rectAfter)) {
261 int16_t x1 = mask.GetLeft();
262 int16_t x2 = mask.GetRight();
263 int16_t y1 = mask.GetTop();
264 int16_t y2 = mask.GetBottom();
265 if (x2 != rectBefore.GetRight()) {
266 UpdateWindowRegion(window, {static_cast<int16_t>(x2 + 1), y1, rectBefore.GetRight(),
267 rectBefore.GetBottom()});
268 }
269 if (y2 != rectBefore.GetBottom()) {
270 UpdateWindowRegion(window, {x1, static_cast<int16_t>(y2 + 1), x2, rectBefore.GetBottom()});
271 }
272 }
273 }
274
UpdateWindow(int32_t id)275 void LiteWM::UpdateWindow(int32_t id)
276 {
277 GRAPHIC_LOGI("UpdateWindow, id=%d", id);
278 LiteWindow* window = GetWindowById(id);
279 if (window != nullptr) {
280 UpdateWindowRegion(window, window->config_.rect);
281 }
282 }
283
GetWindowById(int32_t id)284 LiteWindow* LiteWM::GetWindowById(int32_t id)
285 {
286 if (id == INVALID_WINDOW_ID) {
287 return nullptr;
288 }
289
290 LiteWindow* ret = nullptr;
291 auto node = winList_.Begin();
292 while (node != winList_.End()) {
293 if (node->data_->id_ == id) {
294 ret = node->data_;
295 break;
296 }
297 node = node->next_;
298 }
299 return ret;
300 }
301
GetWindowNodeById(int32_t id)302 ListNode<LiteWindow*>* LiteWM::GetWindowNodeById(int32_t id)
303 {
304 if (id == INVALID_WINDOW_ID) {
305 return nullptr;
306 }
307
308 ListNode<LiteWindow*>* ret = nullptr;
309 auto node = winList_.Begin();
310 while (node != winList_.End()) {
311 if (node->data_->id_ == id) {
312 ret = node;
313 break;
314 }
315 node = node->next_;
316 }
317 return ret;
318 }
319
InitMouseCursor()320 void LiteWM::InitMouseCursor()
321 {
322 GRAPHIC_LOGI("InitMouseCursor");
323 cursorInfo_.rect.SetRect(0, 0, CURSOR_WIDTH - 1, CURSOR_HEIGHT - 1);
324 cursorInfo_.needRedraw = false;
325 cursorInfo_.enableCursor = false;
326 }
327
CreateWindow(const LiteWinConfig & config,pid_t pid)328 LiteWindow* LiteWM::CreateWindow(const LiteWinConfig& config, pid_t pid)
329 {
330 GraphicLocker lock(stackLock_);
331 if (!CheckWinIdIsAvailable()) {
332 return nullptr;
333 }
334 LiteWindow* window = new LiteWindow(config);
335 if (window == nullptr) {
336 return nullptr;
337 }
338 if (!window->CreateSurface()) {
339 delete window;
340 return nullptr;
341 }
342 window->SetPid(pid);
343 winList_.PushFront(window);
344 return window;
345 }
346
RemoveWindow(int32_t id)347 void LiteWM::RemoveWindow(int32_t id)
348 {
349 GraphicLocker lock(stackLock_);
350 auto node = GetWindowNodeById(id);
351 if (node == nullptr) {
352 return;
353 }
354 LiteWindow* window = node->data_;
355 winList_.Remove(node);
356 if (window != nullptr) {
357 AddUpdateRegion(window->config_.rect);
358 delete window;
359 }
360 }
361
CheckWinIdIsAvailable()362 bool LiteWM::CheckWinIdIsAvailable()
363 {
364 if (winIdStorage == WINDOW_ID_FULL_STORAGE) {
365 GRAPHIC_LOGE("reach max window num!");
366 return false;
367 }
368 return true;
369 }
370
GetUniqueWinId()371 int32_t LiteWM::GetUniqueWinId()
372 {
373 static uint8_t winId = 0;
374 if (!CheckWinIdIsAvailable()) {
375 return INVALID_WINDOW_ID;
376 }
377 while (winIdStorage & (1 << winId)) {
378 winId++;
379 winId %= MAX_WINDOW_NUMBLE;
380 }
381 winIdStorage |= (1 << winId);
382 return winId;
383 }
384
RecycleWinId(int32_t id)385 void LiteWM::RecycleWinId(int32_t id)
386 {
387 if (id == INVALID_WINDOW_ID) {
388 return;
389 }
390 winIdStorage &= (~(1 << static_cast<uint32_t>(id)));
391 }
392
InitMutex(pthread_mutex_t & mutex,int type)393 void LiteWM::InitMutex(pthread_mutex_t& mutex, int type)
394 {
395 pthread_mutexattr_t attr;
396 pthread_mutexattr_init(&attr);
397 pthread_mutexattr_settype(&attr, type);
398 pthread_mutex_init(&mutex, &attr);
399 pthread_mutexattr_destroy(&attr);
400 }
401
UpdateWindowRegion(const LiteWindow * window,const Rect & rect)402 void LiteWM::UpdateWindowRegion(const LiteWindow* window, const Rect& rect)
403 {
404 ListNode<LiteWindow *>* winNode = winList_.Tail();
405 while (winNode != winList_.End()) {
406 if (winNode->data_ == window) {
407 CalculateUpdateRegion(winNode->prev_, EXPAND_RECT(rect));
408 return;
409 }
410 winNode = winNode->prev_;
411 }
412 AddUpdateRegion(rect);
413 }
414
CalculateUpdateRegion(const ListNode<LiteWindow * > * winNode,int16_t x1,int16_t y1,int16_t x2,int16_t y2)415 void LiteWM::CalculateUpdateRegion(const ListNode<LiteWindow*>* winNode, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
416 {
417 Rect rect(x1, y1, x2, y2);
418 if (winNode == winList_.End()) {
419 AddUpdateRegion(rect);
420 return;
421 }
422 if (winNode == nullptr) {
423 return;
424 }
425 LiteWindow* window = winNode->data_;
426 if ((window != nullptr) && window->isShow_ && window->IsCoverMode()) {
427 Rect& winRect = window->config_.rect;
428 Rect mask;
429 GRAPHIC_LOGD("winRect={%d,%d,%d,%d}, rect={%d,%d,%d,%d}", EXPAND_RECT(winRect), EXPAND_RECT(rect));
430 if (mask.Intersect(winRect, rect)) {
431 if (x1 != mask.GetLeft()) {
432 CalculateUpdateRegion(winNode->prev_, x1, y1, mask.GetLeft() - 1, y2);
433 }
434
435 if (y1 != mask.GetTop()) {
436 CalculateUpdateRegion(winNode->prev_, mask.GetLeft(), y1, x2, mask.GetTop() - 1);
437 }
438
439 if (x2 != mask.GetRight()) {
440 CalculateUpdateRegion(winNode->prev_, mask.GetRight() + 1, mask.GetTop(), x2, y2);
441 }
442
443 if (y2 != mask.GetBottom()) {
444 CalculateUpdateRegion(winNode->prev_, mask.GetLeft(), mask.GetBottom() + 1, mask.GetRight(), y2);
445 }
446 return;
447 }
448 }
449 CalculateUpdateRegion(winNode->prev_, x1, y1, x2, y2);
450 }
451
AddUpdateRegion(const Rect & rect)452 void LiteWM::AddUpdateRegion(const Rect& rect)
453 {
454 GraphicLocker lock(stackLock_);
455 GRAPHIC_LOGD("AddUpdateRegion, rect={%d,%d,%d,%d}", EXPAND_RECT(rect));
456 if (updates_.num == 0) {
457 updates_.updates[updates_.num++] = rect;
458 updates_.bound = rect;
459 } else {
460 for (int i = 0; i < updates_.num; i++) {
461 Rect& updateRect = updates_.updates[i];
462 if (updateRect.IsIntersect(rect) || updateRect.IsExtends(rect)) {
463 updateRect.Join(updateRect, rect);
464 updates_.bound.Join(updates_.bound, rect);
465 return;
466 }
467 }
468 if (updates_.num == MAX_UPDATE_SIZE) {
469 updates_.bound.Join(updates_.bound, rect);
470 updates_.num = 0;
471 updates_.updates[updates_.num++] = updates_.bound;
472 } else {
473 updates_.updates[updates_.num++] = rect;
474 updates_.bound.Join(updates_.bound, rect);
475 }
476 }
477 }
478
ProcessUpdates()479 void LiteWM::ProcessUpdates()
480 {
481 bool needFlush = false;
482 {
483 GraphicLocker lock(stackLock_);
484 for (int i = 0; i < updates_.num; i++) {
485 ListNode<LiteWindow *>* winNode = winList_.Begin();
486 DrawRegion(winNode, EXPAND_RECT(updates_.updates[i]));
487
488 if (cursorInfo_.enableCursor && cursorInfo_.rect.IsIntersect(updates_.updates[i])) {
489 cursorInfo_.needRedraw = true;
490 }
491 }
492 if (updates_.num != 0 || (cursorInfo_.enableCursor && cursorInfo_.needRedraw)) {
493 needFlush = true;
494 }
495 updates_ = {};
496 }
497
498 if (cursorInfo_.enableCursor && cursorInfo_.needRedraw) {
499 DrawMouseCursor();
500 cursorInfo_.needRedraw = false;
501 }
502
503 if (needFlush) {
504 LcdFlush();
505 }
506 }
507
DrawRegion(const ListNode<LiteWindow * > * winNode,int16_t x1,int16_t y1,int16_t x2,int16_t y2)508 void LiteWM::DrawRegion(const ListNode<LiteWindow*>* winNode, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
509 {
510 if (winNode == nullptr) {
511 return;
512 }
513
514 if (winNode == winList_.End()) {
515 DrawBackground(x1, y1, x2, y2);
516 return;
517 }
518
519 LiteWindow* window = winNode->data_;
520 if (window == nullptr) {
521 return;
522 }
523 window->UpdateBackBuf();
524
525 Rect rect(x1, y1, x2, y2);
526 Rect& winRect = window->config_.rect;
527 Rect mask;
528 if (!window->isShow_ || window->NoNeedToDraw() ||
529 window->backBuf_ == nullptr || !mask.Intersect(winRect, rect)) {
530 GRAPHIC_LOGI("winRect={%d,%d,%d,%d}, rect={%d,%d,%d,%d}", EXPAND_RECT(winRect), EXPAND_RECT(rect));
531 DrawRegion(winNode->next_, x1, y1, x2, y2);
532 return;
533 }
534
535 int x = mask.GetLeft();
536 int y = mask.GetTop();
537
538 if (!window->IsCoverMode()) {
539 DrawRegion(winNode->next_, EXPAND_RECT(mask));
540 }
541
542 Rect srcRect = mask;
543 srcRect.SetPosition(mask.GetLeft() - winRect.GetLeft(), mask.GetTop() - winRect.GetTop());
544 GRAPHIC_LOGD("Blit, id=%d, srcRect={%d,%d,%d,%d}, x=%d, y=%d", window->id_, EXPAND_RECT(srcRect), x, y);
545 window->Flush(srcRect, layerData_, x, y);
546 GRAPHIC_LOGD("Blit finish");
547
548 if (x1 != mask.GetLeft()) {
549 DrawRegion(winNode->next_, x1, y1, mask.GetLeft() - 1, y2);
550 }
551
552 if (y1 != mask.GetTop()) {
553 DrawRegion(winNode->next_, mask.GetLeft(), y1, x2, mask.GetTop() - 1);
554 }
555
556 if (x2 != mask.GetRight()) {
557 DrawRegion(winNode->next_, mask.GetRight() + 1, mask.GetTop(), x2, y2);
558 }
559
560 if (y2 != mask.GetBottom()) {
561 DrawRegion(winNode->next_, mask.GetLeft(), mask.GetBottom() + 1, mask.GetRight(), y2);
562 }
563 }
564
DrawBackground(int16_t x1,int16_t y1,int16_t x2,int16_t y2)565 void LiteWM::DrawBackground(int16_t x1, int16_t y1, int16_t x2, int16_t y2)
566 {
567 Rect rect(0, 0, layerData_->width - 1, layerData_->height - 1);
568 Rect rectBg(x1, y1, x2, y2);
569 if (!rect.Intersect(rect, rectBg)) {
570 return;
571 }
572
573 x1 = rect.GetLeft();
574 x2 = rect.GetRight();
575 y1 = rect.GetTop();
576 y2 = rect.GetBottom();
577
578 GRAPHIC_LOGD("DrawBackground, {%d,%d,%d,%d}", x1, y1, x2, y2);
579 int32_t len = static_cast<int32_t>(x2 - x1 + 1) * layerData_->bytePerPixel;
580 for (int16_t y = y1; y <= y2; y++) {
581 LayerColorType* buf1 = reinterpret_cast<LayerColorType*>(layerData_->virAddr + y * layerData_->stride);
582 if (memset_s(buf1 + x1, len, 0, len) != EOK) {
583 GRAPHIC_LOGE("memset_s error!");
584 }
585 }
586 }
587
DrawMouseCursor()588 void LiteWM::DrawMouseCursor()
589 {
590 Rect rect(0, 0, layerData_->width - 1, layerData_->height - 1);
591 if (!rect.Intersect(rect, cursorInfo_.rect)) {
592 return;
593 }
594
595 int16_t x1 = rect.GetLeft();
596 int16_t x2 = rect.GetRight();
597 int16_t y1 = rect.GetTop();
598 int16_t y2 = rect.GetBottom();
599
600 const uint16_t* srcbuf = reinterpret_cast<const uint16_t*>(CURSOR_MAP);
601 uint8_t* dstBuf = layerData_->virAddr + y1 * layerData_->stride + x1 * sizeof(LayerColorType);
602 for (int16_t y = y1; y <= y2; y++) {
603 const uint16_t* tmpSrc = srcbuf;
604 LayerColorType* tmpDst = reinterpret_cast<LayerColorType*>(dstBuf);
605 for (int16_t x = x1; x <= x2; x++) {
606 if ((*tmpSrc) & 0x8000) {
607 #ifdef LAYER_PF_ARGB1555
608 *tmpDst = *tmpSrc;
609 #elif defined LAYER_PF_ARGB8888
610 *tmpDst = PixelFormatUtils::ARGB1555ToARGB8888(*tmpSrc);
611 #endif
612 }
613 tmpSrc++;
614 tmpDst++;
615 }
616 dstBuf += layerData_->stride;
617 srcbuf += CURSOR_WIDTH;
618 }
619 }
620
FindTargetWindow(const RawEvent & event)621 LiteWindow* LiteWM::FindTargetWindow(const RawEvent& event)
622 {
623 if (winList_.IsEmpty()) {
624 return nullptr;
625 }
626
627 LiteWindow* targetWindow = nullptr;
628 auto node = winList_.Begin();
629 while (node != winList_.End()) {
630 if (node->data_->GetConfig().isModal) {
631 return node->data_;
632 }
633 node = node->next_;
634 }
635
636 switch (event.type) {
637 case InputDevType::INDEV_TYPE_MOUSE:
638 // fall-through
639 case InputDevType::INDEV_TYPE_TOUCH: {
640 auto win = winList_.Begin();
641 while (win != winList_.End()) {
642 Point p = { event.x, event.y };
643 if (win->data_->isShow_ && win->data_->GetConfig().rect.IsContains(p)) {
644 targetWindow = win->data_;
645 break;
646 }
647 win = win->next_;
648 }
649 break;
650 }
651 case InputDevType::INDEV_TYPE_KEY:
652 // fall-through
653 case InputDevType::INDEV_TYPE_BUTTON: {
654 targetWindow = winList_.Front();
655 break;
656 }
657 default:
658 break;
659 }
660 return targetWindow;
661 }
662
OnRawEvent(const RawEvent & rawEvent)663 void LiteWM::OnRawEvent(const RawEvent& rawEvent)
664 {
665 static bool firstTime = true;
666 if (layerData_ == nullptr) {
667 return;
668 }
669
670 RawEvent event = rawEvent;
671 if (GetLayerRotateType() == LAYER_ROTATE_90) {
672 int16_t tmp = layerData_->height - event.x;
673 event.x = event.y;
674 event.y = tmp;
675 }
676
677 if (firstTime) {
678 if (event.type == InputDevType::INDEV_TYPE_MOUSE) {
679 cursorInfo_.enableCursor = true;
680 cursorInfo_.needRedraw = true;
681 } else {
682 cursorInfo_.enableCursor = false;
683 }
684 firstTime = false;
685 }
686
687 if (cursorInfo_.enableCursor) {
688 SetMousePosition(event.x, event.y);
689 }
690
691 LiteWindow* targetWindow = FindTargetWindow(event);
692 if (targetWindow == nullptr) {
693 return;
694 }
695
696 SetEventData(targetWindow, event);
697 }
698
OnScreenshot(Surface * surface)699 bool LiteWM::OnScreenshot(Surface* surface)
700 {
701 GraphicLocker lock(screenshotMutex_);
702 if (!needScreenshot_) {
703 screenshotSurface_ = surface;
704 needScreenshot_ = true;
705 return true;
706 }
707 return false;
708 }
709
Screenshot()710 void LiteWM::Screenshot()
711 {
712 int32_t lineSize = 0;
713 int16_t bpp = 0;
714 uint8_t* dstAddr = nullptr;
715 uint8_t* srcAddr = nullptr;
716 uint32_t width = 0;
717 uint32_t height = 0;
718 if (screenshotSurface_ == nullptr) {
719 return;
720 }
721
722 SurfaceBuffer* buffer = screenshotSurface_->RequestBuffer();
723 if (buffer == nullptr) {
724 goto end2;
725 }
726
727 width = screenshotSurface_->GetWidth();
728 height = screenshotSurface_->GetHeight();
729 if (width > layerData_->width || height > layerData_->height) {
730 goto end1;
731 }
732
733 if (!PixelFormatUtils::BppOfPixelFormat(static_cast<ImagePixelFormat>(screenshotSurface_->GetFormat()), bpp)) {
734 goto end1;
735 }
736
737 lineSize = width * bpp;
738 dstAddr = static_cast<uint8_t*>(buffer->GetVirAddr());
739 srcAddr = layerData_->virAddr;
740 if (dstAddr != nullptr && srcAddr != nullptr) {
741 for (uint32_t i = 0; i < height; i++) {
742 if (memcpy_s(dstAddr, lineSize, srcAddr, lineSize) != EOK) {
743 GRAPHIC_LOGE("memcpy_s error!");
744 }
745 dstAddr += lineSize;
746 srcAddr += layerData_->stride;
747 }
748 }
749 end1:
750 screenshotSurface_->FlushBuffer(buffer);
751 end2:
752 delete screenshotSurface_;
753 screenshotSurface_ = nullptr;
754 }
755
OnClientDeathNotify(pid_t pid)756 void LiteWM::OnClientDeathNotify(pid_t pid)
757 {
758 GRAPHIC_LOGI("OnClientDeathNotify");
759 GraphicLocker lock(stackLock_);
760 auto node = winList_.Begin();
761 while (node != winList_.End()) {
762 auto tmp = node;
763 node = node->next_;
764 LiteWindow* window = tmp->data_;
765 GRAPHIC_LOGI("window->GetPid() = %d,pid = %d", window->GetPid(), pid);
766 if (window->GetPid() == pid) {
767 winList_.Remove(tmp);
768 AddUpdateRegion(window->config_.rect);
769 delete window;
770 }
771 }
772 }
773 }
774