• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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