blob: a0e49ba0dce2baa190d11b309ba97007b9fe863b [file] [log] [blame]
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001/*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090011 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090024 */
25
26/**
27 * A reference implementation how to use ivi-layout APIs in order to manage
28 * layout of ivi_surfaces/ivi_layers. Layout change is triggered by
29 * ivi-hmi-controller protocol, ivi-hmi-controller.xml. A reference how to
30 * use the protocol, see hmi-controller-homescreen.
31 *
32 * In-Vehicle Infotainment system usually manage properties of
33 * ivi_surfaces/ivi_layers by only a central component which decide where
34 * ivi_surfaces/ivi_layers shall be. This reference show examples to
35 * implement the central component as a module of weston.
36 *
37 * Default Scene graph of UI is defined in hmi_controller_create. It
38 * consists of
39 * - In the bottom, a base ivi_layer to group ivi_surfaces of background,
40 * panel, and buttons
Abdur Rehmanb833d742017-01-01 19:46:34 +050041 * - Next, an application ivi_layer to show application ivi_surfaces.
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090042 * - Workspace background ivi_layer to show a ivi_surface of background image.
43 * - Workspace ivi_layer to show launcher to launch application with icons.
44 * Paths to binary and icon are defined in weston.ini. The width of this
45 * ivi_layer is longer than the size of ivi_screen because a workspace has
46 * several pages and is controlled by motion of input.
47 *
48 * TODO: animation method shall be refined
49 * TODO: support fade-in when UI is ready
50 */
51
52#include <sys/wait.h>
53#include <unistd.h>
54#include <stdlib.h>
Jussi Kukkonen649bbce2016-07-19 14:16:27 +030055#include <stdint.h>
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090056#include <stdio.h>
57#include <string.h>
58#include <linux/input.h>
59#include <assert.h>
60#include <time.h>
61
62#include "ivi-layout-export.h"
63#include "ivi-hmi-controller-server-protocol.h"
Jon Cruz867d50e2015-06-15 15:37:10 -070064#include "shared/helpers.h"
Bryce Harringtone99e4bf2016-03-16 14:15:18 -070065#include "shared/xalloc.h"
Pekka Paalanen58f98c92016-06-03 16:45:21 +030066#include "compositor/weston.h"
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090067
68/*****************************************************************************
69 * structure, globals
70 ****************************************************************************/
71struct hmi_controller_layer {
72 struct ivi_layout_layer *ivilayer;
73 uint32_t id_layer;
74 int32_t x;
75 int32_t y;
76 int32_t width;
77 int32_t height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090078 struct wl_list link;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090079};
80
81struct link_layer {
82 struct ivi_layout_layer *layout_layer;
83 struct wl_list link;
84};
85
86struct hmi_controller_fade {
87 uint32_t is_fade_in;
88 struct wl_list layer_list;
89};
90
91struct hmi_server_setting {
92 uint32_t base_layer_id;
93 uint32_t application_layer_id;
94 uint32_t workspace_background_layer_id;
95 uint32_t workspace_layer_id;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090096 uint32_t base_layer_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090097 int32_t panel_height;
98 uint32_t transition_duration;
99 char *ivi_homescreen;
100};
101
102struct ui_setting {
103 uint32_t background_id;
104 uint32_t panel_id;
105 uint32_t tiling_id;
106 uint32_t sidebyside_id;
107 uint32_t fullscreen_id;
108 uint32_t random_id;
109 uint32_t home_id;
110 uint32_t workspace_background_id;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900111 uint32_t surface_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900112};
113
114struct hmi_controller {
115 struct hmi_server_setting *hmi_setting;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900116 /* List of struct hmi_controller_layer */
117 struct wl_list base_layer_list;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900118 struct wl_list application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900119 struct hmi_controller_layer workspace_background_layer;
120 struct hmi_controller_layer workspace_layer;
121 enum ivi_hmi_controller_layout_mode layout_mode;
122
123 struct hmi_controller_fade workspace_fade;
124
125 int32_t workspace_count;
126 struct wl_array ui_widgets;
127 int32_t is_initialized;
128
129 struct weston_compositor *compositor;
130 struct wl_listener destroy_listener;
131
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000132 struct wl_listener surface_created;
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000133 struct wl_listener surface_removed;
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000134 struct wl_listener surface_configured;
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000135
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900136 struct wl_client *user_interface;
137 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900138
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000139 struct weston_output * workspace_background_output;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900140 int32_t screen_num;
Emre Ucana9db8d72018-01-25 14:36:11 +0100141
142 const struct ivi_layout_interface *interface;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900143};
144
145struct launcher_info {
146 uint32_t surface_id;
147 uint32_t workspace_id;
148 int32_t index;
149};
150
151/*****************************************************************************
152 * local functions
153 ****************************************************************************/
154static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900155mem_alloc(size_t size, char *file, int32_t line)
156{
157 return fail_on_null(calloc(1, size), size, file, line);
158}
159
160#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
161
162static int32_t
163is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
164 struct ivi_layout_surface *ivisurf)
165{
Emre Ucana9db8d72018-01-25 14:36:11 +0100166 uint32_t id = hmi_ctrl->interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900167
168 uint32_t *ui_widget_id = NULL;
169 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
170 if (*ui_widget_id == id)
171 return 1;
172 }
173
174 return 0;
175}
176
177static int
178compare_launcher_info(const void *lhs, const void *rhs)
179{
180 const struct launcher_info *left = lhs;
181 const struct launcher_info *right = rhs;
182
183 if (left->workspace_id < right->workspace_id)
184 return -1;
185
186 if (left->workspace_id > right->workspace_id)
187 return 1;
188
189 if (left->index < right->index)
190 return -1;
191
192 if (left->index > right->index)
193 return 1;
194
195 return 0;
196}
197
198/**
199 * Internal methods called by mainly ivi_hmi_controller_switch_mode
200 * This reference shows 4 examples how to use ivi_layout APIs.
201 */
202static void
203mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
204 struct ivi_layout_surface **pp_surface,
205 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900206 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900207{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900208 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900209 const float surface_width = (float)layer->width * 0.25;
210 const float surface_height = (float)layer->height * 0.5;
211 int32_t surface_x = 0;
212 int32_t surface_y = 0;
213 struct ivi_layout_surface *ivisurf = NULL;
214 struct ivi_layout_surface **surfaces;
215 struct ivi_layout_surface **new_order;
216 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900217 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900218
219 int32_t i = 0;
220 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900221 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900222
223 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
224 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
225
226 for (i = 0; i < surface_length; i++) {
227 ivisurf = pp_surface[i];
228
229 /* skip ui widgets */
230 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
231 continue;
232
233 surfaces[surf_num++] = ivisurf;
234 }
235
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900236 wl_list_for_each_reverse(layer, layer_list, link) {
237 if (idx >= surf_num)
238 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900239
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900240 ivilayer = layer->ivilayer;
241
242 for (i = 0; i < 8; i++, idx++) {
243 if (idx >= surf_num)
244 break;
245
246 ivisurf = surfaces[idx];
247 new_order[i] = ivisurf;
248 if (i < 4) {
249 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900250 surface_y = 0;
251 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900252 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900253 surface_y = (int32_t)surface_height;
254 }
255
Emre Ucana9db8d72018-01-25 14:36:11 +0100256 hmi_ctrl->interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900257 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
258 duration);
Emre Ucana9db8d72018-01-25 14:36:11 +0100259 hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
260 hmi_ctrl->interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900261 surface_x, surface_y,
262 (int32_t)surface_width,
263 (int32_t)surface_height);
264
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900265 }
Emre Ucana9db8d72018-01-25 14:36:11 +0100266 hmi_ctrl->interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900267
Emre Ucana9db8d72018-01-25 14:36:11 +0100268 hmi_ctrl->interface->layer_set_transition(ivilayer,
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900269 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
270 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900271 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900272 for (i = idx; i < surf_num; i++)
Emre Ucana9db8d72018-01-25 14:36:11 +0100273 hmi_ctrl->interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900274
275 free(surfaces);
276 free(new_order);
277}
278
279static void
280mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
281 struct ivi_layout_surface **pp_surface,
282 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900283 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900284{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900285 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900286 int32_t surface_width = layer->width / 2;
287 int32_t surface_height = layer->height;
288 struct ivi_layout_surface *ivisurf = NULL;
289
290 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
291 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900292 struct ivi_layout_surface **surfaces;
293 struct ivi_layout_surface **new_order;
294 struct ivi_layout_layer *ivilayer = NULL;
295 int32_t surf_num = 0;
296 int32_t idx = 0;
297
298 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
299 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900300
301 for (i = 0; i < surface_length; i++) {
302 ivisurf = pp_surface[i];
303
304 /* skip ui widgets */
305 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
306 continue;
307
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900308 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900309 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900310
311 wl_list_for_each_reverse(layer, layer_list, link) {
312 if (idx >= surf_num)
313 break;
314
315 ivilayer = layer->ivilayer;
316
317 for (i = 0; i < 2; i++, idx++) {
318 if (idx >= surf_num)
319 break;
320
321 ivisurf = surfaces[idx];
322 new_order[i] = ivisurf;
323
Emre Ucana9db8d72018-01-25 14:36:11 +0100324 hmi_ctrl->interface->surface_set_transition(ivisurf,
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900325 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
326 duration);
Emre Ucana9db8d72018-01-25 14:36:11 +0100327 hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900328
Emre Ucana9db8d72018-01-25 14:36:11 +0100329 hmi_ctrl->interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900330 i * surface_width, 0,
331 surface_width,
332 surface_height);
333 }
Emre Ucana9db8d72018-01-25 14:36:11 +0100334 hmi_ctrl->interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900335 }
336
337 for (i = idx; i < surf_num; i++) {
Emre Ucana9db8d72018-01-25 14:36:11 +0100338 hmi_ctrl->interface->surface_set_transition(surfaces[i],
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900339 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
340 duration);
Emre Ucana9db8d72018-01-25 14:36:11 +0100341 hmi_ctrl->interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900342 }
343
344 free(surfaces);
345 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900346}
347
348static void
349mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
350 struct ivi_layout_surface **pp_surface,
351 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900352 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900353{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900354 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900355 const int32_t surface_width = layer->width;
356 const int32_t surface_height = layer->height;
357 struct ivi_layout_surface *ivisurf = NULL;
358 int32_t i = 0;
359 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900360 int32_t surf_num = 0;
361 struct ivi_layout_surface **surfaces;
362
363 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900364
365 for (i = 0; i < surface_length; i++) {
366 ivisurf = pp_surface[i];
367
368 /* skip ui widgets */
369 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
370 continue;
371
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900372 surfaces[surf_num++] = ivisurf;
373 }
Emre Ucana9db8d72018-01-25 14:36:11 +0100374 hmi_ctrl->interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900375
376 for (i = 0; i < surf_num; i++) {
377 ivisurf = surfaces[i];
378
379 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
380 layer = wl_container_of(layer->link.prev, layer, link);
Emre Ucana9db8d72018-01-25 14:36:11 +0100381 hmi_ctrl->interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900382 }
383
Emre Ucana9db8d72018-01-25 14:36:11 +0100384 hmi_ctrl->interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900385 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
386 duration);
Emre Ucana9db8d72018-01-25 14:36:11 +0100387 hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
388 hmi_ctrl->interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900389 surface_width,
390 surface_height);
391 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900392
393 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900394}
395
396static void
397mode_random_replace(struct hmi_controller *hmi_ctrl,
398 struct ivi_layout_surface **pp_surface,
399 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900400 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900401{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900402 struct hmi_controller_layer *application_layer = NULL;
403 struct hmi_controller_layer **layers = NULL;
404 int32_t surface_width = 0;
405 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900406 int32_t surface_x = 0;
407 int32_t surface_y = 0;
408 struct ivi_layout_surface *ivisurf = NULL;
409 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
410 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900411 int32_t layer_idx = 0;
412
413 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
414
415 wl_list_for_each(application_layer, layer_list, link) {
416 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900417 layer_idx++;
418 }
419
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900420 for (i = 0; i < surface_length; i++) {
421 ivisurf = pp_surface[i];
422
423 /* skip ui widgets */
424 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
425 continue;
426
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900427 /* surface determined at random a layer that belongs */
428 layer_idx = rand() % hmi_ctrl->screen_num;
429
Emre Ucana9db8d72018-01-25 14:36:11 +0100430 hmi_ctrl->interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900431 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
432 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900433
Emre Ucana9db8d72018-01-25 14:36:11 +0100434 hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900435
436 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
437 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
438 surface_x = rand() % (layers[layer_idx]->width - surface_width);
439 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900440
Emre Ucana9db8d72018-01-25 14:36:11 +0100441 hmi_ctrl->interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900442 surface_x,
443 surface_y,
444 surface_width,
445 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900446
Emre Ucana9db8d72018-01-25 14:36:11 +0100447 hmi_ctrl->interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900448 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900449
450 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900451}
452
453static int32_t
454has_application_surface(struct hmi_controller *hmi_ctrl,
455 struct ivi_layout_surface **pp_surface,
456 int32_t surface_length)
457{
458 struct ivi_layout_surface *ivisurf = NULL;
459 int32_t i = 0;
460
461 for (i = 0; i < surface_length; i++) {
462 ivisurf = pp_surface[i];
463
464 /* skip ui widgets */
465 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
466 continue;
467
468 return 1;
469 }
470
471 return 0;
472}
473
474/**
475 * Supports 4 example to layout of application ivi_surfaces;
476 * tiling, side by side, fullscreen, and random.
477 */
478static void
479switch_mode(struct hmi_controller *hmi_ctrl,
480 enum ivi_hmi_controller_layout_mode layout_mode)
481{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900482 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900483 struct ivi_layout_surface **pp_surface = NULL;
484 int32_t surface_length = 0;
485 int32_t ret = 0;
486
487 if (!hmi_ctrl->is_initialized)
488 return;
489
490 hmi_ctrl->layout_mode = layout_mode;
491
Emre Ucana9db8d72018-01-25 14:36:11 +0100492 ret = hmi_ctrl->interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900493 assert(!ret);
494
495 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
496 free(pp_surface);
497 pp_surface = NULL;
498 return;
499 }
500
501 switch (layout_mode) {
502 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
503 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
504 layer);
505 break;
506 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
507 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
508 surface_length, layer);
509 break;
510 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
511 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
512 layer);
513 break;
514 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
515 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
516 layer);
517 break;
518 }
519
Emre Ucana9db8d72018-01-25 14:36:11 +0100520 hmi_ctrl->interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900521 free(pp_surface);
522}
523
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900524/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900525 * Internal method for transition
526 */
527static void
528hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
529 struct hmi_controller_fade *fade)
530{
531 double tint = is_fade_in ? 1.0 : 0.0;
532 struct link_layer *linklayer = NULL;
533 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
534
535 fade->is_fade_in = is_fade_in;
536
537 wl_list_for_each(linklayer, &fade->layer_list, link) {
Emre Ucana9db8d72018-01-25 14:36:11 +0100538 hmi_ctrl->interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900539 IVI_LAYOUT_TRANSITION_LAYER_FADE,
540 duration);
Emre Ucana9db8d72018-01-25 14:36:11 +0100541 hmi_ctrl->interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900542 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900543 }
544}
545
546/**
547 * Internal method to create ivi_layer with hmi_controller_layer and
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000548 * add to a weston_output
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900549 */
550static void
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000551create_layer(struct weston_output *output,
Emre Ucana9db8d72018-01-25 14:36:11 +0100552 struct hmi_controller_layer *layer,
553 struct hmi_controller *hmi_ctrl)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900554{
555 int32_t ret = 0;
556
557 layer->ivilayer =
Emre Ucana9db8d72018-01-25 14:36:11 +0100558 hmi_ctrl->interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900559 layer->width,
560 layer->height);
561 assert(layer->ivilayer != NULL);
562
Emre Ucana9db8d72018-01-25 14:36:11 +0100563 ret = hmi_ctrl->interface->screen_add_layer(output, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900564 assert(!ret);
565
Emre Ucana9db8d72018-01-25 14:36:11 +0100566 ret = hmi_ctrl->interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900567 layer->x, layer->y,
568 layer->width,
569 layer->height);
570 assert(!ret);
571
Emre Ucana9db8d72018-01-25 14:36:11 +0100572 ret = hmi_ctrl->interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900573 assert(!ret);
574}
575
576/**
577 * Internal set notification
578 */
579static void
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000580set_notification_create_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900581{
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000582 struct hmi_controller *hmi_ctrl =
583 wl_container_of(listener, hmi_ctrl,
584 surface_created);
585 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900586 struct hmi_controller_layer *layer_link =
587 wl_container_of(hmi_ctrl->application_layer_list.prev,
588 layer_link,
589 link);
590 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900591 int32_t ret = 0;
592
593 /* skip ui widgets */
594 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
595 return;
596
Emre Ucana9db8d72018-01-25 14:36:11 +0100597 ret = hmi_ctrl->interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900598 assert(!ret);
599}
600
601static void
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000602set_notification_remove_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900603{
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000604 struct hmi_controller *hmi_ctrl =
605 wl_container_of(listener, hmi_ctrl,
606 surface_removed);
607 (void)data;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900608
609 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
610}
611
612static void
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000613set_notification_configure_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900614{
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000615 struct hmi_controller *hmi_ctrl =
616 wl_container_of(listener, hmi_ctrl,
617 surface_configured);
618 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900619 struct hmi_controller_layer *layer_link = NULL;
620 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900621 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900622 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900623 int32_t length = 0;
624 int32_t i;
625
626 /* return if the surface is not application content */
627 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
628 return;
629 }
630
631 /*
632 * if application changes size of wl_buffer. The source rectangle shall be
633 * fit to the size.
634 */
Emre Ucana9db8d72018-01-25 14:36:11 +0100635 surface = hmi_ctrl->interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900636 if (surface) {
Emre Ucana9db8d72018-01-25 14:36:11 +0100637 hmi_ctrl->interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900638 ivisurf, 0, 0, surface->width,
639 surface->height);
640 }
641
642 /*
643 * search if the surface is already added to layer.
644 * If not yet, it is newly invoded application to go to switch_mode.
645 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900646 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
647 application_layer = layer_link->ivilayer;
Emre Ucana9db8d72018-01-25 14:36:11 +0100648 hmi_ctrl->interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900649 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900650 for (i = 0; i < length; i++) {
651 if (ivisurf == ivisurfs[i]) {
652 /*
653 * if it is non new invoked application, just call
654 * commit_changes to apply source_rectangle.
655 */
Emre Ucana9db8d72018-01-25 14:36:11 +0100656 hmi_ctrl->interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900657 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900658 return;
659 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900660 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900661 free(ivisurfs);
662 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900663 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900664
665 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
666}
667
668/**
669 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
670 * corresponding ivi_layer are defined in weston.ini. Default scene graph
671 * of ivi_layers are initialized in hmi_controller_create
672 */
673static struct hmi_server_setting *
674hmi_server_setting_create(struct weston_compositor *ec)
675{
676 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
Giulio Camuffod52f3b72016-06-02 21:48:11 +0300677 struct weston_config *config = wet_get_config(ec);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900678 struct weston_config_section *shell_section = NULL;
Daniel Stone78a42112016-11-28 15:54:06 +0000679 char *ivi_ui_config;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900680
681 shell_section = weston_config_get_section(config, "ivi-shell",
682 NULL, NULL);
683
684 weston_config_section_get_uint(shell_section, "base-layer-id",
685 &setting->base_layer_id, 1000);
686
687 weston_config_section_get_uint(shell_section,
688 "workspace-background-layer-id",
689 &setting->workspace_background_layer_id,
690 2000);
691
692 weston_config_section_get_uint(shell_section, "workspace-layer-id",
693 &setting->workspace_layer_id, 3000);
694
695 weston_config_section_get_uint(shell_section, "application-layer-id",
696 &setting->application_layer_id, 4000);
697
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900698 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
699 &setting->base_layer_id_offset, 10000);
700
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900701 weston_config_section_get_uint(shell_section, "transition-duration",
702 &setting->transition_duration, 300);
703
704 setting->panel_height = 70;
705
706 weston_config_section_get_string(shell_section,
707 "ivi-shell-user-interface",
Daniel Stone78a42112016-11-28 15:54:06 +0000708 &ivi_ui_config, NULL);
709 if (ivi_ui_config && ivi_ui_config[0] != '/') {
710 setting->ivi_homescreen = wet_get_binary_path(ivi_ui_config);
711 if (setting->ivi_homescreen)
712 free(ivi_ui_config);
713 else
714 setting->ivi_homescreen = ivi_ui_config;
715 } else {
716 setting->ivi_homescreen = ivi_ui_config;
717 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900718
719 return setting;
720}
721
722static void
723hmi_controller_destroy(struct wl_listener *listener, void *data)
724{
725 struct link_layer *link = NULL;
726 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900727 struct hmi_controller_layer *ctrl_layer_link = NULL;
728 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900729 struct hmi_controller *hmi_ctrl =
730 container_of(listener, struct hmi_controller, destroy_listener);
731
732 wl_list_for_each_safe(link, next,
733 &hmi_ctrl->workspace_fade.layer_list, link) {
734 wl_list_remove(&link->link);
735 free(link);
736 }
737
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900738 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900739 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
740 &hmi_ctrl->base_layer_list, link) {
741 wl_list_remove(&ctrl_layer_link->link);
742 free(ctrl_layer_link);
743 }
744
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900745 /* clear application_layer_list */
746 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
747 &hmi_ctrl->application_layer_list, link) {
748 wl_list_remove(&ctrl_layer_link->link);
749 free(ctrl_layer_link);
750 }
751
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900752 wl_array_release(&hmi_ctrl->ui_widgets);
753 free(hmi_ctrl->hmi_setting);
754 free(hmi_ctrl);
755}
756
757/**
758 * This is a starting method called from module_init.
759 * This sets up scene graph of ivi_layers; base, application, workspace
760 * background, and workspace. These ivi_layers are created/added to
761 * ivi_screen in create_layer
762 *
763 * base: to group ivi_surfaces of panel and background
764 * application: to group ivi_surfaces of ivi_applications
765 * workspace background: to group a ivi_surface of background in workspace
766 * workspace: to group ivi_surfaces for launching ivi_applications
767 *
768 * ivi_layers of workspace background and workspace is set to invisible at
769 * first. The properties of it is updated with animation when
770 * ivi_hmi_controller_home is requested.
771 */
772static struct hmi_controller *
Emre Ucanffaf09e2018-01-25 14:36:12 +0100773hmi_controller_create(struct weston_compositor *ec)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900774{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900775 struct link_layer *tmp_link_layer = NULL;
776 int32_t panel_height = 0;
Emre Ucanffaf09e2018-01-25 14:36:12 +0100777 struct hmi_controller *hmi_ctrl;
778 const struct ivi_layout_interface *interface;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900779 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900780 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000781 struct weston_output *output;
Emre Ucanffaf09e2018-01-25 14:36:12 +0100782 int32_t i;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900783
Emre Ucanffaf09e2018-01-25 14:36:12 +0100784 interface = ivi_layout_get_api(ec);
785
786 if (!interface) {
787 weston_log("Cannot use ivi_layout_interface.\n");
788 return NULL;
789 }
790
791 hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
792 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900793
794 wl_array_init(&hmi_ctrl->ui_widgets);
795 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
796 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
797 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000798 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Emre Ucana9db8d72018-01-25 14:36:11 +0100799 hmi_ctrl->interface = interface;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900800
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900801 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900802 wl_list_init(&hmi_ctrl->base_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000803 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900804 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
805 base_layer->x = 0;
806 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000807 base_layer->width = output->current_mode->width;
808 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900809 base_layer->id_layer =
810 hmi_ctrl->hmi_setting->base_layer_id +
811 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
812 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900813
Emre Ucana9db8d72018-01-25 14:36:11 +0100814 create_layer(output, base_layer, hmi_ctrl);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000815 i++;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900816 }
817
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000818 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900819 panel_height = hmi_ctrl->hmi_setting->panel_height;
820
821 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900822 wl_list_init(&hmi_ctrl->application_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000823 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900824 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
825 application_layer->x = 0;
826 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000827 application_layer->width = output->current_mode->width;
828 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900829 application_layer->id_layer =
830 hmi_ctrl->hmi_setting->application_layer_id +
831 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
832 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
833
Emre Ucana9db8d72018-01-25 14:36:11 +0100834 create_layer(output, application_layer, hmi_ctrl);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000835 i++;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900836 }
837
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900838 /* init workspace background ivi_layer */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000839 output = wl_container_of(ec->output_list.next, output, link);
840 hmi_ctrl->workspace_background_output = output;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900841 hmi_ctrl->workspace_background_layer.x = 0;
842 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000843 hmi_ctrl->workspace_background_layer.width =
844 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900845 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000846 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900847
848 hmi_ctrl->workspace_background_layer.id_layer =
849 hmi_ctrl->hmi_setting->workspace_background_layer_id;
850
Emre Ucana9db8d72018-01-25 14:36:11 +0100851 create_layer(output, &hmi_ctrl->workspace_background_layer, hmi_ctrl);
852 hmi_ctrl->interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900853 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Emre Ucana9db8d72018-01-25 14:36:11 +0100854 hmi_ctrl->interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900855 hmi_ctrl->workspace_background_layer.ivilayer, false);
856
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900857
858 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
859 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900860 tmp_link_layer->layout_layer =
861 hmi_ctrl->workspace_background_layer.ivilayer;
862 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
863 &tmp_link_layer->link);
864
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000865 hmi_ctrl->surface_removed.notify = set_notification_remove_surface;
Emre Ucana9db8d72018-01-25 14:36:11 +0100866 hmi_ctrl->interface->add_listener_remove_surface(&hmi_ctrl->surface_removed);
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000867
868 hmi_ctrl->surface_configured.notify = set_notification_configure_surface;
Emre Ucana9db8d72018-01-25 14:36:11 +0100869 hmi_ctrl->interface->add_listener_configure_surface(&hmi_ctrl->surface_configured);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900870
871 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
872 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
873 &hmi_ctrl->destroy_listener);
874
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900875 return hmi_ctrl;
876}
877
878/**
879 * Implementations of ivi-hmi-controller.xml
880 */
881
882/**
883 * A ivi_surface drawing background is identified by id_surface.
884 * Properties of the ivi_surface is set by using ivi_layout APIs according to
885 * the scene graph of UI defined in hmi_controller_create.
886 *
887 * UI ivi_layer is used to add this ivi_surface.
888 */
889static void
890ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
891 uint32_t id_surface)
892{
893 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900894 struct hmi_controller_layer *base_layer = NULL;
895 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000896 int32_t dstx;
897 int32_t dsty;
898 int32_t width;
899 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900900 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900901 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900902
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900903 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
904 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
905 sizeof(*add_surface_id));
906 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000907 dstx = base_layer->x;
908 dsty = base_layer->y;
909 width = base_layer->width;
910 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900911 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900912
Emre Ucana9db8d72018-01-25 14:36:11 +0100913 ivisurf = hmi_ctrl->interface->get_surface_from_id(*add_surface_id);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900914 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900915
Emre Ucana9db8d72018-01-25 14:36:11 +0100916 ret = hmi_ctrl->interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900917 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900918
Emre Ucana9db8d72018-01-25 14:36:11 +0100919 ret = hmi_ctrl->interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900920 dstx, dsty, width, height);
921 assert(!ret);
922
Emre Ucana9db8d72018-01-25 14:36:11 +0100923 ret = hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900924 assert(!ret);
925
926 i++;
927 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900928}
929
930/**
931 * A ivi_surface drawing panel is identified by id_surface.
932 * Properties of the ivi_surface is set by using ivi_layout APIs according to
933 * the scene graph of UI defined in hmi_controller_create.
934 *
935 * UI ivi_layer is used to add this ivi_surface.
936 */
937static void
938ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
939 uint32_t id_surface)
940{
941 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000942 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900943 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000944 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900945 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900946 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900947 const int32_t dstx = 0;
948 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900949 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900950
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900951 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
952 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
953 sizeof(*add_surface_id));
954 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900955
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900956 ivilayer = base_layer->ivilayer;
Emre Ucana9db8d72018-01-25 14:36:11 +0100957 ivisurf = hmi_ctrl->interface->get_surface_from_id(*add_surface_id);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900958 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900959
Emre Ucana9db8d72018-01-25 14:36:11 +0100960 ret = hmi_ctrl->interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900961 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900962
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900963 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000964 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900965
Emre Ucana9db8d72018-01-25 14:36:11 +0100966 ret = hmi_ctrl->interface->surface_set_destination_rectangle(
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900967 ivisurf, dstx, dsty, width, panel_height);
968 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900969
Emre Ucana9db8d72018-01-25 14:36:11 +0100970 ret = hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900971 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900972
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900973 i++;
974 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900975}
976
977/**
978 * A ivi_surface drawing buttons in panel is identified by id_surface.
979 * It can set several buttons. Properties of the ivi_surface is set by
980 * using ivi_layout APIs according to the scene graph of UI defined in
981 * hmi_controller_create. Additionally, the position of it is shifted to
982 * right when new one is requested.
983 *
984 * UI ivi_layer is used to add these ivi_surfaces.
985 */
986static void
987ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
988 uint32_t id_surface, int32_t number)
989{
990 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900991 struct hmi_controller_layer *base_layer =
992 wl_container_of(hmi_ctrl->base_layer_list.prev,
993 base_layer,
994 link);
995 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900996 const int32_t width = 48;
997 const int32_t height = 48;
998 int32_t ret = 0;
999 int32_t panel_height = 0;
1000 int32_t dstx = 0;
1001 int32_t dsty = 0;
1002 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1003 sizeof(*add_surface_id));
1004 *add_surface_id = id_surface;
1005
Emre Ucana9db8d72018-01-25 14:36:11 +01001006 ivisurf = hmi_ctrl->interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001007 assert(ivisurf != NULL);
1008
Emre Ucana9db8d72018-01-25 14:36:11 +01001009 ret = hmi_ctrl->interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001010 assert(!ret);
1011
1012 panel_height = hmi_ctrl->hmi_setting->panel_height;
1013
1014 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001015 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001016
Emre Ucana9db8d72018-01-25 14:36:11 +01001017 ret = hmi_ctrl->interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001018 ivisurf,dstx, dsty, width, height);
1019 assert(!ret);
1020
Emre Ucana9db8d72018-01-25 14:36:11 +01001021 ret = hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001022 assert(!ret);
1023}
1024
1025/**
1026 * A ivi_surface drawing home button in panel is identified by id_surface.
1027 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1028 * the scene graph of UI defined in hmi_controller_create.
1029 *
1030 * UI ivi_layer is used to add these ivi_surfaces.
1031 */
1032static void
1033ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1034 uint32_t id_surface)
1035{
1036 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001037 struct hmi_controller_layer *base_layer =
1038 wl_container_of(hmi_ctrl->base_layer_list.prev,
1039 base_layer,
1040 link);
1041 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001042 int32_t ret = 0;
1043 int32_t size = 48;
1044 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001045 const int32_t dstx = (base_layer->width - size) / 2;
1046 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001047
1048 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1049 sizeof(*add_surface_id));
1050 *add_surface_id = id_surface;
1051
Emre Ucana9db8d72018-01-25 14:36:11 +01001052 ivisurf = hmi_ctrl->interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001053 assert(ivisurf != NULL);
1054
Emre Ucana9db8d72018-01-25 14:36:11 +01001055 ret = hmi_ctrl->interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001056 assert(!ret);
1057
Emre Ucana9db8d72018-01-25 14:36:11 +01001058 ret = hmi_ctrl->interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001059 ivisurf, dstx, dsty, size, size);
1060 assert(!ret);
1061
Emre Ucana9db8d72018-01-25 14:36:11 +01001062 ret = hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001063 assert(!ret);
1064}
1065
1066/**
1067 * A ivi_surface drawing background of workspace is identified by id_surface.
1068 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1069 * the scene graph of UI defined in hmi_controller_create.
1070 *
1071 * A ivi_layer of workspace_background is used to add this ivi_surface.
1072 */
1073static void
1074ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1075 uint32_t id_surface)
1076{
1077 struct ivi_layout_surface *ivisurf = NULL;
1078 struct ivi_layout_layer *ivilayer = NULL;
1079 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1080 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1081 int32_t ret = 0;
1082
1083 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1084 sizeof(*add_surface_id));
1085 *add_surface_id = id_surface;
1086 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1087
Emre Ucana9db8d72018-01-25 14:36:11 +01001088 ivisurf = hmi_ctrl->interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001089 assert(ivisurf != NULL);
1090
Emre Ucana9db8d72018-01-25 14:36:11 +01001091 ret = hmi_ctrl->interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001092 assert(!ret);
1093
Emre Ucana9db8d72018-01-25 14:36:11 +01001094 ret = hmi_ctrl->interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001095 0, 0, width, height);
1096 assert(!ret);
1097
Emre Ucana9db8d72018-01-25 14:36:11 +01001098 ret = hmi_ctrl->interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001099 assert(!ret);
1100}
1101
1102/**
1103 * A list of ivi_surfaces drawing launchers in workspace is identified by
1104 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1105 * APIs according to the scene graph of UI defined in hmi_controller_create.
1106 *
1107 * The workspace can have several pages to group ivi_surfaces of launcher.
1108 * Each call of this interface increments a number of page to add a group
1109 * of ivi_surfaces
1110 */
1111static void
1112ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1113 int32_t icon_size)
1114{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001115 int32_t minspace_x = 10;
1116 int32_t minspace_y = minspace_x;
1117
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001118 int32_t width = hmi_ctrl->workspace_background_layer.width;
1119 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001120
1121 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1122 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1123 float fcell_size_x = icon_size + space_x;
1124
1125 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1126 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1127 float fcell_size_y = icon_size + space_y;
1128
1129 struct weston_config *config = NULL;
1130 struct weston_config_section *section = NULL;
1131 const char *name = NULL;
1132 int launcher_count = 0;
1133 struct wl_array launchers;
1134 int32_t nx = 0;
1135 int32_t ny = 0;
1136 int32_t prev = -1;
1137 struct launcher_info *data = NULL;
1138
1139 uint32_t surfaceid = 0;
1140 uint32_t workspaceid = 0;
1141 struct launcher_info *info = NULL;
1142
1143 int32_t x = 0;
1144 int32_t y = 0;
1145 int32_t ret = 0;
1146 struct ivi_layout_surface* layout_surface = NULL;
1147 uint32_t *add_surface_id = NULL;
1148
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001149 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001150
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001151 if (0 == x_count)
1152 x_count = 1;
1153
1154 if (0 == y_count)
1155 y_count = 1;
1156
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001157 config = wet_get_config(hmi_ctrl->compositor);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001158 if (!config)
1159 return;
1160
1161 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1162 if (!section)
1163 return;
1164
1165 wl_array_init(&launchers);
1166
1167 while (weston_config_next_section(config, &section, &name)) {
1168 surfaceid = 0;
1169 workspaceid = 0;
1170 info = NULL;
1171 if (0 != strcmp(name, "ivi-launcher"))
1172 continue;
1173
1174 if (0 != weston_config_section_get_uint(section, "icon-id",
1175 &surfaceid, 0))
1176 continue;
1177
1178 if (0 != weston_config_section_get_uint(section,
1179 "workspace-id",
1180 &workspaceid, 0))
1181 continue;
1182
1183 info = wl_array_add(&launchers, sizeof(*info));
1184
1185 if (info) {
1186 info->surface_id = surfaceid;
1187 info->workspace_id = workspaceid;
1188 info->index = launcher_count;
1189 ++launcher_count;
1190 }
1191 }
1192
1193 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1194 compare_launcher_info);
1195
1196 wl_array_for_each(data, &launchers) {
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001197 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1198 sizeof(*add_surface_id));
1199
1200 *add_surface_id = data->surface_id;
1201
1202 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1203 nx = 0;
1204 ny = 0;
1205 prev = data->workspace_id;
1206
1207 if (0 <= prev)
1208 hmi_ctrl->workspace_count++;
1209 }
1210
1211 if (y_count == ny) {
1212 ny = 0;
1213 hmi_ctrl->workspace_count++;
1214 }
1215
1216 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1217 y = ny * fcell_size_y + space_y;
1218
1219 layout_surface =
Emre Ucana9db8d72018-01-25 14:36:11 +01001220 hmi_ctrl->interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001221 assert(layout_surface);
1222
Emre Ucana9db8d72018-01-25 14:36:11 +01001223 ret = hmi_ctrl->interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001224 layout_surface, x, y, icon_size, icon_size);
1225 assert(!ret);
1226
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001227 nx++;
1228
1229 if (x_count == nx) {
1230 ny++;
1231 nx = 0;
1232 }
1233 }
1234
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001235 /* init workspace ivi_layer */
1236 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1237 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1238 hmi_ctrl->workspace_layer.width =
1239 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1240 hmi_ctrl->workspace_layer.height =
1241 hmi_ctrl->workspace_background_layer.height;
1242 hmi_ctrl->workspace_layer.id_layer =
1243 hmi_ctrl->hmi_setting->workspace_layer_id;
1244
Emre Ucana9db8d72018-01-25 14:36:11 +01001245 create_layer(hmi_ctrl->workspace_background_output,
1246 &hmi_ctrl->workspace_layer, hmi_ctrl);
1247 hmi_ctrl->interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1248 hmi_ctrl->interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001249 false);
1250
1251 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1252 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1253 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1254 &tmp_link_layer->link);
1255
1256 /* Add surface to layer */
1257 wl_array_for_each(data, &launchers) {
1258 layout_surface =
Emre Ucana9db8d72018-01-25 14:36:11 +01001259 hmi_ctrl->interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001260 assert(layout_surface);
1261
Emre Ucana9db8d72018-01-25 14:36:11 +01001262 ret = hmi_ctrl->interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001263 layout_surface);
1264 assert(!ret);
1265
Emre Ucana9db8d72018-01-25 14:36:11 +01001266 ret = hmi_ctrl->interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001267 assert(!ret);
1268 }
1269
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001270 wl_array_release(&launchers);
Emre Ucana9db8d72018-01-25 14:36:11 +01001271 hmi_ctrl->interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001272}
1273
1274static void
1275ivi_hmi_controller_UI_ready(struct wl_client *client,
1276 struct wl_resource *resource)
1277{
1278 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1279
1280 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1281 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1282 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1283 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1284 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1285 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1286 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1287 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Emre Ucana9db8d72018-01-25 14:36:11 +01001288 hmi_ctrl->interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001289
1290 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
Ucan, Emre (ADITG/SW1)d97f1002016-06-17 13:50:16 +00001291
1292 /* Add surface_created listener after the initialization of launchers.
1293 * Otherwise, surfaces of the launchers will be added to application
1294 * layer too.*/
1295 hmi_ctrl->surface_created.notify = set_notification_create_surface;
Emre Ucana9db8d72018-01-25 14:36:11 +01001296 hmi_ctrl->interface->add_listener_create_surface(&hmi_ctrl->surface_created);
Ucan, Emre (ADITG/SW1)d97f1002016-06-17 13:50:16 +00001297
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001298 hmi_ctrl->is_initialized = 1;
1299}
1300
1301/**
1302 * Implementation of request and event of ivi_hmi_controller_workspace_control
1303 * and controlling workspace.
1304 *
1305 * When motion of input is detected in a ivi_surface of workspace background,
1306 * ivi_hmi_controller_workspace_control shall be invoked and to start
1307 * controlling of workspace. The workspace has several pages to show several
1308 * groups of applications.
Abdur Rehmanb833d742017-01-01 19:46:34 +05001309 * The workspace is slid by using ivi-layout to select a page in layer_set_pos
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001310 * according to motion. When motion finished, e.g. touch up detected, control is
1311 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1312 */
1313struct pointer_grab {
1314 struct weston_pointer_grab grab;
1315 struct ivi_layout_layer *layer;
1316 struct wl_resource *resource;
1317};
1318
1319struct touch_grab {
1320 struct weston_touch_grab grab;
1321 struct ivi_layout_layer *layer;
1322 struct wl_resource *resource;
1323};
1324
1325struct move_grab {
1326 wl_fixed_t dst[2];
1327 wl_fixed_t rgn[2][2];
1328 double v[2];
1329 struct timespec start_time;
1330 struct timespec pre_time;
1331 wl_fixed_t start_pos[2];
1332 wl_fixed_t pos[2];
1333 int32_t is_moved;
1334};
1335
1336struct pointer_move_grab {
1337 struct pointer_grab base;
1338 struct move_grab move;
1339};
1340
1341struct touch_move_grab {
1342 struct touch_grab base;
1343 struct move_grab move;
1344 int32_t is_active;
1345};
1346
1347static void
1348pointer_grab_start(struct pointer_grab *grab,
1349 struct ivi_layout_layer *layer,
1350 const struct weston_pointer_grab_interface *interface,
1351 struct weston_pointer *pointer)
1352{
1353 grab->grab.interface = interface;
1354 grab->layer = layer;
1355 weston_pointer_start_grab(pointer, &grab->grab);
1356}
1357
1358static void
1359touch_grab_start(struct touch_grab *grab,
1360 struct ivi_layout_layer *layer,
1361 const struct weston_touch_grab_interface *interface,
1362 struct weston_touch* touch)
1363{
1364 grab->grab.interface = interface;
1365 grab->layer = layer;
1366 weston_touch_start_grab(touch, &grab->grab);
1367}
1368
1369static int32_t
1370clamp(int32_t val, int32_t min, int32_t max)
1371{
1372 if (val < min)
1373 return min;
1374
1375 if (max < val)
1376 return max;
1377
1378 return val;
1379}
1380
1381static void
1382move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1383 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1384{
1385 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1386 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001387 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001388
1389 struct timespec time = {0};
1390 double grab_time = 0.0;
1391 double from_motion_time = 0.0;
1392 double pointer_v = 0.0;
1393 int32_t is_flick = 0;
1394 int32_t pos_x = 0;
1395 int32_t pos_y = 0;
1396 int page_no = 0;
1397 double end_pos = 0.0;
1398 uint32_t duration = 0;
1399
1400 clock_gettime(CLOCK_MONOTONIC, &time);
1401
1402 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1403 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1404
1405 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1406 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1407
1408 pointer_v = move->v[0];
1409
1410 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1411 if (200 < from_motion_time)
1412 pointer_v = 0.0;
1413
Emre Ucana9db8d72018-01-25 14:36:11 +01001414 prop = hmi_ctrl->interface->get_properties_of_layer(layer);
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001415 pos_x = prop->dest_x;
1416 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001417
1418 if (is_flick) {
1419 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1420 page_no = (-orgx + width / 2) / width;
1421
1422 if (pointer_v < 0.0)
1423 page_no++;
1424 else
1425 page_no--;
1426 } else {
1427 page_no = (-pos_x + width / 2) / width;
1428 }
1429
1430 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1431 end_pos = -page_no * width;
1432
1433 duration = hmi_ctrl->hmi_setting->transition_duration;
1434 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Emre Ucana9db8d72018-01-25 14:36:11 +01001435 hmi_ctrl->interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001436 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1437 duration);
Emre Ucana9db8d72018-01-25 14:36:11 +01001438 hmi_ctrl->interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001439 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001440 hmi_ctrl->workspace_layer.width,
1441 hmi_ctrl->workspace_layer.height);
Emre Ucana9db8d72018-01-25 14:36:11 +01001442 hmi_ctrl->interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001443}
1444
1445static void
1446pointer_move_workspace_grab_end(struct pointer_grab *grab)
1447{
1448 struct pointer_move_grab *pnt_move_grab =
1449 (struct pointer_move_grab *)grab;
1450 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1451
1452 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1453 grab->grab.pointer->grab_x, layer);
1454
1455 weston_pointer_end_grab(grab->grab.pointer);
1456}
1457
1458static void
1459touch_move_workspace_grab_end(struct touch_grab *grab)
1460{
1461 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1462 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1463
1464 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1465 grab->grab.touch->grab_x, layer);
1466
1467 weston_touch_end_grab(grab->grab.touch);
1468}
1469
1470static void
1471pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1472{
1473}
1474
1475static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001476pointer_default_grab_axis(struct weston_pointer_grab *grab,
Alexandros Frantzis80321942017-11-16 18:20:56 +02001477 const struct timespec *time,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001478 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001479{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001480 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001481}
1482
1483static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001484pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1485 uint32_t source)
1486{
1487 weston_pointer_send_axis_source(grab->pointer, source);
1488}
1489
1490static void
1491pointer_default_grab_frame(struct weston_pointer_grab *grab)
1492{
1493 weston_pointer_send_frame(grab->pointer);
1494}
1495
1496static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001497move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1498{
1499 struct timespec timestamp = {0};
1500 int32_t ii = 0;
1501 double dt = 0.0;
1502
1503 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1504 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1505 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1506
1507 if (dt < 1e-6)
1508 dt = 1e-6;
1509
1510 move->pre_time = timestamp;
1511
1512 for (ii = 0; ii < 2; ii++) {
1513 wl_fixed_t prepos = move->pos[ii];
1514 move->pos[ii] = pointer[ii] + move->dst[ii];
1515
1516 if (move->pos[ii] < move->rgn[0][ii]) {
1517 move->pos[ii] = move->rgn[0][ii];
1518 move->dst[ii] = move->pos[ii] - pointer[ii];
1519 } else if (move->rgn[1][ii] < move->pos[ii]) {
1520 move->pos[ii] = move->rgn[1][ii];
1521 move->dst[ii] = move->pos[ii] - pointer[ii];
1522 }
1523
1524 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1525
1526 if (!move->is_moved &&
1527 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1528 move->is_moved = 1;
1529 }
1530}
1531
1532static void
Emre Ucana9db8d72018-01-25 14:36:11 +01001533layer_set_pos(struct hmi_controller *hmi_ctrl, struct ivi_layout_layer *layer,
1534 wl_fixed_t pos_x, wl_fixed_t pos_y)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001535{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001536 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001537 int32_t layout_pos_x = 0;
1538 int32_t layout_pos_y = 0;
1539
Emre Ucana9db8d72018-01-25 14:36:11 +01001540 prop = hmi_ctrl->interface->get_properties_of_layer(layer);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001541
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001542 layout_pos_x = wl_fixed_to_int(pos_x);
1543 layout_pos_y = wl_fixed_to_int(pos_y);
Emre Ucana9db8d72018-01-25 14:36:11 +01001544 hmi_ctrl->interface->layer_set_destination_rectangle(layer,
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001545 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Emre Ucana9db8d72018-01-25 14:36:11 +01001546 hmi_ctrl->interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001547}
1548
1549static void
Alexandros Frantzis84b31f82017-11-24 18:01:46 +02001550pointer_move_grab_motion(struct weston_pointer_grab *grab,
1551 const struct timespec *time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001552 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001553{
1554 struct pointer_move_grab *pnt_move_grab =
1555 (struct pointer_move_grab *)grab;
Emre Ucana9db8d72018-01-25 14:36:11 +01001556 struct hmi_controller *hmi_ctrl =
1557 wl_resource_get_user_data(pnt_move_grab->base.resource);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001558 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001559
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001560 weston_pointer_motion_to_abs(grab->pointer, event,
1561 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001562 move_grab_update(&pnt_move_grab->move, pointer_pos);
Emre Ucana9db8d72018-01-25 14:36:11 +01001563 layer_set_pos(hmi_ctrl, pnt_move_grab->base.layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001564 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001565 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001566}
1567
1568static void
Alexandros Frantzis7d2abcf2017-11-16 18:21:00 +02001569touch_move_grab_motion(struct weston_touch_grab *grab,
1570 const struct timespec *time, int touch_id,
1571 wl_fixed_t x, wl_fixed_t y)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001572{
1573 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
Emre Ucana9db8d72018-01-25 14:36:11 +01001574 struct hmi_controller *hmi_ctrl =
1575 wl_resource_get_user_data(tch_move_grab->base.resource);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001576
1577 if (!tch_move_grab->is_active)
1578 return;
1579
1580 wl_fixed_t pointer_pos[2] = {
1581 grab->touch->grab_x,
1582 grab->touch->grab_y
1583 };
1584
1585 move_grab_update(&tch_move_grab->move, pointer_pos);
Emre Ucana9db8d72018-01-25 14:36:11 +01001586 layer_set_pos(hmi_ctrl, tch_move_grab->base.layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001587 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1588}
1589
1590static void
1591pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
Alexandros Frantzis215bedc2017-11-16 18:20:55 +02001592 const struct timespec *time, uint32_t button,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001593 uint32_t state_w)
1594{
1595 if (BTN_LEFT == button &&
1596 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1597 struct pointer_grab *pg = (struct pointer_grab *)grab;
1598
1599 pointer_move_workspace_grab_end(pg);
1600 free(grab);
1601 }
1602}
1603
1604static void
Alexandros Frantzis9448deb2017-11-16 18:20:58 +02001605touch_nope_grab_down(struct weston_touch_grab *grab,
1606 const struct timespec *time,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001607 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1608{
1609}
1610
1611static void
Alexandros Frantzis27a51b82017-11-16 18:20:59 +02001612touch_move_workspace_grab_up(struct weston_touch_grab *grab,
1613 const struct timespec *time,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001614 int touch_id)
1615{
1616 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1617
1618 if (0 == touch_id)
1619 tch_move_grab->is_active = 0;
1620
1621 if (0 == grab->touch->num_tp) {
1622 touch_move_workspace_grab_end(&tch_move_grab->base);
1623 free(grab);
1624 }
1625}
1626
1627static void
1628pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1629{
1630 struct pointer_grab *pg = (struct pointer_grab *)grab;
1631
1632 pointer_move_workspace_grab_end(pg);
1633 free(grab);
1634}
1635
1636static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001637touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1638{
1639}
1640
1641static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001642touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1643{
1644 struct touch_grab *tg = (struct touch_grab *)grab;
1645
1646 touch_move_workspace_grab_end(tg);
1647 free(grab);
1648}
1649
1650static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1651 pointer_noop_grab_focus,
1652 pointer_move_grab_motion,
1653 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001654 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001655 pointer_default_grab_axis_source,
1656 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001657 pointer_move_workspace_grab_cancel
1658};
1659
1660static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1661 touch_nope_grab_down,
1662 touch_move_workspace_grab_up,
1663 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001664 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001665 touch_move_workspace_grab_cancel
1666};
1667
1668enum HMI_GRAB_DEVICE {
1669 HMI_GRAB_DEVICE_NONE,
1670 HMI_GRAB_DEVICE_POINTER,
1671 HMI_GRAB_DEVICE_TOUCH
1672};
1673
1674static enum HMI_GRAB_DEVICE
1675get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1676{
Derek Foreman1281a362015-07-31 16:55:32 -05001677 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1678 struct weston_touch *touch = weston_seat_get_touch(seat);
1679
1680 if (pointer &&
1681 pointer->focus &&
1682 pointer->button_count &&
1683 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001684 return HMI_GRAB_DEVICE_POINTER;
1685
Derek Foreman1281a362015-07-31 16:55:32 -05001686 if (touch &&
1687 touch->focus &&
1688 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001689 return HMI_GRAB_DEVICE_TOUCH;
1690
1691 return HMI_GRAB_DEVICE_NONE;
1692}
1693
1694static void
1695move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1696 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1697 struct wl_resource* resource)
1698{
1699 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1700 move->pre_time = move->start_time;
1701 move->pos[0] = start_pos[0];
1702 move->pos[1] = start_pos[1];
1703 move->start_pos[0] = start_pos[0];
1704 move->start_pos[1] = start_pos[1];
1705 move->dst[0] = start_pos[0] - grab_pos[0];
1706 move->dst[1] = start_pos[1] - grab_pos[1];
1707 memcpy(move->rgn, rgn, sizeof(move->rgn));
1708}
1709
1710static void
1711move_grab_init_workspace(struct move_grab* move,
1712 wl_fixed_t grab_x, wl_fixed_t grab_y,
1713 struct wl_resource *resource)
1714{
1715 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1716 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001717 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001718 int32_t workspace_count = hmi_ctrl->workspace_count;
1719 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1720 int32_t layer_pos_x = 0;
1721 int32_t layer_pos_y = 0;
1722 wl_fixed_t start_pos[2] = {0};
1723 wl_fixed_t rgn[2][2] = {{0}};
1724 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1725
Emre Ucana9db8d72018-01-25 14:36:11 +01001726 prop = hmi_ctrl->interface->get_properties_of_layer(layer);
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001727 layer_pos_x = prop->dest_x;
1728 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001729
1730 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1731 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1732
1733 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1734
1735 rgn[0][1] = wl_fixed_from_int(0);
1736 rgn[1][0] = wl_fixed_from_int(0);
1737 rgn[1][1] = wl_fixed_from_int(0);
1738
1739 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1740}
1741
1742static struct pointer_move_grab *
1743create_workspace_pointer_move(struct weston_pointer *pointer,
1744 struct wl_resource* resource)
1745{
1746 struct pointer_move_grab *pnt_move_grab =
1747 MEM_ALLOC(sizeof(*pnt_move_grab));
1748
1749 pnt_move_grab->base.resource = resource;
1750 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1751 pointer->grab_y, resource);
1752
1753 return pnt_move_grab;
1754}
1755
1756static struct touch_move_grab *
1757create_workspace_touch_move(struct weston_touch *touch,
1758 struct wl_resource* resource)
1759{
1760 struct touch_move_grab *tch_move_grab =
1761 MEM_ALLOC(sizeof(*tch_move_grab));
1762
1763 tch_move_grab->base.resource = resource;
1764 tch_move_grab->is_active = 1;
1765 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1766 touch->grab_y, resource);
1767
1768 return tch_move_grab;
1769}
1770
1771static void
1772ivi_hmi_controller_workspace_control(struct wl_client *client,
1773 struct wl_resource *resource,
1774 struct wl_resource *seat_resource,
1775 uint32_t serial)
1776{
1777 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1778 struct ivi_layout_layer *layer = NULL;
1779 struct pointer_move_grab *pnt_move_grab = NULL;
1780 struct touch_move_grab *tch_move_grab = NULL;
1781 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001782 struct weston_pointer *pointer;
1783 struct weston_touch *touch;
1784
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001785 enum HMI_GRAB_DEVICE device;
1786
1787 if (hmi_ctrl->workspace_count < 2)
1788 return;
1789
1790 seat = wl_resource_get_user_data(seat_resource);
1791 device = get_hmi_grab_device(seat, serial);
1792
1793 if (HMI_GRAB_DEVICE_POINTER != device &&
1794 HMI_GRAB_DEVICE_TOUCH != device)
1795 return;
1796
1797 layer = hmi_ctrl->workspace_layer.ivilayer;
1798
Emre Ucana9db8d72018-01-25 14:36:11 +01001799 hmi_ctrl->interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001800
1801 switch (device) {
1802 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001803 pointer = weston_seat_get_pointer(seat);
1804 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001805 resource);
1806
1807 pointer_grab_start(&pnt_move_grab->base, layer,
1808 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001809 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001810 break;
1811
1812 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001813 touch = weston_seat_get_touch(seat);
1814 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001815 resource);
1816
1817 touch_grab_start(&tch_move_grab->base, layer,
1818 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001819 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001820 break;
1821
1822 default:
1823 break;
1824 }
1825}
1826
1827/**
1828 * Implementation of switch_mode
1829 */
1830static void
1831ivi_hmi_controller_switch_mode(struct wl_client *client,
1832 struct wl_resource *resource,
1833 uint32_t layout_mode)
1834{
1835 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1836
1837 switch_mode(hmi_ctrl, layout_mode);
1838}
1839
1840/**
1841 * Implementation of on/off displaying workspace and workspace background
1842 * ivi_layers.
1843 */
1844static void
1845ivi_hmi_controller_home(struct wl_client *client,
1846 struct wl_resource *resource,
1847 uint32_t home)
1848{
1849 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1850 uint32_t is_fade_in;
1851
1852 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1853 !hmi_ctrl->workspace_fade.is_fade_in) ||
1854 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1855 hmi_ctrl->workspace_fade.is_fade_in)) {
1856 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1857 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1858 &hmi_ctrl->workspace_fade);
1859 }
1860
Emre Ucana9db8d72018-01-25 14:36:11 +01001861 hmi_ctrl->interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001862}
1863
1864/**
1865 * binding ivi-hmi-controller implementation
1866 */
1867static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1868 ivi_hmi_controller_UI_ready,
1869 ivi_hmi_controller_workspace_control,
1870 ivi_hmi_controller_switch_mode,
1871 ivi_hmi_controller_home
1872};
1873
1874static void
1875unbind_hmi_controller(struct wl_resource *resource)
1876{
1877}
1878
1879static void
1880bind_hmi_controller(struct wl_client *client,
1881 void *data, uint32_t version, uint32_t id)
1882{
1883 struct wl_resource *resource = NULL;
1884 struct hmi_controller *hmi_ctrl = data;
1885
1886 if (hmi_ctrl->user_interface != client) {
1887 struct wl_resource *res = wl_client_get_object(client, 1);
1888 wl_resource_post_error(res,
1889 WL_DISPLAY_ERROR_INVALID_OBJECT,
1890 "hmi-controller failed: permission denied");
1891 return;
1892 }
1893
1894 resource = wl_resource_create(
1895 client, &ivi_hmi_controller_interface, 1, id);
1896
1897 wl_resource_set_implementation(
1898 resource, &ivi_hmi_controller_implementation,
1899 hmi_ctrl, unbind_hmi_controller);
1900}
1901
1902static int32_t
1903initialize(struct hmi_controller *hmi_ctrl)
1904{
1905 struct config_command {
1906 char *key;
1907 uint32_t *dest;
1908 };
1909
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001910 struct weston_config *config = wet_get_config(hmi_ctrl->compositor);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001911 struct weston_config_section *section = NULL;
1912 int result = 0;
1913 int i = 0;
1914
1915 const struct config_command uint_commands[] = {
1916 { "background-id", &hmi_ctrl->ui_setting.background_id },
1917 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1918 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1919 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1920 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1921 { "random-id", &hmi_ctrl->ui_setting.random_id },
1922 { "home-id", &hmi_ctrl->ui_setting.home_id },
1923 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001924 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001925 { NULL, NULL }
1926 };
1927
1928 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1929
1930 for (i = 0; -1 != result; ++i) {
1931 const struct config_command *command = &uint_commands[i];
1932
1933 if (!command->key)
1934 break;
1935
1936 if (weston_config_section_get_uint(
1937 section, command->key, command->dest, 0) != 0)
1938 result = -1;
1939 }
1940
1941 if (-1 == result) {
1942 weston_log("Failed to initialize hmi-controller\n");
1943 return 0;
1944 }
1945
1946 return 1;
1947}
1948
1949static void
1950launch_hmi_client_process(void *data)
1951{
1952 struct hmi_controller *hmi_ctrl =
1953 (struct hmi_controller *)data;
1954
1955 hmi_ctrl->user_interface =
1956 weston_client_start(hmi_ctrl->compositor,
1957 hmi_ctrl->hmi_setting->ivi_homescreen);
1958
1959 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1960}
1961
1962/*****************************************************************************
1963 * exported functions
1964 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001965WL_EXPORT int
Emre Ucanffaf09e2018-01-25 14:36:12 +01001966wet_module_init(struct weston_compositor *ec,
1967 int *argc, char *argv[])
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001968{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001969 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001970 struct wl_event_loop *loop = NULL;
1971
Emre Ucanffaf09e2018-01-25 14:36:12 +01001972 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001973 if (hmi_ctrl == NULL)
1974 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001975
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001976 if (!initialize(hmi_ctrl)) {
1977 return -1;
1978 }
1979
1980 if (wl_global_create(ec->wl_display,
1981 &ivi_hmi_controller_interface, 1,
1982 hmi_ctrl, bind_hmi_controller) == NULL) {
1983 return -1;
1984 }
1985
1986 loop = wl_display_get_event_loop(ec->wl_display);
1987 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1988
1989 return 0;
1990}