blob: 97f78af50c0c0d1bf24d1d4503059fb1702939ba [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
41 * - Next, a application ivi_layer to show application ivi_surfaces.
42 * - 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>
55#include <stdio.h>
56#include <string.h>
57#include <linux/input.h>
58#include <assert.h>
59#include <time.h>
60
61#include "ivi-layout-export.h"
62#include "ivi-hmi-controller-server-protocol.h"
Jon Cruz867d50e2015-06-15 15:37:10 -070063#include "shared/helpers.h"
Bryce Harringtone99e4bf2016-03-16 14:15:18 -070064#include "shared/xalloc.h"
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090065
66/*****************************************************************************
67 * structure, globals
68 ****************************************************************************/
69struct hmi_controller_layer {
70 struct ivi_layout_layer *ivilayer;
71 uint32_t id_layer;
72 int32_t x;
73 int32_t y;
74 int32_t width;
75 int32_t height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090076 struct wl_list link;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090077};
78
79struct link_layer {
80 struct ivi_layout_layer *layout_layer;
81 struct wl_list link;
82};
83
84struct hmi_controller_fade {
85 uint32_t is_fade_in;
86 struct wl_list layer_list;
87};
88
89struct hmi_server_setting {
90 uint32_t base_layer_id;
91 uint32_t application_layer_id;
92 uint32_t workspace_background_layer_id;
93 uint32_t workspace_layer_id;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090094 uint32_t base_layer_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090095 int32_t panel_height;
96 uint32_t transition_duration;
97 char *ivi_homescreen;
98};
99
100struct ui_setting {
101 uint32_t background_id;
102 uint32_t panel_id;
103 uint32_t tiling_id;
104 uint32_t sidebyside_id;
105 uint32_t fullscreen_id;
106 uint32_t random_id;
107 uint32_t home_id;
108 uint32_t workspace_background_id;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900109 uint32_t surface_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900110};
111
112struct hmi_controller {
113 struct hmi_server_setting *hmi_setting;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900114 /* List of struct hmi_controller_layer */
115 struct wl_list base_layer_list;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900116 struct wl_list application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900117 struct hmi_controller_layer workspace_background_layer;
118 struct hmi_controller_layer workspace_layer;
119 enum ivi_hmi_controller_layout_mode layout_mode;
120
121 struct hmi_controller_fade workspace_fade;
122
123 int32_t workspace_count;
124 struct wl_array ui_widgets;
125 int32_t is_initialized;
126
127 struct weston_compositor *compositor;
128 struct wl_listener destroy_listener;
129
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000130 struct wl_listener surface_created;
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000131 struct wl_listener surface_removed;
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000132 struct wl_listener surface_configured;
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000133
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900134 struct wl_client *user_interface;
135 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900136
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000137 struct weston_output * workspace_background_output;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900138 int32_t screen_num;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900139};
140
141struct launcher_info {
142 uint32_t surface_id;
143 uint32_t workspace_id;
144 int32_t index;
145};
146
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000147const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900148
149int
150controller_module_init(struct weston_compositor *ec,
151 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000152 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900153 size_t interface_version);
154
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900155/*****************************************************************************
156 * local functions
157 ****************************************************************************/
158static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900159mem_alloc(size_t size, char *file, int32_t line)
160{
161 return fail_on_null(calloc(1, size), size, file, line);
162}
163
164#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
165
166static int32_t
167is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
168 struct ivi_layout_surface *ivisurf)
169{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000170 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900171
172 uint32_t *ui_widget_id = NULL;
173 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
174 if (*ui_widget_id == id)
175 return 1;
176 }
177
178 return 0;
179}
180
181static int
182compare_launcher_info(const void *lhs, const void *rhs)
183{
184 const struct launcher_info *left = lhs;
185 const struct launcher_info *right = rhs;
186
187 if (left->workspace_id < right->workspace_id)
188 return -1;
189
190 if (left->workspace_id > right->workspace_id)
191 return 1;
192
193 if (left->index < right->index)
194 return -1;
195
196 if (left->index > right->index)
197 return 1;
198
199 return 0;
200}
201
202/**
203 * Internal methods called by mainly ivi_hmi_controller_switch_mode
204 * This reference shows 4 examples how to use ivi_layout APIs.
205 */
206static void
207mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
208 struct ivi_layout_surface **pp_surface,
209 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900210 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900211{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900212 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900213 const float surface_width = (float)layer->width * 0.25;
214 const float surface_height = (float)layer->height * 0.5;
215 int32_t surface_x = 0;
216 int32_t surface_y = 0;
217 struct ivi_layout_surface *ivisurf = NULL;
218 struct ivi_layout_surface **surfaces;
219 struct ivi_layout_surface **new_order;
220 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900221 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900222
223 int32_t i = 0;
224 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900225 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900226
227 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
228 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
229
230 for (i = 0; i < surface_length; i++) {
231 ivisurf = pp_surface[i];
232
233 /* skip ui widgets */
234 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
235 continue;
236
237 surfaces[surf_num++] = ivisurf;
238 }
239
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900240 wl_list_for_each_reverse(layer, layer_list, link) {
241 if (idx >= surf_num)
242 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900243
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900244 ivilayer = layer->ivilayer;
245
246 for (i = 0; i < 8; i++, idx++) {
247 if (idx >= surf_num)
248 break;
249
250 ivisurf = surfaces[idx];
251 new_order[i] = ivisurf;
252 if (i < 4) {
253 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900254 surface_y = 0;
255 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900256 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900257 surface_y = (int32_t)surface_height;
258 }
259
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000260 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900261 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
262 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000263 ivi_layout_interface->surface_set_visibility(ivisurf, true);
264 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900265 surface_x, surface_y,
266 (int32_t)surface_width,
267 (int32_t)surface_height);
268
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900269 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900270 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900271
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900272 ivi_layout_interface->layer_set_transition(ivilayer,
273 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
274 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900275 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900276 for (i = idx; i < surf_num; i++)
277 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900278
279 free(surfaces);
280 free(new_order);
281}
282
283static void
284mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
285 struct ivi_layout_surface **pp_surface,
286 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900287 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900288{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900289 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900290 int32_t surface_width = layer->width / 2;
291 int32_t surface_height = layer->height;
292 struct ivi_layout_surface *ivisurf = NULL;
293
294 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
295 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900296 struct ivi_layout_surface **surfaces;
297 struct ivi_layout_surface **new_order;
298 struct ivi_layout_layer *ivilayer = NULL;
299 int32_t surf_num = 0;
300 int32_t idx = 0;
301
302 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
303 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900304
305 for (i = 0; i < surface_length; i++) {
306 ivisurf = pp_surface[i];
307
308 /* skip ui widgets */
309 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
310 continue;
311
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900312 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900313 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900314
315 wl_list_for_each_reverse(layer, layer_list, link) {
316 if (idx >= surf_num)
317 break;
318
319 ivilayer = layer->ivilayer;
320
321 for (i = 0; i < 2; i++, idx++) {
322 if (idx >= surf_num)
323 break;
324
325 ivisurf = surfaces[idx];
326 new_order[i] = ivisurf;
327
328 ivi_layout_interface->surface_set_transition(ivisurf,
329 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
330 duration);
331 ivi_layout_interface->surface_set_visibility(ivisurf, true);
332
333 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
334 i * surface_width, 0,
335 surface_width,
336 surface_height);
337 }
338 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
339 }
340
341 for (i = idx; i < surf_num; i++) {
342 ivi_layout_interface->surface_set_transition(surfaces[i],
343 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
344 duration);
345 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
346 }
347
348 free(surfaces);
349 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900350}
351
352static void
353mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
354 struct ivi_layout_surface **pp_surface,
355 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900356 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900357{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900358 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900359 const int32_t surface_width = layer->width;
360 const int32_t surface_height = layer->height;
361 struct ivi_layout_surface *ivisurf = NULL;
362 int32_t i = 0;
363 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900364 int32_t surf_num = 0;
365 struct ivi_layout_surface **surfaces;
366
367 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900368
369 for (i = 0; i < surface_length; i++) {
370 ivisurf = pp_surface[i];
371
372 /* skip ui widgets */
373 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
374 continue;
375
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900376 surfaces[surf_num++] = ivisurf;
377 }
378 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
379
380 for (i = 0; i < surf_num; i++) {
381 ivisurf = surfaces[i];
382
383 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
384 layer = wl_container_of(layer->link.prev, layer, link);
385 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
386 }
387
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000388 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900389 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
390 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000391 ivi_layout_interface->surface_set_visibility(ivisurf, true);
392 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900393 surface_width,
394 surface_height);
395 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900396
397 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900398}
399
400static void
401mode_random_replace(struct hmi_controller *hmi_ctrl,
402 struct ivi_layout_surface **pp_surface,
403 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900404 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900405{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900406 struct hmi_controller_layer *application_layer = NULL;
407 struct hmi_controller_layer **layers = NULL;
408 int32_t surface_width = 0;
409 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900410 int32_t surface_x = 0;
411 int32_t surface_y = 0;
412 struct ivi_layout_surface *ivisurf = NULL;
413 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
414 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900415 int32_t layer_idx = 0;
416
417 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
418
419 wl_list_for_each(application_layer, layer_list, link) {
420 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900421 layer_idx++;
422 }
423
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900424 for (i = 0; i < surface_length; i++) {
425 ivisurf = pp_surface[i];
426
427 /* skip ui widgets */
428 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
429 continue;
430
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900431 /* surface determined at random a layer that belongs */
432 layer_idx = rand() % hmi_ctrl->screen_num;
433
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000434 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900435 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
436 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900437
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000438 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900439
440 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
441 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
442 surface_x = rand() % (layers[layer_idx]->width - surface_width);
443 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900444
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000445 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900446 surface_x,
447 surface_y,
448 surface_width,
449 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900450
451 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900452 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900453
454 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900455}
456
457static int32_t
458has_application_surface(struct hmi_controller *hmi_ctrl,
459 struct ivi_layout_surface **pp_surface,
460 int32_t surface_length)
461{
462 struct ivi_layout_surface *ivisurf = NULL;
463 int32_t i = 0;
464
465 for (i = 0; i < surface_length; i++) {
466 ivisurf = pp_surface[i];
467
468 /* skip ui widgets */
469 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
470 continue;
471
472 return 1;
473 }
474
475 return 0;
476}
477
478/**
479 * Supports 4 example to layout of application ivi_surfaces;
480 * tiling, side by side, fullscreen, and random.
481 */
482static void
483switch_mode(struct hmi_controller *hmi_ctrl,
484 enum ivi_hmi_controller_layout_mode layout_mode)
485{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900486 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900487 struct ivi_layout_surface **pp_surface = NULL;
488 int32_t surface_length = 0;
489 int32_t ret = 0;
490
491 if (!hmi_ctrl->is_initialized)
492 return;
493
494 hmi_ctrl->layout_mode = layout_mode;
495
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000496 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900497 assert(!ret);
498
499 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
500 free(pp_surface);
501 pp_surface = NULL;
502 return;
503 }
504
505 switch (layout_mode) {
506 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
507 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
508 layer);
509 break;
510 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
511 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
512 surface_length, layer);
513 break;
514 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
515 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
516 layer);
517 break;
518 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
519 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
520 layer);
521 break;
522 }
523
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000524 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900525 free(pp_surface);
526}
527
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900528/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900529 * Internal method for transition
530 */
531static void
532hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
533 struct hmi_controller_fade *fade)
534{
535 double tint = is_fade_in ? 1.0 : 0.0;
536 struct link_layer *linklayer = NULL;
537 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
538
539 fade->is_fade_in = is_fade_in;
540
541 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000542 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900543 IVI_LAYOUT_TRANSITION_LAYER_FADE,
544 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000545 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900546 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900547 }
548}
549
550/**
551 * Internal method to create ivi_layer with hmi_controller_layer and
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000552 * add to a weston_output
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900553 */
554static void
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000555create_layer(struct weston_output *output,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900556 struct hmi_controller_layer *layer)
557{
558 int32_t ret = 0;
559
560 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000561 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900562 layer->width,
563 layer->height);
564 assert(layer->ivilayer != NULL);
565
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000566 ret = ivi_layout_interface->screen_add_layer(output, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900567 assert(!ret);
568
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000569 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900570 layer->x, layer->y,
571 layer->width,
572 layer->height);
573 assert(!ret);
574
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000575 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900576 assert(!ret);
577}
578
579/**
580 * Internal set notification
581 */
582static void
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000583set_notification_create_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900584{
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000585 struct hmi_controller *hmi_ctrl =
586 wl_container_of(listener, hmi_ctrl,
587 surface_created);
588 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900589 struct hmi_controller_layer *layer_link =
590 wl_container_of(hmi_ctrl->application_layer_list.prev,
591 layer_link,
592 link);
593 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900594 int32_t ret = 0;
595
596 /* skip ui widgets */
597 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
598 return;
599
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000600 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900601 assert(!ret);
602}
603
604static void
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000605set_notification_remove_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900606{
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000607 struct hmi_controller *hmi_ctrl =
608 wl_container_of(listener, hmi_ctrl,
609 surface_removed);
610 (void)data;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900611
612 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
613}
614
615static void
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000616set_notification_configure_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900617{
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000618 struct hmi_controller *hmi_ctrl =
619 wl_container_of(listener, hmi_ctrl,
620 surface_configured);
621 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900622 struct hmi_controller_layer *layer_link = NULL;
623 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900624 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900625 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900626 int32_t length = 0;
627 int32_t i;
628
629 /* return if the surface is not application content */
630 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
631 return;
632 }
633
634 /*
635 * if application changes size of wl_buffer. The source rectangle shall be
636 * fit to the size.
637 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000638 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900639 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000640 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900641 ivisurf, 0, 0, surface->width,
642 surface->height);
643 }
644
645 /*
646 * search if the surface is already added to layer.
647 * If not yet, it is newly invoded application to go to switch_mode.
648 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900649 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
650 application_layer = layer_link->ivilayer;
651 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900652 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900653 for (i = 0; i < length; i++) {
654 if (ivisurf == ivisurfs[i]) {
655 /*
656 * if it is non new invoked application, just call
657 * commit_changes to apply source_rectangle.
658 */
659 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900660 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900661 return;
662 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900663 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900664 free(ivisurfs);
665 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900666 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900667
668 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
669}
670
671/**
672 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
673 * corresponding ivi_layer are defined in weston.ini. Default scene graph
674 * of ivi_layers are initialized in hmi_controller_create
675 */
676static struct hmi_server_setting *
677hmi_server_setting_create(struct weston_compositor *ec)
678{
679 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
680 struct weston_config *config = ec->config;
681 struct weston_config_section *shell_section = NULL;
682
683 shell_section = weston_config_get_section(config, "ivi-shell",
684 NULL, NULL);
685
686 weston_config_section_get_uint(shell_section, "base-layer-id",
687 &setting->base_layer_id, 1000);
688
689 weston_config_section_get_uint(shell_section,
690 "workspace-background-layer-id",
691 &setting->workspace_background_layer_id,
692 2000);
693
694 weston_config_section_get_uint(shell_section, "workspace-layer-id",
695 &setting->workspace_layer_id, 3000);
696
697 weston_config_section_get_uint(shell_section, "application-layer-id",
698 &setting->application_layer_id, 4000);
699
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900700 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
701 &setting->base_layer_id_offset, 10000);
702
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900703 weston_config_section_get_uint(shell_section, "transition-duration",
704 &setting->transition_duration, 300);
705
706 setting->panel_height = 70;
707
708 weston_config_section_get_string(shell_section,
709 "ivi-shell-user-interface",
710 &setting->ivi_homescreen, NULL);
711
712 return setting;
713}
714
715static void
716hmi_controller_destroy(struct wl_listener *listener, void *data)
717{
718 struct link_layer *link = NULL;
719 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900720 struct hmi_controller_layer *ctrl_layer_link = NULL;
721 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900722 struct hmi_controller *hmi_ctrl =
723 container_of(listener, struct hmi_controller, destroy_listener);
724
725 wl_list_for_each_safe(link, next,
726 &hmi_ctrl->workspace_fade.layer_list, link) {
727 wl_list_remove(&link->link);
728 free(link);
729 }
730
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900731 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900732 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
733 &hmi_ctrl->base_layer_list, link) {
734 wl_list_remove(&ctrl_layer_link->link);
735 free(ctrl_layer_link);
736 }
737
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900738 /* clear application_layer_list */
739 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
740 &hmi_ctrl->application_layer_list, link) {
741 wl_list_remove(&ctrl_layer_link->link);
742 free(ctrl_layer_link);
743 }
744
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900745 wl_array_release(&hmi_ctrl->ui_widgets);
746 free(hmi_ctrl->hmi_setting);
747 free(hmi_ctrl);
748}
749
750/**
751 * This is a starting method called from module_init.
752 * This sets up scene graph of ivi_layers; base, application, workspace
753 * background, and workspace. These ivi_layers are created/added to
754 * ivi_screen in create_layer
755 *
756 * base: to group ivi_surfaces of panel and background
757 * application: to group ivi_surfaces of ivi_applications
758 * workspace background: to group a ivi_surface of background in workspace
759 * workspace: to group ivi_surfaces for launching ivi_applications
760 *
761 * ivi_layers of workspace background and workspace is set to invisible at
762 * first. The properties of it is updated with animation when
763 * ivi_hmi_controller_home is requested.
764 */
765static struct hmi_controller *
766hmi_controller_create(struct weston_compositor *ec)
767{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900768 struct link_layer *tmp_link_layer = NULL;
769 int32_t panel_height = 0;
770 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900771 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900772 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000773 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900774
775 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900776
777 wl_array_init(&hmi_ctrl->ui_widgets);
778 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
779 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
780 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000781 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900782
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900783 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900784 wl_list_init(&hmi_ctrl->base_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000785 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900786 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
787 base_layer->x = 0;
788 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000789 base_layer->width = output->current_mode->width;
790 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900791 base_layer->id_layer =
792 hmi_ctrl->hmi_setting->base_layer_id +
793 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
794 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900795
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000796 create_layer(output, base_layer);
797 i++;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900798 }
799
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000800 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900801 panel_height = hmi_ctrl->hmi_setting->panel_height;
802
803 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900804 wl_list_init(&hmi_ctrl->application_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000805 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900806 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
807 application_layer->x = 0;
808 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000809 application_layer->width = output->current_mode->width;
810 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900811 application_layer->id_layer =
812 hmi_ctrl->hmi_setting->application_layer_id +
813 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
814 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
815
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000816 create_layer(output, application_layer);
817 i++;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900818 }
819
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900820 /* init workspace background ivi_layer */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000821 output = wl_container_of(ec->output_list.next, output, link);
822 hmi_ctrl->workspace_background_output = output;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900823 hmi_ctrl->workspace_background_layer.x = 0;
824 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000825 hmi_ctrl->workspace_background_layer.width =
826 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900827 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000828 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900829
830 hmi_ctrl->workspace_background_layer.id_layer =
831 hmi_ctrl->hmi_setting->workspace_background_layer_id;
832
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000833 create_layer(output, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000834 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900835 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000836 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900837 hmi_ctrl->workspace_background_layer.ivilayer, false);
838
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900839
840 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
841 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900842 tmp_link_layer->layout_layer =
843 hmi_ctrl->workspace_background_layer.ivilayer;
844 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
845 &tmp_link_layer->link);
846
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000847 hmi_ctrl->surface_created.notify = set_notification_create_surface;
848 ivi_layout_interface->add_listener_create_surface(&hmi_ctrl->surface_created);
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000849
850 hmi_ctrl->surface_removed.notify = set_notification_remove_surface;
851 ivi_layout_interface->add_listener_remove_surface(&hmi_ctrl->surface_removed);
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000852
853 hmi_ctrl->surface_configured.notify = set_notification_configure_surface;
854 ivi_layout_interface->add_listener_configure_surface(&hmi_ctrl->surface_configured);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900855
856 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
857 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
858 &hmi_ctrl->destroy_listener);
859
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900860 return hmi_ctrl;
861}
862
863/**
864 * Implementations of ivi-hmi-controller.xml
865 */
866
867/**
868 * A ivi_surface drawing background is identified by id_surface.
869 * Properties of the ivi_surface is set by using ivi_layout APIs according to
870 * the scene graph of UI defined in hmi_controller_create.
871 *
872 * UI ivi_layer is used to add this ivi_surface.
873 */
874static void
875ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
876 uint32_t id_surface)
877{
878 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900879 struct hmi_controller_layer *base_layer = NULL;
880 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000881 int32_t dstx;
882 int32_t dsty;
883 int32_t width;
884 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900885 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900886 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900887
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900888 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
889 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
890 sizeof(*add_surface_id));
891 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000892 dstx = base_layer->x;
893 dsty = base_layer->y;
894 width = base_layer->width;
895 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900896 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900897
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900898 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
899 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900900
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900901 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
902 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900903
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900904 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
905 dstx, dsty, width, height);
906 assert(!ret);
907
908 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
909 assert(!ret);
910
911 i++;
912 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900913}
914
915/**
916 * A ivi_surface drawing panel is identified by id_surface.
917 * Properties of the ivi_surface is set by using ivi_layout APIs according to
918 * the scene graph of UI defined in hmi_controller_create.
919 *
920 * UI ivi_layer is used to add this ivi_surface.
921 */
922static void
923ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
924 uint32_t id_surface)
925{
926 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000927 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900928 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000929 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900930 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900931 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900932 const int32_t dstx = 0;
933 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900934 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900935
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900936 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
937 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
938 sizeof(*add_surface_id));
939 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900940
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900941 ivilayer = base_layer->ivilayer;
942 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
943 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900944
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900945 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
946 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900947
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900948 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000949 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900950
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900951 ret = ivi_layout_interface->surface_set_destination_rectangle(
952 ivisurf, dstx, dsty, width, panel_height);
953 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900954
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900955 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
956 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900957
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900958 i++;
959 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900960}
961
962/**
963 * A ivi_surface drawing buttons in panel is identified by id_surface.
964 * It can set several buttons. Properties of the ivi_surface is set by
965 * using ivi_layout APIs according to the scene graph of UI defined in
966 * hmi_controller_create. Additionally, the position of it is shifted to
967 * right when new one is requested.
968 *
969 * UI ivi_layer is used to add these ivi_surfaces.
970 */
971static void
972ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
973 uint32_t id_surface, int32_t number)
974{
975 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900976 struct hmi_controller_layer *base_layer =
977 wl_container_of(hmi_ctrl->base_layer_list.prev,
978 base_layer,
979 link);
980 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900981 const int32_t width = 48;
982 const int32_t height = 48;
983 int32_t ret = 0;
984 int32_t panel_height = 0;
985 int32_t dstx = 0;
986 int32_t dsty = 0;
987 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
988 sizeof(*add_surface_id));
989 *add_surface_id = id_surface;
990
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000991 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900992 assert(ivisurf != NULL);
993
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000994 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900995 assert(!ret);
996
997 panel_height = hmi_ctrl->hmi_setting->panel_height;
998
999 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001000 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001001
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001002 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001003 ivisurf,dstx, dsty, width, height);
1004 assert(!ret);
1005
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001006 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001007 assert(!ret);
1008}
1009
1010/**
1011 * A ivi_surface drawing home button in panel is identified by id_surface.
1012 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1013 * the scene graph of UI defined in hmi_controller_create.
1014 *
1015 * UI ivi_layer is used to add these ivi_surfaces.
1016 */
1017static void
1018ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1019 uint32_t id_surface)
1020{
1021 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001022 struct hmi_controller_layer *base_layer =
1023 wl_container_of(hmi_ctrl->base_layer_list.prev,
1024 base_layer,
1025 link);
1026 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001027 int32_t ret = 0;
1028 int32_t size = 48;
1029 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001030 const int32_t dstx = (base_layer->width - size) / 2;
1031 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001032
1033 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1034 sizeof(*add_surface_id));
1035 *add_surface_id = id_surface;
1036
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001037 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001038 assert(ivisurf != NULL);
1039
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001040 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001041 assert(!ret);
1042
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001043 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001044 ivisurf, dstx, dsty, size, size);
1045 assert(!ret);
1046
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001047 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001048 assert(!ret);
1049}
1050
1051/**
1052 * A ivi_surface drawing background of workspace is identified by id_surface.
1053 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1054 * the scene graph of UI defined in hmi_controller_create.
1055 *
1056 * A ivi_layer of workspace_background is used to add this ivi_surface.
1057 */
1058static void
1059ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1060 uint32_t id_surface)
1061{
1062 struct ivi_layout_surface *ivisurf = NULL;
1063 struct ivi_layout_layer *ivilayer = NULL;
1064 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1065 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1066 int32_t ret = 0;
1067
1068 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1069 sizeof(*add_surface_id));
1070 *add_surface_id = id_surface;
1071 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1072
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001073 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001074 assert(ivisurf != NULL);
1075
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001076 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001077 assert(!ret);
1078
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001079 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001080 0, 0, width, height);
1081 assert(!ret);
1082
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001083 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001084 assert(!ret);
1085}
1086
1087/**
1088 * A list of ivi_surfaces drawing launchers in workspace is identified by
1089 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1090 * APIs according to the scene graph of UI defined in hmi_controller_create.
1091 *
1092 * The workspace can have several pages to group ivi_surfaces of launcher.
1093 * Each call of this interface increments a number of page to add a group
1094 * of ivi_surfaces
1095 */
1096static void
1097ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1098 int32_t icon_size)
1099{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001100 int32_t minspace_x = 10;
1101 int32_t minspace_y = minspace_x;
1102
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001103 int32_t width = hmi_ctrl->workspace_background_layer.width;
1104 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001105
1106 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1107 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1108 float fcell_size_x = icon_size + space_x;
1109
1110 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1111 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1112 float fcell_size_y = icon_size + space_y;
1113
1114 struct weston_config *config = NULL;
1115 struct weston_config_section *section = NULL;
1116 const char *name = NULL;
1117 int launcher_count = 0;
1118 struct wl_array launchers;
1119 int32_t nx = 0;
1120 int32_t ny = 0;
1121 int32_t prev = -1;
1122 struct launcher_info *data = NULL;
1123
1124 uint32_t surfaceid = 0;
1125 uint32_t workspaceid = 0;
1126 struct launcher_info *info = NULL;
1127
1128 int32_t x = 0;
1129 int32_t y = 0;
1130 int32_t ret = 0;
1131 struct ivi_layout_surface* layout_surface = NULL;
1132 uint32_t *add_surface_id = NULL;
1133
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001134 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001135
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001136 if (0 == x_count)
1137 x_count = 1;
1138
1139 if (0 == y_count)
1140 y_count = 1;
1141
1142 config = hmi_ctrl->compositor->config;
1143 if (!config)
1144 return;
1145
1146 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1147 if (!section)
1148 return;
1149
1150 wl_array_init(&launchers);
1151
1152 while (weston_config_next_section(config, &section, &name)) {
1153 surfaceid = 0;
1154 workspaceid = 0;
1155 info = NULL;
1156 if (0 != strcmp(name, "ivi-launcher"))
1157 continue;
1158
1159 if (0 != weston_config_section_get_uint(section, "icon-id",
1160 &surfaceid, 0))
1161 continue;
1162
1163 if (0 != weston_config_section_get_uint(section,
1164 "workspace-id",
1165 &workspaceid, 0))
1166 continue;
1167
1168 info = wl_array_add(&launchers, sizeof(*info));
1169
1170 if (info) {
1171 info->surface_id = surfaceid;
1172 info->workspace_id = workspaceid;
1173 info->index = launcher_count;
1174 ++launcher_count;
1175 }
1176 }
1177
1178 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1179 compare_launcher_info);
1180
1181 wl_array_for_each(data, &launchers) {
1182 x = 0;
1183 y = 0;
1184 ret = 0;
1185 layout_surface = NULL;
1186 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1187 sizeof(*add_surface_id));
1188
1189 *add_surface_id = data->surface_id;
1190
1191 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1192 nx = 0;
1193 ny = 0;
1194 prev = data->workspace_id;
1195
1196 if (0 <= prev)
1197 hmi_ctrl->workspace_count++;
1198 }
1199
1200 if (y_count == ny) {
1201 ny = 0;
1202 hmi_ctrl->workspace_count++;
1203 }
1204
1205 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1206 y = ny * fcell_size_y + space_y;
1207
1208 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001209 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001210 assert(layout_surface);
1211
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001212 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001213 layout_surface, x, y, icon_size, icon_size);
1214 assert(!ret);
1215
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001216 nx++;
1217
1218 if (x_count == nx) {
1219 ny++;
1220 nx = 0;
1221 }
1222 }
1223
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001224 /* init workspace ivi_layer */
1225 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1226 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1227 hmi_ctrl->workspace_layer.width =
1228 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1229 hmi_ctrl->workspace_layer.height =
1230 hmi_ctrl->workspace_background_layer.height;
1231 hmi_ctrl->workspace_layer.id_layer =
1232 hmi_ctrl->hmi_setting->workspace_layer_id;
1233
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001234 create_layer(hmi_ctrl->workspace_background_output, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001235 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1236 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001237 false);
1238
1239 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1240 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1241 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1242 &tmp_link_layer->link);
1243
1244 /* Add surface to layer */
1245 wl_array_for_each(data, &launchers) {
1246 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001247 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001248 assert(layout_surface);
1249
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001250 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001251 layout_surface);
1252 assert(!ret);
1253
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001254 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001255 assert(!ret);
1256 }
1257
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001258 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001259 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001260}
1261
1262static void
1263ivi_hmi_controller_UI_ready(struct wl_client *client,
1264 struct wl_resource *resource)
1265{
1266 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1267
1268 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1269 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1270 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1271 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1272 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1273 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1274 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1275 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001276 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001277
1278 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1279 hmi_ctrl->is_initialized = 1;
1280}
1281
1282/**
1283 * Implementation of request and event of ivi_hmi_controller_workspace_control
1284 * and controlling workspace.
1285 *
1286 * When motion of input is detected in a ivi_surface of workspace background,
1287 * ivi_hmi_controller_workspace_control shall be invoked and to start
1288 * controlling of workspace. The workspace has several pages to show several
1289 * groups of applications.
1290 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1291 * according to motion. When motion finished, e.g. touch up detected, control is
1292 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1293 */
1294struct pointer_grab {
1295 struct weston_pointer_grab grab;
1296 struct ivi_layout_layer *layer;
1297 struct wl_resource *resource;
1298};
1299
1300struct touch_grab {
1301 struct weston_touch_grab grab;
1302 struct ivi_layout_layer *layer;
1303 struct wl_resource *resource;
1304};
1305
1306struct move_grab {
1307 wl_fixed_t dst[2];
1308 wl_fixed_t rgn[2][2];
1309 double v[2];
1310 struct timespec start_time;
1311 struct timespec pre_time;
1312 wl_fixed_t start_pos[2];
1313 wl_fixed_t pos[2];
1314 int32_t is_moved;
1315};
1316
1317struct pointer_move_grab {
1318 struct pointer_grab base;
1319 struct move_grab move;
1320};
1321
1322struct touch_move_grab {
1323 struct touch_grab base;
1324 struct move_grab move;
1325 int32_t is_active;
1326};
1327
1328static void
1329pointer_grab_start(struct pointer_grab *grab,
1330 struct ivi_layout_layer *layer,
1331 const struct weston_pointer_grab_interface *interface,
1332 struct weston_pointer *pointer)
1333{
1334 grab->grab.interface = interface;
1335 grab->layer = layer;
1336 weston_pointer_start_grab(pointer, &grab->grab);
1337}
1338
1339static void
1340touch_grab_start(struct touch_grab *grab,
1341 struct ivi_layout_layer *layer,
1342 const struct weston_touch_grab_interface *interface,
1343 struct weston_touch* touch)
1344{
1345 grab->grab.interface = interface;
1346 grab->layer = layer;
1347 weston_touch_start_grab(touch, &grab->grab);
1348}
1349
1350static int32_t
1351clamp(int32_t val, int32_t min, int32_t max)
1352{
1353 if (val < min)
1354 return min;
1355
1356 if (max < val)
1357 return max;
1358
1359 return val;
1360}
1361
1362static void
1363move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1364 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1365{
1366 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1367 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001368 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001369
1370 struct timespec time = {0};
1371 double grab_time = 0.0;
1372 double from_motion_time = 0.0;
1373 double pointer_v = 0.0;
1374 int32_t is_flick = 0;
1375 int32_t pos_x = 0;
1376 int32_t pos_y = 0;
1377 int page_no = 0;
1378 double end_pos = 0.0;
1379 uint32_t duration = 0;
1380
1381 clock_gettime(CLOCK_MONOTONIC, &time);
1382
1383 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1384 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1385
1386 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1387 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1388
1389 pointer_v = move->v[0];
1390
1391 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1392 if (200 < from_motion_time)
1393 pointer_v = 0.0;
1394
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001395 prop = ivi_layout_interface->get_properties_of_layer(layer);
1396 pos_x = prop->dest_x;
1397 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001398
1399 if (is_flick) {
1400 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1401 page_no = (-orgx + width / 2) / width;
1402
1403 if (pointer_v < 0.0)
1404 page_no++;
1405 else
1406 page_no--;
1407 } else {
1408 page_no = (-pos_x + width / 2) / width;
1409 }
1410
1411 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1412 end_pos = -page_no * width;
1413
1414 duration = hmi_ctrl->hmi_setting->transition_duration;
1415 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001416 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001417 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1418 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001419 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001420 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001421 hmi_ctrl->workspace_layer.width,
1422 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001423 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001424}
1425
1426static void
1427pointer_move_workspace_grab_end(struct pointer_grab *grab)
1428{
1429 struct pointer_move_grab *pnt_move_grab =
1430 (struct pointer_move_grab *)grab;
1431 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1432
1433 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1434 grab->grab.pointer->grab_x, layer);
1435
1436 weston_pointer_end_grab(grab->grab.pointer);
1437}
1438
1439static void
1440touch_move_workspace_grab_end(struct touch_grab *grab)
1441{
1442 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1443 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1444
1445 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1446 grab->grab.touch->grab_x, layer);
1447
1448 weston_touch_end_grab(grab->grab.touch);
1449}
1450
1451static void
1452pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1453{
1454}
1455
1456static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001457pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001458 uint32_t time,
1459 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001460{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001461 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001462}
1463
1464static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001465pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1466 uint32_t source)
1467{
1468 weston_pointer_send_axis_source(grab->pointer, source);
1469}
1470
1471static void
1472pointer_default_grab_frame(struct weston_pointer_grab *grab)
1473{
1474 weston_pointer_send_frame(grab->pointer);
1475}
1476
1477static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001478move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1479{
1480 struct timespec timestamp = {0};
1481 int32_t ii = 0;
1482 double dt = 0.0;
1483
1484 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1485 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1486 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1487
1488 if (dt < 1e-6)
1489 dt = 1e-6;
1490
1491 move->pre_time = timestamp;
1492
1493 for (ii = 0; ii < 2; ii++) {
1494 wl_fixed_t prepos = move->pos[ii];
1495 move->pos[ii] = pointer[ii] + move->dst[ii];
1496
1497 if (move->pos[ii] < move->rgn[0][ii]) {
1498 move->pos[ii] = move->rgn[0][ii];
1499 move->dst[ii] = move->pos[ii] - pointer[ii];
1500 } else if (move->rgn[1][ii] < move->pos[ii]) {
1501 move->pos[ii] = move->rgn[1][ii];
1502 move->dst[ii] = move->pos[ii] - pointer[ii];
1503 }
1504
1505 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1506
1507 if (!move->is_moved &&
1508 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1509 move->is_moved = 1;
1510 }
1511}
1512
1513static void
1514layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1515 wl_fixed_t pos_y)
1516{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001517 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001518 int32_t layout_pos_x = 0;
1519 int32_t layout_pos_y = 0;
1520
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001521 prop = ivi_layout_interface->get_properties_of_layer(layer);
1522
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001523 layout_pos_x = wl_fixed_to_int(pos_x);
1524 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001525 ivi_layout_interface->layer_set_destination_rectangle(layer,
1526 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001527 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001528}
1529
1530static void
1531pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001532 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001533{
1534 struct pointer_move_grab *pnt_move_grab =
1535 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001536 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001537
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001538 weston_pointer_motion_to_abs(grab->pointer, event,
1539 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001540 move_grab_update(&pnt_move_grab->move, pointer_pos);
1541 layer_set_pos(pnt_move_grab->base.layer,
1542 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001543 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001544}
1545
1546static void
1547touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1548 int touch_id, wl_fixed_t x, wl_fixed_t y)
1549{
1550 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1551
1552 if (!tch_move_grab->is_active)
1553 return;
1554
1555 wl_fixed_t pointer_pos[2] = {
1556 grab->touch->grab_x,
1557 grab->touch->grab_y
1558 };
1559
1560 move_grab_update(&tch_move_grab->move, pointer_pos);
1561 layer_set_pos(tch_move_grab->base.layer,
1562 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1563}
1564
1565static void
1566pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1567 uint32_t time, uint32_t button,
1568 uint32_t state_w)
1569{
1570 if (BTN_LEFT == button &&
1571 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1572 struct pointer_grab *pg = (struct pointer_grab *)grab;
1573
1574 pointer_move_workspace_grab_end(pg);
1575 free(grab);
1576 }
1577}
1578
1579static void
1580touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1581 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1582{
1583}
1584
1585static void
1586touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1587 int touch_id)
1588{
1589 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1590
1591 if (0 == touch_id)
1592 tch_move_grab->is_active = 0;
1593
1594 if (0 == grab->touch->num_tp) {
1595 touch_move_workspace_grab_end(&tch_move_grab->base);
1596 free(grab);
1597 }
1598}
1599
1600static void
1601pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1602{
1603 struct pointer_grab *pg = (struct pointer_grab *)grab;
1604
1605 pointer_move_workspace_grab_end(pg);
1606 free(grab);
1607}
1608
1609static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001610touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1611{
1612}
1613
1614static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001615touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1616{
1617 struct touch_grab *tg = (struct touch_grab *)grab;
1618
1619 touch_move_workspace_grab_end(tg);
1620 free(grab);
1621}
1622
1623static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1624 pointer_noop_grab_focus,
1625 pointer_move_grab_motion,
1626 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001627 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001628 pointer_default_grab_axis_source,
1629 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001630 pointer_move_workspace_grab_cancel
1631};
1632
1633static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1634 touch_nope_grab_down,
1635 touch_move_workspace_grab_up,
1636 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001637 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001638 touch_move_workspace_grab_cancel
1639};
1640
1641enum HMI_GRAB_DEVICE {
1642 HMI_GRAB_DEVICE_NONE,
1643 HMI_GRAB_DEVICE_POINTER,
1644 HMI_GRAB_DEVICE_TOUCH
1645};
1646
1647static enum HMI_GRAB_DEVICE
1648get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1649{
Derek Foreman1281a362015-07-31 16:55:32 -05001650 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1651 struct weston_touch *touch = weston_seat_get_touch(seat);
1652
1653 if (pointer &&
1654 pointer->focus &&
1655 pointer->button_count &&
1656 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001657 return HMI_GRAB_DEVICE_POINTER;
1658
Derek Foreman1281a362015-07-31 16:55:32 -05001659 if (touch &&
1660 touch->focus &&
1661 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001662 return HMI_GRAB_DEVICE_TOUCH;
1663
1664 return HMI_GRAB_DEVICE_NONE;
1665}
1666
1667static void
1668move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1669 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1670 struct wl_resource* resource)
1671{
1672 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1673 move->pre_time = move->start_time;
1674 move->pos[0] = start_pos[0];
1675 move->pos[1] = start_pos[1];
1676 move->start_pos[0] = start_pos[0];
1677 move->start_pos[1] = start_pos[1];
1678 move->dst[0] = start_pos[0] - grab_pos[0];
1679 move->dst[1] = start_pos[1] - grab_pos[1];
1680 memcpy(move->rgn, rgn, sizeof(move->rgn));
1681}
1682
1683static void
1684move_grab_init_workspace(struct move_grab* move,
1685 wl_fixed_t grab_x, wl_fixed_t grab_y,
1686 struct wl_resource *resource)
1687{
1688 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1689 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001690 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001691 int32_t workspace_count = hmi_ctrl->workspace_count;
1692 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1693 int32_t layer_pos_x = 0;
1694 int32_t layer_pos_y = 0;
1695 wl_fixed_t start_pos[2] = {0};
1696 wl_fixed_t rgn[2][2] = {{0}};
1697 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1698
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001699 prop = ivi_layout_interface->get_properties_of_layer(layer);
1700 layer_pos_x = prop->dest_x;
1701 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001702
1703 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1704 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1705
1706 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1707
1708 rgn[0][1] = wl_fixed_from_int(0);
1709 rgn[1][0] = wl_fixed_from_int(0);
1710 rgn[1][1] = wl_fixed_from_int(0);
1711
1712 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1713}
1714
1715static struct pointer_move_grab *
1716create_workspace_pointer_move(struct weston_pointer *pointer,
1717 struct wl_resource* resource)
1718{
1719 struct pointer_move_grab *pnt_move_grab =
1720 MEM_ALLOC(sizeof(*pnt_move_grab));
1721
1722 pnt_move_grab->base.resource = resource;
1723 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1724 pointer->grab_y, resource);
1725
1726 return pnt_move_grab;
1727}
1728
1729static struct touch_move_grab *
1730create_workspace_touch_move(struct weston_touch *touch,
1731 struct wl_resource* resource)
1732{
1733 struct touch_move_grab *tch_move_grab =
1734 MEM_ALLOC(sizeof(*tch_move_grab));
1735
1736 tch_move_grab->base.resource = resource;
1737 tch_move_grab->is_active = 1;
1738 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1739 touch->grab_y, resource);
1740
1741 return tch_move_grab;
1742}
1743
1744static void
1745ivi_hmi_controller_workspace_control(struct wl_client *client,
1746 struct wl_resource *resource,
1747 struct wl_resource *seat_resource,
1748 uint32_t serial)
1749{
1750 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1751 struct ivi_layout_layer *layer = NULL;
1752 struct pointer_move_grab *pnt_move_grab = NULL;
1753 struct touch_move_grab *tch_move_grab = NULL;
1754 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001755 struct weston_pointer *pointer;
1756 struct weston_touch *touch;
1757
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001758 enum HMI_GRAB_DEVICE device;
1759
1760 if (hmi_ctrl->workspace_count < 2)
1761 return;
1762
1763 seat = wl_resource_get_user_data(seat_resource);
1764 device = get_hmi_grab_device(seat, serial);
1765
1766 if (HMI_GRAB_DEVICE_POINTER != device &&
1767 HMI_GRAB_DEVICE_TOUCH != device)
1768 return;
1769
1770 layer = hmi_ctrl->workspace_layer.ivilayer;
1771
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001772 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001773
1774 switch (device) {
1775 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001776 pointer = weston_seat_get_pointer(seat);
1777 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001778 resource);
1779
1780 pointer_grab_start(&pnt_move_grab->base, layer,
1781 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001782 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001783 break;
1784
1785 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001786 touch = weston_seat_get_touch(seat);
1787 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001788 resource);
1789
1790 touch_grab_start(&tch_move_grab->base, layer,
1791 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001792 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001793 break;
1794
1795 default:
1796 break;
1797 }
1798}
1799
1800/**
1801 * Implementation of switch_mode
1802 */
1803static void
1804ivi_hmi_controller_switch_mode(struct wl_client *client,
1805 struct wl_resource *resource,
1806 uint32_t layout_mode)
1807{
1808 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1809
1810 switch_mode(hmi_ctrl, layout_mode);
1811}
1812
1813/**
1814 * Implementation of on/off displaying workspace and workspace background
1815 * ivi_layers.
1816 */
1817static void
1818ivi_hmi_controller_home(struct wl_client *client,
1819 struct wl_resource *resource,
1820 uint32_t home)
1821{
1822 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1823 uint32_t is_fade_in;
1824
1825 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1826 !hmi_ctrl->workspace_fade.is_fade_in) ||
1827 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1828 hmi_ctrl->workspace_fade.is_fade_in)) {
1829 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1830 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1831 &hmi_ctrl->workspace_fade);
1832 }
1833
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001834 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001835}
1836
1837/**
1838 * binding ivi-hmi-controller implementation
1839 */
1840static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1841 ivi_hmi_controller_UI_ready,
1842 ivi_hmi_controller_workspace_control,
1843 ivi_hmi_controller_switch_mode,
1844 ivi_hmi_controller_home
1845};
1846
1847static void
1848unbind_hmi_controller(struct wl_resource *resource)
1849{
1850}
1851
1852static void
1853bind_hmi_controller(struct wl_client *client,
1854 void *data, uint32_t version, uint32_t id)
1855{
1856 struct wl_resource *resource = NULL;
1857 struct hmi_controller *hmi_ctrl = data;
1858
1859 if (hmi_ctrl->user_interface != client) {
1860 struct wl_resource *res = wl_client_get_object(client, 1);
1861 wl_resource_post_error(res,
1862 WL_DISPLAY_ERROR_INVALID_OBJECT,
1863 "hmi-controller failed: permission denied");
1864 return;
1865 }
1866
1867 resource = wl_resource_create(
1868 client, &ivi_hmi_controller_interface, 1, id);
1869
1870 wl_resource_set_implementation(
1871 resource, &ivi_hmi_controller_implementation,
1872 hmi_ctrl, unbind_hmi_controller);
1873}
1874
1875static int32_t
1876initialize(struct hmi_controller *hmi_ctrl)
1877{
1878 struct config_command {
1879 char *key;
1880 uint32_t *dest;
1881 };
1882
1883 struct weston_config *config = hmi_ctrl->compositor->config;
1884 struct weston_config_section *section = NULL;
1885 int result = 0;
1886 int i = 0;
1887
1888 const struct config_command uint_commands[] = {
1889 { "background-id", &hmi_ctrl->ui_setting.background_id },
1890 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1891 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1892 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1893 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1894 { "random-id", &hmi_ctrl->ui_setting.random_id },
1895 { "home-id", &hmi_ctrl->ui_setting.home_id },
1896 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001897 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001898 { NULL, NULL }
1899 };
1900
1901 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1902
1903 for (i = 0; -1 != result; ++i) {
1904 const struct config_command *command = &uint_commands[i];
1905
1906 if (!command->key)
1907 break;
1908
1909 if (weston_config_section_get_uint(
1910 section, command->key, command->dest, 0) != 0)
1911 result = -1;
1912 }
1913
1914 if (-1 == result) {
1915 weston_log("Failed to initialize hmi-controller\n");
1916 return 0;
1917 }
1918
1919 return 1;
1920}
1921
1922static void
1923launch_hmi_client_process(void *data)
1924{
1925 struct hmi_controller *hmi_ctrl =
1926 (struct hmi_controller *)data;
1927
1928 hmi_ctrl->user_interface =
1929 weston_client_start(hmi_ctrl->compositor,
1930 hmi_ctrl->hmi_setting->ivi_homescreen);
1931
1932 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1933}
1934
1935/*****************************************************************************
1936 * exported functions
1937 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001938WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001939controller_module_init(struct weston_compositor *ec,
1940 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001941 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001942 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001943{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001944 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001945 struct wl_event_loop *loop = NULL;
1946
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001947 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001948 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001949 return -1;
1950 }
1951
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001952 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001953
1954 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001955 if (hmi_ctrl == NULL)
1956 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001957
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001958 if (!initialize(hmi_ctrl)) {
1959 return -1;
1960 }
1961
1962 if (wl_global_create(ec->wl_display,
1963 &ivi_hmi_controller_interface, 1,
1964 hmi_ctrl, bind_hmi_controller) == NULL) {
1965 return -1;
1966 }
1967
1968 loop = wl_display_get_event_loop(ec->wl_display);
1969 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1970
1971 return 0;
1972}