blob: 86f7c50e459823fb29e69ba573211ee78ddc35ee [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 Tanibata1c2201b2015-12-09 15:45:52 +0900412 struct hmi_controller_layer *application_layer = NULL;
413 struct hmi_controller_layer **layers = NULL;
414 int32_t surface_width = 0;
415 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900416 int32_t surface_x = 0;
417 int32_t surface_y = 0;
418 struct ivi_layout_surface *ivisurf = NULL;
419 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
420 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900421 int32_t layer_idx = 0;
422
423 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
424
425 wl_list_for_each(application_layer, layer_list, link) {
426 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900427 layer_idx++;
428 }
429
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900430 for (i = 0; i < surface_length; i++) {
431 ivisurf = pp_surface[i];
432
433 /* skip ui widgets */
434 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
435 continue;
436
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900437 /* surface determined at random a layer that belongs */
438 layer_idx = rand() % hmi_ctrl->screen_num;
439
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000440 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900441 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
442 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900443
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000444 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900445
446 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
447 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
448 surface_x = rand() % (layers[layer_idx]->width - surface_width);
449 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900450
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000451 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900452 surface_x,
453 surface_y,
454 surface_width,
455 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900456
457 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900458 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900459
460 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900461}
462
463static int32_t
464has_application_surface(struct hmi_controller *hmi_ctrl,
465 struct ivi_layout_surface **pp_surface,
466 int32_t surface_length)
467{
468 struct ivi_layout_surface *ivisurf = NULL;
469 int32_t i = 0;
470
471 for (i = 0; i < surface_length; i++) {
472 ivisurf = pp_surface[i];
473
474 /* skip ui widgets */
475 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
476 continue;
477
478 return 1;
479 }
480
481 return 0;
482}
483
484/**
485 * Supports 4 example to layout of application ivi_surfaces;
486 * tiling, side by side, fullscreen, and random.
487 */
488static void
489switch_mode(struct hmi_controller *hmi_ctrl,
490 enum ivi_hmi_controller_layout_mode layout_mode)
491{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900492 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900493 struct ivi_layout_surface **pp_surface = NULL;
494 int32_t surface_length = 0;
495 int32_t ret = 0;
496
497 if (!hmi_ctrl->is_initialized)
498 return;
499
500 hmi_ctrl->layout_mode = layout_mode;
501
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000502 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900503 assert(!ret);
504
505 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
506 free(pp_surface);
507 pp_surface = NULL;
508 return;
509 }
510
511 switch (layout_mode) {
512 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
513 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
514 layer);
515 break;
516 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
517 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
518 surface_length, layer);
519 break;
520 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
521 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
522 layer);
523 break;
524 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
525 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
526 layer);
527 break;
528 }
529
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000530 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900531 free(pp_surface);
532}
533
534/**
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900535 * Internal method to get screens from weston core
536 * TODO: shall support hotplug of screens
537 */
538static int32_t
539get_screens(struct hmi_controller *hmi_ctrl)
540{
541 hmi_ctrl->pp_screen = NULL;
542 hmi_ctrl->screen_num = 0;
543 ivi_layout_interface->get_screens(&hmi_ctrl->screen_num, &hmi_ctrl->pp_screen);
544
545 if (hmi_ctrl->pp_screen == NULL)
546 return -1;
547 else
548 return 0;
549}
550
551/**
552 * Internal method to get ivi_layout_screen
553 */
554static struct ivi_layout_screen *
555get_screen(int32_t screen_idx, struct hmi_controller *hmi_ctrl)
556{
557 struct ivi_layout_screen *iviscrn = NULL;
558
559 if (screen_idx > hmi_ctrl->screen_num - 1)
560 weston_log("Invalid index. Return NULL\n");
561 else
562 iviscrn = hmi_ctrl->pp_screen[screen_idx];
563
564 return iviscrn;
565}
566
567/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900568 * Internal method for transition
569 */
570static void
571hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
572 struct hmi_controller_fade *fade)
573{
574 double tint = is_fade_in ? 1.0 : 0.0;
575 struct link_layer *linklayer = NULL;
576 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
577
578 fade->is_fade_in = is_fade_in;
579
580 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000581 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900582 IVI_LAYOUT_TRANSITION_LAYER_FADE,
583 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000584 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900585 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900586 }
587}
588
589/**
590 * Internal method to create ivi_layer with hmi_controller_layer and
591 * add to a ivi_screen
592 */
593static void
594create_layer(struct ivi_layout_screen *iviscrn,
595 struct hmi_controller_layer *layer)
596{
597 int32_t ret = 0;
598
599 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000600 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900601 layer->width,
602 layer->height);
603 assert(layer->ivilayer != NULL);
604
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000605 ret = ivi_layout_interface->screen_add_layer(iviscrn, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900606 assert(!ret);
607
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000608 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900609 layer->x, layer->y,
610 layer->width,
611 layer->height);
612 assert(!ret);
613
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000614 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900615 assert(!ret);
616}
617
618/**
619 * Internal set notification
620 */
621static void
622set_notification_create_surface(struct ivi_layout_surface *ivisurf,
623 void *userdata)
624{
625 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900626 struct hmi_controller_layer *layer_link =
627 wl_container_of(hmi_ctrl->application_layer_list.prev,
628 layer_link,
629 link);
630 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900631 int32_t ret = 0;
632
633 /* skip ui widgets */
634 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
635 return;
636
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000637 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900638 assert(!ret);
639}
640
641static void
642set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
643 void *userdata)
644{
645 struct hmi_controller *hmi_ctrl = userdata;
646
647 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
648}
649
650static void
651set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
652 void *userdata)
653{
654 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900655 struct hmi_controller_layer *layer_link = NULL;
656 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900657 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900658 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900659 int32_t length = 0;
660 int32_t i;
661
662 /* return if the surface is not application content */
663 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
664 return;
665 }
666
667 /*
668 * if application changes size of wl_buffer. The source rectangle shall be
669 * fit to the size.
670 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000671 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900672 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000673 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900674 ivisurf, 0, 0, surface->width,
675 surface->height);
676 }
677
678 /*
679 * search if the surface is already added to layer.
680 * If not yet, it is newly invoded application to go to switch_mode.
681 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900682 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
683 application_layer = layer_link->ivilayer;
684 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900685 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900686 for (i = 0; i < length; i++) {
687 if (ivisurf == ivisurfs[i]) {
688 /*
689 * if it is non new invoked application, just call
690 * commit_changes to apply source_rectangle.
691 */
692 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900693 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900694 return;
695 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900696 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900697 free(ivisurfs);
698 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900699 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900700
701 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
702}
703
704/**
705 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
706 * corresponding ivi_layer are defined in weston.ini. Default scene graph
707 * of ivi_layers are initialized in hmi_controller_create
708 */
709static struct hmi_server_setting *
710hmi_server_setting_create(struct weston_compositor *ec)
711{
712 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
713 struct weston_config *config = ec->config;
714 struct weston_config_section *shell_section = NULL;
715
716 shell_section = weston_config_get_section(config, "ivi-shell",
717 NULL, NULL);
718
719 weston_config_section_get_uint(shell_section, "base-layer-id",
720 &setting->base_layer_id, 1000);
721
722 weston_config_section_get_uint(shell_section,
723 "workspace-background-layer-id",
724 &setting->workspace_background_layer_id,
725 2000);
726
727 weston_config_section_get_uint(shell_section, "workspace-layer-id",
728 &setting->workspace_layer_id, 3000);
729
730 weston_config_section_get_uint(shell_section, "application-layer-id",
731 &setting->application_layer_id, 4000);
732
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900733 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
734 &setting->base_layer_id_offset, 10000);
735
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900736 weston_config_section_get_uint(shell_section, "transition-duration",
737 &setting->transition_duration, 300);
738
739 setting->panel_height = 70;
740
741 weston_config_section_get_string(shell_section,
742 "ivi-shell-user-interface",
743 &setting->ivi_homescreen, NULL);
744
745 return setting;
746}
747
748static void
749hmi_controller_destroy(struct wl_listener *listener, void *data)
750{
751 struct link_layer *link = NULL;
752 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900753 struct hmi_controller_layer *ctrl_layer_link = NULL;
754 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900755 struct hmi_controller *hmi_ctrl =
756 container_of(listener, struct hmi_controller, destroy_listener);
757
758 wl_list_for_each_safe(link, next,
759 &hmi_ctrl->workspace_fade.layer_list, link) {
760 wl_list_remove(&link->link);
761 free(link);
762 }
763
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900764 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900765 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
766 &hmi_ctrl->base_layer_list, link) {
767 wl_list_remove(&ctrl_layer_link->link);
768 free(ctrl_layer_link);
769 }
770
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900771 /* clear application_layer_list */
772 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
773 &hmi_ctrl->application_layer_list, link) {
774 wl_list_remove(&ctrl_layer_link->link);
775 free(ctrl_layer_link);
776 }
777
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900778 wl_array_release(&hmi_ctrl->ui_widgets);
779 free(hmi_ctrl->hmi_setting);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900780 free(hmi_ctrl->pp_screen);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900781 free(hmi_ctrl);
782}
783
784/**
785 * This is a starting method called from module_init.
786 * This sets up scene graph of ivi_layers; base, application, workspace
787 * background, and workspace. These ivi_layers are created/added to
788 * ivi_screen in create_layer
789 *
790 * base: to group ivi_surfaces of panel and background
791 * application: to group ivi_surfaces of ivi_applications
792 * workspace background: to group a ivi_surface of background in workspace
793 * workspace: to group ivi_surfaces for launching ivi_applications
794 *
795 * ivi_layers of workspace background and workspace is set to invisible at
796 * first. The properties of it is updated with animation when
797 * ivi_hmi_controller_home is requested.
798 */
799static struct hmi_controller *
800hmi_controller_create(struct weston_compositor *ec)
801{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900802 struct ivi_layout_screen *iviscrn = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900803 int32_t screen_width = 0;
804 int32_t screen_height = 0;
805 struct link_layer *tmp_link_layer = NULL;
806 int32_t panel_height = 0;
807 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900808 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900809 struct hmi_controller_layer *application_layer = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900810
811 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900812
813 wl_array_init(&hmi_ctrl->ui_widgets);
814 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
815 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
816 hmi_ctrl->compositor = ec;
817
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900818 /* TODO: shall support hotplug of screens */
819 if (get_screens(hmi_ctrl) < 0) {
820 weston_log("ivi-shell: Failed to get screens\n");
821 hmi_ctrl = NULL;
822 return hmi_ctrl;
823 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900824
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900825 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900826
827 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900828 wl_list_init(&hmi_ctrl->base_layer_list);
829 for (i = 0; i < hmi_ctrl->screen_num; i++) {
830 ivi_layout_interface->get_screen_resolution(get_screen(i, hmi_ctrl),
831 &screen_width,
832 &screen_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900833
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900834 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
835 base_layer->x = 0;
836 base_layer->y = 0;
837 base_layer->width = screen_width;
838 base_layer->height = screen_height;
839 base_layer->id_layer =
840 hmi_ctrl->hmi_setting->base_layer_id +
841 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
842 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900843
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900844 create_layer(get_screen(i, hmi_ctrl), base_layer);
845 }
846
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900847 panel_height = hmi_ctrl->hmi_setting->panel_height;
848
849 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900850 wl_list_init(&hmi_ctrl->application_layer_list);
851 for (i = 0; i < hmi_ctrl->screen_num; i++) {
852 ivi_layout_interface->get_screen_resolution(get_screen(i, hmi_ctrl),
853 &screen_width,
854 &screen_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900855
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900856 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
857 application_layer->x = 0;
858 application_layer->y = 0;
859 application_layer->width = screen_width;
860 application_layer->height = screen_height - panel_height;
861 application_layer->id_layer =
862 hmi_ctrl->hmi_setting->application_layer_id +
863 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
864 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
865
866 create_layer(get_screen(i, hmi_ctrl), application_layer);
867 }
868
869 ivi_layout_interface->get_screen_resolution(iviscrn, &screen_width,
870 &screen_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900871
872 /* init workspace background ivi_layer */
873 hmi_ctrl->workspace_background_layer.x = 0;
874 hmi_ctrl->workspace_background_layer.y = 0;
875 hmi_ctrl->workspace_background_layer.width = screen_width;
876 hmi_ctrl->workspace_background_layer.height =
877 screen_height - panel_height;
878
879 hmi_ctrl->workspace_background_layer.id_layer =
880 hmi_ctrl->hmi_setting->workspace_background_layer_id;
881
882 create_layer(iviscrn, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000883 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900884 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000885 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900886 hmi_ctrl->workspace_background_layer.ivilayer, false);
887
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900888
889 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
890 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900891 tmp_link_layer->layout_layer =
892 hmi_ctrl->workspace_background_layer.ivilayer;
893 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
894 &tmp_link_layer->link);
895
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000896 ivi_layout_interface->add_notification_create_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900897 set_notification_create_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000898 ivi_layout_interface->add_notification_remove_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900899 set_notification_remove_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000900 ivi_layout_interface->add_notification_configure_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900901 set_notification_configure_surface, hmi_ctrl);
902
903 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
904 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
905 &hmi_ctrl->destroy_listener);
906
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900907 return hmi_ctrl;
908}
909
910/**
911 * Implementations of ivi-hmi-controller.xml
912 */
913
914/**
915 * A ivi_surface drawing background is identified by id_surface.
916 * Properties of the ivi_surface is set by using ivi_layout APIs according to
917 * the scene graph of UI defined in hmi_controller_create.
918 *
919 * UI ivi_layer is used to add this ivi_surface.
920 */
921static void
922ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
923 uint32_t id_surface)
924{
925 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900926 struct hmi_controller_layer *base_layer = NULL;
927 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900928 struct hmi_controller_layer *application_layer =
929 wl_container_of(hmi_ctrl->application_layer_list.prev,
930 application_layer,
931 link);
932 const int32_t dstx = application_layer->x;
933 const int32_t dsty = application_layer->y;
934 const int32_t width = application_layer->width;
935 const int32_t height = application_layer->height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900936 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900937 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900938
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900939 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
940 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
941 sizeof(*add_surface_id));
942 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900943
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900944 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900945
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900946 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
947 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900948
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900949 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
950 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900951
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900952 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
953 dstx, dsty, width, height);
954 assert(!ret);
955
956 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
957 assert(!ret);
958
959 i++;
960 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900961}
962
963/**
964 * A ivi_surface drawing panel is identified by id_surface.
965 * Properties of the ivi_surface is set by using ivi_layout APIs according to
966 * the scene graph of UI defined in hmi_controller_create.
967 *
968 * UI ivi_layer is used to add this ivi_surface.
969 */
970static void
971ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
972 uint32_t id_surface)
973{
974 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900975 struct hmi_controller_layer *base_layer =
976 wl_container_of(hmi_ctrl->base_layer_list.prev,
977 base_layer,
978 link);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900979 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900980 const int32_t width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900981 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900982 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900983 const int32_t dstx = 0;
984 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900985 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900986
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900987 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
988 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
989 sizeof(*add_surface_id));
990 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900991
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900992 ivilayer = base_layer->ivilayer;
993 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
994 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900995
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900996 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
997 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900998
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900999 dsty = base_layer->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001000
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001001 ret = ivi_layout_interface->surface_set_destination_rectangle(
1002 ivisurf, dstx, dsty, width, panel_height);
1003 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001004
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001005 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
1006 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001007
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001008 i++;
1009 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001010}
1011
1012/**
1013 * A ivi_surface drawing buttons in panel is identified by id_surface.
1014 * It can set several buttons. Properties of the ivi_surface is set by
1015 * using ivi_layout APIs according to the scene graph of UI defined in
1016 * hmi_controller_create. Additionally, the position of it is shifted to
1017 * right when new one is requested.
1018 *
1019 * UI ivi_layer is used to add these ivi_surfaces.
1020 */
1021static void
1022ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
1023 uint32_t id_surface, int32_t number)
1024{
1025 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001026 struct hmi_controller_layer *base_layer =
1027 wl_container_of(hmi_ctrl->base_layer_list.prev,
1028 base_layer,
1029 link);
1030 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001031 const int32_t width = 48;
1032 const int32_t height = 48;
1033 int32_t ret = 0;
1034 int32_t panel_height = 0;
1035 int32_t dstx = 0;
1036 int32_t dsty = 0;
1037 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1038 sizeof(*add_surface_id));
1039 *add_surface_id = id_surface;
1040
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001041 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001042 assert(ivisurf != NULL);
1043
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001044 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001045 assert(!ret);
1046
1047 panel_height = hmi_ctrl->hmi_setting->panel_height;
1048
1049 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001050 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001051
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001052 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001053 ivisurf,dstx, dsty, width, height);
1054 assert(!ret);
1055
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001056 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001057 assert(!ret);
1058}
1059
1060/**
1061 * A ivi_surface drawing home button in panel is identified by id_surface.
1062 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1063 * the scene graph of UI defined in hmi_controller_create.
1064 *
1065 * UI ivi_layer is used to add these ivi_surfaces.
1066 */
1067static void
1068ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1069 uint32_t id_surface)
1070{
1071 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001072 struct hmi_controller_layer *base_layer =
1073 wl_container_of(hmi_ctrl->base_layer_list.prev,
1074 base_layer,
1075 link);
1076 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001077 int32_t ret = 0;
1078 int32_t size = 48;
1079 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001080 const int32_t dstx = (base_layer->width - size) / 2;
1081 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001082
1083 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1084 sizeof(*add_surface_id));
1085 *add_surface_id = id_surface;
1086
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001087 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001088 assert(ivisurf != NULL);
1089
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001090 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001091 assert(!ret);
1092
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001093 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001094 ivisurf, dstx, dsty, size, size);
1095 assert(!ret);
1096
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001097 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001098 assert(!ret);
1099}
1100
1101/**
1102 * A ivi_surface drawing background of workspace is identified by id_surface.
1103 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1104 * the scene graph of UI defined in hmi_controller_create.
1105 *
1106 * A ivi_layer of workspace_background is used to add this ivi_surface.
1107 */
1108static void
1109ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1110 uint32_t id_surface)
1111{
1112 struct ivi_layout_surface *ivisurf = NULL;
1113 struct ivi_layout_layer *ivilayer = NULL;
1114 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1115 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1116 int32_t ret = 0;
1117
1118 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1119 sizeof(*add_surface_id));
1120 *add_surface_id = id_surface;
1121 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1122
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001123 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001124 assert(ivisurf != NULL);
1125
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001126 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001127 assert(!ret);
1128
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001129 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001130 0, 0, width, height);
1131 assert(!ret);
1132
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001133 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001134 assert(!ret);
1135}
1136
1137/**
1138 * A list of ivi_surfaces drawing launchers in workspace is identified by
1139 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1140 * APIs according to the scene graph of UI defined in hmi_controller_create.
1141 *
1142 * The workspace can have several pages to group ivi_surfaces of launcher.
1143 * Each call of this interface increments a number of page to add a group
1144 * of ivi_surfaces
1145 */
1146static void
1147ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1148 int32_t icon_size)
1149{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001150 int32_t minspace_x = 10;
1151 int32_t minspace_y = minspace_x;
1152
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001153 int32_t width = hmi_ctrl->workspace_background_layer.width;
1154 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001155
1156 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1157 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1158 float fcell_size_x = icon_size + space_x;
1159
1160 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1161 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1162 float fcell_size_y = icon_size + space_y;
1163
1164 struct weston_config *config = NULL;
1165 struct weston_config_section *section = NULL;
1166 const char *name = NULL;
1167 int launcher_count = 0;
1168 struct wl_array launchers;
1169 int32_t nx = 0;
1170 int32_t ny = 0;
1171 int32_t prev = -1;
1172 struct launcher_info *data = NULL;
1173
1174 uint32_t surfaceid = 0;
1175 uint32_t workspaceid = 0;
1176 struct launcher_info *info = NULL;
1177
1178 int32_t x = 0;
1179 int32_t y = 0;
1180 int32_t ret = 0;
1181 struct ivi_layout_surface* layout_surface = NULL;
1182 uint32_t *add_surface_id = NULL;
1183
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001184 struct ivi_layout_screen *iviscrn = NULL;
1185 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001186
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001187 if (0 == x_count)
1188 x_count = 1;
1189
1190 if (0 == y_count)
1191 y_count = 1;
1192
1193 config = hmi_ctrl->compositor->config;
1194 if (!config)
1195 return;
1196
1197 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1198 if (!section)
1199 return;
1200
1201 wl_array_init(&launchers);
1202
1203 while (weston_config_next_section(config, &section, &name)) {
1204 surfaceid = 0;
1205 workspaceid = 0;
1206 info = NULL;
1207 if (0 != strcmp(name, "ivi-launcher"))
1208 continue;
1209
1210 if (0 != weston_config_section_get_uint(section, "icon-id",
1211 &surfaceid, 0))
1212 continue;
1213
1214 if (0 != weston_config_section_get_uint(section,
1215 "workspace-id",
1216 &workspaceid, 0))
1217 continue;
1218
1219 info = wl_array_add(&launchers, sizeof(*info));
1220
1221 if (info) {
1222 info->surface_id = surfaceid;
1223 info->workspace_id = workspaceid;
1224 info->index = launcher_count;
1225 ++launcher_count;
1226 }
1227 }
1228
1229 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1230 compare_launcher_info);
1231
1232 wl_array_for_each(data, &launchers) {
1233 x = 0;
1234 y = 0;
1235 ret = 0;
1236 layout_surface = NULL;
1237 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1238 sizeof(*add_surface_id));
1239
1240 *add_surface_id = data->surface_id;
1241
1242 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1243 nx = 0;
1244 ny = 0;
1245 prev = data->workspace_id;
1246
1247 if (0 <= prev)
1248 hmi_ctrl->workspace_count++;
1249 }
1250
1251 if (y_count == ny) {
1252 ny = 0;
1253 hmi_ctrl->workspace_count++;
1254 }
1255
1256 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1257 y = ny * fcell_size_y + space_y;
1258
1259 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001260 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001261 assert(layout_surface);
1262
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001263 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001264 layout_surface, x, y, icon_size, icon_size);
1265 assert(!ret);
1266
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001267 nx++;
1268
1269 if (x_count == nx) {
1270 ny++;
1271 nx = 0;
1272 }
1273 }
1274
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001275 /* init workspace ivi_layer */
1276 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1277 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1278 hmi_ctrl->workspace_layer.width =
1279 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1280 hmi_ctrl->workspace_layer.height =
1281 hmi_ctrl->workspace_background_layer.height;
1282 hmi_ctrl->workspace_layer.id_layer =
1283 hmi_ctrl->hmi_setting->workspace_layer_id;
1284
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001285 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001286 create_layer(iviscrn, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001287 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1288 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001289 false);
1290
1291 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1292 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1293 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1294 &tmp_link_layer->link);
1295
1296 /* Add surface to layer */
1297 wl_array_for_each(data, &launchers) {
1298 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001299 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001300 assert(layout_surface);
1301
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001302 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001303 layout_surface);
1304 assert(!ret);
1305
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001306 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001307 assert(!ret);
1308 }
1309
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001310 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001311 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001312}
1313
1314static void
1315ivi_hmi_controller_UI_ready(struct wl_client *client,
1316 struct wl_resource *resource)
1317{
1318 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1319
1320 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1321 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1322 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1323 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1324 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1325 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1326 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1327 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001328 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001329
1330 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1331 hmi_ctrl->is_initialized = 1;
1332}
1333
1334/**
1335 * Implementation of request and event of ivi_hmi_controller_workspace_control
1336 * and controlling workspace.
1337 *
1338 * When motion of input is detected in a ivi_surface of workspace background,
1339 * ivi_hmi_controller_workspace_control shall be invoked and to start
1340 * controlling of workspace. The workspace has several pages to show several
1341 * groups of applications.
1342 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1343 * according to motion. When motion finished, e.g. touch up detected, control is
1344 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1345 */
1346struct pointer_grab {
1347 struct weston_pointer_grab grab;
1348 struct ivi_layout_layer *layer;
1349 struct wl_resource *resource;
1350};
1351
1352struct touch_grab {
1353 struct weston_touch_grab grab;
1354 struct ivi_layout_layer *layer;
1355 struct wl_resource *resource;
1356};
1357
1358struct move_grab {
1359 wl_fixed_t dst[2];
1360 wl_fixed_t rgn[2][2];
1361 double v[2];
1362 struct timespec start_time;
1363 struct timespec pre_time;
1364 wl_fixed_t start_pos[2];
1365 wl_fixed_t pos[2];
1366 int32_t is_moved;
1367};
1368
1369struct pointer_move_grab {
1370 struct pointer_grab base;
1371 struct move_grab move;
1372};
1373
1374struct touch_move_grab {
1375 struct touch_grab base;
1376 struct move_grab move;
1377 int32_t is_active;
1378};
1379
1380static void
1381pointer_grab_start(struct pointer_grab *grab,
1382 struct ivi_layout_layer *layer,
1383 const struct weston_pointer_grab_interface *interface,
1384 struct weston_pointer *pointer)
1385{
1386 grab->grab.interface = interface;
1387 grab->layer = layer;
1388 weston_pointer_start_grab(pointer, &grab->grab);
1389}
1390
1391static void
1392touch_grab_start(struct touch_grab *grab,
1393 struct ivi_layout_layer *layer,
1394 const struct weston_touch_grab_interface *interface,
1395 struct weston_touch* touch)
1396{
1397 grab->grab.interface = interface;
1398 grab->layer = layer;
1399 weston_touch_start_grab(touch, &grab->grab);
1400}
1401
1402static int32_t
1403clamp(int32_t val, int32_t min, int32_t max)
1404{
1405 if (val < min)
1406 return min;
1407
1408 if (max < val)
1409 return max;
1410
1411 return val;
1412}
1413
1414static void
1415move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1416 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1417{
1418 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1419 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001420 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001421
1422 struct timespec time = {0};
1423 double grab_time = 0.0;
1424 double from_motion_time = 0.0;
1425 double pointer_v = 0.0;
1426 int32_t is_flick = 0;
1427 int32_t pos_x = 0;
1428 int32_t pos_y = 0;
1429 int page_no = 0;
1430 double end_pos = 0.0;
1431 uint32_t duration = 0;
1432
1433 clock_gettime(CLOCK_MONOTONIC, &time);
1434
1435 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1436 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1437
1438 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1439 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1440
1441 pointer_v = move->v[0];
1442
1443 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1444 if (200 < from_motion_time)
1445 pointer_v = 0.0;
1446
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001447 prop = ivi_layout_interface->get_properties_of_layer(layer);
1448 pos_x = prop->dest_x;
1449 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001450
1451 if (is_flick) {
1452 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1453 page_no = (-orgx + width / 2) / width;
1454
1455 if (pointer_v < 0.0)
1456 page_no++;
1457 else
1458 page_no--;
1459 } else {
1460 page_no = (-pos_x + width / 2) / width;
1461 }
1462
1463 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1464 end_pos = -page_no * width;
1465
1466 duration = hmi_ctrl->hmi_setting->transition_duration;
1467 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001468 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001469 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1470 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001471 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001472 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001473 hmi_ctrl->workspace_layer.width,
1474 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001475 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001476}
1477
1478static void
1479pointer_move_workspace_grab_end(struct pointer_grab *grab)
1480{
1481 struct pointer_move_grab *pnt_move_grab =
1482 (struct pointer_move_grab *)grab;
1483 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1484
1485 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1486 grab->grab.pointer->grab_x, layer);
1487
1488 weston_pointer_end_grab(grab->grab.pointer);
1489}
1490
1491static void
1492touch_move_workspace_grab_end(struct touch_grab *grab)
1493{
1494 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1495 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1496
1497 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1498 grab->grab.touch->grab_x, layer);
1499
1500 weston_touch_end_grab(grab->grab.touch);
1501}
1502
1503static void
1504pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1505{
1506}
1507
1508static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001509pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001510 uint32_t time,
1511 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001512{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001513 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001514}
1515
1516static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001517pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1518 uint32_t source)
1519{
1520 weston_pointer_send_axis_source(grab->pointer, source);
1521}
1522
1523static void
1524pointer_default_grab_frame(struct weston_pointer_grab *grab)
1525{
1526 weston_pointer_send_frame(grab->pointer);
1527}
1528
1529static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001530move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1531{
1532 struct timespec timestamp = {0};
1533 int32_t ii = 0;
1534 double dt = 0.0;
1535
1536 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1537 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1538 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1539
1540 if (dt < 1e-6)
1541 dt = 1e-6;
1542
1543 move->pre_time = timestamp;
1544
1545 for (ii = 0; ii < 2; ii++) {
1546 wl_fixed_t prepos = move->pos[ii];
1547 move->pos[ii] = pointer[ii] + move->dst[ii];
1548
1549 if (move->pos[ii] < move->rgn[0][ii]) {
1550 move->pos[ii] = move->rgn[0][ii];
1551 move->dst[ii] = move->pos[ii] - pointer[ii];
1552 } else if (move->rgn[1][ii] < move->pos[ii]) {
1553 move->pos[ii] = move->rgn[1][ii];
1554 move->dst[ii] = move->pos[ii] - pointer[ii];
1555 }
1556
1557 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1558
1559 if (!move->is_moved &&
1560 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1561 move->is_moved = 1;
1562 }
1563}
1564
1565static void
1566layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1567 wl_fixed_t pos_y)
1568{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001569 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001570 int32_t layout_pos_x = 0;
1571 int32_t layout_pos_y = 0;
1572
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001573 prop = ivi_layout_interface->get_properties_of_layer(layer);
1574
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001575 layout_pos_x = wl_fixed_to_int(pos_x);
1576 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001577 ivi_layout_interface->layer_set_destination_rectangle(layer,
1578 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001579 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001580}
1581
1582static void
1583pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001584 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001585{
1586 struct pointer_move_grab *pnt_move_grab =
1587 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001588 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001589
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001590 weston_pointer_motion_to_abs(grab->pointer, event,
1591 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001592 move_grab_update(&pnt_move_grab->move, pointer_pos);
1593 layer_set_pos(pnt_move_grab->base.layer,
1594 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001595 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001596}
1597
1598static void
1599touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1600 int touch_id, wl_fixed_t x, wl_fixed_t y)
1601{
1602 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1603
1604 if (!tch_move_grab->is_active)
1605 return;
1606
1607 wl_fixed_t pointer_pos[2] = {
1608 grab->touch->grab_x,
1609 grab->touch->grab_y
1610 };
1611
1612 move_grab_update(&tch_move_grab->move, pointer_pos);
1613 layer_set_pos(tch_move_grab->base.layer,
1614 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1615}
1616
1617static void
1618pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1619 uint32_t time, uint32_t button,
1620 uint32_t state_w)
1621{
1622 if (BTN_LEFT == button &&
1623 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1624 struct pointer_grab *pg = (struct pointer_grab *)grab;
1625
1626 pointer_move_workspace_grab_end(pg);
1627 free(grab);
1628 }
1629}
1630
1631static void
1632touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1633 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1634{
1635}
1636
1637static void
1638touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1639 int touch_id)
1640{
1641 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1642
1643 if (0 == touch_id)
1644 tch_move_grab->is_active = 0;
1645
1646 if (0 == grab->touch->num_tp) {
1647 touch_move_workspace_grab_end(&tch_move_grab->base);
1648 free(grab);
1649 }
1650}
1651
1652static void
1653pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1654{
1655 struct pointer_grab *pg = (struct pointer_grab *)grab;
1656
1657 pointer_move_workspace_grab_end(pg);
1658 free(grab);
1659}
1660
1661static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001662touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1663{
1664}
1665
1666static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001667touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1668{
1669 struct touch_grab *tg = (struct touch_grab *)grab;
1670
1671 touch_move_workspace_grab_end(tg);
1672 free(grab);
1673}
1674
1675static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1676 pointer_noop_grab_focus,
1677 pointer_move_grab_motion,
1678 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001679 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001680 pointer_default_grab_axis_source,
1681 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001682 pointer_move_workspace_grab_cancel
1683};
1684
1685static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1686 touch_nope_grab_down,
1687 touch_move_workspace_grab_up,
1688 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001689 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001690 touch_move_workspace_grab_cancel
1691};
1692
1693enum HMI_GRAB_DEVICE {
1694 HMI_GRAB_DEVICE_NONE,
1695 HMI_GRAB_DEVICE_POINTER,
1696 HMI_GRAB_DEVICE_TOUCH
1697};
1698
1699static enum HMI_GRAB_DEVICE
1700get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1701{
Derek Foreman1281a362015-07-31 16:55:32 -05001702 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1703 struct weston_touch *touch = weston_seat_get_touch(seat);
1704
1705 if (pointer &&
1706 pointer->focus &&
1707 pointer->button_count &&
1708 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001709 return HMI_GRAB_DEVICE_POINTER;
1710
Derek Foreman1281a362015-07-31 16:55:32 -05001711 if (touch &&
1712 touch->focus &&
1713 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001714 return HMI_GRAB_DEVICE_TOUCH;
1715
1716 return HMI_GRAB_DEVICE_NONE;
1717}
1718
1719static void
1720move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1721 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1722 struct wl_resource* resource)
1723{
1724 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1725 move->pre_time = move->start_time;
1726 move->pos[0] = start_pos[0];
1727 move->pos[1] = start_pos[1];
1728 move->start_pos[0] = start_pos[0];
1729 move->start_pos[1] = start_pos[1];
1730 move->dst[0] = start_pos[0] - grab_pos[0];
1731 move->dst[1] = start_pos[1] - grab_pos[1];
1732 memcpy(move->rgn, rgn, sizeof(move->rgn));
1733}
1734
1735static void
1736move_grab_init_workspace(struct move_grab* move,
1737 wl_fixed_t grab_x, wl_fixed_t grab_y,
1738 struct wl_resource *resource)
1739{
1740 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1741 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001742 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001743 int32_t workspace_count = hmi_ctrl->workspace_count;
1744 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1745 int32_t layer_pos_x = 0;
1746 int32_t layer_pos_y = 0;
1747 wl_fixed_t start_pos[2] = {0};
1748 wl_fixed_t rgn[2][2] = {{0}};
1749 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1750
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001751 prop = ivi_layout_interface->get_properties_of_layer(layer);
1752 layer_pos_x = prop->dest_x;
1753 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001754
1755 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1756 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1757
1758 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1759
1760 rgn[0][1] = wl_fixed_from_int(0);
1761 rgn[1][0] = wl_fixed_from_int(0);
1762 rgn[1][1] = wl_fixed_from_int(0);
1763
1764 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1765}
1766
1767static struct pointer_move_grab *
1768create_workspace_pointer_move(struct weston_pointer *pointer,
1769 struct wl_resource* resource)
1770{
1771 struct pointer_move_grab *pnt_move_grab =
1772 MEM_ALLOC(sizeof(*pnt_move_grab));
1773
1774 pnt_move_grab->base.resource = resource;
1775 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1776 pointer->grab_y, resource);
1777
1778 return pnt_move_grab;
1779}
1780
1781static struct touch_move_grab *
1782create_workspace_touch_move(struct weston_touch *touch,
1783 struct wl_resource* resource)
1784{
1785 struct touch_move_grab *tch_move_grab =
1786 MEM_ALLOC(sizeof(*tch_move_grab));
1787
1788 tch_move_grab->base.resource = resource;
1789 tch_move_grab->is_active = 1;
1790 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1791 touch->grab_y, resource);
1792
1793 return tch_move_grab;
1794}
1795
1796static void
1797ivi_hmi_controller_workspace_control(struct wl_client *client,
1798 struct wl_resource *resource,
1799 struct wl_resource *seat_resource,
1800 uint32_t serial)
1801{
1802 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1803 struct ivi_layout_layer *layer = NULL;
1804 struct pointer_move_grab *pnt_move_grab = NULL;
1805 struct touch_move_grab *tch_move_grab = NULL;
1806 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001807 struct weston_pointer *pointer;
1808 struct weston_touch *touch;
1809
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001810 enum HMI_GRAB_DEVICE device;
1811
1812 if (hmi_ctrl->workspace_count < 2)
1813 return;
1814
1815 seat = wl_resource_get_user_data(seat_resource);
1816 device = get_hmi_grab_device(seat, serial);
1817
1818 if (HMI_GRAB_DEVICE_POINTER != device &&
1819 HMI_GRAB_DEVICE_TOUCH != device)
1820 return;
1821
1822 layer = hmi_ctrl->workspace_layer.ivilayer;
1823
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001824 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001825
1826 switch (device) {
1827 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001828 pointer = weston_seat_get_pointer(seat);
1829 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001830 resource);
1831
1832 pointer_grab_start(&pnt_move_grab->base, layer,
1833 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001834 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001835 break;
1836
1837 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001838 touch = weston_seat_get_touch(seat);
1839 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001840 resource);
1841
1842 touch_grab_start(&tch_move_grab->base, layer,
1843 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001844 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001845 break;
1846
1847 default:
1848 break;
1849 }
1850}
1851
1852/**
1853 * Implementation of switch_mode
1854 */
1855static void
1856ivi_hmi_controller_switch_mode(struct wl_client *client,
1857 struct wl_resource *resource,
1858 uint32_t layout_mode)
1859{
1860 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1861
1862 switch_mode(hmi_ctrl, layout_mode);
1863}
1864
1865/**
1866 * Implementation of on/off displaying workspace and workspace background
1867 * ivi_layers.
1868 */
1869static void
1870ivi_hmi_controller_home(struct wl_client *client,
1871 struct wl_resource *resource,
1872 uint32_t home)
1873{
1874 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1875 uint32_t is_fade_in;
1876
1877 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1878 !hmi_ctrl->workspace_fade.is_fade_in) ||
1879 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1880 hmi_ctrl->workspace_fade.is_fade_in)) {
1881 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1882 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1883 &hmi_ctrl->workspace_fade);
1884 }
1885
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001886 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001887}
1888
1889/**
1890 * binding ivi-hmi-controller implementation
1891 */
1892static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1893 ivi_hmi_controller_UI_ready,
1894 ivi_hmi_controller_workspace_control,
1895 ivi_hmi_controller_switch_mode,
1896 ivi_hmi_controller_home
1897};
1898
1899static void
1900unbind_hmi_controller(struct wl_resource *resource)
1901{
1902}
1903
1904static void
1905bind_hmi_controller(struct wl_client *client,
1906 void *data, uint32_t version, uint32_t id)
1907{
1908 struct wl_resource *resource = NULL;
1909 struct hmi_controller *hmi_ctrl = data;
1910
1911 if (hmi_ctrl->user_interface != client) {
1912 struct wl_resource *res = wl_client_get_object(client, 1);
1913 wl_resource_post_error(res,
1914 WL_DISPLAY_ERROR_INVALID_OBJECT,
1915 "hmi-controller failed: permission denied");
1916 return;
1917 }
1918
1919 resource = wl_resource_create(
1920 client, &ivi_hmi_controller_interface, 1, id);
1921
1922 wl_resource_set_implementation(
1923 resource, &ivi_hmi_controller_implementation,
1924 hmi_ctrl, unbind_hmi_controller);
1925}
1926
1927static int32_t
1928initialize(struct hmi_controller *hmi_ctrl)
1929{
1930 struct config_command {
1931 char *key;
1932 uint32_t *dest;
1933 };
1934
1935 struct weston_config *config = hmi_ctrl->compositor->config;
1936 struct weston_config_section *section = NULL;
1937 int result = 0;
1938 int i = 0;
1939
1940 const struct config_command uint_commands[] = {
1941 { "background-id", &hmi_ctrl->ui_setting.background_id },
1942 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1943 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1944 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1945 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1946 { "random-id", &hmi_ctrl->ui_setting.random_id },
1947 { "home-id", &hmi_ctrl->ui_setting.home_id },
1948 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001949 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001950 { NULL, NULL }
1951 };
1952
1953 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1954
1955 for (i = 0; -1 != result; ++i) {
1956 const struct config_command *command = &uint_commands[i];
1957
1958 if (!command->key)
1959 break;
1960
1961 if (weston_config_section_get_uint(
1962 section, command->key, command->dest, 0) != 0)
1963 result = -1;
1964 }
1965
1966 if (-1 == result) {
1967 weston_log("Failed to initialize hmi-controller\n");
1968 return 0;
1969 }
1970
1971 return 1;
1972}
1973
1974static void
1975launch_hmi_client_process(void *data)
1976{
1977 struct hmi_controller *hmi_ctrl =
1978 (struct hmi_controller *)data;
1979
1980 hmi_ctrl->user_interface =
1981 weston_client_start(hmi_ctrl->compositor,
1982 hmi_ctrl->hmi_setting->ivi_homescreen);
1983
1984 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1985}
1986
1987/*****************************************************************************
1988 * exported functions
1989 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001990WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001991controller_module_init(struct weston_compositor *ec,
1992 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001993 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001994 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001995{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001996 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001997 struct wl_event_loop *loop = NULL;
1998
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001999 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04002000 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002001 return -1;
2002 }
2003
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00002004 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002005
2006 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09002007 if (hmi_ctrl == NULL)
2008 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002009
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09002010 if (!initialize(hmi_ctrl)) {
2011 return -1;
2012 }
2013
2014 if (wl_global_create(ec->wl_display,
2015 &ivi_hmi_controller_interface, 1,
2016 hmi_ctrl, bind_hmi_controller) == NULL) {
2017 return -1;
2018 }
2019
2020 loop = wl_display_get_event_loop(ec->wl_display);
2021 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
2022
2023 return 0;
2024}