blob: c35f39cd2e44a2f65356958b32bfe1c0c7327d2d [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
130 struct wl_client *user_interface;
131 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900132
133 int32_t screen_num;
134 struct ivi_layout_screen **pp_screen;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900135};
136
137struct launcher_info {
138 uint32_t surface_id;
139 uint32_t workspace_id;
140 int32_t index;
141};
142
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000143const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900144
145int
146controller_module_init(struct weston_compositor *ec,
147 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000148 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900149 size_t interface_version);
150
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900151/*****************************************************************************
152 * local functions
153 ****************************************************************************/
154static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900155mem_alloc(size_t size, char *file, int32_t line)
156{
157 return fail_on_null(calloc(1, size), size, file, line);
158}
159
160#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
161
162static int32_t
163is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
164 struct ivi_layout_surface *ivisurf)
165{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000166 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900167
168 uint32_t *ui_widget_id = NULL;
169 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
170 if (*ui_widget_id == id)
171 return 1;
172 }
173
174 return 0;
175}
176
177static int
178compare_launcher_info(const void *lhs, const void *rhs)
179{
180 const struct launcher_info *left = lhs;
181 const struct launcher_info *right = rhs;
182
183 if (left->workspace_id < right->workspace_id)
184 return -1;
185
186 if (left->workspace_id > right->workspace_id)
187 return 1;
188
189 if (left->index < right->index)
190 return -1;
191
192 if (left->index > right->index)
193 return 1;
194
195 return 0;
196}
197
198/**
199 * Internal methods called by mainly ivi_hmi_controller_switch_mode
200 * This reference shows 4 examples how to use ivi_layout APIs.
201 */
202static void
203mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
204 struct ivi_layout_surface **pp_surface,
205 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900206 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900207{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900208 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900209 const float surface_width = (float)layer->width * 0.25;
210 const float surface_height = (float)layer->height * 0.5;
211 int32_t surface_x = 0;
212 int32_t surface_y = 0;
213 struct ivi_layout_surface *ivisurf = NULL;
214 struct ivi_layout_surface **surfaces;
215 struct ivi_layout_surface **new_order;
216 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900217 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900218
219 int32_t i = 0;
220 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900221 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900222
223 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
224 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
225
226 for (i = 0; i < surface_length; i++) {
227 ivisurf = pp_surface[i];
228
229 /* skip ui widgets */
230 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
231 continue;
232
233 surfaces[surf_num++] = ivisurf;
234 }
235
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900236 wl_list_for_each_reverse(layer, layer_list, link) {
237 if (idx >= surf_num)
238 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900239
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900240 ivilayer = layer->ivilayer;
241
242 for (i = 0; i < 8; i++, idx++) {
243 if (idx >= surf_num)
244 break;
245
246 ivisurf = surfaces[idx];
247 new_order[i] = ivisurf;
248 if (i < 4) {
249 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900250 surface_y = 0;
251 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900252 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900253 surface_y = (int32_t)surface_height;
254 }
255
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000256 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900257 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
258 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000259 ivi_layout_interface->surface_set_visibility(ivisurf, true);
260 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900261 surface_x, surface_y,
262 (int32_t)surface_width,
263 (int32_t)surface_height);
264
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900265 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900266 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900267
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900268 ivi_layout_interface->layer_set_transition(ivilayer,
269 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
270 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900271 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900272 for (i = idx; i < surf_num; i++)
273 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900274
275 free(surfaces);
276 free(new_order);
277}
278
279static void
280mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
281 struct ivi_layout_surface **pp_surface,
282 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900283 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900284{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900285 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900286 int32_t surface_width = layer->width / 2;
287 int32_t surface_height = layer->height;
288 struct ivi_layout_surface *ivisurf = NULL;
289
290 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
291 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900292 struct ivi_layout_surface **surfaces;
293 struct ivi_layout_surface **new_order;
294 struct ivi_layout_layer *ivilayer = NULL;
295 int32_t surf_num = 0;
296 int32_t idx = 0;
297
298 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
299 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900300
301 for (i = 0; i < surface_length; i++) {
302 ivisurf = pp_surface[i];
303
304 /* skip ui widgets */
305 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
306 continue;
307
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900308 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900309 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900310
311 wl_list_for_each_reverse(layer, layer_list, link) {
312 if (idx >= surf_num)
313 break;
314
315 ivilayer = layer->ivilayer;
316
317 for (i = 0; i < 2; i++, idx++) {
318 if (idx >= surf_num)
319 break;
320
321 ivisurf = surfaces[idx];
322 new_order[i] = ivisurf;
323
324 ivi_layout_interface->surface_set_transition(ivisurf,
325 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
326 duration);
327 ivi_layout_interface->surface_set_visibility(ivisurf, true);
328
329 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
330 i * surface_width, 0,
331 surface_width,
332 surface_height);
333 }
334 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
335 }
336
337 for (i = idx; i < surf_num; i++) {
338 ivi_layout_interface->surface_set_transition(surfaces[i],
339 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
340 duration);
341 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
342 }
343
344 free(surfaces);
345 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900346}
347
348static void
349mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
350 struct ivi_layout_surface **pp_surface,
351 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900352 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900353{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900354 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900355 const int32_t surface_width = layer->width;
356 const int32_t surface_height = layer->height;
357 struct ivi_layout_surface *ivisurf = NULL;
358 int32_t i = 0;
359 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900360 int32_t surf_num = 0;
361 struct ivi_layout_surface **surfaces;
362
363 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900364
365 for (i = 0; i < surface_length; i++) {
366 ivisurf = pp_surface[i];
367
368 /* skip ui widgets */
369 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
370 continue;
371
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900372 surfaces[surf_num++] = ivisurf;
373 }
374 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
375
376 for (i = 0; i < surf_num; i++) {
377 ivisurf = surfaces[i];
378
379 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
380 layer = wl_container_of(layer->link.prev, layer, link);
381 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
382 }
383
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000384 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900385 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
386 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000387 ivi_layout_interface->surface_set_visibility(ivisurf, true);
388 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900389 surface_width,
390 surface_height);
391 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900392
393 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900394}
395
396static void
397mode_random_replace(struct hmi_controller *hmi_ctrl,
398 struct ivi_layout_surface **pp_surface,
399 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900400 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900401{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900402 struct hmi_controller_layer *application_layer = NULL;
403 struct hmi_controller_layer **layers = NULL;
404 int32_t surface_width = 0;
405 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900406 int32_t surface_x = 0;
407 int32_t surface_y = 0;
408 struct ivi_layout_surface *ivisurf = NULL;
409 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
410 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900411 int32_t layer_idx = 0;
412
413 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
414
415 wl_list_for_each(application_layer, layer_list, link) {
416 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900417 layer_idx++;
418 }
419
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900420 for (i = 0; i < surface_length; i++) {
421 ivisurf = pp_surface[i];
422
423 /* skip ui widgets */
424 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
425 continue;
426
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900427 /* surface determined at random a layer that belongs */
428 layer_idx = rand() % hmi_ctrl->screen_num;
429
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000430 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900431 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
432 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900433
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000434 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900435
436 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
437 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
438 surface_x = rand() % (layers[layer_idx]->width - surface_width);
439 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900440
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000441 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900442 surface_x,
443 surface_y,
444 surface_width,
445 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900446
447 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900448 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900449
450 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900451}
452
453static int32_t
454has_application_surface(struct hmi_controller *hmi_ctrl,
455 struct ivi_layout_surface **pp_surface,
456 int32_t surface_length)
457{
458 struct ivi_layout_surface *ivisurf = NULL;
459 int32_t i = 0;
460
461 for (i = 0; i < surface_length; i++) {
462 ivisurf = pp_surface[i];
463
464 /* skip ui widgets */
465 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
466 continue;
467
468 return 1;
469 }
470
471 return 0;
472}
473
474/**
475 * Supports 4 example to layout of application ivi_surfaces;
476 * tiling, side by side, fullscreen, and random.
477 */
478static void
479switch_mode(struct hmi_controller *hmi_ctrl,
480 enum ivi_hmi_controller_layout_mode layout_mode)
481{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900482 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900483 struct ivi_layout_surface **pp_surface = NULL;
484 int32_t surface_length = 0;
485 int32_t ret = 0;
486
487 if (!hmi_ctrl->is_initialized)
488 return;
489
490 hmi_ctrl->layout_mode = layout_mode;
491
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000492 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900493 assert(!ret);
494
495 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
496 free(pp_surface);
497 pp_surface = NULL;
498 return;
499 }
500
501 switch (layout_mode) {
502 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
503 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
504 layer);
505 break;
506 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
507 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
508 surface_length, layer);
509 break;
510 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
511 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
512 layer);
513 break;
514 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
515 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
516 layer);
517 break;
518 }
519
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000520 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900521 free(pp_surface);
522}
523
524/**
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900525 * Internal method to get screens from weston core
526 * TODO: shall support hotplug of screens
527 */
528static int32_t
529get_screens(struct hmi_controller *hmi_ctrl)
530{
531 hmi_ctrl->pp_screen = NULL;
532 hmi_ctrl->screen_num = 0;
533 ivi_layout_interface->get_screens(&hmi_ctrl->screen_num, &hmi_ctrl->pp_screen);
534
535 if (hmi_ctrl->pp_screen == NULL)
536 return -1;
537 else
538 return 0;
539}
540
541/**
542 * Internal method to get ivi_layout_screen
543 */
544static struct ivi_layout_screen *
545get_screen(int32_t screen_idx, struct hmi_controller *hmi_ctrl)
546{
547 struct ivi_layout_screen *iviscrn = NULL;
548
549 if (screen_idx > hmi_ctrl->screen_num - 1)
550 weston_log("Invalid index. Return NULL\n");
551 else
552 iviscrn = hmi_ctrl->pp_screen[screen_idx];
553
554 return iviscrn;
555}
556
557/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900558 * Internal method for transition
559 */
560static void
561hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
562 struct hmi_controller_fade *fade)
563{
564 double tint = is_fade_in ? 1.0 : 0.0;
565 struct link_layer *linklayer = NULL;
566 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
567
568 fade->is_fade_in = is_fade_in;
569
570 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000571 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900572 IVI_LAYOUT_TRANSITION_LAYER_FADE,
573 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000574 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900575 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900576 }
577}
578
579/**
580 * Internal method to create ivi_layer with hmi_controller_layer and
581 * add to a ivi_screen
582 */
583static void
584create_layer(struct ivi_layout_screen *iviscrn,
585 struct hmi_controller_layer *layer)
586{
587 int32_t ret = 0;
588
589 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000590 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900591 layer->width,
592 layer->height);
593 assert(layer->ivilayer != NULL);
594
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000595 ret = ivi_layout_interface->screen_add_layer(iviscrn, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900596 assert(!ret);
597
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000598 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900599 layer->x, layer->y,
600 layer->width,
601 layer->height);
602 assert(!ret);
603
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000604 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900605 assert(!ret);
606}
607
608/**
609 * Internal set notification
610 */
611static void
612set_notification_create_surface(struct ivi_layout_surface *ivisurf,
613 void *userdata)
614{
615 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900616 struct hmi_controller_layer *layer_link =
617 wl_container_of(hmi_ctrl->application_layer_list.prev,
618 layer_link,
619 link);
620 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900621 int32_t ret = 0;
622
623 /* skip ui widgets */
624 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
625 return;
626
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000627 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900628 assert(!ret);
629}
630
631static void
632set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
633 void *userdata)
634{
635 struct hmi_controller *hmi_ctrl = userdata;
636
637 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
638}
639
640static void
641set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
642 void *userdata)
643{
644 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900645 struct hmi_controller_layer *layer_link = NULL;
646 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900647 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900648 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900649 int32_t length = 0;
650 int32_t i;
651
652 /* return if the surface is not application content */
653 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
654 return;
655 }
656
657 /*
658 * if application changes size of wl_buffer. The source rectangle shall be
659 * fit to the size.
660 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000661 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900662 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000663 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900664 ivisurf, 0, 0, surface->width,
665 surface->height);
666 }
667
668 /*
669 * search if the surface is already added to layer.
670 * If not yet, it is newly invoded application to go to switch_mode.
671 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900672 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
673 application_layer = layer_link->ivilayer;
674 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900675 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900676 for (i = 0; i < length; i++) {
677 if (ivisurf == ivisurfs[i]) {
678 /*
679 * if it is non new invoked application, just call
680 * commit_changes to apply source_rectangle.
681 */
682 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900683 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900684 return;
685 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900686 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900687 free(ivisurfs);
688 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900689 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900690
691 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
692}
693
694/**
695 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
696 * corresponding ivi_layer are defined in weston.ini. Default scene graph
697 * of ivi_layers are initialized in hmi_controller_create
698 */
699static struct hmi_server_setting *
700hmi_server_setting_create(struct weston_compositor *ec)
701{
702 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
703 struct weston_config *config = ec->config;
704 struct weston_config_section *shell_section = NULL;
705
706 shell_section = weston_config_get_section(config, "ivi-shell",
707 NULL, NULL);
708
709 weston_config_section_get_uint(shell_section, "base-layer-id",
710 &setting->base_layer_id, 1000);
711
712 weston_config_section_get_uint(shell_section,
713 "workspace-background-layer-id",
714 &setting->workspace_background_layer_id,
715 2000);
716
717 weston_config_section_get_uint(shell_section, "workspace-layer-id",
718 &setting->workspace_layer_id, 3000);
719
720 weston_config_section_get_uint(shell_section, "application-layer-id",
721 &setting->application_layer_id, 4000);
722
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900723 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
724 &setting->base_layer_id_offset, 10000);
725
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900726 weston_config_section_get_uint(shell_section, "transition-duration",
727 &setting->transition_duration, 300);
728
729 setting->panel_height = 70;
730
731 weston_config_section_get_string(shell_section,
732 "ivi-shell-user-interface",
733 &setting->ivi_homescreen, NULL);
734
735 return setting;
736}
737
738static void
739hmi_controller_destroy(struct wl_listener *listener, void *data)
740{
741 struct link_layer *link = NULL;
742 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900743 struct hmi_controller_layer *ctrl_layer_link = NULL;
744 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900745 struct hmi_controller *hmi_ctrl =
746 container_of(listener, struct hmi_controller, destroy_listener);
747
748 wl_list_for_each_safe(link, next,
749 &hmi_ctrl->workspace_fade.layer_list, link) {
750 wl_list_remove(&link->link);
751 free(link);
752 }
753
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900754 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900755 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
756 &hmi_ctrl->base_layer_list, link) {
757 wl_list_remove(&ctrl_layer_link->link);
758 free(ctrl_layer_link);
759 }
760
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900761 /* clear application_layer_list */
762 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
763 &hmi_ctrl->application_layer_list, link) {
764 wl_list_remove(&ctrl_layer_link->link);
765 free(ctrl_layer_link);
766 }
767
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900768 wl_array_release(&hmi_ctrl->ui_widgets);
769 free(hmi_ctrl->hmi_setting);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900770 free(hmi_ctrl->pp_screen);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900771 free(hmi_ctrl);
772}
773
774/**
775 * This is a starting method called from module_init.
776 * This sets up scene graph of ivi_layers; base, application, workspace
777 * background, and workspace. These ivi_layers are created/added to
778 * ivi_screen in create_layer
779 *
780 * base: to group ivi_surfaces of panel and background
781 * application: to group ivi_surfaces of ivi_applications
782 * workspace background: to group a ivi_surface of background in workspace
783 * workspace: to group ivi_surfaces for launching ivi_applications
784 *
785 * ivi_layers of workspace background and workspace is set to invisible at
786 * first. The properties of it is updated with animation when
787 * ivi_hmi_controller_home is requested.
788 */
789static struct hmi_controller *
790hmi_controller_create(struct weston_compositor *ec)
791{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900792 struct ivi_layout_screen *iviscrn = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900793 struct link_layer *tmp_link_layer = NULL;
794 int32_t panel_height = 0;
795 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900796 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900797 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000798 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900799
800 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900801
802 wl_array_init(&hmi_ctrl->ui_widgets);
803 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
804 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
805 hmi_ctrl->compositor = ec;
806
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900807 /* TODO: shall support hotplug of screens */
808 if (get_screens(hmi_ctrl) < 0) {
809 weston_log("ivi-shell: Failed to get screens\n");
810 hmi_ctrl = NULL;
811 return hmi_ctrl;
812 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900813
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900814 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900815
816 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900817 wl_list_init(&hmi_ctrl->base_layer_list);
818 for (i = 0; i < hmi_ctrl->screen_num; i++) {
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000819 output = ivi_layout_interface->screen_get_output(get_screen(i, hmi_ctrl));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900820
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900821 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
822 base_layer->x = 0;
823 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000824 base_layer->width = output->current_mode->width;
825 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900826 base_layer->id_layer =
827 hmi_ctrl->hmi_setting->base_layer_id +
828 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
829 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900830
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900831 create_layer(get_screen(i, hmi_ctrl), base_layer);
832 }
833
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900834 panel_height = hmi_ctrl->hmi_setting->panel_height;
835
836 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900837 wl_list_init(&hmi_ctrl->application_layer_list);
838 for (i = 0; i < hmi_ctrl->screen_num; i++) {
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000839 output = ivi_layout_interface->screen_get_output(get_screen(i, hmi_ctrl));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900840
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900841 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
842 application_layer->x = 0;
843 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000844 application_layer->width = output->current_mode->width;
845 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900846 application_layer->id_layer =
847 hmi_ctrl->hmi_setting->application_layer_id +
848 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
849 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
850
851 create_layer(get_screen(i, hmi_ctrl), application_layer);
852 }
853
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000854 output = ivi_layout_interface->screen_get_output(iviscrn);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900855
856 /* init workspace background ivi_layer */
857 hmi_ctrl->workspace_background_layer.x = 0;
858 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000859 hmi_ctrl->workspace_background_layer.width =
860 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900861 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000862 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900863
864 hmi_ctrl->workspace_background_layer.id_layer =
865 hmi_ctrl->hmi_setting->workspace_background_layer_id;
866
867 create_layer(iviscrn, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000868 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900869 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000870 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900871 hmi_ctrl->workspace_background_layer.ivilayer, false);
872
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900873
874 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
875 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900876 tmp_link_layer->layout_layer =
877 hmi_ctrl->workspace_background_layer.ivilayer;
878 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
879 &tmp_link_layer->link);
880
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000881 ivi_layout_interface->add_notification_create_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900882 set_notification_create_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000883 ivi_layout_interface->add_notification_remove_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900884 set_notification_remove_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000885 ivi_layout_interface->add_notification_configure_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900886 set_notification_configure_surface, hmi_ctrl);
887
888 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
889 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
890 &hmi_ctrl->destroy_listener);
891
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900892 return hmi_ctrl;
893}
894
895/**
896 * Implementations of ivi-hmi-controller.xml
897 */
898
899/**
900 * A ivi_surface drawing background is identified by id_surface.
901 * Properties of the ivi_surface is set by using ivi_layout APIs according to
902 * the scene graph of UI defined in hmi_controller_create.
903 *
904 * UI ivi_layer is used to add this ivi_surface.
905 */
906static void
907ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
908 uint32_t id_surface)
909{
910 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900911 struct hmi_controller_layer *base_layer = NULL;
912 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000913 int32_t dstx;
914 int32_t dsty;
915 int32_t width;
916 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900917 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900918 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900919
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900920 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
921 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
922 sizeof(*add_surface_id));
923 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000924 dstx = base_layer->x;
925 dsty = base_layer->y;
926 width = base_layer->width;
927 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900928 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900929
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900930 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
931 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900932
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900933 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
934 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900935
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900936 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
937 dstx, dsty, width, height);
938 assert(!ret);
939
940 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
941 assert(!ret);
942
943 i++;
944 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900945}
946
947/**
948 * A ivi_surface drawing panel is identified by id_surface.
949 * Properties of the ivi_surface is set by using ivi_layout APIs according to
950 * the scene graph of UI defined in hmi_controller_create.
951 *
952 * UI ivi_layer is used to add this ivi_surface.
953 */
954static void
955ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
956 uint32_t id_surface)
957{
958 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000959 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900960 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000961 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900962 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900963 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900964 const int32_t dstx = 0;
965 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900966 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900967
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900968 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
969 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
970 sizeof(*add_surface_id));
971 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900972
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900973 ivilayer = base_layer->ivilayer;
974 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
975 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900976
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900977 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
978 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900979
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900980 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000981 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900982
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900983 ret = ivi_layout_interface->surface_set_destination_rectangle(
984 ivisurf, dstx, dsty, width, panel_height);
985 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900986
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900987 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
988 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900989
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900990 i++;
991 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900992}
993
994/**
995 * A ivi_surface drawing buttons in panel is identified by id_surface.
996 * It can set several buttons. Properties of the ivi_surface is set by
997 * using ivi_layout APIs according to the scene graph of UI defined in
998 * hmi_controller_create. Additionally, the position of it is shifted to
999 * right when new one is requested.
1000 *
1001 * UI ivi_layer is used to add these ivi_surfaces.
1002 */
1003static void
1004ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
1005 uint32_t id_surface, int32_t number)
1006{
1007 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001008 struct hmi_controller_layer *base_layer =
1009 wl_container_of(hmi_ctrl->base_layer_list.prev,
1010 base_layer,
1011 link);
1012 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001013 const int32_t width = 48;
1014 const int32_t height = 48;
1015 int32_t ret = 0;
1016 int32_t panel_height = 0;
1017 int32_t dstx = 0;
1018 int32_t dsty = 0;
1019 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1020 sizeof(*add_surface_id));
1021 *add_surface_id = id_surface;
1022
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001023 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001024 assert(ivisurf != NULL);
1025
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001026 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001027 assert(!ret);
1028
1029 panel_height = hmi_ctrl->hmi_setting->panel_height;
1030
1031 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001032 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001033
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001034 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001035 ivisurf,dstx, dsty, width, height);
1036 assert(!ret);
1037
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001038 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001039 assert(!ret);
1040}
1041
1042/**
1043 * A ivi_surface drawing home button in panel is identified by id_surface.
1044 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1045 * the scene graph of UI defined in hmi_controller_create.
1046 *
1047 * UI ivi_layer is used to add these ivi_surfaces.
1048 */
1049static void
1050ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1051 uint32_t id_surface)
1052{
1053 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001054 struct hmi_controller_layer *base_layer =
1055 wl_container_of(hmi_ctrl->base_layer_list.prev,
1056 base_layer,
1057 link);
1058 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001059 int32_t ret = 0;
1060 int32_t size = 48;
1061 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001062 const int32_t dstx = (base_layer->width - size) / 2;
1063 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001064
1065 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1066 sizeof(*add_surface_id));
1067 *add_surface_id = id_surface;
1068
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001069 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001070 assert(ivisurf != NULL);
1071
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001072 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001073 assert(!ret);
1074
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001075 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001076 ivisurf, dstx, dsty, size, size);
1077 assert(!ret);
1078
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001079 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001080 assert(!ret);
1081}
1082
1083/**
1084 * A ivi_surface drawing background of workspace is identified by id_surface.
1085 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1086 * the scene graph of UI defined in hmi_controller_create.
1087 *
1088 * A ivi_layer of workspace_background is used to add this ivi_surface.
1089 */
1090static void
1091ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1092 uint32_t id_surface)
1093{
1094 struct ivi_layout_surface *ivisurf = NULL;
1095 struct ivi_layout_layer *ivilayer = NULL;
1096 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1097 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1098 int32_t ret = 0;
1099
1100 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1101 sizeof(*add_surface_id));
1102 *add_surface_id = id_surface;
1103 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1104
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001105 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001106 assert(ivisurf != NULL);
1107
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001108 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001109 assert(!ret);
1110
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001111 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001112 0, 0, width, height);
1113 assert(!ret);
1114
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001115 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001116 assert(!ret);
1117}
1118
1119/**
1120 * A list of ivi_surfaces drawing launchers in workspace is identified by
1121 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1122 * APIs according to the scene graph of UI defined in hmi_controller_create.
1123 *
1124 * The workspace can have several pages to group ivi_surfaces of launcher.
1125 * Each call of this interface increments a number of page to add a group
1126 * of ivi_surfaces
1127 */
1128static void
1129ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1130 int32_t icon_size)
1131{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001132 int32_t minspace_x = 10;
1133 int32_t minspace_y = minspace_x;
1134
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001135 int32_t width = hmi_ctrl->workspace_background_layer.width;
1136 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001137
1138 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1139 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1140 float fcell_size_x = icon_size + space_x;
1141
1142 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1143 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1144 float fcell_size_y = icon_size + space_y;
1145
1146 struct weston_config *config = NULL;
1147 struct weston_config_section *section = NULL;
1148 const char *name = NULL;
1149 int launcher_count = 0;
1150 struct wl_array launchers;
1151 int32_t nx = 0;
1152 int32_t ny = 0;
1153 int32_t prev = -1;
1154 struct launcher_info *data = NULL;
1155
1156 uint32_t surfaceid = 0;
1157 uint32_t workspaceid = 0;
1158 struct launcher_info *info = NULL;
1159
1160 int32_t x = 0;
1161 int32_t y = 0;
1162 int32_t ret = 0;
1163 struct ivi_layout_surface* layout_surface = NULL;
1164 uint32_t *add_surface_id = NULL;
1165
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001166 struct ivi_layout_screen *iviscrn = NULL;
1167 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001168
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001169 if (0 == x_count)
1170 x_count = 1;
1171
1172 if (0 == y_count)
1173 y_count = 1;
1174
1175 config = hmi_ctrl->compositor->config;
1176 if (!config)
1177 return;
1178
1179 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1180 if (!section)
1181 return;
1182
1183 wl_array_init(&launchers);
1184
1185 while (weston_config_next_section(config, &section, &name)) {
1186 surfaceid = 0;
1187 workspaceid = 0;
1188 info = NULL;
1189 if (0 != strcmp(name, "ivi-launcher"))
1190 continue;
1191
1192 if (0 != weston_config_section_get_uint(section, "icon-id",
1193 &surfaceid, 0))
1194 continue;
1195
1196 if (0 != weston_config_section_get_uint(section,
1197 "workspace-id",
1198 &workspaceid, 0))
1199 continue;
1200
1201 info = wl_array_add(&launchers, sizeof(*info));
1202
1203 if (info) {
1204 info->surface_id = surfaceid;
1205 info->workspace_id = workspaceid;
1206 info->index = launcher_count;
1207 ++launcher_count;
1208 }
1209 }
1210
1211 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1212 compare_launcher_info);
1213
1214 wl_array_for_each(data, &launchers) {
1215 x = 0;
1216 y = 0;
1217 ret = 0;
1218 layout_surface = NULL;
1219 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1220 sizeof(*add_surface_id));
1221
1222 *add_surface_id = data->surface_id;
1223
1224 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1225 nx = 0;
1226 ny = 0;
1227 prev = data->workspace_id;
1228
1229 if (0 <= prev)
1230 hmi_ctrl->workspace_count++;
1231 }
1232
1233 if (y_count == ny) {
1234 ny = 0;
1235 hmi_ctrl->workspace_count++;
1236 }
1237
1238 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1239 y = ny * fcell_size_y + space_y;
1240
1241 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001242 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001243 assert(layout_surface);
1244
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001245 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001246 layout_surface, x, y, icon_size, icon_size);
1247 assert(!ret);
1248
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001249 nx++;
1250
1251 if (x_count == nx) {
1252 ny++;
1253 nx = 0;
1254 }
1255 }
1256
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001257 /* init workspace ivi_layer */
1258 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1259 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1260 hmi_ctrl->workspace_layer.width =
1261 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1262 hmi_ctrl->workspace_layer.height =
1263 hmi_ctrl->workspace_background_layer.height;
1264 hmi_ctrl->workspace_layer.id_layer =
1265 hmi_ctrl->hmi_setting->workspace_layer_id;
1266
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001267 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001268 create_layer(iviscrn, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001269 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1270 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001271 false);
1272
1273 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1274 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1275 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1276 &tmp_link_layer->link);
1277
1278 /* Add surface to layer */
1279 wl_array_for_each(data, &launchers) {
1280 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001281 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001282 assert(layout_surface);
1283
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001284 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001285 layout_surface);
1286 assert(!ret);
1287
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001288 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001289 assert(!ret);
1290 }
1291
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001292 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001293 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001294}
1295
1296static void
1297ivi_hmi_controller_UI_ready(struct wl_client *client,
1298 struct wl_resource *resource)
1299{
1300 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1301
1302 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1303 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1304 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1305 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1306 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1307 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1308 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1309 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001310 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001311
1312 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1313 hmi_ctrl->is_initialized = 1;
1314}
1315
1316/**
1317 * Implementation of request and event of ivi_hmi_controller_workspace_control
1318 * and controlling workspace.
1319 *
1320 * When motion of input is detected in a ivi_surface of workspace background,
1321 * ivi_hmi_controller_workspace_control shall be invoked and to start
1322 * controlling of workspace. The workspace has several pages to show several
1323 * groups of applications.
1324 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1325 * according to motion. When motion finished, e.g. touch up detected, control is
1326 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1327 */
1328struct pointer_grab {
1329 struct weston_pointer_grab grab;
1330 struct ivi_layout_layer *layer;
1331 struct wl_resource *resource;
1332};
1333
1334struct touch_grab {
1335 struct weston_touch_grab grab;
1336 struct ivi_layout_layer *layer;
1337 struct wl_resource *resource;
1338};
1339
1340struct move_grab {
1341 wl_fixed_t dst[2];
1342 wl_fixed_t rgn[2][2];
1343 double v[2];
1344 struct timespec start_time;
1345 struct timespec pre_time;
1346 wl_fixed_t start_pos[2];
1347 wl_fixed_t pos[2];
1348 int32_t is_moved;
1349};
1350
1351struct pointer_move_grab {
1352 struct pointer_grab base;
1353 struct move_grab move;
1354};
1355
1356struct touch_move_grab {
1357 struct touch_grab base;
1358 struct move_grab move;
1359 int32_t is_active;
1360};
1361
1362static void
1363pointer_grab_start(struct pointer_grab *grab,
1364 struct ivi_layout_layer *layer,
1365 const struct weston_pointer_grab_interface *interface,
1366 struct weston_pointer *pointer)
1367{
1368 grab->grab.interface = interface;
1369 grab->layer = layer;
1370 weston_pointer_start_grab(pointer, &grab->grab);
1371}
1372
1373static void
1374touch_grab_start(struct touch_grab *grab,
1375 struct ivi_layout_layer *layer,
1376 const struct weston_touch_grab_interface *interface,
1377 struct weston_touch* touch)
1378{
1379 grab->grab.interface = interface;
1380 grab->layer = layer;
1381 weston_touch_start_grab(touch, &grab->grab);
1382}
1383
1384static int32_t
1385clamp(int32_t val, int32_t min, int32_t max)
1386{
1387 if (val < min)
1388 return min;
1389
1390 if (max < val)
1391 return max;
1392
1393 return val;
1394}
1395
1396static void
1397move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1398 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1399{
1400 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1401 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001402 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001403
1404 struct timespec time = {0};
1405 double grab_time = 0.0;
1406 double from_motion_time = 0.0;
1407 double pointer_v = 0.0;
1408 int32_t is_flick = 0;
1409 int32_t pos_x = 0;
1410 int32_t pos_y = 0;
1411 int page_no = 0;
1412 double end_pos = 0.0;
1413 uint32_t duration = 0;
1414
1415 clock_gettime(CLOCK_MONOTONIC, &time);
1416
1417 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1418 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1419
1420 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1421 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1422
1423 pointer_v = move->v[0];
1424
1425 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1426 if (200 < from_motion_time)
1427 pointer_v = 0.0;
1428
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001429 prop = ivi_layout_interface->get_properties_of_layer(layer);
1430 pos_x = prop->dest_x;
1431 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001432
1433 if (is_flick) {
1434 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1435 page_no = (-orgx + width / 2) / width;
1436
1437 if (pointer_v < 0.0)
1438 page_no++;
1439 else
1440 page_no--;
1441 } else {
1442 page_no = (-pos_x + width / 2) / width;
1443 }
1444
1445 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1446 end_pos = -page_no * width;
1447
1448 duration = hmi_ctrl->hmi_setting->transition_duration;
1449 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001450 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001451 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1452 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001453 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001454 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001455 hmi_ctrl->workspace_layer.width,
1456 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001457 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001458}
1459
1460static void
1461pointer_move_workspace_grab_end(struct pointer_grab *grab)
1462{
1463 struct pointer_move_grab *pnt_move_grab =
1464 (struct pointer_move_grab *)grab;
1465 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1466
1467 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1468 grab->grab.pointer->grab_x, layer);
1469
1470 weston_pointer_end_grab(grab->grab.pointer);
1471}
1472
1473static void
1474touch_move_workspace_grab_end(struct touch_grab *grab)
1475{
1476 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1477 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1478
1479 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1480 grab->grab.touch->grab_x, layer);
1481
1482 weston_touch_end_grab(grab->grab.touch);
1483}
1484
1485static void
1486pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1487{
1488}
1489
1490static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001491pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001492 uint32_t time,
1493 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001494{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001495 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001496}
1497
1498static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001499pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1500 uint32_t source)
1501{
1502 weston_pointer_send_axis_source(grab->pointer, source);
1503}
1504
1505static void
1506pointer_default_grab_frame(struct weston_pointer_grab *grab)
1507{
1508 weston_pointer_send_frame(grab->pointer);
1509}
1510
1511static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001512move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1513{
1514 struct timespec timestamp = {0};
1515 int32_t ii = 0;
1516 double dt = 0.0;
1517
1518 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1519 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1520 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1521
1522 if (dt < 1e-6)
1523 dt = 1e-6;
1524
1525 move->pre_time = timestamp;
1526
1527 for (ii = 0; ii < 2; ii++) {
1528 wl_fixed_t prepos = move->pos[ii];
1529 move->pos[ii] = pointer[ii] + move->dst[ii];
1530
1531 if (move->pos[ii] < move->rgn[0][ii]) {
1532 move->pos[ii] = move->rgn[0][ii];
1533 move->dst[ii] = move->pos[ii] - pointer[ii];
1534 } else if (move->rgn[1][ii] < move->pos[ii]) {
1535 move->pos[ii] = move->rgn[1][ii];
1536 move->dst[ii] = move->pos[ii] - pointer[ii];
1537 }
1538
1539 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1540
1541 if (!move->is_moved &&
1542 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1543 move->is_moved = 1;
1544 }
1545}
1546
1547static void
1548layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1549 wl_fixed_t pos_y)
1550{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001551 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001552 int32_t layout_pos_x = 0;
1553 int32_t layout_pos_y = 0;
1554
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001555 prop = ivi_layout_interface->get_properties_of_layer(layer);
1556
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001557 layout_pos_x = wl_fixed_to_int(pos_x);
1558 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001559 ivi_layout_interface->layer_set_destination_rectangle(layer,
1560 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001561 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001562}
1563
1564static void
1565pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001566 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001567{
1568 struct pointer_move_grab *pnt_move_grab =
1569 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001570 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001571
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001572 weston_pointer_motion_to_abs(grab->pointer, event,
1573 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001574 move_grab_update(&pnt_move_grab->move, pointer_pos);
1575 layer_set_pos(pnt_move_grab->base.layer,
1576 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001577 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001578}
1579
1580static void
1581touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1582 int touch_id, wl_fixed_t x, wl_fixed_t y)
1583{
1584 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1585
1586 if (!tch_move_grab->is_active)
1587 return;
1588
1589 wl_fixed_t pointer_pos[2] = {
1590 grab->touch->grab_x,
1591 grab->touch->grab_y
1592 };
1593
1594 move_grab_update(&tch_move_grab->move, pointer_pos);
1595 layer_set_pos(tch_move_grab->base.layer,
1596 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1597}
1598
1599static void
1600pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1601 uint32_t time, uint32_t button,
1602 uint32_t state_w)
1603{
1604 if (BTN_LEFT == button &&
1605 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1606 struct pointer_grab *pg = (struct pointer_grab *)grab;
1607
1608 pointer_move_workspace_grab_end(pg);
1609 free(grab);
1610 }
1611}
1612
1613static void
1614touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1615 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1616{
1617}
1618
1619static void
1620touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1621 int touch_id)
1622{
1623 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1624
1625 if (0 == touch_id)
1626 tch_move_grab->is_active = 0;
1627
1628 if (0 == grab->touch->num_tp) {
1629 touch_move_workspace_grab_end(&tch_move_grab->base);
1630 free(grab);
1631 }
1632}
1633
1634static void
1635pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1636{
1637 struct pointer_grab *pg = (struct pointer_grab *)grab;
1638
1639 pointer_move_workspace_grab_end(pg);
1640 free(grab);
1641}
1642
1643static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001644touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1645{
1646}
1647
1648static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001649touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1650{
1651 struct touch_grab *tg = (struct touch_grab *)grab;
1652
1653 touch_move_workspace_grab_end(tg);
1654 free(grab);
1655}
1656
1657static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1658 pointer_noop_grab_focus,
1659 pointer_move_grab_motion,
1660 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001661 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001662 pointer_default_grab_axis_source,
1663 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001664 pointer_move_workspace_grab_cancel
1665};
1666
1667static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1668 touch_nope_grab_down,
1669 touch_move_workspace_grab_up,
1670 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001671 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001672 touch_move_workspace_grab_cancel
1673};
1674
1675enum HMI_GRAB_DEVICE {
1676 HMI_GRAB_DEVICE_NONE,
1677 HMI_GRAB_DEVICE_POINTER,
1678 HMI_GRAB_DEVICE_TOUCH
1679};
1680
1681static enum HMI_GRAB_DEVICE
1682get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1683{
Derek Foreman1281a362015-07-31 16:55:32 -05001684 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1685 struct weston_touch *touch = weston_seat_get_touch(seat);
1686
1687 if (pointer &&
1688 pointer->focus &&
1689 pointer->button_count &&
1690 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001691 return HMI_GRAB_DEVICE_POINTER;
1692
Derek Foreman1281a362015-07-31 16:55:32 -05001693 if (touch &&
1694 touch->focus &&
1695 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001696 return HMI_GRAB_DEVICE_TOUCH;
1697
1698 return HMI_GRAB_DEVICE_NONE;
1699}
1700
1701static void
1702move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1703 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1704 struct wl_resource* resource)
1705{
1706 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1707 move->pre_time = move->start_time;
1708 move->pos[0] = start_pos[0];
1709 move->pos[1] = start_pos[1];
1710 move->start_pos[0] = start_pos[0];
1711 move->start_pos[1] = start_pos[1];
1712 move->dst[0] = start_pos[0] - grab_pos[0];
1713 move->dst[1] = start_pos[1] - grab_pos[1];
1714 memcpy(move->rgn, rgn, sizeof(move->rgn));
1715}
1716
1717static void
1718move_grab_init_workspace(struct move_grab* move,
1719 wl_fixed_t grab_x, wl_fixed_t grab_y,
1720 struct wl_resource *resource)
1721{
1722 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1723 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001724 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001725 int32_t workspace_count = hmi_ctrl->workspace_count;
1726 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1727 int32_t layer_pos_x = 0;
1728 int32_t layer_pos_y = 0;
1729 wl_fixed_t start_pos[2] = {0};
1730 wl_fixed_t rgn[2][2] = {{0}};
1731 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1732
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001733 prop = ivi_layout_interface->get_properties_of_layer(layer);
1734 layer_pos_x = prop->dest_x;
1735 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001736
1737 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1738 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1739
1740 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1741
1742 rgn[0][1] = wl_fixed_from_int(0);
1743 rgn[1][0] = wl_fixed_from_int(0);
1744 rgn[1][1] = wl_fixed_from_int(0);
1745
1746 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1747}
1748
1749static struct pointer_move_grab *
1750create_workspace_pointer_move(struct weston_pointer *pointer,
1751 struct wl_resource* resource)
1752{
1753 struct pointer_move_grab *pnt_move_grab =
1754 MEM_ALLOC(sizeof(*pnt_move_grab));
1755
1756 pnt_move_grab->base.resource = resource;
1757 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1758 pointer->grab_y, resource);
1759
1760 return pnt_move_grab;
1761}
1762
1763static struct touch_move_grab *
1764create_workspace_touch_move(struct weston_touch *touch,
1765 struct wl_resource* resource)
1766{
1767 struct touch_move_grab *tch_move_grab =
1768 MEM_ALLOC(sizeof(*tch_move_grab));
1769
1770 tch_move_grab->base.resource = resource;
1771 tch_move_grab->is_active = 1;
1772 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1773 touch->grab_y, resource);
1774
1775 return tch_move_grab;
1776}
1777
1778static void
1779ivi_hmi_controller_workspace_control(struct wl_client *client,
1780 struct wl_resource *resource,
1781 struct wl_resource *seat_resource,
1782 uint32_t serial)
1783{
1784 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1785 struct ivi_layout_layer *layer = NULL;
1786 struct pointer_move_grab *pnt_move_grab = NULL;
1787 struct touch_move_grab *tch_move_grab = NULL;
1788 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001789 struct weston_pointer *pointer;
1790 struct weston_touch *touch;
1791
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001792 enum HMI_GRAB_DEVICE device;
1793
1794 if (hmi_ctrl->workspace_count < 2)
1795 return;
1796
1797 seat = wl_resource_get_user_data(seat_resource);
1798 device = get_hmi_grab_device(seat, serial);
1799
1800 if (HMI_GRAB_DEVICE_POINTER != device &&
1801 HMI_GRAB_DEVICE_TOUCH != device)
1802 return;
1803
1804 layer = hmi_ctrl->workspace_layer.ivilayer;
1805
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001806 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001807
1808 switch (device) {
1809 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001810 pointer = weston_seat_get_pointer(seat);
1811 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001812 resource);
1813
1814 pointer_grab_start(&pnt_move_grab->base, layer,
1815 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001816 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001817 break;
1818
1819 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001820 touch = weston_seat_get_touch(seat);
1821 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001822 resource);
1823
1824 touch_grab_start(&tch_move_grab->base, layer,
1825 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001826 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001827 break;
1828
1829 default:
1830 break;
1831 }
1832}
1833
1834/**
1835 * Implementation of switch_mode
1836 */
1837static void
1838ivi_hmi_controller_switch_mode(struct wl_client *client,
1839 struct wl_resource *resource,
1840 uint32_t layout_mode)
1841{
1842 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1843
1844 switch_mode(hmi_ctrl, layout_mode);
1845}
1846
1847/**
1848 * Implementation of on/off displaying workspace and workspace background
1849 * ivi_layers.
1850 */
1851static void
1852ivi_hmi_controller_home(struct wl_client *client,
1853 struct wl_resource *resource,
1854 uint32_t home)
1855{
1856 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1857 uint32_t is_fade_in;
1858
1859 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1860 !hmi_ctrl->workspace_fade.is_fade_in) ||
1861 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1862 hmi_ctrl->workspace_fade.is_fade_in)) {
1863 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1864 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1865 &hmi_ctrl->workspace_fade);
1866 }
1867
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001868 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001869}
1870
1871/**
1872 * binding ivi-hmi-controller implementation
1873 */
1874static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1875 ivi_hmi_controller_UI_ready,
1876 ivi_hmi_controller_workspace_control,
1877 ivi_hmi_controller_switch_mode,
1878 ivi_hmi_controller_home
1879};
1880
1881static void
1882unbind_hmi_controller(struct wl_resource *resource)
1883{
1884}
1885
1886static void
1887bind_hmi_controller(struct wl_client *client,
1888 void *data, uint32_t version, uint32_t id)
1889{
1890 struct wl_resource *resource = NULL;
1891 struct hmi_controller *hmi_ctrl = data;
1892
1893 if (hmi_ctrl->user_interface != client) {
1894 struct wl_resource *res = wl_client_get_object(client, 1);
1895 wl_resource_post_error(res,
1896 WL_DISPLAY_ERROR_INVALID_OBJECT,
1897 "hmi-controller failed: permission denied");
1898 return;
1899 }
1900
1901 resource = wl_resource_create(
1902 client, &ivi_hmi_controller_interface, 1, id);
1903
1904 wl_resource_set_implementation(
1905 resource, &ivi_hmi_controller_implementation,
1906 hmi_ctrl, unbind_hmi_controller);
1907}
1908
1909static int32_t
1910initialize(struct hmi_controller *hmi_ctrl)
1911{
1912 struct config_command {
1913 char *key;
1914 uint32_t *dest;
1915 };
1916
1917 struct weston_config *config = hmi_ctrl->compositor->config;
1918 struct weston_config_section *section = NULL;
1919 int result = 0;
1920 int i = 0;
1921
1922 const struct config_command uint_commands[] = {
1923 { "background-id", &hmi_ctrl->ui_setting.background_id },
1924 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1925 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1926 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1927 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1928 { "random-id", &hmi_ctrl->ui_setting.random_id },
1929 { "home-id", &hmi_ctrl->ui_setting.home_id },
1930 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001931 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001932 { NULL, NULL }
1933 };
1934
1935 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1936
1937 for (i = 0; -1 != result; ++i) {
1938 const struct config_command *command = &uint_commands[i];
1939
1940 if (!command->key)
1941 break;
1942
1943 if (weston_config_section_get_uint(
1944 section, command->key, command->dest, 0) != 0)
1945 result = -1;
1946 }
1947
1948 if (-1 == result) {
1949 weston_log("Failed to initialize hmi-controller\n");
1950 return 0;
1951 }
1952
1953 return 1;
1954}
1955
1956static void
1957launch_hmi_client_process(void *data)
1958{
1959 struct hmi_controller *hmi_ctrl =
1960 (struct hmi_controller *)data;
1961
1962 hmi_ctrl->user_interface =
1963 weston_client_start(hmi_ctrl->compositor,
1964 hmi_ctrl->hmi_setting->ivi_homescreen);
1965
1966 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1967}
1968
1969/*****************************************************************************
1970 * exported functions
1971 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001972WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001973controller_module_init(struct weston_compositor *ec,
1974 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001975 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001976 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001977{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001978 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001979 struct wl_event_loop *loop = NULL;
1980
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001981 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001982 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001983 return -1;
1984 }
1985
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001986 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001987
1988 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001989 if (hmi_ctrl == NULL)
1990 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001991
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001992 if (!initialize(hmi_ctrl)) {
1993 return -1;
1994 }
1995
1996 if (wl_global_create(ec->wl_display,
1997 &ivi_hmi_controller_interface, 1,
1998 hmi_ctrl, bind_hmi_controller) == NULL) {
1999 return -1;
2000 }
2001
2002 loop = wl_display_get_event_loop(ec->wl_display);
2003 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
2004
2005 return 0;
2006}