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 22namespace OHOS { 23namespace { 24#define EXPAND_RECT(x) x.GetLeft(), x.GetTop(), x.GetRight(), x.GetBottom() 25const uint16_t CURSOR_WIDTH = 24; 26const uint16_t CURSOR_HEIGHT = 25; 27const 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 95const uint8_t MAX_WINDOW_NUMBLE = 32; 96const uint32_t WINDOW_ID_FULL_STORAGE = 0xFFFFFFFF; 97} 98 99LiteWM::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 123LiteWM::~LiteWM() 124{ 125} 126 127LiteWM* LiteWM::GetInstance() 128{ 129 static LiteWM liteWm; 130 return &liteWm; 131} 132 133void 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 151void 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 163void 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 173Surface* 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 182void 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 192void 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 202void 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 221void 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 240void 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 249void 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 275void 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 284LiteWindow* 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 302ListNode<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 320void 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 328LiteWindow* 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 347void 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 362bool 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 371int32_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 385void 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 393void 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 402void 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 415void 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 452void 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 479void 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 508void 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 565void 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 588void 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 621LiteWindow* 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 663void 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 699bool 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 710void 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 } 749end1: 750 screenshotSurface_->FlushBuffer(buffer); 751end2: 752 delete screenshotSurface_; 753 screenshotSurface_ = nullptr; 754} 755 756void 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