1 /*
2 * Copyright (c) 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 "wmserver.h"
17
18 #include <assert.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/mman.h>
22 #include <unistd.h>
23
24 #include <window_manager_type.h>
25
26 #include "backend.h"
27 #include "ivi-layout-private.h"
28 #include "layout_controller.h"
29 #include "libweston-internal.h"
30 #include "screen_info.h"
31 #include "weston.h"
32 #include "split_mode.h"
33
34 #define LOG_LABEL "wms-controller"
35
36 #define DEBUG_LOG(fmt, ...) weston_log("%{public}s debug %{public}d:%{public}s " fmt "\n", \
37 LOG_LABEL, __LINE__, __func__, ##__VA_ARGS__)
38
39 #define LOGI(fmt, ...) weston_log("%{public}s info %{public}d:%{public}s " fmt "\n", \
40 LOG_LABEL, __LINE__, __func__, ##__VA_ARGS__)
41
42 #define LOGE(fmt, ...) weston_log("%{public}s error %{public}d:%{public}s " fmt "\n", \
43 LOG_LABEL, __LINE__, __func__, ##__VA_ARGS__)
44
45 #define WINDOW_ID_BIT 5
46 #define WINDOW_ID_LIMIT (1 << WINDOW_ID_BIT)
47 #define WINDOW_ID_FLAGS_FILL_ALL ((uint32_t) ~0)
48 #define WINDOW_ID_NUM_MAX 1024
49 #define WINDOW_ID_INVALID 0
50
51 #define LAYER_ID_SCREEN_BASE 100000
52 #define BAR_WIDTH_PERCENT 0.07
53 #define SCREEN_SHOT_FILE_PATH "/data/screenshot-XXXXXX"
54 #define TIMER_INTERVAL_MS 300
55 #define HEIGHT_AVERAGE 2
56 #define PIXMAN_FORMAT_AVERAGE 8
57 #define BYTE_SPP_SIZE 4
58 #define ASSERT assert
59 #define DEFAULT_SEAT_NAME "default"
60
61 static struct WmsContext g_wmsCtx = {0};
62
63 static ScreenInfoChangeListener g_screenInfoChangeListener = NULL;
64 static SeatInfoChangeListener g_seatInfoChangeListener = NULL;
65
66 static int32_t CreateScreen(struct WmsContext *pCtx,
67 struct weston_output *pOutput,
68 uint32_t screenType);
69 static void DestroyScreen(struct WmsScreen *pScreen);
70
SendGlobalWindowStatus(const struct WmsController * pController,uint32_t window_id,uint32_t status)71 static void SendGlobalWindowStatus(const struct WmsController *pController, uint32_t window_id, uint32_t status)
72 {
73 DEBUG_LOG("start.");
74 struct WmsContext *pWmsCtx = pController->pWmsCtx;
75 struct WmsController *pControllerTemp = NULL;
76 pid_t pid = 0;
77
78 wl_client_get_credentials(pController->pWlClient, &pid, NULL, NULL);
79
80 wl_list_for_each(pControllerTemp, &pWmsCtx->wlListGlobalEventResource, wlListLinkRes) {
81 wms_send_global_window_status(pControllerTemp->pWlResource, pid, window_id, status);
82 wl_client_flush(wl_resource_get_client(pControllerTemp->pWlResource));
83 }
84 DEBUG_LOG("end.");
85 }
86
SetSeatListener(const SeatInfoChangeListener listener)87 void SetSeatListener(const SeatInfoChangeListener listener)
88 {
89 g_seatInfoChangeListener = listener;
90 }
91
SeatInfoChangerNotify(void)92 static void SeatInfoChangerNotify(void)
93 {
94 if (g_seatInfoChangeListener) {
95 DEBUG_LOG("call seatInfoChangeListener.");
96 g_seatInfoChangeListener();
97 } else {
98 DEBUG_LOG("seatInfoChangeListener is not set.");
99 }
100 }
101
SetScreenListener(const ScreenInfoChangeListener listener)102 void SetScreenListener(const ScreenInfoChangeListener listener)
103 {
104 g_screenInfoChangeListener = listener;
105 }
106
ScreenInfoChangerNotify(void)107 static void ScreenInfoChangerNotify(void)
108 {
109 if (g_screenInfoChangeListener) {
110 DEBUG_LOG("call screenInfoChangeListener.");
111 g_screenInfoChangeListener();
112 } else {
113 DEBUG_LOG("screenInfoChangeListener is not set.");
114 }
115 }
116
GetWmsInstance(void)117 struct WmsContext *GetWmsInstance(void)
118 {
119 return &g_wmsCtx;
120 }
121
GetBit(uint32_t flags,uint32_t n)122 static inline uint32_t GetBit(uint32_t flags, uint32_t n)
123 {
124 return flags & (1u << n);
125 }
126
SetBit(uint32_t * flags,uint32_t n)127 static inline void SetBit(uint32_t *flags, uint32_t n)
128 {
129 *flags |= (1u << n);
130 }
131
ClearBit(uint32_t * flags,uint32_t n)132 static inline void ClearBit(uint32_t *flags, uint32_t n)
133 {
134 *flags &= ~(1u << n);
135 }
136
GetLayerId(uint32_t screenId,uint32_t type,uint32_t mode)137 static inline int GetLayerId(uint32_t screenId, uint32_t type, uint32_t mode)
138 {
139 uint32_t z = 0;
140 LayoutControllerCalcWindowDefaultLayout(type, mode, &z, NULL);
141 return z + screenId * LAYER_ID_SCREEN_BASE;
142 }
143
ChangeLayerId(uint32_t layerIdOld,uint32_t screenIdOld,uint32_t screenIdNew)144 static inline int ChangeLayerId(uint32_t layerIdOld, uint32_t screenIdOld, uint32_t screenIdNew)
145 {
146 uint32_t z = layerIdOld - screenIdOld * LAYER_ID_SCREEN_BASE;
147 return z + screenIdNew * LAYER_ID_SCREEN_BASE;
148 }
149
150 static void WindowSurfaceCommitted(struct weston_surface *surf, int32_t sx, int32_t sy);
151
GetWindowSurface(const struct weston_surface * surf)152 static struct WindowSurface *GetWindowSurface(const struct weston_surface *surf)
153 {
154 struct WindowSurface *windowSurface = NULL;
155
156 if (surf->committed != WindowSurfaceCommitted) {
157 return NULL;
158 }
159
160 windowSurface = surf->committed_private;
161 ASSERT(windowSurface);
162 ASSERT(windowSurface->surf == surf);
163
164 return windowSurface;
165 }
166
SetSourceRectangle(const struct WindowSurface * windowSurface,int32_t x,int32_t y,int32_t width,int32_t height)167 void SetSourceRectangle(const struct WindowSurface *windowSurface,
168 int32_t x, int32_t y, int32_t width, int32_t height)
169 {
170 const struct ivi_layout_interface_for_wms *layoutInterface = windowSurface->controller->pWmsCtx->pLayoutInterface;
171 struct ivi_layout_surface *layoutSurface = windowSurface->layoutSurface;
172
173 const struct ivi_layout_surface_properties *prop = layoutInterface->get_properties_of_surface(layoutSurface);
174
175 if (x < 0) {
176 x = prop->source_x;
177 }
178 if (y < 0) {
179 y = prop->source_y;
180 }
181
182 if (width < 0) {
183 width = prop->source_width;
184 }
185
186 if (height < 0) {
187 height = prop->source_height;
188 }
189
190 layoutInterface->surface_set_source_rectangle(layoutSurface,
191 (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
192 }
193
SetDestinationRectangle(struct WindowSurface * windowSurface,int32_t x,int32_t y,int32_t width,int32_t height)194 void SetDestinationRectangle(struct WindowSurface *windowSurface,
195 int32_t x, int32_t y, int32_t width, int32_t height)
196 {
197 const struct ivi_layout_interface_for_wms *layoutInterface = windowSurface->controller->pWmsCtx->pLayoutInterface;
198 struct ivi_layout_surface *layoutSurface = windowSurface->layoutSurface;
199
200 const struct ivi_layout_surface_properties *prop = layoutInterface->get_properties_of_surface(layoutSurface);
201 if (windowSurface->firstCommit == 1) {
202 layoutInterface->surface_set_transition(layoutSurface,
203 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, TIMER_INTERVAL_MS); // ms
204 } else {
205 layoutInterface->surface_set_transition(layoutSurface,
206 IVI_LAYOUT_TRANSITION_NONE, TIMER_INTERVAL_MS); // ms
207 windowSurface->firstCommit = 1;
208 }
209
210 if (width < 0) {
211 width = prop->dest_width;
212 }
213 if (height < 0) {
214 height = prop->dest_height;
215 }
216
217 layoutInterface->surface_set_destination_rectangle(layoutSurface,
218 (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
219 }
220
WindowSurfaceCommitted(struct weston_surface * surf,int32_t sx,int32_t sy)221 static void WindowSurfaceCommitted(struct weston_surface *surf, int32_t sx, int32_t sy)
222 {
223 struct WindowSurface *windowSurface = GetWindowSurface(surf);
224
225 ASSERT(windowSurface);
226
227 if (!windowSurface) {
228 return;
229 }
230
231 if (surf->width == 0 || surf->height == 0) {
232 return;
233 }
234
235 if (windowSurface->lastSurfaceWidth != surf->width || windowSurface->lastSurfaceHeight != surf->height) {
236 LOGI(" width = %{public}d, height = %{public}d", surf->width, surf->height);
237
238 const struct ivi_layout_interface_for_wms *layoutInterface =
239 windowSurface->controller->pWmsCtx->pLayoutInterface;
240
241 SetSourceRectangle(windowSurface, 0, 0, surf->width, surf->height);
242 SetDestinationRectangle(windowSurface,
243 windowSurface->x, windowSurface->y, windowSurface->width, windowSurface->height);
244
245 layoutInterface->surface_set_force_refresh(windowSurface->layoutSurface);
246 layoutInterface->commit_changes();
247
248 windowSurface->lastSurfaceWidth = surf->width;
249 windowSurface->lastSurfaceHeight = surf->height;
250 }
251 }
252
GetDisplayModeFlag(const struct WmsContext * ctx)253 static uint32_t GetDisplayModeFlag(const struct WmsContext *ctx)
254 {
255 uint32_t screen_num = wl_list_length(&ctx->wlListScreen);
256 uint32_t flag = WMS_DISPLAY_MODE_SINGLE;
257
258 if (screen_num > 1) {
259 flag = WMS_DISPLAY_MODE_SINGLE | WMS_DISPLAY_MODE_CLONE |
260 WMS_DISPLAY_MODE_EXTEND | WMS_DISPLAY_MODE_EXPAND;
261 }
262
263 return flag;
264 }
265
DisplayModeUpdate(const struct WmsContext * pCtx)266 static void DisplayModeUpdate(const struct WmsContext *pCtx)
267 {
268 struct WmsController *pController = NULL;
269 uint32_t flag = GetDisplayModeFlag(pCtx);
270
271 wl_list_for_each(pController, &pCtx->wlListController, wlListLink) {
272 wms_send_display_mode(pController->pWlResource, flag);
273 wl_client_flush(wl_resource_get_client(pController->pWlResource));
274 }
275 }
276
CheckWindowId(struct wl_client * client,uint32_t windowId)277 static bool CheckWindowId(struct wl_client *client,
278 uint32_t windowId)
279 {
280 pid_t pid = 0;
281
282 wl_client_get_credentials(client, &pid, NULL, NULL);
283 if ((windowId >> WINDOW_ID_BIT) == pid) {
284 return true;
285 }
286
287 return false;
288 }
289
GetSurface(const struct wl_list * surfaceList,uint32_t surfaceId)290 static struct WindowSurface *GetSurface(const struct wl_list *surfaceList,
291 uint32_t surfaceId)
292 {
293 struct WindowSurface *windowSurface = NULL;
294
295 wl_list_for_each(windowSurface, surfaceList, link) {
296 if (windowSurface->surfaceId == surfaceId) {
297 return windowSurface;
298 }
299 }
300
301 return NULL;
302 }
303
ClearWindowId(struct WmsController * pController,uint32_t windowId)304 static void ClearWindowId(struct WmsController *pController, uint32_t windowId)
305 {
306 DEBUG_LOG("windowId %{public}d.", windowId);
307 if (GetBit(pController->windowIdFlags, windowId % WINDOW_ID_LIMIT) != 0) {
308 ClearBit(&pController->windowIdFlags, windowId % WINDOW_ID_LIMIT);
309 return;
310 }
311 LOGE("windowIdFlags %{public}d is not set.", windowId % WINDOW_ID_LIMIT);
312 }
313
GetWindowId(struct WmsController * pController)314 static uint32_t GetWindowId(struct WmsController *pController)
315 {
316 pid_t pid = 0;
317 uint32_t windowId = WINDOW_ID_INVALID;
318 uint32_t windowCount = wl_list_length(&pController->pWmsCtx->wlListWindow);
319 if (windowCount >= WINDOW_ID_NUM_MAX) {
320 LOGE("failed, window count = %{public}d", WINDOW_ID_NUM_MAX);
321 return windowId;
322 }
323
324 if (pController->windowIdFlags == WINDOW_ID_FLAGS_FILL_ALL) {
325 LOGE("failed, number of window per process = %{public}d", WINDOW_ID_LIMIT);
326 return windowId;
327 }
328
329 wl_client_get_credentials(pController->pWlClient, &pid, NULL, NULL);
330
331 for (int i = 0; i < WINDOW_ID_LIMIT; i++) {
332 if (GetBit(pController->windowIdFlags, i) == 0) {
333 SetBit(&pController->windowIdFlags, i);
334 windowId = pid * WINDOW_ID_LIMIT + i;
335 break;
336 }
337 }
338
339 DEBUG_LOG("success, windowId = %{public}d", windowId);
340
341 return windowId;
342 }
343
GetLayer(struct weston_output * westonOutput,uint32_t layerId,bool * isNewLayer)344 struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput, uint32_t layerId, bool *isNewLayer)
345 {
346 struct ivi_layout_interface_for_wms *pLayoutInterface = GetWmsInstance()->pLayoutInterface;
347 DEBUG_LOG("start.");
348 struct ivi_layout_layer *layoutLayer = pLayoutInterface->get_layer_from_id(layerId);
349 if (!layoutLayer) {
350 layoutLayer = pLayoutInterface->layer_create_with_dimension(
351 layerId, westonOutput->width, westonOutput->height);
352 if (!layoutLayer) {
353 LOGE("ivi_layout_layer_create_with_dimension failed.");
354 return NULL;
355 }
356
357 pLayoutInterface->screen_add_layer(westonOutput, layoutLayer);
358 pLayoutInterface->layer_set_visibility(layoutLayer, true);
359 if (isNewLayer != NULL)
360 *isNewLayer = true;
361 }
362
363 DEBUG_LOG("end.");
364 return layoutLayer;
365 }
366
GetScreenFromId(const struct WmsContext * ctx,uint32_t screenId)367 static struct WmsScreen *GetScreenFromId(const struct WmsContext *ctx,
368 uint32_t screenId)
369 {
370 struct WmsScreen *screen = NULL;
371 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
372 if (screen->screenId == screenId) {
373 return screen;
374 }
375 }
376 return NULL;
377 }
378
GetScreen(const struct WindowSurface * windowSurface)379 static struct WmsScreen *GetScreen(const struct WindowSurface *windowSurface)
380 {
381 struct WmsScreen *screen = NULL;
382 struct WmsContext *ctx = windowSurface->controller->pWmsCtx;
383 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
384 if (screen->screenId == windowSurface->screenId) {
385 return screen;
386 }
387 }
388 return NULL;
389 }
390
CalcWindowInfo(struct WindowSurface * surf)391 static void CalcWindowInfo(struct WindowSurface *surf)
392 {
393 struct WmsContext *ctx = surf->controller->pWmsCtx;
394 struct WmsScreen *screen = GetScreen(surf);
395 int maxWidth = 0;
396 int maxHeight = 0;
397 if (!screen) {
398 LOGE("GetScreen error.");
399 return;
400 }
401 if (ctx->displayMode == WM_DISPLAY_MODE_EXPAND) {
402 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
403 maxWidth += screen->westonOutput->width;
404 }
405 maxHeight = ctx->pMainScreen->westonOutput->height;
406 } else {
407 maxWidth = screen->westonOutput->width;
408 maxHeight = screen->westonOutput->height;
409 }
410
411 LayoutControllerInit(maxWidth, maxHeight);
412 struct layout layout = {};
413 LayoutControllerCalcWindowDefaultLayout(surf->type, surf->mode, NULL, &layout);
414 surf->x = layout.x;
415 surf->y = layout.y;
416 surf->width = layout.w;
417 surf->height = layout.h;
418 }
419
AddSurface(struct WindowSurface * windowSurface,uint32_t windowType,uint32_t windowMode)420 static bool AddSurface(struct WindowSurface *windowSurface,
421 uint32_t windowType, uint32_t windowMode)
422 {
423 struct WmsContext *ctx = windowSurface->controller->pWmsCtx;
424 struct ivi_layout_interface_for_wms *layoutInterface = ctx->pLayoutInterface;
425 struct weston_output *mainWestonOutput = ctx->pMainScreen->westonOutput;
426 struct WmsScreen *screen = NULL;
427 int32_t x = mainWestonOutput->width;
428
429 DEBUG_LOG("start.");
430
431 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
432 if (screen->screenId == windowSurface->screenId
433 || ctx->displayMode == WMS_DISPLAY_MODE_CLONE
434 || ctx->displayMode == WMS_DISPLAY_MODE_EXPAND) {
435 bool isNewLayer = false;
436 struct weston_output *westonOutput = screen->westonOutput;
437 uint32_t layerId = GetLayerId(screen->screenId, windowType, windowMode);
438 struct ivi_layout_layer *layoutLayer = GetLayer(screen->westonOutput, layerId, &isNewLayer);
439 if (!layoutLayer) {
440 LOGE("GetLayer failed.");
441 return false;
442 }
443
444 if (screen->screenId != mainWestonOutput->id && isNewLayer) {
445 if (ctx->displayMode == WMS_DISPLAY_MODE_CLONE) {
446 layoutInterface->layer_set_source_rectangle(layoutLayer, 0, 0,
447 mainWestonOutput->width, mainWestonOutput->height);
448 } else if (ctx->displayMode == WMS_DISPLAY_MODE_EXPAND) {
449 layoutInterface->layer_set_source_rectangle(layoutLayer, x, 0,
450 westonOutput->width, mainWestonOutput->height);
451 x += westonOutput->width;
452 }
453 }
454
455 layoutInterface->layer_add_surface(layoutLayer, windowSurface->layoutSurface);
456 }
457 }
458 layoutInterface->surface_set_visibility(windowSurface->layoutSurface, true);
459
460 DEBUG_LOG("end.");
461 return true;
462 }
463
RemoveSurface(struct WindowSurface * windowSurface)464 static bool RemoveSurface(struct WindowSurface *windowSurface)
465 {
466 struct WmsContext *ctx = windowSurface->controller->pWmsCtx;
467 struct ivi_layout_interface_for_wms *layoutInterface = ctx->pLayoutInterface;
468 struct WmsScreen *screen = NULL;
469
470 DEBUG_LOG("start.");
471
472 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
473 if (screen->screenId == windowSurface->screenId
474 || ctx->displayMode == WMS_DISPLAY_MODE_CLONE
475 || ctx->displayMode == WMS_DISPLAY_MODE_EXPAND) {
476 uint32_t layerId = GetLayerId(screen->screenId, windowSurface->type, windowSurface->mode);
477 struct ivi_layout_layer *layoutLayer = layoutInterface->get_layer_from_id(layerId);
478 if (!layoutLayer && screen->screenId == windowSurface->screenId) {
479 LOGE("get_layer_from_id failed. layerId=%{public}d", layerId);
480 continue;
481 }
482
483 layoutInterface->layer_remove_surface(layoutLayer, windowSurface->layoutSurface);
484 }
485 }
486
487 DEBUG_LOG("end.");
488 return true;
489 }
490
AddWindow(struct WindowSurface * windowSurface)491 static bool AddWindow(struct WindowSurface *windowSurface)
492 {
493 struct ivi_layout_layer *layoutLayer = NULL;
494 struct WmsContext *ctx = windowSurface->controller->pWmsCtx;
495 struct WmsScreen *screen = NULL;
496
497 DEBUG_LOG("start.");
498
499 if (!AddSurface(windowSurface, windowSurface->type, windowSurface->mode)) {
500 LOGE("AddSurface failed.");
501 return false;
502 }
503
504 // window position,size calc.
505 CalcWindowInfo(windowSurface);
506 DEBUG_LOG("end.");
507 return true;
508 }
509
ControllerGetDisplayPower(const struct wl_client * client,const struct wl_resource * resource,int32_t displayId)510 static void ControllerGetDisplayPower(const struct wl_client *client,
511 const struct wl_resource *resource,
512 int32_t displayId)
513 {
514 struct WmsContext *ctx = GetWmsInstance();
515 if (ctx->deviceFuncs == NULL) {
516 wms_send_display_power(resource, WMS_ERROR_API_FAILED, 0);
517 wl_client_flush(wl_resource_get_client(resource));
518 }
519
520 DispPowerStatus status;
521 int32_t ret = ctx->deviceFuncs->GetDisplayPowerStatus(displayId, &status);
522 if (ret != 0) {
523 LOGE("GetDisplayPowerStatus failed, return %{public}d", ret);
524 wms_send_display_power(resource, WMS_ERROR_API_FAILED, 0);
525 wl_client_flush(wl_resource_get_client(resource));
526 }
527 wms_send_display_power(resource, WMS_ERROR_OK, status);
528 wl_client_flush(wl_resource_get_client(resource));
529 }
530
ControllerSetDisplayPower(const struct wl_client * client,const struct wl_resource * resource,int32_t displayId,int32_t status)531 static void ControllerSetDisplayPower(const struct wl_client *client,
532 const struct wl_resource *resource,
533 int32_t displayId, int32_t status)
534 {
535 struct WmsContext *ctx = GetWmsInstance();
536 if (ctx->deviceFuncs == NULL) {
537 wms_send_reply_error(resource, WMS_ERROR_API_FAILED);
538 wl_client_flush(wl_resource_get_client(resource));
539 }
540
541 int32_t ret = ctx->deviceFuncs->SetDisplayPowerStatus(displayId, status);
542 if (ret != 0) {
543 LOGE("SetDisplayPowerStatus failed, return %{public}d", ret);
544 wms_send_reply_error(resource, WMS_ERROR_API_FAILED);
545 wl_client_flush(wl_resource_get_client(resource));
546 }
547 wms_send_reply_error(resource, WMS_ERROR_OK);
548 wl_client_flush(wl_resource_get_client(resource));
549 }
550
ControllerGetDisplayBacklight(const struct wl_client * client,const struct wl_resource * resource,int32_t displayId)551 static void ControllerGetDisplayBacklight(const struct wl_client *client,
552 const struct wl_resource *resource,
553 int32_t displayId)
554 {
555 struct WmsContext *ctx = GetWmsInstance();
556 if (ctx->deviceFuncs == NULL) {
557 wms_send_display_backlight(resource, WMS_ERROR_API_FAILED, 0);
558 wl_client_flush(wl_resource_get_client(resource));
559 }
560
561 uint32_t level;
562 int32_t ret = ctx->deviceFuncs->GetDisplayBacklight(displayId, &level);
563 if (ret != 0) {
564 LOGE("GetDisplayBacklight failed, return %{public}d", ret);
565 wms_send_display_backlight(resource, WMS_ERROR_API_FAILED, 0);
566 wl_client_flush(wl_resource_get_client(resource));
567 }
568 wms_send_display_backlight(resource, WMS_ERROR_OK, level);
569 wl_client_flush(wl_resource_get_client(resource));
570 }
571
ControllerSetDisplayBacklight(const struct wl_client * client,const struct wl_resource * resource,int32_t displayId,uint32_t level)572 static void ControllerSetDisplayBacklight(const struct wl_client *client,
573 const struct wl_resource *resource,
574 int32_t displayId, uint32_t level)
575 {
576 struct WmsContext *ctx = GetWmsInstance();
577 if (ctx->deviceFuncs == NULL) {
578 wms_send_reply_error(resource, WMS_ERROR_API_FAILED);
579 wl_client_flush(wl_resource_get_client(resource));
580 }
581
582 int32_t ret = ctx->deviceFuncs->SetDisplayBacklight(displayId, level);
583 if (ret != 0) {
584 LOGE("SetDisplayBacklight failed, return %{public}d", ret);
585 wms_send_reply_error(resource, WMS_ERROR_API_FAILED);
586 wl_client_flush(wl_resource_get_client(resource));
587 }
588 wms_send_reply_error(resource, WMS_ERROR_OK);
589 wl_client_flush(wl_resource_get_client(resource));
590 }
591
ControllerCommitChanges(struct wl_client * client,struct wl_resource * resource)592 static void ControllerCommitChanges(struct wl_client *client,
593 struct wl_resource *resource)
594 {
595 DEBUG_LOG("start.");
596 struct WmsController *controller = wl_resource_get_user_data(resource);
597 struct WmsContext *ctx = controller->pWmsCtx;
598
599 ctx->pLayoutInterface->commit_changes();
600
601 DEBUG_LOG("end.");
602 }
603
LayerCopySurfaces(struct WmsContext * ctx,struct ivi_layout_layer * layerFrom,struct ivi_layout_layer * layerTo)604 static bool LayerCopySurfaces(struct WmsContext *ctx, struct ivi_layout_layer *layerFrom,
605 struct ivi_layout_layer *layerTo)
606 {
607 DEBUG_LOG("start.");
608 struct ivi_layout_surface **surfaces = NULL;
609 int32_t surfacesCount = 0;
610 uint32_t surfaceId = 0;
611 int32_t ret;
612
613 ret = ctx->pLayoutInterface->get_surfaces_on_layer(layerFrom, &surfacesCount, &surfaces);
614 if (ret != IVI_SUCCEEDED) {
615 LOGE("ivi_layout_get_surfaces_on_layer failed.");
616 return false;
617 }
618
619 for (int32_t surf_i = 0; surf_i < surfacesCount; surf_i++) {
620 ctx->pLayoutInterface->layer_add_surface(layerTo, surfaces[surf_i]);
621 }
622
623 if (surfaces != NULL) {
624 free(surfaces);
625 }
626
627 DEBUG_LOG("end.");
628 return true;
629 }
630
ScreenCopyLayers(struct WmsContext * ctx,struct WmsScreen * screenFrom,struct WmsScreen * screenTo)631 static bool ScreenCopyLayers(struct WmsContext *ctx, struct WmsScreen *screenFrom,
632 struct WmsScreen *screenTo)
633 {
634 DEBUG_LOG("start.");
635 struct ivi_layout_layer **layers = NULL;
636 int32_t layersCount = 0;
637 int32_t ret;
638
639 ret = ctx->pLayoutInterface->get_layers_on_screen(screenFrom->westonOutput, &layersCount, &layers);
640 if (ret != IVI_SUCCEEDED) {
641 LOGE("ivi_layout_get_layers_on_screen failed.");
642 return false;
643 }
644 for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
645 uint32_t layerIdOld = ctx->pLayoutInterface->get_id_of_layer(layers[layer_i]);
646 uint32_t layerIdNew = ChangeLayerId(layerIdOld, screenFrom->screenId, screenTo->screenId);
647 struct ivi_layout_layer *layerNew = GetLayer(screenTo->westonOutput, layerIdNew, NULL);
648 if (!layerNew) {
649 LOGE("GetLayer failed.");
650 free(layers);
651 return false;
652 }
653
654 if (!LayerCopySurfaces(ctx, layers[layer_i], layerNew)) {
655 LOGE("LayerCopySurfaces failed.");
656 free(layers);
657 return false;
658 }
659 }
660 if (layers != NULL) {
661 free(layers);
662 }
663
664 ctx->pLayoutInterface->commit_changes();
665 DEBUG_LOG("end.");
666 return true;
667 }
668
ScreenSetLayersSourceRect(struct WmsScreen * screen,int32_t x,int32_t y,int32_t w,int32_t h)669 static bool ScreenSetLayersSourceRect(struct WmsScreen *screen,
670 int32_t x, int32_t y, int32_t w, int32_t h)
671 {
672 DEBUG_LOG("start.");
673 struct WmsContext *ctx = screen->pWmsCtx;
674 struct ivi_layout_layer **layers = NULL;
675 int32_t layersCount = 0;
676 int32_t ret;
677
678 ret = ctx->pLayoutInterface->get_layers_on_screen(screen->westonOutput, &layersCount, &layers);
679 if (ret != IVI_SUCCEEDED) {
680 LOGE("ivi_layout_get_layers_on_screen failed.");
681 return false;
682 }
683 for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
684 ret = ctx->pLayoutInterface->layer_set_source_rectangle(layers[layer_i], x, y, w, h);
685 if (ret != IVI_SUCCEEDED) {
686 free(layers);
687 return false;
688 }
689 }
690 if (layers != NULL) {
691 free(layers);
692 }
693
694 DEBUG_LOG("end.");
695 return true;
696 }
697
ScreenClone(struct WmsScreen * screenFrom,struct WmsScreen * screenTo)698 static bool ScreenClone(struct WmsScreen *screenFrom, struct WmsScreen *screenTo)
699 {
700 DEBUG_LOG("start.");
701 struct WmsContext *ctx = screenFrom->pWmsCtx;
702 bool ret;
703
704 ret = ScreenCopyLayers(ctx, screenFrom, screenTo);
705 if (!ret) {
706 LOGE("ScreenCopyLayers failed.");
707 return ret;
708 }
709
710 ret = ScreenSetLayersSourceRect(screenTo, 0, 0,
711 screenFrom->westonOutput->width, screenFrom->westonOutput->height);
712 if (!ret) {
713 LOGE("ScreenSetLayersSourceRect failed.");
714 return ret;
715 }
716
717 DEBUG_LOG("end.");
718 return true;
719 }
720
ScreenExpand(struct WmsScreen * screenMain,struct WmsScreen * screenExpand,int32_t expandX,int32_t expandY)721 static bool ScreenExpand(struct WmsScreen *screenMain, struct WmsScreen *screenExpand,
722 int32_t expandX, int32_t expandY)
723 {
724 DEBUG_LOG("start.");
725 struct WmsContext *ctx = screenMain->pWmsCtx;
726 bool ret;
727
728 ret = ScreenCopyLayers(ctx, screenMain, screenExpand);
729 if (!ret) {
730 LOGE("ScreenCopyLayers failed.");
731 return ret;
732 }
733
734 ret = ScreenSetLayersSourceRect(screenExpand, expandX, expandY,
735 screenExpand->westonOutput->width, screenMain->westonOutput->height);
736 if (!ret) {
737 LOGE("ScreenSetLayersSourceRect failed.");
738 return ret;
739 }
740
741 DEBUG_LOG("end.");
742 return true;
743 }
744
ScreenClear(struct WmsScreen * screen)745 static bool ScreenClear(struct WmsScreen *screen)
746 {
747 DEBUG_LOG("start.");
748 struct WmsContext *ctx = screen->pWmsCtx;
749 struct ivi_layout_layer **layers = NULL;
750 int32_t layersCount = 0;
751 int32_t ret;
752
753 ret = ctx->pLayoutInterface->get_layers_on_screen(screen->westonOutput, &layersCount, &layers);
754 if (ret != IVI_SUCCEEDED) {
755 LOGE("ivi_layout_get_layers_on_screen failed.");
756 return false;
757 }
758
759 for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
760 struct ivi_layout_surface **surfaces = NULL;
761 int32_t surfacesCount = 0;
762 ret = ctx->pLayoutInterface->get_surfaces_on_layer(layers[layer_i], &surfacesCount, &surfaces);
763 if (ret != IVI_SUCCEEDED) {
764 LOGE("ivi_layout_get_surfaces_on_layer failed.");
765 return false;
766 }
767 for (int32_t surf_i = 0; surf_i < surfacesCount; surf_i++) {
768 ctx->pLayoutInterface->layer_remove_surface(layers[layer_i], surfaces[surf_i]);
769 }
770 if (surfaces != NULL) {
771 free(surfaces);
772 }
773
774 ctx->pLayoutInterface->layer_set_source_rectangle(layers[layer_i], 0, 0,
775 screen->westonOutput->width, screen->westonOutput->height);
776 }
777
778 if (layers != NULL) {
779 free(layers);
780 }
781
782 DEBUG_LOG("end.");
783 return true;
784 }
785
SetDisplayMode(struct WmsContext * ctx,uint32_t displayMode)786 static bool SetDisplayMode(struct WmsContext *ctx, uint32_t displayMode)
787 {
788 struct WmsScreen *screen = NULL;
789 bool ret = true;
790
791 ctx->pLayoutInterface->commit_changes();
792
793 if (ctx->displayMode != WMS_DISPLAY_MODE_SINGLE) {
794 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
795 if (screen->screenId == ctx->pMainScreen->screenId) {
796 continue;
797 }
798 ret = ScreenClear(screen);
799 LOGI("screen_clear, id: %{public}d, ret = %{public}d", screen->screenId, ret);
800 }
801 }
802
803 int32_t x = ctx->pMainScreen->westonOutput->width;
804 if (displayMode == WMS_DISPLAY_MODE_CLONE
805 || displayMode == WMS_DISPLAY_MODE_EXPAND) {
806 wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
807 if (screen->screenId == ctx->pMainScreen->screenId) {
808 continue;
809 }
810 if (displayMode == WMS_DISPLAY_MODE_CLONE) {
811 ret = ScreenClone(ctx->pMainScreen, screen);
812 LOGI("screen_clone from %{public}d to %{public}d, ret = %{public}d",
813 ctx->pMainScreen->screenId, screen->screenId, ret);
814 } else {
815 ret = ScreenExpand(ctx->pMainScreen, screen, x, 0);
816 x += screen->westonOutput->width;
817 LOGI("screen_expand from %{public}d to %{public}d, ret = %{public}d",
818 ctx->pMainScreen->screenId, screen->screenId, ret);
819 }
820 }
821 }
822 ctx->pLayoutInterface->commit_changes();
823
824 return ret;
825 }
826
ControllerSetDisplayMode(struct wl_client * client,struct wl_resource * resource,uint32_t displayMode)827 static void ControllerSetDisplayMode(struct wl_client *client,
828 struct wl_resource *resource,
829 uint32_t displayMode)
830 {
831 DEBUG_LOG("start. displayMode %{public}d", displayMode);
832 struct WmsController *controller = wl_resource_get_user_data(resource);
833 struct WmsContext *ctx = controller->pWmsCtx;
834 bool ret = true;
835
836 if (displayMode != WMS_DISPLAY_MODE_SINGLE &&
837 displayMode != WMS_DISPLAY_MODE_CLONE &&
838 displayMode != WMS_DISPLAY_MODE_EXTEND &&
839 displayMode != WMS_DISPLAY_MODE_EXPAND) {
840 LOGE("displayMode %{public}d erorr.", displayMode);
841 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
842 wl_client_flush(wl_resource_get_client(resource));
843 return;
844 }
845
846 uint32_t flag = GetDisplayModeFlag(ctx);
847 if (flag == WMS_DISPLAY_MODE_SINGLE
848 && displayMode != WMS_DISPLAY_MODE_SINGLE) {
849 LOGE("displayMode is invalid.");
850 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
851 wl_client_flush(wl_resource_get_client(resource));
852 return;
853 }
854
855 if (ctx->displayMode == displayMode) {
856 LOGE("current displayMode is the same.");
857 wms_send_reply_error(resource, WMS_ERROR_OK);
858 wl_client_flush(wl_resource_get_client(resource));
859 return;
860 }
861
862 ret = SetDisplayMode(ctx, displayMode);
863 if (ret == true) {
864 ctx->displayMode = displayMode;
865 wms_send_reply_error(resource, WMS_ERROR_OK);
866 wl_client_flush(wl_resource_get_client(resource));
867 ScreenInfoChangerNotify();
868 } else {
869 wms_send_reply_error(resource, WMS_ERROR_INNER_ERROR);
870 wl_client_flush(wl_resource_get_client(resource));
871 }
872
873 DEBUG_LOG("end. displayMode %{public}d", ctx->displayMode);
874 }
875
ControllerCreateVirtualDisplay(struct wl_client * pWlClient,struct wl_resource * pWlResource,int32_t x,int32_t y,int32_t width,int32_t height)876 static void ControllerCreateVirtualDisplay(struct wl_client *pWlClient,
877 struct wl_resource *pWlResource, int32_t x, int32_t y, int32_t width, int32_t height)
878 {
879 DEBUG_LOG("start. CreateVirtualDisplay, x:%{public}d, y:%{public}d, "
880 "w:%{public}d, h:%{public}d", x, y, width, height);
881 struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
882 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
883 struct ivi_layout_interface_for_wms *pLayoutInterface = pWmsCtx->pLayoutInterface;
884 struct weston_output *pOutput = NULL;
885 struct WmsScreen *pScreen = NULL;
886
887 wl_list_for_each(pScreen, &pWmsCtx->wlListScreen, wlListLink) {
888 if (pScreen->screenType == WMS_SCREEN_TYPE_VIRTUAL) {
889 LOGE("virtual display already exists.");
890 wms_send_reply_error(pWlResource, WMS_ERROR_OK);
891 return;
892 }
893 }
894 pOutput = pLayoutInterface->create_virtual_screen(x, y, width, height);
895 if (pOutput == NULL) {
896 LOGE("layout create_virtual_screen failed.");
897 wms_send_reply_error(pWlResource, WMS_ERROR_NO_MEMORY);
898 return;
899 }
900
901 if (CreateScreen(pWmsCtx, pOutput, WMS_SCREEN_TYPE_VIRTUAL) < 0) {
902 pLayoutInterface->destroy_virtual_screen(pOutput->id);
903 wms_send_reply_error(pWlResource, WMS_ERROR_NO_MEMORY);
904 return;
905 }
906
907 wms_send_screen_status(pWlResource, pOutput->id, pOutput->name, WMS_SCREEN_STATUS_ADD,
908 pOutput->width, pOutput->height, WMS_SCREEN_TYPE_VIRTUAL);
909 wms_send_reply_error(pWlResource, WMS_ERROR_OK);
910 DisplayModeUpdate(pWmsCtx);
911 wl_list_for_each(pWmsController, &pWmsCtx->wlListController, wlListLink) {
912 wms_send_screen_status(pWmsController->pWlResource, pOutput->id, pOutput->name,
913 WMS_SCREEN_STATUS_ADD, pOutput->width, pOutput->height, WMS_SCREEN_TYPE_VIRTUAL);
914 }
915 DEBUG_LOG("end. CreateVirtualDisplay");
916 }
917
ControllerDestroyVirtualDisplay(struct wl_client * pWlClient,struct wl_resource * pWlResource,uint32_t screenID)918 static void ControllerDestroyVirtualDisplay(struct wl_client *pWlClient,
919 struct wl_resource *pWlResource,
920 uint32_t screenID)
921 {
922 DEBUG_LOG("start. DestroyVirtualDisplay, screen id:%{public}d", screenID);
923 struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
924 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
925 struct ivi_layout_interface_for_wms *pLayoutInterface = pWmsCtx->pLayoutInterface;
926 struct WmsScreen *pScreen = NULL;
927
928 pScreen = GetScreenFromId(pWmsCtx, screenID);
929 if (!pScreen || pScreen->screenType != WMS_SCREEN_TYPE_VIRTUAL) {
930 LOGE("screen is not found[%{public}d].", screenID);
931 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
932 return;
933 }
934
935 pLayoutInterface->destroy_virtual_screen(screenID);
936
937 DestroyScreen(pScreen);
938
939 wms_send_screen_status(pWlResource, screenID, "", WMS_SCREEN_STATUS_REMOVE,
940 0, 0, 0);
941 wms_send_reply_error(pWlResource, WMS_ERROR_OK);
942 DisplayModeUpdate(pWmsCtx);
943
944 wl_list_for_each(pWmsController, &pWmsCtx->wlListController, wlListLink) {
945 wms_send_screen_status(pWmsController->pWlResource, screenID, "",
946 WMS_SCREEN_STATUS_REMOVE, 0, 0, 0);
947 }
948 DEBUG_LOG("end. DestroyVirtualDisplay");
949 }
950
SetWindowPosition(struct WindowSurface * ws,int32_t x,int32_t y)951 void SetWindowPosition(struct WindowSurface *ws,
952 int32_t x, int32_t y)
953 {
954 SetDestinationRectangle(ws, x, y, ws->width, ws->height);
955 ws->x = x;
956 ws->y = y;
957 }
958
SetWindowSize(struct WindowSurface * ws,uint32_t width,uint32_t height)959 void SetWindowSize(struct WindowSurface *ws,
960 uint32_t width, uint32_t height)
961 {
962 SetSourceRectangle(ws, 0, 0, width, height);
963 SetDestinationRectangle(ws, ws->x, ws->y, width, height);
964 ws->width = width;
965 ws->height = height;
966 }
967
SetWindowType(struct WindowSurface * ws,uint32_t windowType)968 static void SetWindowType(struct WindowSurface *ws,
969 uint32_t windowType)
970 {
971 RemoveSurface(ws);
972 AddSurface(ws, windowType, ws->mode);
973 }
974
SetWindowMode(struct WindowSurface * ws,uint32_t windowMode)975 static void SetWindowMode(struct WindowSurface *ws,
976 uint32_t windowMode)
977 {
978 RemoveSurface(ws);
979 AddSurface(ws, ws->type, windowMode);
980 }
981
ControllerSetWindowType(struct wl_client * pWlClient,struct wl_resource * pWlResource,uint32_t windowId,uint32_t windowType)982 static void ControllerSetWindowType(struct wl_client *pWlClient,
983 struct wl_resource *pWlResource,
984 uint32_t windowId, uint32_t windowType)
985 {
986 DEBUG_LOG("start. windowId=%{public}d, windowType=%{public}d", windowId, windowType);
987 struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
988 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
989 struct WindowSurface *pWindowSurface = NULL;
990
991 if (!CheckWindowId(pWlClient, windowId)) {
992 LOGE("CheckWindowId failed [%{public}d].", windowId);
993 wms_send_reply_error(pWlResource, WMS_ERROR_PID_CHECK);
994 wl_client_flush(wl_resource_get_client(pWlResource));
995 return;
996 }
997
998 if (windowType >= WINDOW_TYPE_MAX) {
999 LOGE("windowType %{public}d error.", windowType);
1000 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
1001 wl_client_flush(wl_resource_get_client(pWlResource));
1002 return;
1003 }
1004
1005 pWindowSurface = GetSurface(&pWmsCtx->wlListWindow, windowId);
1006 if (!pWindowSurface) {
1007 LOGE("pWindowSurface is not found[%{public}d].", windowId);
1008 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
1009 wl_client_flush(wl_resource_get_client(pWlResource));
1010 return;
1011 }
1012
1013 if (pWindowSurface->type == windowType) {
1014 LOGE("window type is not need change.");
1015 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
1016 wl_client_flush(wl_resource_get_client(pWlResource));
1017 return;
1018 }
1019
1020 SetWindowType(pWindowSurface, windowType);
1021
1022 pWindowSurface->type = windowType;
1023
1024 wms_send_reply_error(pWlResource, WMS_ERROR_OK);
1025 wl_client_flush(wl_resource_get_client(pWlResource));
1026 DEBUG_LOG("end.");
1027 }
1028
ControllerSetWindowMode(struct wl_client * pWlClient,struct wl_resource * pWlResource,uint32_t windowId,uint32_t windowMode)1029 static void ControllerSetWindowMode(struct wl_client *pWlClient,
1030 struct wl_resource *pWlResource,
1031 uint32_t windowId, uint32_t windowMode)
1032 {
1033 DEBUG_LOG("start. windowId=%{public}d, windowMode=%{public}d", windowId, windowMode);
1034 struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
1035 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
1036 struct WindowSurface *pWindowSurface = NULL;
1037
1038 if (!CheckWindowId(pWlClient, windowId)) {
1039 LOGE("CheckWindowId failed [%{public}d].", windowId);
1040 wms_send_reply_error(pWlResource, WMS_ERROR_PID_CHECK);
1041 wl_client_flush(wl_resource_get_client(pWlResource));
1042 return;
1043 }
1044
1045 if (windowMode >= WINDOW_MODE_MAX) {
1046 LOGE("windowMode %{public}d error.", windowMode);
1047 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
1048 wl_client_flush(wl_resource_get_client(pWlResource));
1049 return;
1050 }
1051
1052 pWindowSurface = GetSurface(&pWmsCtx->wlListWindow, windowId);
1053 if (!pWindowSurface) {
1054 LOGE("pWindowSurface is not found[%{public}d].", windowId);
1055 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
1056 wl_client_flush(wl_resource_get_client(pWlResource));
1057 return;
1058 }
1059
1060 if (pWindowSurface->mode == windowMode) {
1061 LOGE("window type is not need change.");
1062 wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
1063 wl_client_flush(wl_resource_get_client(pWlResource));
1064 return;
1065 }
1066
1067 SetWindowMode(pWindowSurface, windowMode);
1068 pWindowSurface->mode = windowMode;
1069 wms_send_reply_error(pWlResource, WMS_ERROR_OK);
1070 wl_client_flush(wl_resource_get_client(pWlResource));
1071 DEBUG_LOG("end.");
1072 }
1073
ControllerSetWindowVisibility(struct wl_client * client,struct wl_resource * resource,uint32_t windowId,uint32_t visibility)1074 static void ControllerSetWindowVisibility(
1075 struct wl_client *client, struct wl_resource *resource,
1076 uint32_t windowId, uint32_t visibility)
1077 {
1078 DEBUG_LOG("start. windowId=%{public}d, visibility=%{public}d", windowId, visibility);
1079 struct WmsController *controller = wl_resource_get_user_data(resource);
1080 struct WmsContext *ctx = controller->pWmsCtx;
1081 struct WindowSurface *windowSurface = NULL;
1082
1083 if (!CheckWindowId(client, windowId)) {
1084 LOGE("CheckWindowId failed [%{public}d].", windowId);
1085 wms_send_reply_error(resource, WMS_ERROR_PID_CHECK);
1086 wl_client_flush(wl_resource_get_client(resource));
1087 return;
1088 }
1089
1090 windowSurface = GetSurface(&ctx->wlListWindow, windowId);
1091 if (!windowSurface) {
1092 LOGE("windowSurface is not found[%{public}d].", windowId);
1093 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
1094 wl_client_flush(wl_resource_get_client(resource));
1095 return;
1096 }
1097
1098 ctx->pLayoutInterface->surface_set_visibility(windowSurface->layoutSurface, visibility);
1099
1100 wms_send_reply_error(resource, WMS_ERROR_OK);
1101 wl_client_flush(wl_resource_get_client(resource));
1102 DEBUG_LOG("end.");
1103 }
1104
ControllerSetWindowSize(struct wl_client * client,struct wl_resource * resource,uint32_t windowId,int32_t width,int32_t height)1105 static void ControllerSetWindowSize(struct wl_client *client,
1106 struct wl_resource *resource, uint32_t windowId,
1107 int32_t width, int32_t height)
1108 {
1109 DEBUG_LOG("start. windowId=%{public}d, width=%{public}d, height=%{public}d", windowId, width, height);
1110 struct WmsController *controller = wl_resource_get_user_data(resource);
1111 struct WmsContext *ctx = controller->pWmsCtx;
1112 struct WindowSurface *windowSurface = NULL;
1113
1114 if (!CheckWindowId(client, windowId)) {
1115 LOGE("CheckWindowId failed [%{public}d].", windowId);
1116 wms_send_reply_error(resource, WMS_ERROR_PID_CHECK);
1117 wl_client_flush(wl_resource_get_client(resource));
1118 return;
1119 }
1120
1121 windowSurface = GetSurface(&ctx->wlListWindow, windowId);
1122 if (!windowSurface) {
1123 LOGE("windowSurface is not found[%{public}d].", windowId);
1124 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
1125 wl_client_flush(wl_resource_get_client(resource));
1126 return;
1127 }
1128
1129 SetWindowSize(windowSurface, width, height);
1130 wms_send_reply_error(resource, WMS_ERROR_OK);
1131 wl_client_flush(wl_resource_get_client(resource));
1132
1133 DEBUG_LOG("end.");
1134 }
1135
ControllerSetWindowScale(struct wl_client * client,struct wl_resource * resource,uint32_t windowId,int32_t width,int32_t height)1136 static void ControllerSetWindowScale(struct wl_client *client,
1137 struct wl_resource *resource, uint32_t windowId,
1138 int32_t width, int32_t height)
1139 {
1140 DEBUG_LOG("start. windowId=%{public}d, width=%{public}d, height=%{public}d", windowId, width, height);
1141 struct WmsController *controller = wl_resource_get_user_data(resource);
1142 struct WmsContext *ctx = controller->pWmsCtx;
1143 struct WindowSurface *windowSurface = NULL;
1144
1145 if (!CheckWindowId(client, windowId)) {
1146 LOGE("CheckWindowId failed [%{public}d].", windowId);
1147 wms_send_reply_error(resource, WMS_ERROR_PID_CHECK);
1148 wl_client_flush(wl_resource_get_client(resource));
1149 return;
1150 }
1151
1152 windowSurface = GetSurface(&ctx->wlListWindow, windowId);
1153 if (!windowSurface) {
1154 LOGE("windowSurface is not found[%{public}d].", windowId);
1155 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
1156 wl_client_flush(wl_resource_get_client(resource));
1157 return;
1158 }
1159
1160 SetDestinationRectangle(windowSurface, windowSurface->x, windowSurface->y, width, height);
1161 windowSurface->width = width;
1162 windowSurface->height = height;
1163
1164 wms_send_reply_error(resource, WMS_ERROR_OK);
1165 wl_client_flush(wl_resource_get_client(resource));
1166
1167 DEBUG_LOG("end.");
1168 }
1169
ControllerSetWindowPosition(struct wl_client * client,struct wl_resource * resource,uint32_t windowId,int32_t x,int32_t y)1170 static void ControllerSetWindowPosition(struct wl_client *client,
1171 struct wl_resource *resource, uint32_t windowId, int32_t x, int32_t y)
1172 {
1173 DEBUG_LOG("start. windowId=%{public}d, x=%{public}d, y=%{public}d", windowId, x, y);
1174 struct WmsController *controller = wl_resource_get_user_data(resource);
1175 struct WmsContext *ctx = controller->pWmsCtx;
1176
1177 if (!CheckWindowId(client, windowId)) {
1178 LOGE("CheckWindowId failed [%{public}d].", windowId);
1179 wms_send_reply_error(resource, WMS_ERROR_PID_CHECK);
1180 wl_client_flush(wl_resource_get_client(resource));
1181 return;
1182 }
1183
1184 struct WindowSurface *windowSurface = GetSurface(&ctx->wlListWindow, windowId);
1185 if (!windowSurface) {
1186 LOGE("windowSurface is not found[%{public}d].", windowId);
1187 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
1188 wl_client_flush(wl_resource_get_client(resource));
1189 return;
1190 }
1191
1192 SetWindowPosition(windowSurface, x, y);
1193
1194 wms_send_reply_error(resource, WMS_ERROR_OK);
1195 wl_client_flush(wl_resource_get_client(resource));
1196 DEBUG_LOG("end.");
1197 }
1198
1199 #ifndef USE_IVI_INPUT_FOCUS
PointerSetFocus(const struct WmsSeat * seat)1200 static void PointerSetFocus(const struct WmsSeat *seat)
1201 {
1202 DEBUG_LOG("start.");
1203 DEBUG_LOG("seat->pWestonSeat->seat_name: [%{public}s]\n", seat->pWestonSeat->seat_name);
1204 DEBUG_LOG("seat->deviceFlags: %{public}d", seat->deviceFlags);
1205 DEBUG_LOG("seat->focusWindowId: %{public}d", seat->focusWindowId);
1206
1207 struct WindowSurface *forcedWindow = GetSurface(&seat->pWmsCtx->wlListWindow, seat->focusWindowId);
1208 if (!forcedWindow) {
1209 LOGE("forcedWindow is not found[%{public}d].", seat->focusWindowId);
1210 return;
1211 }
1212
1213 struct weston_pointer *pointer = weston_seat_get_pointer(seat->pWestonSeat);
1214 if (!pointer) {
1215 LOGE("weston_seat_get_pointer is NULL.");
1216 return;
1217 }
1218
1219 if (pointer->button_count > 0) {
1220 LOGE("pointer->button_count > 0");
1221 return;
1222 }
1223
1224 if (pointer->focus != NULL) {
1225 LOGE("weston_pointer_clear_focus.");
1226 weston_pointer_clear_focus(pointer);
1227 }
1228
1229 struct weston_surface *forcedSurface = forcedWindow->surf;
1230 LOGI("weston_pointer_set_focus0.");
1231 if ((forcedSurface != NULL) && !wl_list_empty(&forcedSurface->views)) {
1232 LOGI("weston_pointer_set_focus1.");
1233 struct weston_view *view = wl_container_of(forcedSurface->views.next, view, surface_link);
1234 wl_fixed_t sx, sy;
1235 weston_view_from_global_fixed(view, pointer->x, pointer->y, &sx, &sy);
1236 LOGI("weston_pointer_set_focus x[%{public}d], y[%{public}d], sx[%{public}d], sy[%{public}d].",
1237 pointer->x, pointer->y, sx, sy);
1238 if (pointer->focus != view) {
1239 LOGI("weston_pointer_set_focus2.");
1240 weston_pointer_set_focus(pointer, view, sx, sy);
1241 }
1242 LOGI("weston_pointer_set_focus3.");
1243 }
1244
1245 DEBUG_LOG("end.");
1246 }
1247 #endif
1248
GetWmsSeat(const char * seatName)1249 static struct WmsSeat *GetWmsSeat(const char *seatName)
1250 {
1251 struct WmsContext *pWmsCtx = GetWmsInstance();
1252 struct WmsSeat *pSeat = NULL;
1253 wl_list_for_each(pSeat, &pWmsCtx->wlListSeat, wlListLink) {
1254 if (!strcmp(pSeat->pWestonSeat->seat_name, seatName)) {
1255 return pSeat;
1256 }
1257 }
1258 return NULL;
1259 }
1260
GetDefaultFocusableWindow(uint32_t screenId)1261 static struct WindowSurface *GetDefaultFocusableWindow(uint32_t screenId)
1262 {
1263 struct WmsContext *pWmsCtx = GetWmsInstance();
1264 struct WmsScreen *pWmsScreen = GetScreenFromId(pWmsCtx, screenId);
1265
1266 if (!pWmsScreen) {
1267 LOGE("GetScreenFromId failed.");
1268 return NULL;
1269 }
1270
1271 int layerCount = 0;
1272 struct ivi_layout_layer **layerList = NULL;
1273 struct ivi_layout_interface_for_wms *pLayoutInterface = pWmsCtx->pLayoutInterface;
1274 pLayoutInterface->get_layers_on_screen(pWmsScreen->westonOutput, &layerCount, &layerList);
1275
1276 for (int i = layerCount - 1; i >= 0; i--) {
1277 int surfaceCnt = 0;
1278 struct ivi_layout_surface **surfaceList = NULL;
1279 pLayoutInterface->get_surfaces_on_layer(layerList[i], &surfaceCnt, &surfaceList);
1280
1281 for (int j = surfaceCnt - 1; j >= 0; j--) {
1282 struct WindowSurface *pWindow = GetSurface(&pWmsCtx->wlListWindow, surfaceList[j]->id_surface);
1283 if (pWindow && pWindow->type != WINDOW_TYPE_STATUS_BAR
1284 && pWindow->type != WINDOW_TYPE_NAVI_BAR) {
1285 LOGI("DefaultFocusableWindow found %{public}d.", pWindow->surfaceId);
1286 free(surfaceList);
1287 free(layerList);
1288 return pWindow;
1289 }
1290 }
1291 if (surfaceCnt > 0) {
1292 free(surfaceList);
1293 }
1294 }
1295 if (layerCount > 0) {
1296 free(layerList);
1297 }
1298
1299 LOGI("DefaultFocusableWindow not found.");
1300 return NULL;
1301 }
1302
SetWindowFocus(const struct WindowSurface * surf)1303 static bool SetWindowFocus(const struct WindowSurface *surf)
1304 {
1305 DEBUG_LOG("start.");
1306 int flag = INPUT_DEVICE_ALL;
1307
1308 if ((surf->type == WINDOW_TYPE_STATUS_BAR) || (surf->type == WINDOW_TYPE_NAVI_BAR)) {
1309 flag = INPUT_DEVICE_POINTER | INPUT_DEVICE_TOUCH;
1310 }
1311
1312 #ifdef USE_IVI_INPUT_FOCUS
1313 int surfaceCount = 0;
1314 struct ivi_layout_surface **surfaceList = NULL;
1315 struct ivi_layout_interface_for_wms *layoutInterface = surf->controller->pWmsCtx->pLayoutInterface;
1316 const struct ivi_input_interface_for_wms *pInputInterface = surf->controller->pWmsCtx->pInputInterface;
1317 int32_t layerId = GetLayerId(surf->screenId, surf->type, surf->mode);
1318 struct ivi_layout_layer *layoutLayer = layoutInterface->get_layer_from_id(layerId);
1319 if (!layoutLayer) {
1320 LOGE("get_layer_from_id failed.");
1321 return false;
1322 }
1323
1324 if (layoutInterface->get_surfaces_on_layer(layoutLayer, &surfaceCount, &surfaceList) == IVI_FAILED) {
1325 LOGE("get_surfaces_on_layer failed.");
1326 return false;
1327 }
1328
1329 for (int j = 0; j < surfaceCount; j++) {
1330 pInputInterface->set_focus(surfaceList[j]->id_surface, flag, false);
1331 }
1332 pInputInterface->set_focus(surf->surfaceId, flag, true);
1333
1334 if (surfaceCount) {
1335 free(surfaceList);
1336 }
1337 #endif
1338 struct WmsSeat *pSeat = GetWmsSeat(DEFAULT_SEAT_NAME);
1339 if (!pSeat) {
1340 LOGE("GetWmsSeat error.");
1341 return false;
1342 }
1343 pSeat->deviceFlags = flag;
1344 pSeat->focusWindowId = surf->surfaceId;
1345 #ifndef USE_IVI_INPUT_FOCUS
1346 PointerSetFocus(pSeat);
1347 #endif
1348 SeatInfoChangerNotify();
1349
1350 DEBUG_LOG("end.");
1351 return true;
1352 }
1353
ControllerSetStatusBarVisibility(const struct wl_client * client,const struct wl_resource * resource,uint32_t visibility)1354 static void ControllerSetStatusBarVisibility(const struct wl_client *client,
1355 const struct wl_resource *resource,
1356 uint32_t visibility)
1357 {
1358 DEBUG_LOG("start. visibility=%{public}d", visibility);
1359 struct WmsController *controller = wl_resource_get_user_data(resource);
1360 struct WmsContext *ctx = controller->pWmsCtx;
1361
1362 struct WindowSurface *windowSurface = NULL;
1363 bool have = false;
1364 wl_list_for_each(windowSurface, (&ctx->wlListWindow), link) {
1365 if (windowSurface->type == WINDOW_TYPE_STATUS_BAR) {
1366 have = true;
1367 break;
1368 }
1369 }
1370 if (!have) {
1371 LOGE("StatusBar is not found");
1372 wms_send_reply_error(resource, WMS_ERROR_INNER_ERROR);
1373 wl_client_flush(wl_resource_get_client(resource));
1374 return;
1375 }
1376
1377 ctx->pLayoutInterface->surface_set_visibility(windowSurface->layoutSurface, visibility);
1378 ctx->pLayoutInterface->commit_changes();
1379 wms_send_reply_error(resource, WMS_ERROR_OK);
1380 wl_client_flush(wl_resource_get_client(resource));
1381 DEBUG_LOG("end.");
1382 }
1383
FocusWindowUpdate(const struct WindowSurface * surf)1384 static bool FocusWindowUpdate(const struct WindowSurface *surf)
1385 {
1386 struct WmsSeat *pSeat = GetWmsSeat(DEFAULT_SEAT_NAME);
1387 if (!pSeat) {
1388 LOGE("GetWmsSeat error.");
1389 return false;
1390 }
1391
1392 if (pSeat->focusWindowId == surf->surfaceId) {
1393 struct WindowSurface *focus = GetDefaultFocusableWindow(surf->screenId);
1394 if (focus && !SetWindowFocus(focus)) {
1395 LOGE("SetWindowFocus failed.");
1396 return false;
1397 }
1398 }
1399
1400 return true;
1401 }
1402
ControllerSetNavigationBarVisibility(const struct wl_client * client,const struct wl_resource * resource,uint32_t visibility)1403 static void ControllerSetNavigationBarVisibility(const struct wl_client *client,
1404 const struct wl_resource *resource,
1405 uint32_t visibility)
1406 {
1407 (void)client;
1408 DEBUG_LOG("start. visibility=%{public}d", visibility);
1409 struct WmsController *controller = wl_resource_get_user_data(resource);
1410 struct WmsContext *ctx = controller->pWmsCtx;
1411
1412 struct WindowSurface *windowSurface = NULL;
1413 bool have = false;
1414 wl_list_for_each(windowSurface, (&ctx->wlListWindow), link) {
1415 if (windowSurface->type == WINDOW_TYPE_NAVI_BAR) {
1416 have = true;
1417 break;
1418 }
1419 }
1420 if (!have) {
1421 LOGE("NavigationBar is not found");
1422 wms_send_reply_error(resource, WMS_ERROR_INNER_ERROR);
1423 wl_client_flush(wl_resource_get_client(resource));
1424 return;
1425 }
1426
1427 ctx->pLayoutInterface->surface_set_visibility(windowSurface->layoutSurface, visibility);
1428 ctx->pLayoutInterface->commit_changes();
1429 wms_send_reply_error(resource, WMS_ERROR_OK);
1430 wl_client_flush(wl_resource_get_client(resource));
1431 DEBUG_LOG("end.");
1432 }
1433
1434 void(*g_onSetWindowTop)(struct WindowSurface *ws);
AddSetWindowTopListener(void (* fn)(struct WindowSurface * ws))1435 void AddSetWindowTopListener(void(*fn)(struct WindowSurface *ws))
1436 {
1437 g_onSetWindowTop = fn;
1438 }
1439
ControllerSetWindowTop(struct wl_client * client,struct wl_resource * resource,uint32_t windowId)1440 static void ControllerSetWindowTop(struct wl_client *client,
1441 struct wl_resource *resource, uint32_t windowId)
1442 {
1443 DEBUG_LOG("start. windowId=%{public}d", windowId);
1444 struct WmsController *controller = wl_resource_get_user_data(resource);
1445 struct WmsContext *ctx = controller->pWmsCtx;
1446 struct WindowSurface *windowSurface = NULL;
1447
1448 if (!CheckWindowId(client, windowId)) {
1449 LOGE("CheckWindowId failed [%{public}d].", windowId);
1450 wms_send_reply_error(resource, WMS_ERROR_PID_CHECK);
1451 wl_client_flush(wl_resource_get_client(resource));
1452 return;
1453 }
1454
1455 windowSurface = GetSurface(&ctx->wlListWindow, windowId);
1456 if (!windowSurface) {
1457 LOGE("windowSurface is not found[%{public}d].", windowId);
1458 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
1459 wl_client_flush(wl_resource_get_client(resource));
1460 return;
1461 }
1462
1463 ctx->pLayoutInterface->surface_change_top(windowSurface->layoutSurface);
1464
1465 if (g_onSetWindowTop) {
1466 g_onSetWindowTop(windowSurface);
1467 }
1468
1469 if (!SetWindowFocus(windowSurface)) {
1470 LOGE("SetWindowFocus failed.");
1471 wms_send_reply_error(resource, WMS_ERROR_INNER_ERROR);
1472 wl_client_flush(wl_resource_get_client(resource));
1473 return;
1474 }
1475
1476 wms_send_reply_error(resource, WMS_ERROR_OK);
1477 wl_client_flush(wl_resource_get_client(resource));
1478 DEBUG_LOG("end.");
1479 }
1480
1481 void(*g_onSurfaceDestroy)(struct WindowSurface *ws);
AddSurfaceDestroyListener(void (* fn)(struct WindowSurface * ws))1482 void AddSurfaceDestroyListener(void(*fn)(struct WindowSurface *ws))
1483 {
1484 g_onSurfaceDestroy = fn;
1485 }
1486
SurfaceDestroy(const struct WindowSurface * surf)1487 static void SurfaceDestroy(const struct WindowSurface *surf)
1488 {
1489 ASSERT(surf != NULL);
1490 DEBUG_LOG("surfaceId:%{public}d start.", surf->surfaceId);
1491 if (g_onSurfaceDestroy) {
1492 g_onSurfaceDestroy(surf);
1493 }
1494
1495 wl_list_remove(&surf->surfaceDestroyListener.link);
1496 wl_list_remove(&surf->propertyChangedListener.link);
1497
1498 if (surf->layoutSurface != NULL) {
1499 surf->controller->pWmsCtx->pLayoutInterface->surface_destroy(
1500 surf->layoutSurface);
1501 }
1502
1503 ClearWindowId(surf->controller, surf->surfaceId);
1504 wl_list_remove(&surf->link);
1505
1506 if (surf->surf) {
1507 surf->surf->committed = NULL;
1508 surf->surf->committed_private = NULL;
1509 }
1510
1511 if (!FocusWindowUpdate(surf)) {
1512 LOGE("FocusWindowUpdate failed.");
1513 }
1514
1515 wms_send_window_status(surf->controller->pWlResource,
1516 WMS_WINDOW_STATUS_DESTROYED, surf->surfaceId, 0, 0, 0, 0);
1517 wl_client_flush(wl_resource_get_client(surf->controller->pWlResource));
1518
1519 SendGlobalWindowStatus(surf->controller, surf->surfaceId, WMS_WINDOW_STATUS_DESTROYED);
1520
1521 ScreenInfoChangerNotify();
1522
1523 free(surf);
1524
1525 DEBUG_LOG(" end.");
1526 }
ControllerDestroyWindow(struct wl_client * client,struct wl_resource * resource,uint32_t windowId)1527 static void ControllerDestroyWindow(struct wl_client *client,
1528 struct wl_resource *resource, uint32_t windowId)
1529 {
1530 DEBUG_LOG("start. windowId=%{public}d", windowId);
1531 struct WmsController *controller = wl_resource_get_user_data(resource);
1532 struct WmsContext *ctx = controller->pWmsCtx;
1533 struct WindowSurface *windowSurface = NULL;
1534
1535 if (!CheckWindowId(client, windowId)) {
1536 LOGE("CheckWindowId failed [%{public}d].", windowId);
1537 wms_send_reply_error(resource, WMS_ERROR_PID_CHECK);
1538 wl_client_flush(wl_resource_get_client(resource));
1539 return;
1540 }
1541
1542 windowSurface = GetSurface(&ctx->wlListWindow, windowId);
1543 if (!windowSurface) {
1544 LOGE("windowSurface is not found[%{public}d].", windowId);
1545 wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
1546 wl_client_flush(wl_resource_get_client(resource));
1547 return;
1548 }
1549
1550 SurfaceDestroy(windowSurface);
1551 wms_send_reply_error(resource, WMS_ERROR_OK);
1552 wl_client_flush(wl_resource_get_client(resource));
1553 DEBUG_LOG("end.");
1554 }
1555
WindowPropertyChanged(struct wl_listener * listener,void * data)1556 static void WindowPropertyChanged(struct wl_listener *listener, void *data)
1557 {
1558 DEBUG_LOG("start.");
1559 ScreenInfoChangerNotify();
1560 DEBUG_LOG("end.");
1561 }
1562
WindowSurfaceDestroy(const struct wl_listener * listener,const struct weston_compositor * data)1563 static void WindowSurfaceDestroy(const struct wl_listener *listener,
1564 const struct weston_compositor *data)
1565 {
1566 DEBUG_LOG("start.");
1567
1568 struct WindowSurface *windowSurface = wl_container_of(listener, windowSurface, surfaceDestroyListener);
1569 SurfaceDestroy(windowSurface);
1570
1571 DEBUG_LOG("end.");
1572 }
1573
AllocWindow(struct WmsController * pWmsController,struct weston_surface * pWestonSurface,uint32_t windowId)1574 static struct WindowSurface *AllocWindow(struct WmsController *pWmsController,
1575 struct weston_surface *pWestonSurface, uint32_t windowId)
1576 {
1577 struct WindowSurface *pWindow = calloc(1, sizeof(*pWindow));
1578 if (!pWindow) {
1579 LOGE("calloc failed.");
1580 wl_client_post_no_memory(pWmsController->pWlClient);
1581 wms_send_window_status(pWmsController->pWlResource,
1582 WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1583 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1584
1585 ClearWindowId(pWmsController, windowId);
1586 return NULL;
1587 }
1588
1589 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
1590 pWindow->layoutSurface = pWmsCtx->pLayoutInterface->surface_create(pWestonSurface, windowId);
1591 /* check if windowId is already used for wl_surf */
1592 if (pWindow->layoutSurface == NULL) {
1593 LOGE("layoutInterface->surface_create failed.");
1594 wms_send_window_status(pWmsController->pWlResource,
1595 WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1596 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1597
1598 ClearWindowId(pWmsController, windowId);
1599 free(pWindow);
1600 return NULL;
1601 }
1602
1603 return pWindow;
1604 }
1605
CreateWindow(struct WmsController * pWmsController,struct weston_surface * pWestonSurface,uint32_t windowId,uint32_t screenId,uint32_t windowType)1606 static void CreateWindow(struct WmsController *pWmsController,
1607 struct weston_surface *pWestonSurface,
1608 uint32_t windowId, uint32_t screenId, uint32_t windowType)
1609 {
1610 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
1611 struct wl_resource *pWlResource = pWmsController->pWlResource;
1612 struct WindowSurface *pWindow = AllocWindow(pWmsController, pWestonSurface, windowId);
1613 if (pWindow == NULL) {
1614 return;
1615 }
1616
1617 pWindow->controller = pWmsController;
1618 pWindow->surf = pWestonSurface;
1619 pWindow->surfaceId = windowId;
1620 pWindow->type = windowType;
1621 pWindow->mode = WINDOW_MODE_UNSET;
1622 pWindow->isSplited = false;
1623 pWindow->screenId = screenId;
1624
1625 if (!AddWindow(pWindow)) {
1626 LOGE("AddWindow failed.");
1627 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1628 wl_client_flush(wl_resource_get_client(pWlResource));
1629
1630 pWmsCtx->pLayoutInterface->surface_destroy(pWindow->layoutSurface);
1631 ClearWindowId(pWmsController, windowId);
1632 free(pWindow);
1633 return;
1634 }
1635
1636 pWestonSurface->committed = WindowSurfaceCommitted;
1637 pWestonSurface->committed_private = pWindow;
1638
1639 wl_list_init(&pWindow->link);
1640 wl_list_insert(&pWmsCtx->wlListWindow, &pWindow->link);
1641
1642 pWindow->surfaceDestroyListener.notify = WindowSurfaceDestroy;
1643 wl_signal_add(&pWestonSurface->destroy_signal, &pWindow->surfaceDestroyListener);
1644
1645 pWindow->propertyChangedListener.notify = WindowPropertyChanged;
1646 wl_signal_add(&pWindow->layoutSurface->property_changed, &pWindow->propertyChangedListener);
1647
1648 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_CREATED, windowId,
1649 pWindow->x, pWindow->y, pWindow->width, pWindow->height);
1650 wl_client_flush(wl_resource_get_client(pWlResource));
1651 SendGlobalWindowStatus(pWmsController, windowId, WMS_WINDOW_STATUS_CREATED);
1652 }
1653
ControllerCreateWindow(struct wl_client * pWlClient,struct wl_resource * pWlResource,struct wl_resource * pWlSurfaceResource,uint32_t screenId,uint32_t windowType)1654 static void ControllerCreateWindow(struct wl_client *pWlClient,
1655 struct wl_resource *pWlResource,
1656 struct wl_resource *pWlSurfaceResource,
1657 uint32_t screenId, uint32_t windowType)
1658 {
1659 DEBUG_LOG("start. screenId=%{public}d, windowType=%{public}d", screenId, windowType);
1660 uint32_t windowId = WINDOW_ID_INVALID;
1661 struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
1662 struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
1663 struct weston_surface *westonSurface = wl_resource_get_user_data(pWlSurfaceResource);
1664
1665 if (windowType >= WINDOW_TYPE_MAX) {
1666 LOGE("windowType %{public}d error.", windowType);
1667 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1668 wl_client_flush(wl_resource_get_client(pWlResource));
1669 return;
1670 }
1671
1672 if (!GetScreenFromId(pWmsCtx, screenId)) {
1673 LOGE("screen is not found[%{public}d].", screenId);
1674 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1675 wl_client_flush(wl_resource_get_client(pWlResource));
1676 return;
1677 }
1678
1679 if (screenId > 0 && pWmsCtx->displayMode != WMS_DISPLAY_MODE_EXTEND) {
1680 LOGE("screenId %{public}d error.", screenId);
1681 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1682 wl_client_flush(wl_resource_get_client(pWlResource));
1683 return;
1684 }
1685
1686 if (westonSurface->committed == WindowSurfaceCommitted &&
1687 westonSurface->committed_private != NULL) {
1688 LOGE("the westonSurface is using by other window.");
1689 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1690 wl_client_flush(wl_resource_get_client(pWlResource));
1691 return;
1692 }
1693
1694 windowId = GetWindowId(pWmsController);
1695 if (windowId != WINDOW_ID_INVALID) {
1696 CreateWindow(pWmsController, westonSurface, windowId, screenId, windowType);
1697 } else {
1698 LOGE("create window restriction..");
1699 wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
1700 wl_client_flush(wl_resource_get_client(pWlResource));
1701 }
1702
1703 DEBUG_LOG("end.");
1704 }
1705
CreateScreenshotFile(off_t size)1706 static int CreateScreenshotFile(off_t size)
1707 {
1708 char template[] = SCREEN_SHOT_FILE_PATH;
1709 int fd = mkstemp(template);
1710 if (fd < 0) {
1711 return -1;
1712 }
1713
1714 unlink(template);
1715 if (ftruncate(fd, size) < 0) {
1716 close(fd);
1717 return -1;
1718 }
1719
1720 return fd;
1721 }
1722
ControllerWindowshot(struct wl_client * pWlClient,struct wl_resource * pWlResource,uint32_t windowId)1723 static void ControllerWindowshot(struct wl_client *pWlClient,
1724 struct wl_resource *pWlResource, uint32_t windowId)
1725 {
1726 DEBUG_LOG("start. windowId = %{public}d.", windowId);
1727 struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
1728
1729 struct WindowSurface *pWindowSurface = GetSurface(&pWmsController->pWmsCtx->wlListWindow, windowId);
1730 if (!pWindowSurface) {
1731 LOGE("pWindowSurface is not found[%{public}d].", windowId);
1732 wms_send_windowshot_error(pWlResource, WMS_ERROR_INVALID_PARAM, windowId);
1733 wl_client_flush(wl_resource_get_client(pWlResource));
1734 return;
1735 }
1736
1737 if (!pWindowSurface->surf) {
1738 LOGE("pWindowSurface->surf is NULL.");
1739 wms_send_windowshot_error(pWlResource, WMS_ERROR_INNER_ERROR, windowId);
1740 wl_client_flush(wl_resource_get_client(pWlResource));
1741 return;
1742 }
1743
1744 int32_t width = 0;
1745 int32_t height = 0;
1746 weston_surface_get_content_size(pWindowSurface->surf, &width, &height);
1747 int32_t stride = width * BYTE_SPP_SIZE;
1748
1749 if (!width || !height || !stride) {
1750 LOGE("weston_surface_get_content_size error.");
1751 wms_send_windowshot_error(pWlResource, WMS_ERROR_INNER_ERROR, windowId);
1752 wl_client_flush(wl_resource_get_client(pWlResource));
1753 return;
1754 }
1755
1756 int32_t size = stride * height;
1757 int fd = CreateScreenshotFile(size);
1758 if (fd < 0) {
1759 LOGE("CreateScreenshotFile error.");
1760 wms_send_windowshot_error(pWlResource, WMS_ERROR_INNER_ERROR, windowId);
1761 wl_client_flush(wl_resource_get_client(pWlResource));
1762 return;
1763 }
1764
1765 char *pBuffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1766 if (pBuffer == MAP_FAILED) {
1767 LOGE("mmap error.");
1768 wms_send_windowshot_error(pWlResource, WMS_ERROR_INNER_ERROR, windowId);
1769 wl_client_flush(wl_resource_get_client(pWlResource));
1770 close(fd);
1771 return;
1772 }
1773
1774 if (weston_surface_copy_content(pWindowSurface->surf, pBuffer, size, 0, 0, width, height) != 0) {
1775 LOGE("weston_surface_copy_content error.");
1776 wms_send_windowshot_error(pWlResource, WMS_ERROR_INNER_ERROR, windowId);
1777 wl_client_flush(wl_resource_get_client(pWlResource));
1778 munmap(pBuffer, size);
1779 close(fd);
1780 return;
1781 }
1782
1783 struct timespec timeStamp = {};
1784 weston_compositor_read_presentation_clock(pWmsController->pWmsCtx->pCompositor, &timeStamp);
1785
1786 wms_send_windowshot_done(pWlResource, windowId, fd, width, height,
1787 stride, WL_SHM_FORMAT_ABGR8888, timeStamp.tv_sec, timeStamp.tv_nsec);
1788 wl_client_flush(wl_resource_get_client(pWlResource));
1789
1790 munmap(pBuffer, size);
1791 close(fd);
1792 }
1793
FlipY(int32_t stride,int32_t height,uint32_t * data)1794 static void FlipY(int32_t stride, int32_t height, uint32_t *data)
1795 {
1796 // assuming stride aligned to 4 bytes
1797 int pitch = stride / sizeof(*data);
1798 for (int y = 0; y < height / HEIGHT_AVERAGE; ++y) {
1799 int p = y * pitch;
1800 int q = (height - y - 1) * pitch;
1801 for (int i = 0; i < pitch; ++i) {
1802 uint32_t tmp = data[p + i];
1803 data[p + i] = data[q + i];
1804 data[q + i] = tmp;
1805 }
1806 }
1807 }
1808
ClearFrameListener(struct ScreenshotFrameListener * pListener)1809 static void ClearFrameListener(struct ScreenshotFrameListener *pListener)
1810 {
1811 wl_list_remove(&pListener->frameListener.link);
1812 wl_list_init(&pListener->frameListener.link);
1813 wl_list_remove(&pListener->outputDestroyed.link);
1814 wl_list_init(&pListener->outputDestroyed.link);
1815 }
1816
Screenshot(const struct ScreenshotFrameListener * pFrameListener,uint32_t shmFormat)1817 static void Screenshot(const struct ScreenshotFrameListener *pFrameListener, uint32_t shmFormat)
1818 {
1819 struct WmsController *pWmsController = wl_container_of(pFrameListener, pWmsController, stListener);
1820 struct weston_output *westonOutput = pFrameListener->output;
1821 int32_t width = westonOutput->current_mode->width;
1822 int32_t height = westonOutput->current_mode->height;
1823 pixman_format_code_t format = westonOutput->compositor->read_format;
1824 int32_t stride = width * PIXMAN_FORMAT_BPP((uint32_t)format) / PIXMAN_FORMAT_AVERAGE;
1825 size_t size = stride * height;
1826
1827 int fd = CreateScreenshotFile(size);
1828 if (fd < 0) {
1829 LOGE("CreateScreenshotFile error.");
1830 wms_send_screenshot_error(pWmsController->pWlResource, WMS_ERROR_INNER_ERROR, pFrameListener->idScreen);
1831 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1832 return;
1833 }
1834
1835 uint32_t *readPixs = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1836 if (readPixs == MAP_FAILED) {
1837 LOGE("mmap error.");
1838 wms_send_screenshot_error(pWmsController->pWlResource, WMS_ERROR_INNER_ERROR, pFrameListener->idScreen);
1839 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1840 close(fd);
1841 return;
1842 }
1843
1844 if (westonOutput->compositor->renderer->read_pixels(westonOutput, format, readPixs, 0, 0, width, height) < 0) {
1845 LOGE("read_pixels error.");
1846 wms_send_screenshot_error(pWmsController->pWlResource, WMS_ERROR_INNER_ERROR, pFrameListener->idScreen);
1847 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1848 munmap(readPixs, size);
1849 close(fd);
1850 return;
1851 }
1852
1853 if (westonOutput->compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP) {
1854 FlipY(stride, height, readPixs);
1855 }
1856
1857 wms_send_screenshot_done(pWmsController->pWlResource, pFrameListener->idScreen, fd, width, height, stride,
1858 shmFormat, westonOutput->frame_time.tv_sec, westonOutput->frame_time.tv_nsec);
1859 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1860
1861 munmap(readPixs, size);
1862 close(fd);
1863 }
1864
ScreenshotNotify(struct wl_listener * pWlListener,void * pCompositor)1865 static void ScreenshotNotify(struct wl_listener *pWlListener, void *pCompositor)
1866 {
1867 DEBUG_LOG("start.");
1868 struct ScreenshotFrameListener *pFrameListener = wl_container_of(pWlListener, pFrameListener, frameListener);
1869 struct WmsController *pWmsController = wl_container_of(pFrameListener, pWmsController, stListener);
1870 pixman_format_code_t format = pFrameListener->output->compositor->read_format;
1871 uint32_t shmFormat = 0;
1872
1873 --pFrameListener->output->disable_planes;
1874 ClearFrameListener(pFrameListener);
1875
1876 switch (format) {
1877 case PIXMAN_a8r8g8b8:
1878 shmFormat = WL_SHM_FORMAT_ARGB8888;
1879 break;
1880 case PIXMAN_x8r8g8b8:
1881 shmFormat = WL_SHM_FORMAT_XRGB8888;
1882 break;
1883 case PIXMAN_a8b8g8r8:
1884 shmFormat = WL_SHM_FORMAT_ABGR8888;
1885 break;
1886 case PIXMAN_x8b8g8r8:
1887 shmFormat = WL_SHM_FORMAT_XBGR8888;
1888 break;
1889 default:
1890 LOGE("unsupported pixel format = %{public}d", format);
1891 wms_send_screenshot_error(pWmsController->pWlResource, WMS_ERROR_INNER_ERROR, pFrameListener->idScreen);
1892 wl_client_flush(wl_resource_get_client(pWmsController->pWlResource));
1893 return;
1894 }
1895
1896 Screenshot(pFrameListener, shmFormat);
1897 DEBUG_LOG("end.");
1898 }
1899
ScreenshotOutputDestroyed(struct wl_listener * pListener,void * pData)1900 static void ScreenshotOutputDestroyed(struct wl_listener *pListener, void *pData)
1901 {
1902 DEBUG_LOG("start.");
1903 struct ScreenshotFrameListener *pFrameListener =
1904 wl_container_of(pListener, pFrameListener, outputDestroyed);
1905 struct WmsController *pController =
1906 wl_container_of(pFrameListener, pController, stListener);
1907
1908 LOGE("screen[%{public}d] output destroyed.", pFrameListener->idScreen);
1909 wms_send_screenshot_error(pController->pWlResource, WMS_ERROR_INNER_ERROR, pFrameListener->idScreen);
1910 wl_client_flush(wl_resource_get_client(pController->pWlResource));
1911 ClearFrameListener(pFrameListener);
1912
1913 DEBUG_LOG("end.");
1914 }
1915
ControllerScreenshot(struct wl_client * pClient,struct wl_resource * pResource,uint32_t screenId)1916 static void ControllerScreenshot(struct wl_client *pClient,
1917 struct wl_resource *pResource, uint32_t screenId)
1918 {
1919 DEBUG_LOG("start. screenId = %{public}d.", screenId);
1920 struct WmsController *pWmsController = wl_resource_get_user_data(pResource);
1921
1922 struct WmsScreen *pWmsScreen = GetScreenFromId(pWmsController->pWmsCtx, screenId);
1923 if (!pWmsScreen) {
1924 LOGE("screen is not found[%{public}d].", screenId);
1925 wms_send_screenshot_error(pResource, WMS_ERROR_INVALID_PARAM, screenId);
1926 wl_client_flush(wl_resource_get_client(pResource));
1927 return;
1928 }
1929
1930 pWmsController->stListener.output = pWmsScreen->westonOutput;
1931
1932 pWmsController->stListener.outputDestroyed.notify = ScreenshotOutputDestroyed;
1933 wl_signal_add(&pWmsScreen->westonOutput->destroy_signal, &pWmsController->stListener.outputDestroyed);
1934
1935 pWmsController->stListener.frameListener.notify = ScreenshotNotify;
1936 wl_signal_add(&pWmsScreen->westonOutput->frame_signal, &pWmsController->stListener.frameListener);
1937
1938 pWmsScreen->westonOutput->disable_planes++;
1939 weston_output_damage(pWmsScreen->westonOutput);
1940
1941 DEBUG_LOG("end.");
1942 }
1943
AddGlobalWindowStatus(struct WmsController * pController)1944 static void AddGlobalWindowStatus(struct WmsController *pController)
1945 {
1946 DEBUG_LOG("start.");
1947 struct WmsContext *pWmsCtx = pController->pWmsCtx;
1948 struct WmsController *pControllerTemp = NULL;
1949 bool found = false;
1950
1951 wl_list_for_each(pControllerTemp, &pWmsCtx->wlListGlobalEventResource, wlListLinkRes) {
1952 if (pControllerTemp == pController) {
1953 LOGE("GlobalWindowStatus is already set.");
1954 found = true;
1955 }
1956 }
1957
1958 if (!found) {
1959 wl_list_insert(&pWmsCtx->wlListGlobalEventResource, &pController->wlListLinkRes);
1960 }
1961
1962 DEBUG_LOG("end.");
1963 }
1964
ControllerSetGlobalWindowStatus(struct wl_client * pClient,struct wl_resource * pResource,int32_t status)1965 static void ControllerSetGlobalWindowStatus(struct wl_client *pClient,
1966 struct wl_resource *pResource, int32_t status)
1967 {
1968 DEBUG_LOG("start. status = %{public}d.", status);
1969 struct WmsController *pWmsController = wl_resource_get_user_data(pResource);
1970
1971 if (status == 0) {
1972 wl_list_remove(&pWmsController->wlListLinkRes);
1973 } else {
1974 AddGlobalWindowStatus(pWmsController);
1975 }
1976
1977 wms_send_reply_error(pResource, WMS_ERROR_OK);
1978 wl_client_flush(wl_resource_get_client(pResource));
1979 DEBUG_LOG("end.");
1980 }
1981
1982 // wms controller interface implementation
1983 static const struct wms_interface g_controllerImplementation = {
1984 ControllerGetDisplayPower,
1985 ControllerSetDisplayPower,
1986 ControllerGetDisplayBacklight,
1987 ControllerSetDisplayBacklight,
1988 ControllerSetDisplayMode,
1989 ControllerCreateWindow,
1990 ControllerDestroyWindow,
1991 ControllerSetGlobalWindowStatus,
1992 ControllerSetStatusBarVisibility,
1993 ControllerSetNavigationBarVisibility,
1994 ControllerSetWindowTop,
1995 ControllerSetWindowSize,
1996 ControllerSetWindowScale,
1997 ControllerSetWindowPosition,
1998 ControllerSetWindowVisibility,
1999 ControllerSetWindowType,
2000 ControllerSetWindowMode,
2001 ControllerCommitChanges,
2002 ControllerScreenshot,
2003 ControllerWindowshot,
2004 ControllerCreateVirtualDisplay,
2005 ControllerDestroyVirtualDisplay,
2006 ControllerSetSplitMode,
2007 };
2008
UnbindWmsController(struct wl_resource * pResource)2009 static void UnbindWmsController(struct wl_resource *pResource)
2010 {
2011 DEBUG_LOG("start.");
2012 struct WmsController *pController = wl_resource_get_user_data(pResource);
2013 struct WmsContext *pWmsCtx = pController->pWmsCtx;
2014 struct WindowSurface *pWindowSurface = NULL;
2015 struct WindowSurface *pNext = NULL;
2016
2017 wl_list_remove(&pController->wlListLinkRes);
2018
2019 wl_list_for_each_safe(pWindowSurface, pNext, &pWmsCtx->wlListWindow, link) {
2020 if (pWindowSurface->controller == pController) {
2021 SurfaceDestroy(pWindowSurface);
2022 }
2023 }
2024
2025 wl_list_remove(&pController->wlListLink);
2026 wl_list_remove(&pController->stListener.frameListener.link);
2027 wl_list_remove(&pController->stListener.outputDestroyed.link);
2028
2029 free(pController);
2030 pController = NULL;
2031 DEBUG_LOG("end.");
2032 }
2033
BindWmsController(struct wl_client * pClient,void * pData,uint32_t version,uint32_t id)2034 static void BindWmsController(struct wl_client *pClient,
2035 void *pData, uint32_t version, uint32_t id)
2036 {
2037 DEBUG_LOG("start.");
2038 struct WmsContext *pCtx = pData;
2039 (void)version;
2040
2041 struct WmsController *pController = calloc(1, sizeof(*pController));
2042 if (pController == NULL) {
2043 LOGE("calloc failed");
2044 wl_client_post_no_memory(pClient);
2045 return;
2046 }
2047
2048 pController->pWlResource = wl_resource_create(pClient, &wms_interface, version, id);
2049 if (pController->pWlResource == NULL) {
2050 LOGE("wl_resource_create failed");
2051 wl_client_post_no_memory(pClient);
2052 return;
2053 }
2054
2055 wl_resource_set_implementation(pController->pWlResource,
2056 &g_controllerImplementation, pController, UnbindWmsController);
2057 pController->pWmsCtx = pCtx;
2058 pController->pWlClient = pClient;
2059 pController->id = id;
2060
2061 wl_list_init(&pController->wlListLinkRes);
2062 wl_list_insert(&pCtx->wlListController, &pController->wlListLink);
2063 wl_list_init(&pController->stListener.frameListener.link);
2064 wl_list_init(&pController->stListener.outputDestroyed.link);
2065
2066 struct WmsScreen *pScreen = NULL;
2067 struct weston_output *pOutput = NULL;
2068 wl_list_for_each(pScreen, &pCtx->wlListScreen, wlListLink) {
2069 pOutput = pScreen->westonOutput;
2070 wms_send_screen_status(pController->pWlResource, pOutput->id, pOutput->name, WMS_SCREEN_STATUS_ADD,
2071 pOutput->width, pOutput->height, pScreen->screenType);
2072 }
2073
2074 uint32_t flag = GetDisplayModeFlag(pController->pWmsCtx);
2075 wms_send_display_mode(pController->pWlResource, flag);
2076 wl_client_flush(wl_resource_get_client(pController->pWlResource));
2077
2078 DEBUG_LOG("end.");
2079 }
2080
DestroyScreen(struct WmsScreen * pScreen)2081 static void DestroyScreen(struct WmsScreen *pScreen)
2082 {
2083 wl_list_remove(&pScreen->wlListLink);
2084 free(pScreen);
2085 }
2086
WmsScreenDestroy(struct WmsContext * pCtx)2087 static void WmsScreenDestroy(struct WmsContext *pCtx)
2088 {
2089 DEBUG_LOG("start.");
2090 struct WmsScreen *pScreen = NULL;
2091 struct WmsScreen *pNext = NULL;
2092
2093 wl_list_for_each_safe(pScreen, pNext, &pCtx->wlListScreen, wlListLink) {
2094 DestroyScreen(pScreen);
2095 }
2096 DEBUG_LOG("end.");
2097 }
2098
DestroySeat(struct WmsSeat * pSeat)2099 static void DestroySeat(struct WmsSeat *pSeat)
2100 {
2101 DEBUG_LOG("start.");
2102 wl_list_remove(&pSeat->wlListenerDestroyed.link);
2103 wl_list_remove(&pSeat->wlListLink);
2104 free(pSeat);
2105 DEBUG_LOG("end.");
2106 }
2107
SeatDestroyedEvent(struct wl_listener * listener,void * seat)2108 static void SeatDestroyedEvent(struct wl_listener *listener, void *seat)
2109 {
2110 DEBUG_LOG("start.");
2111 struct WmsSeat *pSeat = wl_container_of(listener, pSeat, wlListenerDestroyed);
2112 wl_list_remove(&pSeat->wlListenerDestroyed.link);
2113 wl_list_remove(&pSeat->wlListLink);
2114 free(pSeat);
2115 SeatInfoChangerNotify();
2116 DEBUG_LOG("end.");
2117 }
2118
WmsControllerDestroy(struct wl_listener * listener,void * data)2119 static void WmsControllerDestroy(struct wl_listener *listener, void *data)
2120 {
2121 DEBUG_LOG("start.");
2122 struct WmsContext *ctx =
2123 wl_container_of(listener, ctx, wlListenerDestroy);
2124 struct WmsController *pController = NULL;
2125 struct WmsController *pCtlNext = NULL;
2126 struct WmsSeat *pSeat = NULL;
2127 struct WmsSeat *pNext = NULL;
2128
2129 wl_list_for_each_safe(pController, pCtlNext, &ctx->wlListController, wlListLink) {
2130 wl_resource_destroy(pController->pWlResource);
2131 }
2132
2133 wl_list_remove(&ctx->wlListenerDestroy.link);
2134 wl_list_remove(&ctx->wlListenerOutputCreated.link);
2135 wl_list_remove(&ctx->wlListenerOutputDestroyed.link);
2136 wl_list_remove(&ctx->wlListenerSeatCreated.link);
2137
2138 WmsScreenDestroy(ctx);
2139 wl_list_for_each_safe(pSeat, pNext, &ctx->wlListSeat, wlListLink) {
2140 DestroySeat(pSeat);
2141 }
2142
2143 free(ctx);
2144 DEBUG_LOG("end.");
2145 }
2146
CreateScreen(struct WmsContext * pCtx,struct weston_output * pOutput,uint32_t screenType)2147 static int32_t CreateScreen(struct WmsContext *pCtx,
2148 struct weston_output *pOutput,
2149 uint32_t screenType)
2150 {
2151 struct WmsScreen *pScreen = NULL;
2152
2153 pScreen = calloc(1, sizeof(*pScreen));
2154 if (pScreen == NULL) {
2155 LOGE("no memory to allocate client screen\n");
2156 return -1;
2157 }
2158 pScreen->pWmsCtx = pCtx;
2159 pScreen->westonOutput = pOutput;
2160 pScreen->screenId = pOutput->id;
2161 pScreen->screenType = screenType;
2162
2163 if (pScreen->screenId == 0) {
2164 pCtx->pMainScreen = pScreen;
2165 }
2166
2167 wl_list_insert(pCtx->wlListScreen.prev, &pScreen->wlListLink);
2168
2169 return 0;
2170 }
2171
OutputDestroyedEvent(struct wl_listener * listener,void * data)2172 static void OutputDestroyedEvent(struct wl_listener *listener,
2173 void *data)
2174 {
2175 DEBUG_LOG("start.");
2176 struct WmsContext *pCtx = wl_container_of(listener, pCtx, wlListenerOutputDestroyed);
2177 struct WmsScreen *pScreen = NULL;
2178 struct WmsScreen *pNext = NULL;
2179 struct weston_output *destroyedOutput = (struct weston_output*)data;
2180
2181 wl_list_for_each_safe(pScreen, pNext, &pCtx->wlListScreen, wlListLink) {
2182 if (pScreen->westonOutput == destroyedOutput) {
2183 DestroyScreen(pScreen);
2184 }
2185 }
2186
2187 DisplayModeUpdate(pCtx);
2188
2189 ScreenInfoChangerNotify();
2190
2191 DEBUG_LOG("end.");
2192 }
2193
OutputCreatedEvent(struct wl_listener * listener,void * data)2194 static void OutputCreatedEvent(struct wl_listener *listener, void *data)
2195 {
2196 DEBUG_LOG("start.");
2197 struct WmsContext *ctx = wl_container_of(listener, ctx, wlListenerOutputCreated);
2198 struct weston_output *createdOutput = (struct weston_output*)data;
2199
2200 CreateScreen(ctx, createdOutput, WMS_SCREEN_TYPE_PHYSICAL);
2201
2202 DisplayModeUpdate(ctx);
2203
2204 SetDisplayMode(ctx, ctx->displayMode);
2205
2206 ScreenInfoChangerNotify();
2207
2208 DEBUG_LOG("end.");
2209 }
2210
SeatCreatedEvent(struct wl_listener * listener,void * data)2211 static void SeatCreatedEvent(struct wl_listener *listener, void *data)
2212 {
2213 DEBUG_LOG("start.");
2214 struct WmsContext *pCtx = wl_container_of(listener, pCtx, wlListenerSeatCreated);
2215 struct weston_seat *seat = (struct weston_seat *)data;
2216
2217 struct WmsSeat *pSeat = NULL;
2218 pSeat = calloc(1, sizeof(*pSeat));
2219 if (pSeat == NULL) {
2220 LOGE("no memory to allocate wms seat.");
2221 return;
2222 }
2223 pSeat->pWmsCtx = pCtx;
2224 pSeat->pWestonSeat = seat;
2225 wl_list_insert(&pCtx->wlListSeat, &pSeat->wlListLink);
2226
2227 pSeat->wlListenerDestroyed.notify = &SeatDestroyedEvent;
2228 wl_signal_add(&seat->destroy_signal, &pSeat->wlListenerDestroyed);
2229 SeatInfoChangerNotify();
2230 DEBUG_LOG("end.");
2231 }
2232
2233 int ScreenInfoInit(const struct weston_compositor *pCompositor);
2234
WmsContextInit(struct WmsContext * ctx,struct weston_compositor * compositor)2235 static int WmsContextInit(struct WmsContext *ctx, struct weston_compositor *compositor)
2236 {
2237 int32_t ret = DeviceInitialize(&ctx->deviceFuncs);
2238 if (ret != 0) {
2239 LOGE("DeviceInitialize failed, return %{public}d", ret);
2240 ctx->deviceFuncs = NULL;
2241 }
2242
2243 wl_list_init(&ctx->wlListController);
2244 wl_list_init(&ctx->wlListWindow);
2245 wl_list_init(&ctx->wlListScreen);
2246 wl_list_init(&ctx->wlListSeat);
2247 wl_list_init(&ctx->wlListGlobalEventResource);
2248
2249 ctx->pCompositor = compositor;
2250 ctx->pLayoutInterface = (struct ivi_layout_interface_for_wms *)ivi_layout_get_api_for_wms(compositor);
2251 if (!ctx->pLayoutInterface) {
2252 free(ctx);
2253 LOGE("ivi_xxx_get_api_for_wms failed.");
2254 return -1;
2255 }
2256
2257 #ifdef USE_IVI_INPUT_FOCUS
2258 ctx->pInputInterface = ivi_input_get_api_for_wms(compositor);
2259 if (!ctx->pInputInterface) {
2260 free(ctx);
2261 LOGE("ivi_xxx_get_api_for_wms failed.");
2262 return -1;
2263 }
2264 #endif
2265
2266 ctx->wlListenerOutputCreated.notify = OutputCreatedEvent;
2267 ctx->wlListenerOutputDestroyed.notify = OutputDestroyedEvent;
2268
2269 wl_signal_add(&compositor->output_created_signal, &ctx->wlListenerOutputCreated);
2270 wl_signal_add(&compositor->output_destroyed_signal, &ctx->wlListenerOutputDestroyed);
2271
2272 ctx->wlListenerSeatCreated.notify = &SeatCreatedEvent;
2273 wl_signal_add(&compositor->seat_created_signal, &ctx->wlListenerSeatCreated);
2274
2275 struct weston_seat *seat = NULL;
2276 wl_list_for_each(seat, &compositor->seat_list, link) {
2277 SeatCreatedEvent(&ctx->wlListenerSeatCreated, seat);
2278 }
2279
2280 if (!wl_global_create(compositor->wl_display,
2281 &wms_interface, 1, ctx, BindWmsController)) {
2282 LOGE("wl_global_create failed.");
2283 return -1;
2284 }
2285
2286 ctx->wlListenerDestroy.notify = WmsControllerDestroy;
2287
2288 ctx->displayMode = WMS_DISPLAY_MODE_CLONE;
2289
2290 wl_signal_add(&compositor->destroy_signal, &ctx->wlListenerDestroy);
2291
2292 ctx->splitMode = SPLIT_MODE_NULL;
2293
2294 LayoutControllerInit(0, 0);
2295 return 0;
2296 }
2297
wet_module_init(struct weston_compositor * compositor,int * argc,char * argv[])2298 WL_EXPORT int wet_module_init(struct weston_compositor *compositor,
2299 int *argc, char *argv[])
2300 {
2301 DEBUG_LOG("start.");
2302 struct weston_output *output = NULL;
2303 struct WmsContext *ctx = GetWmsInstance();
2304
2305 if (WmsContextInit(ctx, compositor) < 0) {
2306 LOGE("WmsContextInit failed.");
2307 return -1;
2308 }
2309
2310 wl_list_for_each(output, &compositor->output_list, link) {
2311 if (CreateScreen(ctx, output, WMS_SCREEN_TYPE_PHYSICAL) < 0) {
2312 WmsScreenDestroy(ctx);
2313 free(ctx);
2314 return -1;
2315 }
2316 }
2317
2318 ScreenInfoInit(compositor);
2319
2320 DEBUG_LOG("end.");
2321 return 0;
2322 }
2323