blob: 9b69dd2034d85e0fae1a805898825fc4efdffe90 [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"
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090064
65/*****************************************************************************
66 * structure, globals
67 ****************************************************************************/
68struct hmi_controller_layer {
69 struct ivi_layout_layer *ivilayer;
70 uint32_t id_layer;
71 int32_t x;
72 int32_t y;
73 int32_t width;
74 int32_t height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090075 struct wl_list link;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090076};
77
78struct link_layer {
79 struct ivi_layout_layer *layout_layer;
80 struct wl_list link;
81};
82
83struct hmi_controller_fade {
84 uint32_t is_fade_in;
85 struct wl_list layer_list;
86};
87
88struct hmi_server_setting {
89 uint32_t base_layer_id;
90 uint32_t application_layer_id;
91 uint32_t workspace_background_layer_id;
92 uint32_t workspace_layer_id;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090093 uint32_t base_layer_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090094 int32_t panel_height;
95 uint32_t transition_duration;
96 char *ivi_homescreen;
97};
98
99struct ui_setting {
100 uint32_t background_id;
101 uint32_t panel_id;
102 uint32_t tiling_id;
103 uint32_t sidebyside_id;
104 uint32_t fullscreen_id;
105 uint32_t random_id;
106 uint32_t home_id;
107 uint32_t workspace_background_id;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900108 uint32_t surface_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900109};
110
111struct hmi_controller {
112 struct hmi_server_setting *hmi_setting;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900113 /* List of struct hmi_controller_layer */
114 struct wl_list base_layer_list;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900115 struct wl_list application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900116 struct hmi_controller_layer workspace_background_layer;
117 struct hmi_controller_layer workspace_layer;
118 enum ivi_hmi_controller_layout_mode layout_mode;
119
120 struct hmi_controller_fade workspace_fade;
121
122 int32_t workspace_count;
123 struct wl_array ui_widgets;
124 int32_t is_initialized;
125
126 struct weston_compositor *compositor;
127 struct wl_listener destroy_listener;
128
129 struct wl_client *user_interface;
130 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900131
132 int32_t screen_num;
133 struct ivi_layout_screen **pp_screen;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900134};
135
136struct launcher_info {
137 uint32_t surface_id;
138 uint32_t workspace_id;
139 int32_t index;
140};
141
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000142const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900143
144int
145controller_module_init(struct weston_compositor *ec,
146 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000147 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900148 size_t interface_version);
149
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900150/*****************************************************************************
151 * local functions
152 ****************************************************************************/
153static void *
154fail_on_null(void *p, size_t size, char *file, int32_t line)
155{
156 if (size && !p) {
157 weston_log("%s(%d) %zd: out of memory\n", file, line, size);
158 exit(EXIT_FAILURE);
159 }
160
161 return p;
162}
163
164static void *
165mem_alloc(size_t size, char *file, int32_t line)
166{
167 return fail_on_null(calloc(1, size), size, file, line);
168}
169
170#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
171
172static int32_t
173is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
174 struct ivi_layout_surface *ivisurf)
175{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000176 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900177
178 uint32_t *ui_widget_id = NULL;
179 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
180 if (*ui_widget_id == id)
181 return 1;
182 }
183
184 return 0;
185}
186
187static int
188compare_launcher_info(const void *lhs, const void *rhs)
189{
190 const struct launcher_info *left = lhs;
191 const struct launcher_info *right = rhs;
192
193 if (left->workspace_id < right->workspace_id)
194 return -1;
195
196 if (left->workspace_id > right->workspace_id)
197 return 1;
198
199 if (left->index < right->index)
200 return -1;
201
202 if (left->index > right->index)
203 return 1;
204
205 return 0;
206}
207
208/**
209 * Internal methods called by mainly ivi_hmi_controller_switch_mode
210 * This reference shows 4 examples how to use ivi_layout APIs.
211 */
212static void
213mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
214 struct ivi_layout_surface **pp_surface,
215 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900216 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900217{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900218 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900219 const float surface_width = (float)layer->width * 0.25;
220 const float surface_height = (float)layer->height * 0.5;
221 int32_t surface_x = 0;
222 int32_t surface_y = 0;
223 struct ivi_layout_surface *ivisurf = NULL;
224 struct ivi_layout_surface **surfaces;
225 struct ivi_layout_surface **new_order;
226 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900227 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900228
229 int32_t i = 0;
230 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900231 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900232
233 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
234 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
235
236 for (i = 0; i < surface_length; i++) {
237 ivisurf = pp_surface[i];
238
239 /* skip ui widgets */
240 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
241 continue;
242
243 surfaces[surf_num++] = ivisurf;
244 }
245
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900246 wl_list_for_each_reverse(layer, layer_list, link) {
247 if (idx >= surf_num)
248 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900249
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900250 ivilayer = layer->ivilayer;
251
252 for (i = 0; i < 8; i++, idx++) {
253 if (idx >= surf_num)
254 break;
255
256 ivisurf = surfaces[idx];
257 new_order[i] = ivisurf;
258 if (i < 4) {
259 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900260 surface_y = 0;
261 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900262 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900263 surface_y = (int32_t)surface_height;
264 }
265
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000266 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900267 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
268 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000269 ivi_layout_interface->surface_set_visibility(ivisurf, true);
270 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900271 surface_x, surface_y,
272 (int32_t)surface_width,
273 (int32_t)surface_height);
274
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900275 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900276 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900277
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900278 ivi_layout_interface->layer_set_transition(ivilayer,
279 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
280 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900281 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900282 for (i = idx; i < surf_num; i++)
283 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900284
285 free(surfaces);
286 free(new_order);
287}
288
289static void
290mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
291 struct ivi_layout_surface **pp_surface,
292 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900293 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900294{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900295 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900296 int32_t surface_width = layer->width / 2;
297 int32_t surface_height = layer->height;
298 struct ivi_layout_surface *ivisurf = NULL;
299
300 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
301 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900302 struct ivi_layout_surface **surfaces;
303 struct ivi_layout_surface **new_order;
304 struct ivi_layout_layer *ivilayer = NULL;
305 int32_t surf_num = 0;
306 int32_t idx = 0;
307
308 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
309 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900310
311 for (i = 0; i < surface_length; i++) {
312 ivisurf = pp_surface[i];
313
314 /* skip ui widgets */
315 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
316 continue;
317
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900318 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900319 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900320
321 wl_list_for_each_reverse(layer, layer_list, link) {
322 if (idx >= surf_num)
323 break;
324
325 ivilayer = layer->ivilayer;
326
327 for (i = 0; i < 2; i++, idx++) {
328 if (idx >= surf_num)
329 break;
330
331 ivisurf = surfaces[idx];
332 new_order[i] = ivisurf;
333
334 ivi_layout_interface->surface_set_transition(ivisurf,
335 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
336 duration);
337 ivi_layout_interface->surface_set_visibility(ivisurf, true);
338
339 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
340 i * surface_width, 0,
341 surface_width,
342 surface_height);
343 }
344 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
345 }
346
347 for (i = idx; i < surf_num; i++) {
348 ivi_layout_interface->surface_set_transition(surfaces[i],
349 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
350 duration);
351 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
352 }
353
354 free(surfaces);
355 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900356}
357
358static void
359mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
360 struct ivi_layout_surface **pp_surface,
361 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900362 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900363{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900364 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900365 const int32_t surface_width = layer->width;
366 const int32_t surface_height = layer->height;
367 struct ivi_layout_surface *ivisurf = NULL;
368 int32_t i = 0;
369 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900370 int32_t surf_num = 0;
371 struct ivi_layout_surface **surfaces;
372
373 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900374
375 for (i = 0; i < surface_length; i++) {
376 ivisurf = pp_surface[i];
377
378 /* skip ui widgets */
379 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
380 continue;
381
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900382 surfaces[surf_num++] = ivisurf;
383 }
384 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
385
386 for (i = 0; i < surf_num; i++) {
387 ivisurf = surfaces[i];
388
389 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
390 layer = wl_container_of(layer->link.prev, layer, link);
391 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
392 }
393
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000394 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900395 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
396 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000397 ivi_layout_interface->surface_set_visibility(ivisurf, true);
398 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900399 surface_width,
400 surface_height);
401 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900402
403 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900404}
405
406static void
407mode_random_replace(struct hmi_controller *hmi_ctrl,
408 struct ivi_layout_surface **pp_surface,
409 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900410 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900411{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900412 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900413 const int32_t surface_width = (int32_t)(layer->width * 0.25f);
414 const int32_t surface_height = (int32_t)(layer->height * 0.25f);
415 int32_t surface_x = 0;
416 int32_t surface_y = 0;
417 struct ivi_layout_surface *ivisurf = NULL;
418 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
419 int32_t i = 0;
420
421 for (i = 0; i < surface_length; i++) {
422 ivisurf = pp_surface[i];
423
424 /* skip ui widgets */
425 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
426 continue;
427
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000428 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900429 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
430 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000431 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900432 surface_x = rand() % (layer->width - surface_width);
433 surface_y = rand() % (layer->height - surface_height);
434
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000435 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900436 surface_x,
437 surface_y,
438 surface_width,
439 surface_height);
440 }
441}
442
443static int32_t
444has_application_surface(struct hmi_controller *hmi_ctrl,
445 struct ivi_layout_surface **pp_surface,
446 int32_t surface_length)
447{
448 struct ivi_layout_surface *ivisurf = NULL;
449 int32_t i = 0;
450
451 for (i = 0; i < surface_length; i++) {
452 ivisurf = pp_surface[i];
453
454 /* skip ui widgets */
455 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
456 continue;
457
458 return 1;
459 }
460
461 return 0;
462}
463
464/**
465 * Supports 4 example to layout of application ivi_surfaces;
466 * tiling, side by side, fullscreen, and random.
467 */
468static void
469switch_mode(struct hmi_controller *hmi_ctrl,
470 enum ivi_hmi_controller_layout_mode layout_mode)
471{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900472 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900473 struct ivi_layout_surface **pp_surface = NULL;
474 int32_t surface_length = 0;
475 int32_t ret = 0;
476
477 if (!hmi_ctrl->is_initialized)
478 return;
479
480 hmi_ctrl->layout_mode = layout_mode;
481
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000482 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900483 assert(!ret);
484
485 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
486 free(pp_surface);
487 pp_surface = NULL;
488 return;
489 }
490
491 switch (layout_mode) {
492 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
493 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
494 layer);
495 break;
496 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
497 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
498 surface_length, layer);
499 break;
500 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
501 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
502 layer);
503 break;
504 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
505 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
506 layer);
507 break;
508 }
509
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000510 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900511 free(pp_surface);
512}
513
514/**
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900515 * Internal method to get screens from weston core
516 * TODO: shall support hotplug of screens
517 */
518static int32_t
519get_screens(struct hmi_controller *hmi_ctrl)
520{
521 hmi_ctrl->pp_screen = NULL;
522 hmi_ctrl->screen_num = 0;
523 ivi_layout_interface->get_screens(&hmi_ctrl->screen_num, &hmi_ctrl->pp_screen);
524
525 if (hmi_ctrl->pp_screen == NULL)
526 return -1;
527 else
528 return 0;
529}
530
531/**
532 * Internal method to get ivi_layout_screen
533 */
534static struct ivi_layout_screen *
535get_screen(int32_t screen_idx, struct hmi_controller *hmi_ctrl)
536{
537 struct ivi_layout_screen *iviscrn = NULL;
538
539 if (screen_idx > hmi_ctrl->screen_num - 1)
540 weston_log("Invalid index. Return NULL\n");
541 else
542 iviscrn = hmi_ctrl->pp_screen[screen_idx];
543
544 return iviscrn;
545}
546
547/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900548 * Internal method for transition
549 */
550static void
551hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
552 struct hmi_controller_fade *fade)
553{
554 double tint = is_fade_in ? 1.0 : 0.0;
555 struct link_layer *linklayer = NULL;
556 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
557
558 fade->is_fade_in = is_fade_in;
559
560 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000561 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900562 IVI_LAYOUT_TRANSITION_LAYER_FADE,
563 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000564 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900565 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900566 }
567}
568
569/**
570 * Internal method to create ivi_layer with hmi_controller_layer and
571 * add to a ivi_screen
572 */
573static void
574create_layer(struct ivi_layout_screen *iviscrn,
575 struct hmi_controller_layer *layer)
576{
577 int32_t ret = 0;
578
579 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000580 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900581 layer->width,
582 layer->height);
583 assert(layer->ivilayer != NULL);
584
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000585 ret = ivi_layout_interface->screen_add_layer(iviscrn, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900586 assert(!ret);
587
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000588 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900589 layer->x, layer->y,
590 layer->width,
591 layer->height);
592 assert(!ret);
593
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000594 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900595 assert(!ret);
596}
597
598/**
599 * Internal set notification
600 */
601static void
602set_notification_create_surface(struct ivi_layout_surface *ivisurf,
603 void *userdata)
604{
605 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900606 struct hmi_controller_layer *layer_link =
607 wl_container_of(hmi_ctrl->application_layer_list.prev,
608 layer_link,
609 link);
610 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900611 int32_t ret = 0;
612
613 /* skip ui widgets */
614 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
615 return;
616
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000617 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900618 assert(!ret);
619}
620
621static void
622set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
623 void *userdata)
624{
625 struct hmi_controller *hmi_ctrl = userdata;
626
627 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
628}
629
630static void
631set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
632 void *userdata)
633{
634 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900635 struct hmi_controller_layer *layer_link = NULL;
636 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900637 struct weston_surface *surface;
638 struct ivi_layout_surface **ivisurfs;
639 int32_t length = 0;
640 int32_t i;
641
642 /* return if the surface is not application content */
643 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
644 return;
645 }
646
647 /*
648 * if application changes size of wl_buffer. The source rectangle shall be
649 * fit to the size.
650 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000651 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900652 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000653 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900654 ivisurf, 0, 0, surface->width,
655 surface->height);
656 }
657
658 /*
659 * search if the surface is already added to layer.
660 * If not yet, it is newly invoded application to go to switch_mode.
661 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900662 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
663 application_layer = layer_link->ivilayer;
664 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900665 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900666 for (i = 0; i < length; i++) {
667 if (ivisurf == ivisurfs[i]) {
668 /*
669 * if it is non new invoked application, just call
670 * commit_changes to apply source_rectangle.
671 */
672 ivi_layout_interface->commit_changes();
673 return;
674 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900675 }
676 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900677
678 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
679}
680
681/**
682 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
683 * corresponding ivi_layer are defined in weston.ini. Default scene graph
684 * of ivi_layers are initialized in hmi_controller_create
685 */
686static struct hmi_server_setting *
687hmi_server_setting_create(struct weston_compositor *ec)
688{
689 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
690 struct weston_config *config = ec->config;
691 struct weston_config_section *shell_section = NULL;
692
693 shell_section = weston_config_get_section(config, "ivi-shell",
694 NULL, NULL);
695
696 weston_config_section_get_uint(shell_section, "base-layer-id",
697 &setting->base_layer_id, 1000);
698
699 weston_config_section_get_uint(shell_section,
700 "workspace-background-layer-id",
701 &setting->workspace_background_layer_id,
702 2000);
703
704 weston_config_section_get_uint(shell_section, "workspace-layer-id",
705 &setting->workspace_layer_id, 3000);
706
707 weston_config_section_get_uint(shell_section, "application-layer-id",
708 &setting->application_layer_id, 4000);
709
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900710 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
711 &setting->base_layer_id_offset, 10000);
712
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900713 weston_config_section_get_uint(shell_section, "transition-duration",
714 &setting->transition_duration, 300);
715
716 setting->panel_height = 70;
717
718 weston_config_section_get_string(shell_section,
719 "ivi-shell-user-interface",
720 &setting->ivi_homescreen, NULL);
721
722 return setting;
723}
724
725static void
726hmi_controller_destroy(struct wl_listener *listener, void *data)
727{
728 struct link_layer *link = NULL;
729 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900730 struct hmi_controller_layer *ctrl_layer_link = NULL;
731 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900732 struct hmi_controller *hmi_ctrl =
733 container_of(listener, struct hmi_controller, destroy_listener);
734
735 wl_list_for_each_safe(link, next,
736 &hmi_ctrl->workspace_fade.layer_list, link) {
737 wl_list_remove(&link->link);
738 free(link);
739 }
740
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900741 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900742 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
743 &hmi_ctrl->base_layer_list, link) {
744 wl_list_remove(&ctrl_layer_link->link);
745 free(ctrl_layer_link);
746 }
747
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900748 /* clear application_layer_list */
749 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
750 &hmi_ctrl->application_layer_list, link) {
751 wl_list_remove(&ctrl_layer_link->link);
752 free(ctrl_layer_link);
753 }
754
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900755 wl_array_release(&hmi_ctrl->ui_widgets);
756 free(hmi_ctrl->hmi_setting);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900757 free(hmi_ctrl->pp_screen);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900758 free(hmi_ctrl);
759}
760
761/**
762 * This is a starting method called from module_init.
763 * This sets up scene graph of ivi_layers; base, application, workspace
764 * background, and workspace. These ivi_layers are created/added to
765 * ivi_screen in create_layer
766 *
767 * base: to group ivi_surfaces of panel and background
768 * application: to group ivi_surfaces of ivi_applications
769 * workspace background: to group a ivi_surface of background in workspace
770 * workspace: to group ivi_surfaces for launching ivi_applications
771 *
772 * ivi_layers of workspace background and workspace is set to invisible at
773 * first. The properties of it is updated with animation when
774 * ivi_hmi_controller_home is requested.
775 */
776static struct hmi_controller *
777hmi_controller_create(struct weston_compositor *ec)
778{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900779 struct ivi_layout_screen *iviscrn = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900780 int32_t screen_width = 0;
781 int32_t screen_height = 0;
782 struct link_layer *tmp_link_layer = NULL;
783 int32_t panel_height = 0;
784 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900785 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900786 struct hmi_controller_layer *application_layer = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900787
788 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900789
790 wl_array_init(&hmi_ctrl->ui_widgets);
791 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
792 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
793 hmi_ctrl->compositor = ec;
794
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900795 /* TODO: shall support hotplug of screens */
796 if (get_screens(hmi_ctrl) < 0) {
797 weston_log("ivi-shell: Failed to get screens\n");
798 hmi_ctrl = NULL;
799 return hmi_ctrl;
800 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900801
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900802 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900803
804 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900805 wl_list_init(&hmi_ctrl->base_layer_list);
806 for (i = 0; i < hmi_ctrl->screen_num; i++) {
807 ivi_layout_interface->get_screen_resolution(get_screen(i, hmi_ctrl),
808 &screen_width,
809 &screen_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900810
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900811 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
812 base_layer->x = 0;
813 base_layer->y = 0;
814 base_layer->width = screen_width;
815 base_layer->height = screen_height;
816 base_layer->id_layer =
817 hmi_ctrl->hmi_setting->base_layer_id +
818 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
819 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900820
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900821 create_layer(get_screen(i, hmi_ctrl), base_layer);
822 }
823
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900824 panel_height = hmi_ctrl->hmi_setting->panel_height;
825
826 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900827 wl_list_init(&hmi_ctrl->application_layer_list);
828 for (i = 0; i < hmi_ctrl->screen_num; i++) {
829 ivi_layout_interface->get_screen_resolution(get_screen(i, hmi_ctrl),
830 &screen_width,
831 &screen_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900832
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900833 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
834 application_layer->x = 0;
835 application_layer->y = 0;
836 application_layer->width = screen_width;
837 application_layer->height = screen_height - panel_height;
838 application_layer->id_layer =
839 hmi_ctrl->hmi_setting->application_layer_id +
840 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
841 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
842
843 create_layer(get_screen(i, hmi_ctrl), application_layer);
844 }
845
846 ivi_layout_interface->get_screen_resolution(iviscrn, &screen_width,
847 &screen_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900848
849 /* init workspace background ivi_layer */
850 hmi_ctrl->workspace_background_layer.x = 0;
851 hmi_ctrl->workspace_background_layer.y = 0;
852 hmi_ctrl->workspace_background_layer.width = screen_width;
853 hmi_ctrl->workspace_background_layer.height =
854 screen_height - panel_height;
855
856 hmi_ctrl->workspace_background_layer.id_layer =
857 hmi_ctrl->hmi_setting->workspace_background_layer_id;
858
859 create_layer(iviscrn, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000860 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900861 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000862 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900863 hmi_ctrl->workspace_background_layer.ivilayer, false);
864
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900865
866 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
867 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900868 tmp_link_layer->layout_layer =
869 hmi_ctrl->workspace_background_layer.ivilayer;
870 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
871 &tmp_link_layer->link);
872
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000873 ivi_layout_interface->add_notification_create_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900874 set_notification_create_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000875 ivi_layout_interface->add_notification_remove_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900876 set_notification_remove_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000877 ivi_layout_interface->add_notification_configure_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900878 set_notification_configure_surface, hmi_ctrl);
879
880 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
881 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
882 &hmi_ctrl->destroy_listener);
883
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900884 return hmi_ctrl;
885}
886
887/**
888 * Implementations of ivi-hmi-controller.xml
889 */
890
891/**
892 * A ivi_surface drawing background is identified by id_surface.
893 * Properties of the ivi_surface is set by using ivi_layout APIs according to
894 * the scene graph of UI defined in hmi_controller_create.
895 *
896 * UI ivi_layer is used to add this ivi_surface.
897 */
898static void
899ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
900 uint32_t id_surface)
901{
902 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900903 struct hmi_controller_layer *base_layer = NULL;
904 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900905 struct hmi_controller_layer *application_layer =
906 wl_container_of(hmi_ctrl->application_layer_list.prev,
907 application_layer,
908 link);
909 const int32_t dstx = application_layer->x;
910 const int32_t dsty = application_layer->y;
911 const int32_t width = application_layer->width;
912 const int32_t height = application_layer->height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900913 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900914 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900915
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900916 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
917 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
918 sizeof(*add_surface_id));
919 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900920
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900921 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900922
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900923 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
924 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900925
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900926 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
927 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900928
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900929 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
930 dstx, dsty, width, height);
931 assert(!ret);
932
933 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
934 assert(!ret);
935
936 i++;
937 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900938}
939
940/**
941 * A ivi_surface drawing panel is identified by id_surface.
942 * Properties of the ivi_surface is set by using ivi_layout APIs according to
943 * the scene graph of UI defined in hmi_controller_create.
944 *
945 * UI ivi_layer is used to add this ivi_surface.
946 */
947static void
948ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
949 uint32_t id_surface)
950{
951 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900952 struct hmi_controller_layer *base_layer =
953 wl_container_of(hmi_ctrl->base_layer_list.prev,
954 base_layer,
955 link);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900956 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900957 const int32_t width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900958 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900959 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900960 const int32_t dstx = 0;
961 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900962 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900963
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900964 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
965 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
966 sizeof(*add_surface_id));
967 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900968
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900969 ivilayer = base_layer->ivilayer;
970 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
971 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900972
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900973 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
974 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900975
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900976 dsty = base_layer->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900977
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900978 ret = ivi_layout_interface->surface_set_destination_rectangle(
979 ivisurf, dstx, dsty, width, panel_height);
980 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900981
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900982 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
983 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900984
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900985 i++;
986 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900987}
988
989/**
990 * A ivi_surface drawing buttons in panel is identified by id_surface.
991 * It can set several buttons. Properties of the ivi_surface is set by
992 * using ivi_layout APIs according to the scene graph of UI defined in
993 * hmi_controller_create. Additionally, the position of it is shifted to
994 * right when new one is requested.
995 *
996 * UI ivi_layer is used to add these ivi_surfaces.
997 */
998static void
999ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
1000 uint32_t id_surface, int32_t number)
1001{
1002 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001003 struct hmi_controller_layer *base_layer =
1004 wl_container_of(hmi_ctrl->base_layer_list.prev,
1005 base_layer,
1006 link);
1007 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001008 const int32_t width = 48;
1009 const int32_t height = 48;
1010 int32_t ret = 0;
1011 int32_t panel_height = 0;
1012 int32_t dstx = 0;
1013 int32_t dsty = 0;
1014 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1015 sizeof(*add_surface_id));
1016 *add_surface_id = id_surface;
1017
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001018 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001019 assert(ivisurf != NULL);
1020
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001021 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001022 assert(!ret);
1023
1024 panel_height = hmi_ctrl->hmi_setting->panel_height;
1025
1026 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001027 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001028
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001029 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001030 ivisurf,dstx, dsty, width, height);
1031 assert(!ret);
1032
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001033 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001034 assert(!ret);
1035}
1036
1037/**
1038 * A ivi_surface drawing home button in panel is identified by id_surface.
1039 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1040 * the scene graph of UI defined in hmi_controller_create.
1041 *
1042 * UI ivi_layer is used to add these ivi_surfaces.
1043 */
1044static void
1045ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1046 uint32_t id_surface)
1047{
1048 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001049 struct hmi_controller_layer *base_layer =
1050 wl_container_of(hmi_ctrl->base_layer_list.prev,
1051 base_layer,
1052 link);
1053 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001054 int32_t ret = 0;
1055 int32_t size = 48;
1056 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001057 const int32_t dstx = (base_layer->width - size) / 2;
1058 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001059
1060 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1061 sizeof(*add_surface_id));
1062 *add_surface_id = id_surface;
1063
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001064 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001065 assert(ivisurf != NULL);
1066
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001067 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001068 assert(!ret);
1069
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001070 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001071 ivisurf, dstx, dsty, size, size);
1072 assert(!ret);
1073
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001074 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001075 assert(!ret);
1076}
1077
1078/**
1079 * A ivi_surface drawing background of workspace is identified by id_surface.
1080 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1081 * the scene graph of UI defined in hmi_controller_create.
1082 *
1083 * A ivi_layer of workspace_background is used to add this ivi_surface.
1084 */
1085static void
1086ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1087 uint32_t id_surface)
1088{
1089 struct ivi_layout_surface *ivisurf = NULL;
1090 struct ivi_layout_layer *ivilayer = NULL;
1091 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1092 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1093 int32_t ret = 0;
1094
1095 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1096 sizeof(*add_surface_id));
1097 *add_surface_id = id_surface;
1098 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1099
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001100 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001101 assert(ivisurf != NULL);
1102
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001103 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001104 assert(!ret);
1105
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001106 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001107 0, 0, width, height);
1108 assert(!ret);
1109
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001110 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001111 assert(!ret);
1112}
1113
1114/**
1115 * A list of ivi_surfaces drawing launchers in workspace is identified by
1116 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1117 * APIs according to the scene graph of UI defined in hmi_controller_create.
1118 *
1119 * The workspace can have several pages to group ivi_surfaces of launcher.
1120 * Each call of this interface increments a number of page to add a group
1121 * of ivi_surfaces
1122 */
1123static void
1124ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1125 int32_t icon_size)
1126{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001127 int32_t minspace_x = 10;
1128 int32_t minspace_y = minspace_x;
1129
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001130 int32_t width = hmi_ctrl->workspace_background_layer.width;
1131 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001132
1133 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1134 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1135 float fcell_size_x = icon_size + space_x;
1136
1137 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1138 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1139 float fcell_size_y = icon_size + space_y;
1140
1141 struct weston_config *config = NULL;
1142 struct weston_config_section *section = NULL;
1143 const char *name = NULL;
1144 int launcher_count = 0;
1145 struct wl_array launchers;
1146 int32_t nx = 0;
1147 int32_t ny = 0;
1148 int32_t prev = -1;
1149 struct launcher_info *data = NULL;
1150
1151 uint32_t surfaceid = 0;
1152 uint32_t workspaceid = 0;
1153 struct launcher_info *info = NULL;
1154
1155 int32_t x = 0;
1156 int32_t y = 0;
1157 int32_t ret = 0;
1158 struct ivi_layout_surface* layout_surface = NULL;
1159 uint32_t *add_surface_id = NULL;
1160
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001161 struct ivi_layout_screen *iviscrn = NULL;
1162 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001163
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001164 if (0 == x_count)
1165 x_count = 1;
1166
1167 if (0 == y_count)
1168 y_count = 1;
1169
1170 config = hmi_ctrl->compositor->config;
1171 if (!config)
1172 return;
1173
1174 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1175 if (!section)
1176 return;
1177
1178 wl_array_init(&launchers);
1179
1180 while (weston_config_next_section(config, &section, &name)) {
1181 surfaceid = 0;
1182 workspaceid = 0;
1183 info = NULL;
1184 if (0 != strcmp(name, "ivi-launcher"))
1185 continue;
1186
1187 if (0 != weston_config_section_get_uint(section, "icon-id",
1188 &surfaceid, 0))
1189 continue;
1190
1191 if (0 != weston_config_section_get_uint(section,
1192 "workspace-id",
1193 &workspaceid, 0))
1194 continue;
1195
1196 info = wl_array_add(&launchers, sizeof(*info));
1197
1198 if (info) {
1199 info->surface_id = surfaceid;
1200 info->workspace_id = workspaceid;
1201 info->index = launcher_count;
1202 ++launcher_count;
1203 }
1204 }
1205
1206 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1207 compare_launcher_info);
1208
1209 wl_array_for_each(data, &launchers) {
1210 x = 0;
1211 y = 0;
1212 ret = 0;
1213 layout_surface = NULL;
1214 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1215 sizeof(*add_surface_id));
1216
1217 *add_surface_id = data->surface_id;
1218
1219 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1220 nx = 0;
1221 ny = 0;
1222 prev = data->workspace_id;
1223
1224 if (0 <= prev)
1225 hmi_ctrl->workspace_count++;
1226 }
1227
1228 if (y_count == ny) {
1229 ny = 0;
1230 hmi_ctrl->workspace_count++;
1231 }
1232
1233 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1234 y = ny * fcell_size_y + space_y;
1235
1236 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001237 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001238 assert(layout_surface);
1239
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001240 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001241 layout_surface, x, y, icon_size, icon_size);
1242 assert(!ret);
1243
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001244 nx++;
1245
1246 if (x_count == nx) {
1247 ny++;
1248 nx = 0;
1249 }
1250 }
1251
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001252 /* init workspace ivi_layer */
1253 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1254 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1255 hmi_ctrl->workspace_layer.width =
1256 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1257 hmi_ctrl->workspace_layer.height =
1258 hmi_ctrl->workspace_background_layer.height;
1259 hmi_ctrl->workspace_layer.id_layer =
1260 hmi_ctrl->hmi_setting->workspace_layer_id;
1261
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001262 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001263 create_layer(iviscrn, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001264 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1265 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001266 false);
1267
1268 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1269 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1270 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1271 &tmp_link_layer->link);
1272
1273 /* Add surface to layer */
1274 wl_array_for_each(data, &launchers) {
1275 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001276 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001277 assert(layout_surface);
1278
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001279 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001280 layout_surface);
1281 assert(!ret);
1282
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001283 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001284 assert(!ret);
1285 }
1286
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001287 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001288 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001289}
1290
1291static void
1292ivi_hmi_controller_UI_ready(struct wl_client *client,
1293 struct wl_resource *resource)
1294{
1295 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1296
1297 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1298 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1299 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1300 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1301 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1302 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1303 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1304 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001305 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001306
1307 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1308 hmi_ctrl->is_initialized = 1;
1309}
1310
1311/**
1312 * Implementation of request and event of ivi_hmi_controller_workspace_control
1313 * and controlling workspace.
1314 *
1315 * When motion of input is detected in a ivi_surface of workspace background,
1316 * ivi_hmi_controller_workspace_control shall be invoked and to start
1317 * controlling of workspace. The workspace has several pages to show several
1318 * groups of applications.
1319 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1320 * according to motion. When motion finished, e.g. touch up detected, control is
1321 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1322 */
1323struct pointer_grab {
1324 struct weston_pointer_grab grab;
1325 struct ivi_layout_layer *layer;
1326 struct wl_resource *resource;
1327};
1328
1329struct touch_grab {
1330 struct weston_touch_grab grab;
1331 struct ivi_layout_layer *layer;
1332 struct wl_resource *resource;
1333};
1334
1335struct move_grab {
1336 wl_fixed_t dst[2];
1337 wl_fixed_t rgn[2][2];
1338 double v[2];
1339 struct timespec start_time;
1340 struct timespec pre_time;
1341 wl_fixed_t start_pos[2];
1342 wl_fixed_t pos[2];
1343 int32_t is_moved;
1344};
1345
1346struct pointer_move_grab {
1347 struct pointer_grab base;
1348 struct move_grab move;
1349};
1350
1351struct touch_move_grab {
1352 struct touch_grab base;
1353 struct move_grab move;
1354 int32_t is_active;
1355};
1356
1357static void
1358pointer_grab_start(struct pointer_grab *grab,
1359 struct ivi_layout_layer *layer,
1360 const struct weston_pointer_grab_interface *interface,
1361 struct weston_pointer *pointer)
1362{
1363 grab->grab.interface = interface;
1364 grab->layer = layer;
1365 weston_pointer_start_grab(pointer, &grab->grab);
1366}
1367
1368static void
1369touch_grab_start(struct touch_grab *grab,
1370 struct ivi_layout_layer *layer,
1371 const struct weston_touch_grab_interface *interface,
1372 struct weston_touch* touch)
1373{
1374 grab->grab.interface = interface;
1375 grab->layer = layer;
1376 weston_touch_start_grab(touch, &grab->grab);
1377}
1378
1379static int32_t
1380clamp(int32_t val, int32_t min, int32_t max)
1381{
1382 if (val < min)
1383 return min;
1384
1385 if (max < val)
1386 return max;
1387
1388 return val;
1389}
1390
1391static void
1392move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1393 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1394{
1395 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1396 int32_t width = hmi_ctrl->workspace_background_layer.width;
1397
1398 struct timespec time = {0};
1399 double grab_time = 0.0;
1400 double from_motion_time = 0.0;
1401 double pointer_v = 0.0;
1402 int32_t is_flick = 0;
1403 int32_t pos_x = 0;
1404 int32_t pos_y = 0;
1405 int page_no = 0;
1406 double end_pos = 0.0;
1407 uint32_t duration = 0;
1408
1409 clock_gettime(CLOCK_MONOTONIC, &time);
1410
1411 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1412 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1413
1414 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1415 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1416
1417 pointer_v = move->v[0];
1418
1419 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1420 if (200 < from_motion_time)
1421 pointer_v = 0.0;
1422
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001423 ivi_layout_interface->layer_get_position(layer, &pos_x, &pos_y);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001424
1425
1426 if (is_flick) {
1427 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1428 page_no = (-orgx + width / 2) / width;
1429
1430 if (pointer_v < 0.0)
1431 page_no++;
1432 else
1433 page_no--;
1434 } else {
1435 page_no = (-pos_x + width / 2) / width;
1436 }
1437
1438 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1439 end_pos = -page_no * width;
1440
1441 duration = hmi_ctrl->hmi_setting->transition_duration;
1442 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001443 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001444 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1445 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001446 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001447 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001448 hmi_ctrl->workspace_layer.width,
1449 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001450 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001451}
1452
1453static void
1454pointer_move_workspace_grab_end(struct pointer_grab *grab)
1455{
1456 struct pointer_move_grab *pnt_move_grab =
1457 (struct pointer_move_grab *)grab;
1458 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1459
1460 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1461 grab->grab.pointer->grab_x, layer);
1462
1463 weston_pointer_end_grab(grab->grab.pointer);
1464}
1465
1466static void
1467touch_move_workspace_grab_end(struct touch_grab *grab)
1468{
1469 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1470 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1471
1472 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1473 grab->grab.touch->grab_x, layer);
1474
1475 weston_touch_end_grab(grab->grab.touch);
1476}
1477
1478static void
1479pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1480{
1481}
1482
1483static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001484pointer_default_grab_axis(struct weston_pointer_grab *grab,
1485 uint32_t time, uint32_t axis, wl_fixed_t value)
1486{
1487 weston_pointer_send_axis(grab->pointer, time, axis, value);
1488}
1489
1490static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001491move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1492{
1493 struct timespec timestamp = {0};
1494 int32_t ii = 0;
1495 double dt = 0.0;
1496
1497 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1498 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1499 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1500
1501 if (dt < 1e-6)
1502 dt = 1e-6;
1503
1504 move->pre_time = timestamp;
1505
1506 for (ii = 0; ii < 2; ii++) {
1507 wl_fixed_t prepos = move->pos[ii];
1508 move->pos[ii] = pointer[ii] + move->dst[ii];
1509
1510 if (move->pos[ii] < move->rgn[0][ii]) {
1511 move->pos[ii] = move->rgn[0][ii];
1512 move->dst[ii] = move->pos[ii] - pointer[ii];
1513 } else if (move->rgn[1][ii] < move->pos[ii]) {
1514 move->pos[ii] = move->rgn[1][ii];
1515 move->dst[ii] = move->pos[ii] - pointer[ii];
1516 }
1517
1518 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1519
1520 if (!move->is_moved &&
1521 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1522 move->is_moved = 1;
1523 }
1524}
1525
1526static void
1527layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1528 wl_fixed_t pos_y)
1529{
1530 int32_t layout_pos_x = 0;
1531 int32_t layout_pos_y = 0;
1532
1533 layout_pos_x = wl_fixed_to_int(pos_x);
1534 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001535 ivi_layout_interface->layer_set_position(layer, layout_pos_x, layout_pos_y);
1536 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001537}
1538
1539static void
1540pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001541 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001542{
1543 struct pointer_move_grab *pnt_move_grab =
1544 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001545 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001546
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001547 weston_pointer_motion_to_abs(grab->pointer, event,
1548 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001549 move_grab_update(&pnt_move_grab->move, pointer_pos);
1550 layer_set_pos(pnt_move_grab->base.layer,
1551 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001552 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001553}
1554
1555static void
1556touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1557 int touch_id, wl_fixed_t x, wl_fixed_t y)
1558{
1559 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1560
1561 if (!tch_move_grab->is_active)
1562 return;
1563
1564 wl_fixed_t pointer_pos[2] = {
1565 grab->touch->grab_x,
1566 grab->touch->grab_y
1567 };
1568
1569 move_grab_update(&tch_move_grab->move, pointer_pos);
1570 layer_set_pos(tch_move_grab->base.layer,
1571 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1572}
1573
1574static void
1575pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1576 uint32_t time, uint32_t button,
1577 uint32_t state_w)
1578{
1579 if (BTN_LEFT == button &&
1580 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1581 struct pointer_grab *pg = (struct pointer_grab *)grab;
1582
1583 pointer_move_workspace_grab_end(pg);
1584 free(grab);
1585 }
1586}
1587
1588static void
1589touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1590 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1591{
1592}
1593
1594static void
1595touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1596 int touch_id)
1597{
1598 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1599
1600 if (0 == touch_id)
1601 tch_move_grab->is_active = 0;
1602
1603 if (0 == grab->touch->num_tp) {
1604 touch_move_workspace_grab_end(&tch_move_grab->base);
1605 free(grab);
1606 }
1607}
1608
1609static void
1610pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1611{
1612 struct pointer_grab *pg = (struct pointer_grab *)grab;
1613
1614 pointer_move_workspace_grab_end(pg);
1615 free(grab);
1616}
1617
1618static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001619touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1620{
1621}
1622
1623static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001624touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1625{
1626 struct touch_grab *tg = (struct touch_grab *)grab;
1627
1628 touch_move_workspace_grab_end(tg);
1629 free(grab);
1630}
1631
1632static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1633 pointer_noop_grab_focus,
1634 pointer_move_grab_motion,
1635 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001636 pointer_default_grab_axis,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001637 pointer_move_workspace_grab_cancel
1638};
1639
1640static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1641 touch_nope_grab_down,
1642 touch_move_workspace_grab_up,
1643 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001644 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001645 touch_move_workspace_grab_cancel
1646};
1647
1648enum HMI_GRAB_DEVICE {
1649 HMI_GRAB_DEVICE_NONE,
1650 HMI_GRAB_DEVICE_POINTER,
1651 HMI_GRAB_DEVICE_TOUCH
1652};
1653
1654static enum HMI_GRAB_DEVICE
1655get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1656{
Derek Foreman1281a362015-07-31 16:55:32 -05001657 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1658 struct weston_touch *touch = weston_seat_get_touch(seat);
1659
1660 if (pointer &&
1661 pointer->focus &&
1662 pointer->button_count &&
1663 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001664 return HMI_GRAB_DEVICE_POINTER;
1665
Derek Foreman1281a362015-07-31 16:55:32 -05001666 if (touch &&
1667 touch->focus &&
1668 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001669 return HMI_GRAB_DEVICE_TOUCH;
1670
1671 return HMI_GRAB_DEVICE_NONE;
1672}
1673
1674static void
1675move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1676 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1677 struct wl_resource* resource)
1678{
1679 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1680 move->pre_time = move->start_time;
1681 move->pos[0] = start_pos[0];
1682 move->pos[1] = start_pos[1];
1683 move->start_pos[0] = start_pos[0];
1684 move->start_pos[1] = start_pos[1];
1685 move->dst[0] = start_pos[0] - grab_pos[0];
1686 move->dst[1] = start_pos[1] - grab_pos[1];
1687 memcpy(move->rgn, rgn, sizeof(move->rgn));
1688}
1689
1690static void
1691move_grab_init_workspace(struct move_grab* move,
1692 wl_fixed_t grab_x, wl_fixed_t grab_y,
1693 struct wl_resource *resource)
1694{
1695 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1696 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
1697 int32_t workspace_count = hmi_ctrl->workspace_count;
1698 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1699 int32_t layer_pos_x = 0;
1700 int32_t layer_pos_y = 0;
1701 wl_fixed_t start_pos[2] = {0};
1702 wl_fixed_t rgn[2][2] = {{0}};
1703 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1704
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001705 ivi_layout_interface->layer_get_position(layer, &layer_pos_x, &layer_pos_y);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001706
1707 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1708 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1709
1710 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1711
1712 rgn[0][1] = wl_fixed_from_int(0);
1713 rgn[1][0] = wl_fixed_from_int(0);
1714 rgn[1][1] = wl_fixed_from_int(0);
1715
1716 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1717}
1718
1719static struct pointer_move_grab *
1720create_workspace_pointer_move(struct weston_pointer *pointer,
1721 struct wl_resource* resource)
1722{
1723 struct pointer_move_grab *pnt_move_grab =
1724 MEM_ALLOC(sizeof(*pnt_move_grab));
1725
1726 pnt_move_grab->base.resource = resource;
1727 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1728 pointer->grab_y, resource);
1729
1730 return pnt_move_grab;
1731}
1732
1733static struct touch_move_grab *
1734create_workspace_touch_move(struct weston_touch *touch,
1735 struct wl_resource* resource)
1736{
1737 struct touch_move_grab *tch_move_grab =
1738 MEM_ALLOC(sizeof(*tch_move_grab));
1739
1740 tch_move_grab->base.resource = resource;
1741 tch_move_grab->is_active = 1;
1742 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1743 touch->grab_y, resource);
1744
1745 return tch_move_grab;
1746}
1747
1748static void
1749ivi_hmi_controller_workspace_control(struct wl_client *client,
1750 struct wl_resource *resource,
1751 struct wl_resource *seat_resource,
1752 uint32_t serial)
1753{
1754 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1755 struct ivi_layout_layer *layer = NULL;
1756 struct pointer_move_grab *pnt_move_grab = NULL;
1757 struct touch_move_grab *tch_move_grab = NULL;
1758 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001759 struct weston_pointer *pointer;
1760 struct weston_touch *touch;
1761
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001762 enum HMI_GRAB_DEVICE device;
1763
1764 if (hmi_ctrl->workspace_count < 2)
1765 return;
1766
1767 seat = wl_resource_get_user_data(seat_resource);
1768 device = get_hmi_grab_device(seat, serial);
1769
1770 if (HMI_GRAB_DEVICE_POINTER != device &&
1771 HMI_GRAB_DEVICE_TOUCH != device)
1772 return;
1773
1774 layer = hmi_ctrl->workspace_layer.ivilayer;
1775
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001776 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001777
1778 switch (device) {
1779 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001780 pointer = weston_seat_get_pointer(seat);
1781 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001782 resource);
1783
1784 pointer_grab_start(&pnt_move_grab->base, layer,
1785 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001786 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001787 break;
1788
1789 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001790 touch = weston_seat_get_touch(seat);
1791 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001792 resource);
1793
1794 touch_grab_start(&tch_move_grab->base, layer,
1795 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001796 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001797 break;
1798
1799 default:
1800 break;
1801 }
1802}
1803
1804/**
1805 * Implementation of switch_mode
1806 */
1807static void
1808ivi_hmi_controller_switch_mode(struct wl_client *client,
1809 struct wl_resource *resource,
1810 uint32_t layout_mode)
1811{
1812 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1813
1814 switch_mode(hmi_ctrl, layout_mode);
1815}
1816
1817/**
1818 * Implementation of on/off displaying workspace and workspace background
1819 * ivi_layers.
1820 */
1821static void
1822ivi_hmi_controller_home(struct wl_client *client,
1823 struct wl_resource *resource,
1824 uint32_t home)
1825{
1826 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1827 uint32_t is_fade_in;
1828
1829 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1830 !hmi_ctrl->workspace_fade.is_fade_in) ||
1831 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1832 hmi_ctrl->workspace_fade.is_fade_in)) {
1833 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1834 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1835 &hmi_ctrl->workspace_fade);
1836 }
1837
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001838 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001839}
1840
1841/**
1842 * binding ivi-hmi-controller implementation
1843 */
1844static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1845 ivi_hmi_controller_UI_ready,
1846 ivi_hmi_controller_workspace_control,
1847 ivi_hmi_controller_switch_mode,
1848 ivi_hmi_controller_home
1849};
1850
1851static void
1852unbind_hmi_controller(struct wl_resource *resource)
1853{
1854}
1855
1856static void
1857bind_hmi_controller(struct wl_client *client,
1858 void *data, uint32_t version, uint32_t id)
1859{
1860 struct wl_resource *resource = NULL;
1861 struct hmi_controller *hmi_ctrl = data;
1862
1863 if (hmi_ctrl->user_interface != client) {
1864 struct wl_resource *res = wl_client_get_object(client, 1);
1865 wl_resource_post_error(res,
1866 WL_DISPLAY_ERROR_INVALID_OBJECT,
1867 "hmi-controller failed: permission denied");
1868 return;
1869 }
1870
1871 resource = wl_resource_create(
1872 client, &ivi_hmi_controller_interface, 1, id);
1873
1874 wl_resource_set_implementation(
1875 resource, &ivi_hmi_controller_implementation,
1876 hmi_ctrl, unbind_hmi_controller);
1877}
1878
1879static int32_t
1880initialize(struct hmi_controller *hmi_ctrl)
1881{
1882 struct config_command {
1883 char *key;
1884 uint32_t *dest;
1885 };
1886
1887 struct weston_config *config = hmi_ctrl->compositor->config;
1888 struct weston_config_section *section = NULL;
1889 int result = 0;
1890 int i = 0;
1891
1892 const struct config_command uint_commands[] = {
1893 { "background-id", &hmi_ctrl->ui_setting.background_id },
1894 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1895 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1896 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1897 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1898 { "random-id", &hmi_ctrl->ui_setting.random_id },
1899 { "home-id", &hmi_ctrl->ui_setting.home_id },
1900 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001901 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001902 { NULL, NULL }
1903 };
1904
1905 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1906
1907 for (i = 0; -1 != result; ++i) {
1908 const struct config_command *command = &uint_commands[i];
1909
1910 if (!command->key)
1911 break;
1912
1913 if (weston_config_section_get_uint(
1914 section, command->key, command->dest, 0) != 0)
1915 result = -1;
1916 }
1917
1918 if (-1 == result) {
1919 weston_log("Failed to initialize hmi-controller\n");
1920 return 0;
1921 }
1922
1923 return 1;
1924}
1925
1926static void
1927launch_hmi_client_process(void *data)
1928{
1929 struct hmi_controller *hmi_ctrl =
1930 (struct hmi_controller *)data;
1931
1932 hmi_ctrl->user_interface =
1933 weston_client_start(hmi_ctrl->compositor,
1934 hmi_ctrl->hmi_setting->ivi_homescreen);
1935
1936 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1937}
1938
1939/*****************************************************************************
1940 * exported functions
1941 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001942WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001943controller_module_init(struct weston_compositor *ec,
1944 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001945 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001946 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001947{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001948 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001949 struct wl_event_loop *loop = NULL;
1950
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001951 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001952 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001953 return -1;
1954 }
1955
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001956 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001957
1958 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001959 if (hmi_ctrl == NULL)
1960 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001961
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001962 if (!initialize(hmi_ctrl)) {
1963 return -1;
1964 }
1965
1966 if (wl_global_create(ec->wl_display,
1967 &ivi_hmi_controller_interface, 1,
1968 hmi_ctrl, bind_hmi_controller) == NULL) {
1969 return -1;
1970 }
1971
1972 loop = wl_display_get_event_loop(ec->wl_display);
1973 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1974
1975 return 0;
1976}