blob: fced66b9adf77785389574bdeb1aad2e24b62cf6 [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;
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 *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900154mem_alloc(size_t size, char *file, int32_t line)
155{
156 return fail_on_null(calloc(1, size), size, file, line);
157}
158
159#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
160
161static int32_t
162is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
163 struct ivi_layout_surface *ivisurf)
164{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000165 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900166
167 uint32_t *ui_widget_id = NULL;
168 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
169 if (*ui_widget_id == id)
170 return 1;
171 }
172
173 return 0;
174}
175
176static int
177compare_launcher_info(const void *lhs, const void *rhs)
178{
179 const struct launcher_info *left = lhs;
180 const struct launcher_info *right = rhs;
181
182 if (left->workspace_id < right->workspace_id)
183 return -1;
184
185 if (left->workspace_id > right->workspace_id)
186 return 1;
187
188 if (left->index < right->index)
189 return -1;
190
191 if (left->index > right->index)
192 return 1;
193
194 return 0;
195}
196
197/**
198 * Internal methods called by mainly ivi_hmi_controller_switch_mode
199 * This reference shows 4 examples how to use ivi_layout APIs.
200 */
201static void
202mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
203 struct ivi_layout_surface **pp_surface,
204 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900205 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900206{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900207 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900208 const float surface_width = (float)layer->width * 0.25;
209 const float surface_height = (float)layer->height * 0.5;
210 int32_t surface_x = 0;
211 int32_t surface_y = 0;
212 struct ivi_layout_surface *ivisurf = NULL;
213 struct ivi_layout_surface **surfaces;
214 struct ivi_layout_surface **new_order;
215 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900216 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900217
218 int32_t i = 0;
219 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900220 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900221
222 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
223 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
224
225 for (i = 0; i < surface_length; i++) {
226 ivisurf = pp_surface[i];
227
228 /* skip ui widgets */
229 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
230 continue;
231
232 surfaces[surf_num++] = ivisurf;
233 }
234
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900235 wl_list_for_each_reverse(layer, layer_list, link) {
236 if (idx >= surf_num)
237 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900238
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900239 ivilayer = layer->ivilayer;
240
241 for (i = 0; i < 8; i++, idx++) {
242 if (idx >= surf_num)
243 break;
244
245 ivisurf = surfaces[idx];
246 new_order[i] = ivisurf;
247 if (i < 4) {
248 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900249 surface_y = 0;
250 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900251 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900252 surface_y = (int32_t)surface_height;
253 }
254
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000255 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900256 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
257 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000258 ivi_layout_interface->surface_set_visibility(ivisurf, true);
259 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900260 surface_x, surface_y,
261 (int32_t)surface_width,
262 (int32_t)surface_height);
263
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900264 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900265 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900266
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900267 ivi_layout_interface->layer_set_transition(ivilayer,
268 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
269 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900270 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900271 for (i = idx; i < surf_num; i++)
272 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900273
274 free(surfaces);
275 free(new_order);
276}
277
278static void
279mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
280 struct ivi_layout_surface **pp_surface,
281 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900282 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900283{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900284 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900285 int32_t surface_width = layer->width / 2;
286 int32_t surface_height = layer->height;
287 struct ivi_layout_surface *ivisurf = NULL;
288
289 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
290 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900291 struct ivi_layout_surface **surfaces;
292 struct ivi_layout_surface **new_order;
293 struct ivi_layout_layer *ivilayer = NULL;
294 int32_t surf_num = 0;
295 int32_t idx = 0;
296
297 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
298 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900299
300 for (i = 0; i < surface_length; i++) {
301 ivisurf = pp_surface[i];
302
303 /* skip ui widgets */
304 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
305 continue;
306
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900307 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900308 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900309
310 wl_list_for_each_reverse(layer, layer_list, link) {
311 if (idx >= surf_num)
312 break;
313
314 ivilayer = layer->ivilayer;
315
316 for (i = 0; i < 2; i++, idx++) {
317 if (idx >= surf_num)
318 break;
319
320 ivisurf = surfaces[idx];
321 new_order[i] = ivisurf;
322
323 ivi_layout_interface->surface_set_transition(ivisurf,
324 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
325 duration);
326 ivi_layout_interface->surface_set_visibility(ivisurf, true);
327
328 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
329 i * surface_width, 0,
330 surface_width,
331 surface_height);
332 }
333 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
334 }
335
336 for (i = idx; i < surf_num; i++) {
337 ivi_layout_interface->surface_set_transition(surfaces[i],
338 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
339 duration);
340 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
341 }
342
343 free(surfaces);
344 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900345}
346
347static void
348mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
349 struct ivi_layout_surface **pp_surface,
350 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900351 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900352{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900353 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900354 const int32_t surface_width = layer->width;
355 const int32_t surface_height = layer->height;
356 struct ivi_layout_surface *ivisurf = NULL;
357 int32_t i = 0;
358 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900359 int32_t surf_num = 0;
360 struct ivi_layout_surface **surfaces;
361
362 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900363
364 for (i = 0; i < surface_length; i++) {
365 ivisurf = pp_surface[i];
366
367 /* skip ui widgets */
368 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
369 continue;
370
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900371 surfaces[surf_num++] = ivisurf;
372 }
373 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
374
375 for (i = 0; i < surf_num; i++) {
376 ivisurf = surfaces[i];
377
378 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
379 layer = wl_container_of(layer->link.prev, layer, link);
380 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
381 }
382
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000383 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900384 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
385 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000386 ivi_layout_interface->surface_set_visibility(ivisurf, true);
387 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900388 surface_width,
389 surface_height);
390 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900391
392 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900393}
394
395static void
396mode_random_replace(struct hmi_controller *hmi_ctrl,
397 struct ivi_layout_surface **pp_surface,
398 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900399 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900400{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900401 struct hmi_controller_layer *application_layer = NULL;
402 struct hmi_controller_layer **layers = NULL;
403 int32_t surface_width = 0;
404 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900405 int32_t surface_x = 0;
406 int32_t surface_y = 0;
407 struct ivi_layout_surface *ivisurf = NULL;
408 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
409 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900410 int32_t layer_idx = 0;
411
412 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
413
414 wl_list_for_each(application_layer, layer_list, link) {
415 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900416 layer_idx++;
417 }
418
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900419 for (i = 0; i < surface_length; i++) {
420 ivisurf = pp_surface[i];
421
422 /* skip ui widgets */
423 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
424 continue;
425
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900426 /* surface determined at random a layer that belongs */
427 layer_idx = rand() % hmi_ctrl->screen_num;
428
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000429 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900430 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
431 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900432
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000433 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900434
435 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
436 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
437 surface_x = rand() % (layers[layer_idx]->width - surface_width);
438 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900439
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000440 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900441 surface_x,
442 surface_y,
443 surface_width,
444 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900445
446 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900447 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900448
449 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900450}
451
452static int32_t
453has_application_surface(struct hmi_controller *hmi_ctrl,
454 struct ivi_layout_surface **pp_surface,
455 int32_t surface_length)
456{
457 struct ivi_layout_surface *ivisurf = NULL;
458 int32_t i = 0;
459
460 for (i = 0; i < surface_length; i++) {
461 ivisurf = pp_surface[i];
462
463 /* skip ui widgets */
464 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
465 continue;
466
467 return 1;
468 }
469
470 return 0;
471}
472
473/**
474 * Supports 4 example to layout of application ivi_surfaces;
475 * tiling, side by side, fullscreen, and random.
476 */
477static void
478switch_mode(struct hmi_controller *hmi_ctrl,
479 enum ivi_hmi_controller_layout_mode layout_mode)
480{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900481 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900482 struct ivi_layout_surface **pp_surface = NULL;
483 int32_t surface_length = 0;
484 int32_t ret = 0;
485
486 if (!hmi_ctrl->is_initialized)
487 return;
488
489 hmi_ctrl->layout_mode = layout_mode;
490
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000491 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900492 assert(!ret);
493
494 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
495 free(pp_surface);
496 pp_surface = NULL;
497 return;
498 }
499
500 switch (layout_mode) {
501 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
502 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
503 layer);
504 break;
505 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
506 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
507 surface_length, layer);
508 break;
509 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
510 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
511 layer);
512 break;
513 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
514 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
515 layer);
516 break;
517 }
518
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000519 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900520 free(pp_surface);
521}
522
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900523
524/**
525 * Internal method to get ivi_layout_screen
526 */
527static struct ivi_layout_screen *
528get_screen(int32_t screen_idx, struct hmi_controller *hmi_ctrl)
529{
530 struct ivi_layout_screen *iviscrn = NULL;
531
532 if (screen_idx > hmi_ctrl->screen_num - 1)
533 weston_log("Invalid index. Return NULL\n");
534 else
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000535 iviscrn = ivi_layout_interface->get_screen_from_id(screen_idx);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900536
537 return iviscrn;
538}
539
540/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900541 * Internal method for transition
542 */
543static void
544hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
545 struct hmi_controller_fade *fade)
546{
547 double tint = is_fade_in ? 1.0 : 0.0;
548 struct link_layer *linklayer = NULL;
549 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
550
551 fade->is_fade_in = is_fade_in;
552
553 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000554 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900555 IVI_LAYOUT_TRANSITION_LAYER_FADE,
556 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000557 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900558 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900559 }
560}
561
562/**
563 * Internal method to create ivi_layer with hmi_controller_layer and
564 * add to a ivi_screen
565 */
566static void
567create_layer(struct ivi_layout_screen *iviscrn,
568 struct hmi_controller_layer *layer)
569{
570 int32_t ret = 0;
571
572 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000573 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900574 layer->width,
575 layer->height);
576 assert(layer->ivilayer != NULL);
577
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000578 ret = ivi_layout_interface->screen_add_layer(iviscrn, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900579 assert(!ret);
580
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000581 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900582 layer->x, layer->y,
583 layer->width,
584 layer->height);
585 assert(!ret);
586
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000587 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900588 assert(!ret);
589}
590
591/**
592 * Internal set notification
593 */
594static void
595set_notification_create_surface(struct ivi_layout_surface *ivisurf,
596 void *userdata)
597{
598 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900599 struct hmi_controller_layer *layer_link =
600 wl_container_of(hmi_ctrl->application_layer_list.prev,
601 layer_link,
602 link);
603 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900604 int32_t ret = 0;
605
606 /* skip ui widgets */
607 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
608 return;
609
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000610 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900611 assert(!ret);
612}
613
614static void
615set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
616 void *userdata)
617{
618 struct hmi_controller *hmi_ctrl = userdata;
619
620 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
621}
622
623static void
624set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
625 void *userdata)
626{
627 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900628 struct hmi_controller_layer *layer_link = NULL;
629 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900630 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900631 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900632 int32_t length = 0;
633 int32_t i;
634
635 /* return if the surface is not application content */
636 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
637 return;
638 }
639
640 /*
641 * if application changes size of wl_buffer. The source rectangle shall be
642 * fit to the size.
643 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000644 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900645 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000646 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900647 ivisurf, 0, 0, surface->width,
648 surface->height);
649 }
650
651 /*
652 * search if the surface is already added to layer.
653 * If not yet, it is newly invoded application to go to switch_mode.
654 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900655 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
656 application_layer = layer_link->ivilayer;
657 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900658 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900659 for (i = 0; i < length; i++) {
660 if (ivisurf == ivisurfs[i]) {
661 /*
662 * if it is non new invoked application, just call
663 * commit_changes to apply source_rectangle.
664 */
665 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900666 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900667 return;
668 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900669 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900670 free(ivisurfs);
671 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900672 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900673
674 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
675}
676
677/**
678 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
679 * corresponding ivi_layer are defined in weston.ini. Default scene graph
680 * of ivi_layers are initialized in hmi_controller_create
681 */
682static struct hmi_server_setting *
683hmi_server_setting_create(struct weston_compositor *ec)
684{
685 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
686 struct weston_config *config = ec->config;
687 struct weston_config_section *shell_section = NULL;
688
689 shell_section = weston_config_get_section(config, "ivi-shell",
690 NULL, NULL);
691
692 weston_config_section_get_uint(shell_section, "base-layer-id",
693 &setting->base_layer_id, 1000);
694
695 weston_config_section_get_uint(shell_section,
696 "workspace-background-layer-id",
697 &setting->workspace_background_layer_id,
698 2000);
699
700 weston_config_section_get_uint(shell_section, "workspace-layer-id",
701 &setting->workspace_layer_id, 3000);
702
703 weston_config_section_get_uint(shell_section, "application-layer-id",
704 &setting->application_layer_id, 4000);
705
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900706 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
707 &setting->base_layer_id_offset, 10000);
708
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900709 weston_config_section_get_uint(shell_section, "transition-duration",
710 &setting->transition_duration, 300);
711
712 setting->panel_height = 70;
713
714 weston_config_section_get_string(shell_section,
715 "ivi-shell-user-interface",
716 &setting->ivi_homescreen, NULL);
717
718 return setting;
719}
720
721static void
722hmi_controller_destroy(struct wl_listener *listener, void *data)
723{
724 struct link_layer *link = NULL;
725 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900726 struct hmi_controller_layer *ctrl_layer_link = NULL;
727 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900728 struct hmi_controller *hmi_ctrl =
729 container_of(listener, struct hmi_controller, destroy_listener);
730
731 wl_list_for_each_safe(link, next,
732 &hmi_ctrl->workspace_fade.layer_list, link) {
733 wl_list_remove(&link->link);
734 free(link);
735 }
736
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900737 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900738 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
739 &hmi_ctrl->base_layer_list, link) {
740 wl_list_remove(&ctrl_layer_link->link);
741 free(ctrl_layer_link);
742 }
743
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900744 /* clear application_layer_list */
745 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
746 &hmi_ctrl->application_layer_list, link) {
747 wl_list_remove(&ctrl_layer_link->link);
748 free(ctrl_layer_link);
749 }
750
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900751 wl_array_release(&hmi_ctrl->ui_widgets);
752 free(hmi_ctrl->hmi_setting);
753 free(hmi_ctrl);
754}
755
756/**
757 * This is a starting method called from module_init.
758 * This sets up scene graph of ivi_layers; base, application, workspace
759 * background, and workspace. These ivi_layers are created/added to
760 * ivi_screen in create_layer
761 *
762 * base: to group ivi_surfaces of panel and background
763 * application: to group ivi_surfaces of ivi_applications
764 * workspace background: to group a ivi_surface of background in workspace
765 * workspace: to group ivi_surfaces for launching ivi_applications
766 *
767 * ivi_layers of workspace background and workspace is set to invisible at
768 * first. The properties of it is updated with animation when
769 * ivi_hmi_controller_home is requested.
770 */
771static struct hmi_controller *
772hmi_controller_create(struct weston_compositor *ec)
773{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900774 struct ivi_layout_screen *iviscrn = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900775 struct link_layer *tmp_link_layer = NULL;
776 int32_t panel_height = 0;
777 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900778 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900779 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000780 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900781
782 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900783
784 wl_array_init(&hmi_ctrl->ui_widgets);
785 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
786 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
787 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000788 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900789
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900790 /* TODO: shall support hotplug of screens */
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900791 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900792
793 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900794 wl_list_init(&hmi_ctrl->base_layer_list);
795 for (i = 0; i < hmi_ctrl->screen_num; i++) {
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000796 output = ivi_layout_interface->screen_get_output(get_screen(i, hmi_ctrl));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900797
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900798 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
799 base_layer->x = 0;
800 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000801 base_layer->width = output->current_mode->width;
802 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900803 base_layer->id_layer =
804 hmi_ctrl->hmi_setting->base_layer_id +
805 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
806 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900807
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900808 create_layer(get_screen(i, hmi_ctrl), base_layer);
809 }
810
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900811 panel_height = hmi_ctrl->hmi_setting->panel_height;
812
813 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900814 wl_list_init(&hmi_ctrl->application_layer_list);
815 for (i = 0; i < hmi_ctrl->screen_num; i++) {
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000816 output = ivi_layout_interface->screen_get_output(get_screen(i, hmi_ctrl));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900817
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900818 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
819 application_layer->x = 0;
820 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000821 application_layer->width = output->current_mode->width;
822 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900823 application_layer->id_layer =
824 hmi_ctrl->hmi_setting->application_layer_id +
825 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
826 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
827
828 create_layer(get_screen(i, hmi_ctrl), application_layer);
829 }
830
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000831 output = ivi_layout_interface->screen_get_output(iviscrn);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900832
833 /* init workspace background ivi_layer */
834 hmi_ctrl->workspace_background_layer.x = 0;
835 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000836 hmi_ctrl->workspace_background_layer.width =
837 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900838 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000839 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900840
841 hmi_ctrl->workspace_background_layer.id_layer =
842 hmi_ctrl->hmi_setting->workspace_background_layer_id;
843
844 create_layer(iviscrn, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000845 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900846 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000847 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900848 hmi_ctrl->workspace_background_layer.ivilayer, false);
849
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900850
851 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
852 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900853 tmp_link_layer->layout_layer =
854 hmi_ctrl->workspace_background_layer.ivilayer;
855 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
856 &tmp_link_layer->link);
857
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000858 ivi_layout_interface->add_notification_create_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900859 set_notification_create_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000860 ivi_layout_interface->add_notification_remove_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900861 set_notification_remove_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000862 ivi_layout_interface->add_notification_configure_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900863 set_notification_configure_surface, hmi_ctrl);
864
865 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
866 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
867 &hmi_ctrl->destroy_listener);
868
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900869 return hmi_ctrl;
870}
871
872/**
873 * Implementations of ivi-hmi-controller.xml
874 */
875
876/**
877 * A ivi_surface drawing background is identified by id_surface.
878 * Properties of the ivi_surface is set by using ivi_layout APIs according to
879 * the scene graph of UI defined in hmi_controller_create.
880 *
881 * UI ivi_layer is used to add this ivi_surface.
882 */
883static void
884ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
885 uint32_t id_surface)
886{
887 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900888 struct hmi_controller_layer *base_layer = NULL;
889 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000890 int32_t dstx;
891 int32_t dsty;
892 int32_t width;
893 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900894 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900895 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900896
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900897 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
898 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
899 sizeof(*add_surface_id));
900 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000901 dstx = base_layer->x;
902 dsty = base_layer->y;
903 width = base_layer->width;
904 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900905 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900906
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900907 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
908 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900909
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900910 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
911 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900912
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900913 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
914 dstx, dsty, width, height);
915 assert(!ret);
916
917 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
918 assert(!ret);
919
920 i++;
921 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900922}
923
924/**
925 * A ivi_surface drawing panel is identified by id_surface.
926 * Properties of the ivi_surface is set by using ivi_layout APIs according to
927 * the scene graph of UI defined in hmi_controller_create.
928 *
929 * UI ivi_layer is used to add this ivi_surface.
930 */
931static void
932ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
933 uint32_t id_surface)
934{
935 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000936 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900937 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000938 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900939 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900940 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900941 const int32_t dstx = 0;
942 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900943 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900944
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900945 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
946 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
947 sizeof(*add_surface_id));
948 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900949
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900950 ivilayer = base_layer->ivilayer;
951 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
952 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900953
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900954 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
955 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900956
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900957 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000958 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900959
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900960 ret = ivi_layout_interface->surface_set_destination_rectangle(
961 ivisurf, dstx, dsty, width, panel_height);
962 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900963
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900964 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
965 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900966
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900967 i++;
968 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900969}
970
971/**
972 * A ivi_surface drawing buttons in panel is identified by id_surface.
973 * It can set several buttons. Properties of the ivi_surface is set by
974 * using ivi_layout APIs according to the scene graph of UI defined in
975 * hmi_controller_create. Additionally, the position of it is shifted to
976 * right when new one is requested.
977 *
978 * UI ivi_layer is used to add these ivi_surfaces.
979 */
980static void
981ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
982 uint32_t id_surface, int32_t number)
983{
984 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900985 struct hmi_controller_layer *base_layer =
986 wl_container_of(hmi_ctrl->base_layer_list.prev,
987 base_layer,
988 link);
989 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900990 const int32_t width = 48;
991 const int32_t height = 48;
992 int32_t ret = 0;
993 int32_t panel_height = 0;
994 int32_t dstx = 0;
995 int32_t dsty = 0;
996 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
997 sizeof(*add_surface_id));
998 *add_surface_id = id_surface;
999
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001000 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001001 assert(ivisurf != NULL);
1002
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001003 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001004 assert(!ret);
1005
1006 panel_height = hmi_ctrl->hmi_setting->panel_height;
1007
1008 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001009 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001010
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001011 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001012 ivisurf,dstx, dsty, width, height);
1013 assert(!ret);
1014
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001015 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001016 assert(!ret);
1017}
1018
1019/**
1020 * A ivi_surface drawing home button in panel is identified by id_surface.
1021 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1022 * the scene graph of UI defined in hmi_controller_create.
1023 *
1024 * UI ivi_layer is used to add these ivi_surfaces.
1025 */
1026static void
1027ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1028 uint32_t id_surface)
1029{
1030 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001031 struct hmi_controller_layer *base_layer =
1032 wl_container_of(hmi_ctrl->base_layer_list.prev,
1033 base_layer,
1034 link);
1035 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001036 int32_t ret = 0;
1037 int32_t size = 48;
1038 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001039 const int32_t dstx = (base_layer->width - size) / 2;
1040 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001041
1042 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1043 sizeof(*add_surface_id));
1044 *add_surface_id = id_surface;
1045
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001046 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001047 assert(ivisurf != NULL);
1048
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001049 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001050 assert(!ret);
1051
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, size, size);
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 background of workspace 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 * A ivi_layer of workspace_background is used to add this ivi_surface.
1066 */
1067static void
1068ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1069 uint32_t id_surface)
1070{
1071 struct ivi_layout_surface *ivisurf = NULL;
1072 struct ivi_layout_layer *ivilayer = NULL;
1073 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1074 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1075 int32_t ret = 0;
1076
1077 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1078 sizeof(*add_surface_id));
1079 *add_surface_id = id_surface;
1080 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1081
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001082 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001083 assert(ivisurf != NULL);
1084
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001085 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001086 assert(!ret);
1087
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001088 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001089 0, 0, width, height);
1090 assert(!ret);
1091
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001092 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001093 assert(!ret);
1094}
1095
1096/**
1097 * A list of ivi_surfaces drawing launchers in workspace is identified by
1098 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1099 * APIs according to the scene graph of UI defined in hmi_controller_create.
1100 *
1101 * The workspace can have several pages to group ivi_surfaces of launcher.
1102 * Each call of this interface increments a number of page to add a group
1103 * of ivi_surfaces
1104 */
1105static void
1106ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1107 int32_t icon_size)
1108{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001109 int32_t minspace_x = 10;
1110 int32_t minspace_y = minspace_x;
1111
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001112 int32_t width = hmi_ctrl->workspace_background_layer.width;
1113 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001114
1115 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1116 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1117 float fcell_size_x = icon_size + space_x;
1118
1119 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1120 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1121 float fcell_size_y = icon_size + space_y;
1122
1123 struct weston_config *config = NULL;
1124 struct weston_config_section *section = NULL;
1125 const char *name = NULL;
1126 int launcher_count = 0;
1127 struct wl_array launchers;
1128 int32_t nx = 0;
1129 int32_t ny = 0;
1130 int32_t prev = -1;
1131 struct launcher_info *data = NULL;
1132
1133 uint32_t surfaceid = 0;
1134 uint32_t workspaceid = 0;
1135 struct launcher_info *info = NULL;
1136
1137 int32_t x = 0;
1138 int32_t y = 0;
1139 int32_t ret = 0;
1140 struct ivi_layout_surface* layout_surface = NULL;
1141 uint32_t *add_surface_id = NULL;
1142
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001143 struct ivi_layout_screen *iviscrn = NULL;
1144 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001145
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001146 if (0 == x_count)
1147 x_count = 1;
1148
1149 if (0 == y_count)
1150 y_count = 1;
1151
1152 config = hmi_ctrl->compositor->config;
1153 if (!config)
1154 return;
1155
1156 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1157 if (!section)
1158 return;
1159
1160 wl_array_init(&launchers);
1161
1162 while (weston_config_next_section(config, &section, &name)) {
1163 surfaceid = 0;
1164 workspaceid = 0;
1165 info = NULL;
1166 if (0 != strcmp(name, "ivi-launcher"))
1167 continue;
1168
1169 if (0 != weston_config_section_get_uint(section, "icon-id",
1170 &surfaceid, 0))
1171 continue;
1172
1173 if (0 != weston_config_section_get_uint(section,
1174 "workspace-id",
1175 &workspaceid, 0))
1176 continue;
1177
1178 info = wl_array_add(&launchers, sizeof(*info));
1179
1180 if (info) {
1181 info->surface_id = surfaceid;
1182 info->workspace_id = workspaceid;
1183 info->index = launcher_count;
1184 ++launcher_count;
1185 }
1186 }
1187
1188 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1189 compare_launcher_info);
1190
1191 wl_array_for_each(data, &launchers) {
1192 x = 0;
1193 y = 0;
1194 ret = 0;
1195 layout_surface = NULL;
1196 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1197 sizeof(*add_surface_id));
1198
1199 *add_surface_id = data->surface_id;
1200
1201 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1202 nx = 0;
1203 ny = 0;
1204 prev = data->workspace_id;
1205
1206 if (0 <= prev)
1207 hmi_ctrl->workspace_count++;
1208 }
1209
1210 if (y_count == ny) {
1211 ny = 0;
1212 hmi_ctrl->workspace_count++;
1213 }
1214
1215 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1216 y = ny * fcell_size_y + space_y;
1217
1218 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001219 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001220 assert(layout_surface);
1221
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001222 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001223 layout_surface, x, y, icon_size, icon_size);
1224 assert(!ret);
1225
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001226 nx++;
1227
1228 if (x_count == nx) {
1229 ny++;
1230 nx = 0;
1231 }
1232 }
1233
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001234 /* init workspace ivi_layer */
1235 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1236 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1237 hmi_ctrl->workspace_layer.width =
1238 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1239 hmi_ctrl->workspace_layer.height =
1240 hmi_ctrl->workspace_background_layer.height;
1241 hmi_ctrl->workspace_layer.id_layer =
1242 hmi_ctrl->hmi_setting->workspace_layer_id;
1243
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001244 iviscrn = get_screen(0, hmi_ctrl);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001245 create_layer(iviscrn, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001246 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1247 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001248 false);
1249
1250 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1251 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1252 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1253 &tmp_link_layer->link);
1254
1255 /* Add surface to layer */
1256 wl_array_for_each(data, &launchers) {
1257 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001258 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001259 assert(layout_surface);
1260
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001261 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001262 layout_surface);
1263 assert(!ret);
1264
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001265 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001266 assert(!ret);
1267 }
1268
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001269 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001270 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001271}
1272
1273static void
1274ivi_hmi_controller_UI_ready(struct wl_client *client,
1275 struct wl_resource *resource)
1276{
1277 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1278
1279 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1280 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1281 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1282 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1283 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1284 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1285 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1286 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001287 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001288
1289 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1290 hmi_ctrl->is_initialized = 1;
1291}
1292
1293/**
1294 * Implementation of request and event of ivi_hmi_controller_workspace_control
1295 * and controlling workspace.
1296 *
1297 * When motion of input is detected in a ivi_surface of workspace background,
1298 * ivi_hmi_controller_workspace_control shall be invoked and to start
1299 * controlling of workspace. The workspace has several pages to show several
1300 * groups of applications.
1301 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1302 * according to motion. When motion finished, e.g. touch up detected, control is
1303 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1304 */
1305struct pointer_grab {
1306 struct weston_pointer_grab grab;
1307 struct ivi_layout_layer *layer;
1308 struct wl_resource *resource;
1309};
1310
1311struct touch_grab {
1312 struct weston_touch_grab grab;
1313 struct ivi_layout_layer *layer;
1314 struct wl_resource *resource;
1315};
1316
1317struct move_grab {
1318 wl_fixed_t dst[2];
1319 wl_fixed_t rgn[2][2];
1320 double v[2];
1321 struct timespec start_time;
1322 struct timespec pre_time;
1323 wl_fixed_t start_pos[2];
1324 wl_fixed_t pos[2];
1325 int32_t is_moved;
1326};
1327
1328struct pointer_move_grab {
1329 struct pointer_grab base;
1330 struct move_grab move;
1331};
1332
1333struct touch_move_grab {
1334 struct touch_grab base;
1335 struct move_grab move;
1336 int32_t is_active;
1337};
1338
1339static void
1340pointer_grab_start(struct pointer_grab *grab,
1341 struct ivi_layout_layer *layer,
1342 const struct weston_pointer_grab_interface *interface,
1343 struct weston_pointer *pointer)
1344{
1345 grab->grab.interface = interface;
1346 grab->layer = layer;
1347 weston_pointer_start_grab(pointer, &grab->grab);
1348}
1349
1350static void
1351touch_grab_start(struct touch_grab *grab,
1352 struct ivi_layout_layer *layer,
1353 const struct weston_touch_grab_interface *interface,
1354 struct weston_touch* touch)
1355{
1356 grab->grab.interface = interface;
1357 grab->layer = layer;
1358 weston_touch_start_grab(touch, &grab->grab);
1359}
1360
1361static int32_t
1362clamp(int32_t val, int32_t min, int32_t max)
1363{
1364 if (val < min)
1365 return min;
1366
1367 if (max < val)
1368 return max;
1369
1370 return val;
1371}
1372
1373static void
1374move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1375 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1376{
1377 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1378 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001379 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001380
1381 struct timespec time = {0};
1382 double grab_time = 0.0;
1383 double from_motion_time = 0.0;
1384 double pointer_v = 0.0;
1385 int32_t is_flick = 0;
1386 int32_t pos_x = 0;
1387 int32_t pos_y = 0;
1388 int page_no = 0;
1389 double end_pos = 0.0;
1390 uint32_t duration = 0;
1391
1392 clock_gettime(CLOCK_MONOTONIC, &time);
1393
1394 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1395 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1396
1397 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1398 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1399
1400 pointer_v = move->v[0];
1401
1402 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1403 if (200 < from_motion_time)
1404 pointer_v = 0.0;
1405
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001406 prop = ivi_layout_interface->get_properties_of_layer(layer);
1407 pos_x = prop->dest_x;
1408 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001409
1410 if (is_flick) {
1411 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1412 page_no = (-orgx + width / 2) / width;
1413
1414 if (pointer_v < 0.0)
1415 page_no++;
1416 else
1417 page_no--;
1418 } else {
1419 page_no = (-pos_x + width / 2) / width;
1420 }
1421
1422 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1423 end_pos = -page_no * width;
1424
1425 duration = hmi_ctrl->hmi_setting->transition_duration;
1426 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001427 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001428 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1429 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001430 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001431 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001432 hmi_ctrl->workspace_layer.width,
1433 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001434 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001435}
1436
1437static void
1438pointer_move_workspace_grab_end(struct pointer_grab *grab)
1439{
1440 struct pointer_move_grab *pnt_move_grab =
1441 (struct pointer_move_grab *)grab;
1442 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1443
1444 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1445 grab->grab.pointer->grab_x, layer);
1446
1447 weston_pointer_end_grab(grab->grab.pointer);
1448}
1449
1450static void
1451touch_move_workspace_grab_end(struct touch_grab *grab)
1452{
1453 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1454 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1455
1456 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1457 grab->grab.touch->grab_x, layer);
1458
1459 weston_touch_end_grab(grab->grab.touch);
1460}
1461
1462static void
1463pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1464{
1465}
1466
1467static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001468pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001469 uint32_t time,
1470 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001471{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001472 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001473}
1474
1475static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001476pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1477 uint32_t source)
1478{
1479 weston_pointer_send_axis_source(grab->pointer, source);
1480}
1481
1482static void
1483pointer_default_grab_frame(struct weston_pointer_grab *grab)
1484{
1485 weston_pointer_send_frame(grab->pointer);
1486}
1487
1488static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001489move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1490{
1491 struct timespec timestamp = {0};
1492 int32_t ii = 0;
1493 double dt = 0.0;
1494
1495 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1496 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1497 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1498
1499 if (dt < 1e-6)
1500 dt = 1e-6;
1501
1502 move->pre_time = timestamp;
1503
1504 for (ii = 0; ii < 2; ii++) {
1505 wl_fixed_t prepos = move->pos[ii];
1506 move->pos[ii] = pointer[ii] + move->dst[ii];
1507
1508 if (move->pos[ii] < move->rgn[0][ii]) {
1509 move->pos[ii] = move->rgn[0][ii];
1510 move->dst[ii] = move->pos[ii] - pointer[ii];
1511 } else if (move->rgn[1][ii] < move->pos[ii]) {
1512 move->pos[ii] = move->rgn[1][ii];
1513 move->dst[ii] = move->pos[ii] - pointer[ii];
1514 }
1515
1516 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1517
1518 if (!move->is_moved &&
1519 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1520 move->is_moved = 1;
1521 }
1522}
1523
1524static void
1525layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1526 wl_fixed_t pos_y)
1527{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001528 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001529 int32_t layout_pos_x = 0;
1530 int32_t layout_pos_y = 0;
1531
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001532 prop = ivi_layout_interface->get_properties_of_layer(layer);
1533
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001534 layout_pos_x = wl_fixed_to_int(pos_x);
1535 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001536 ivi_layout_interface->layer_set_destination_rectangle(layer,
1537 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001538 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001539}
1540
1541static void
1542pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001543 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001544{
1545 struct pointer_move_grab *pnt_move_grab =
1546 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001547 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001548
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001549 weston_pointer_motion_to_abs(grab->pointer, event,
1550 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001551 move_grab_update(&pnt_move_grab->move, pointer_pos);
1552 layer_set_pos(pnt_move_grab->base.layer,
1553 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001554 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001555}
1556
1557static void
1558touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1559 int touch_id, wl_fixed_t x, wl_fixed_t y)
1560{
1561 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1562
1563 if (!tch_move_grab->is_active)
1564 return;
1565
1566 wl_fixed_t pointer_pos[2] = {
1567 grab->touch->grab_x,
1568 grab->touch->grab_y
1569 };
1570
1571 move_grab_update(&tch_move_grab->move, pointer_pos);
1572 layer_set_pos(tch_move_grab->base.layer,
1573 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1574}
1575
1576static void
1577pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1578 uint32_t time, uint32_t button,
1579 uint32_t state_w)
1580{
1581 if (BTN_LEFT == button &&
1582 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1583 struct pointer_grab *pg = (struct pointer_grab *)grab;
1584
1585 pointer_move_workspace_grab_end(pg);
1586 free(grab);
1587 }
1588}
1589
1590static void
1591touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1592 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1593{
1594}
1595
1596static void
1597touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1598 int touch_id)
1599{
1600 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1601
1602 if (0 == touch_id)
1603 tch_move_grab->is_active = 0;
1604
1605 if (0 == grab->touch->num_tp) {
1606 touch_move_workspace_grab_end(&tch_move_grab->base);
1607 free(grab);
1608 }
1609}
1610
1611static void
1612pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1613{
1614 struct pointer_grab *pg = (struct pointer_grab *)grab;
1615
1616 pointer_move_workspace_grab_end(pg);
1617 free(grab);
1618}
1619
1620static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001621touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1622{
1623}
1624
1625static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001626touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1627{
1628 struct touch_grab *tg = (struct touch_grab *)grab;
1629
1630 touch_move_workspace_grab_end(tg);
1631 free(grab);
1632}
1633
1634static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1635 pointer_noop_grab_focus,
1636 pointer_move_grab_motion,
1637 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001638 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001639 pointer_default_grab_axis_source,
1640 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001641 pointer_move_workspace_grab_cancel
1642};
1643
1644static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1645 touch_nope_grab_down,
1646 touch_move_workspace_grab_up,
1647 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001648 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001649 touch_move_workspace_grab_cancel
1650};
1651
1652enum HMI_GRAB_DEVICE {
1653 HMI_GRAB_DEVICE_NONE,
1654 HMI_GRAB_DEVICE_POINTER,
1655 HMI_GRAB_DEVICE_TOUCH
1656};
1657
1658static enum HMI_GRAB_DEVICE
1659get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1660{
Derek Foreman1281a362015-07-31 16:55:32 -05001661 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1662 struct weston_touch *touch = weston_seat_get_touch(seat);
1663
1664 if (pointer &&
1665 pointer->focus &&
1666 pointer->button_count &&
1667 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001668 return HMI_GRAB_DEVICE_POINTER;
1669
Derek Foreman1281a362015-07-31 16:55:32 -05001670 if (touch &&
1671 touch->focus &&
1672 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001673 return HMI_GRAB_DEVICE_TOUCH;
1674
1675 return HMI_GRAB_DEVICE_NONE;
1676}
1677
1678static void
1679move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1680 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1681 struct wl_resource* resource)
1682{
1683 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1684 move->pre_time = move->start_time;
1685 move->pos[0] = start_pos[0];
1686 move->pos[1] = start_pos[1];
1687 move->start_pos[0] = start_pos[0];
1688 move->start_pos[1] = start_pos[1];
1689 move->dst[0] = start_pos[0] - grab_pos[0];
1690 move->dst[1] = start_pos[1] - grab_pos[1];
1691 memcpy(move->rgn, rgn, sizeof(move->rgn));
1692}
1693
1694static void
1695move_grab_init_workspace(struct move_grab* move,
1696 wl_fixed_t grab_x, wl_fixed_t grab_y,
1697 struct wl_resource *resource)
1698{
1699 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1700 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001701 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001702 int32_t workspace_count = hmi_ctrl->workspace_count;
1703 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1704 int32_t layer_pos_x = 0;
1705 int32_t layer_pos_y = 0;
1706 wl_fixed_t start_pos[2] = {0};
1707 wl_fixed_t rgn[2][2] = {{0}};
1708 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1709
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001710 prop = ivi_layout_interface->get_properties_of_layer(layer);
1711 layer_pos_x = prop->dest_x;
1712 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001713
1714 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1715 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1716
1717 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1718
1719 rgn[0][1] = wl_fixed_from_int(0);
1720 rgn[1][0] = wl_fixed_from_int(0);
1721 rgn[1][1] = wl_fixed_from_int(0);
1722
1723 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1724}
1725
1726static struct pointer_move_grab *
1727create_workspace_pointer_move(struct weston_pointer *pointer,
1728 struct wl_resource* resource)
1729{
1730 struct pointer_move_grab *pnt_move_grab =
1731 MEM_ALLOC(sizeof(*pnt_move_grab));
1732
1733 pnt_move_grab->base.resource = resource;
1734 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1735 pointer->grab_y, resource);
1736
1737 return pnt_move_grab;
1738}
1739
1740static struct touch_move_grab *
1741create_workspace_touch_move(struct weston_touch *touch,
1742 struct wl_resource* resource)
1743{
1744 struct touch_move_grab *tch_move_grab =
1745 MEM_ALLOC(sizeof(*tch_move_grab));
1746
1747 tch_move_grab->base.resource = resource;
1748 tch_move_grab->is_active = 1;
1749 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1750 touch->grab_y, resource);
1751
1752 return tch_move_grab;
1753}
1754
1755static void
1756ivi_hmi_controller_workspace_control(struct wl_client *client,
1757 struct wl_resource *resource,
1758 struct wl_resource *seat_resource,
1759 uint32_t serial)
1760{
1761 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1762 struct ivi_layout_layer *layer = NULL;
1763 struct pointer_move_grab *pnt_move_grab = NULL;
1764 struct touch_move_grab *tch_move_grab = NULL;
1765 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001766 struct weston_pointer *pointer;
1767 struct weston_touch *touch;
1768
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001769 enum HMI_GRAB_DEVICE device;
1770
1771 if (hmi_ctrl->workspace_count < 2)
1772 return;
1773
1774 seat = wl_resource_get_user_data(seat_resource);
1775 device = get_hmi_grab_device(seat, serial);
1776
1777 if (HMI_GRAB_DEVICE_POINTER != device &&
1778 HMI_GRAB_DEVICE_TOUCH != device)
1779 return;
1780
1781 layer = hmi_ctrl->workspace_layer.ivilayer;
1782
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001783 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001784
1785 switch (device) {
1786 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001787 pointer = weston_seat_get_pointer(seat);
1788 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001789 resource);
1790
1791 pointer_grab_start(&pnt_move_grab->base, layer,
1792 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001793 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001794 break;
1795
1796 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001797 touch = weston_seat_get_touch(seat);
1798 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001799 resource);
1800
1801 touch_grab_start(&tch_move_grab->base, layer,
1802 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001803 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001804 break;
1805
1806 default:
1807 break;
1808 }
1809}
1810
1811/**
1812 * Implementation of switch_mode
1813 */
1814static void
1815ivi_hmi_controller_switch_mode(struct wl_client *client,
1816 struct wl_resource *resource,
1817 uint32_t layout_mode)
1818{
1819 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1820
1821 switch_mode(hmi_ctrl, layout_mode);
1822}
1823
1824/**
1825 * Implementation of on/off displaying workspace and workspace background
1826 * ivi_layers.
1827 */
1828static void
1829ivi_hmi_controller_home(struct wl_client *client,
1830 struct wl_resource *resource,
1831 uint32_t home)
1832{
1833 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1834 uint32_t is_fade_in;
1835
1836 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1837 !hmi_ctrl->workspace_fade.is_fade_in) ||
1838 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1839 hmi_ctrl->workspace_fade.is_fade_in)) {
1840 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1841 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1842 &hmi_ctrl->workspace_fade);
1843 }
1844
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001845 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001846}
1847
1848/**
1849 * binding ivi-hmi-controller implementation
1850 */
1851static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1852 ivi_hmi_controller_UI_ready,
1853 ivi_hmi_controller_workspace_control,
1854 ivi_hmi_controller_switch_mode,
1855 ivi_hmi_controller_home
1856};
1857
1858static void
1859unbind_hmi_controller(struct wl_resource *resource)
1860{
1861}
1862
1863static void
1864bind_hmi_controller(struct wl_client *client,
1865 void *data, uint32_t version, uint32_t id)
1866{
1867 struct wl_resource *resource = NULL;
1868 struct hmi_controller *hmi_ctrl = data;
1869
1870 if (hmi_ctrl->user_interface != client) {
1871 struct wl_resource *res = wl_client_get_object(client, 1);
1872 wl_resource_post_error(res,
1873 WL_DISPLAY_ERROR_INVALID_OBJECT,
1874 "hmi-controller failed: permission denied");
1875 return;
1876 }
1877
1878 resource = wl_resource_create(
1879 client, &ivi_hmi_controller_interface, 1, id);
1880
1881 wl_resource_set_implementation(
1882 resource, &ivi_hmi_controller_implementation,
1883 hmi_ctrl, unbind_hmi_controller);
1884}
1885
1886static int32_t
1887initialize(struct hmi_controller *hmi_ctrl)
1888{
1889 struct config_command {
1890 char *key;
1891 uint32_t *dest;
1892 };
1893
1894 struct weston_config *config = hmi_ctrl->compositor->config;
1895 struct weston_config_section *section = NULL;
1896 int result = 0;
1897 int i = 0;
1898
1899 const struct config_command uint_commands[] = {
1900 { "background-id", &hmi_ctrl->ui_setting.background_id },
1901 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1902 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1903 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1904 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1905 { "random-id", &hmi_ctrl->ui_setting.random_id },
1906 { "home-id", &hmi_ctrl->ui_setting.home_id },
1907 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001908 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001909 { NULL, NULL }
1910 };
1911
1912 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1913
1914 for (i = 0; -1 != result; ++i) {
1915 const struct config_command *command = &uint_commands[i];
1916
1917 if (!command->key)
1918 break;
1919
1920 if (weston_config_section_get_uint(
1921 section, command->key, command->dest, 0) != 0)
1922 result = -1;
1923 }
1924
1925 if (-1 == result) {
1926 weston_log("Failed to initialize hmi-controller\n");
1927 return 0;
1928 }
1929
1930 return 1;
1931}
1932
1933static void
1934launch_hmi_client_process(void *data)
1935{
1936 struct hmi_controller *hmi_ctrl =
1937 (struct hmi_controller *)data;
1938
1939 hmi_ctrl->user_interface =
1940 weston_client_start(hmi_ctrl->compositor,
1941 hmi_ctrl->hmi_setting->ivi_homescreen);
1942
1943 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1944}
1945
1946/*****************************************************************************
1947 * exported functions
1948 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001949WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001950controller_module_init(struct weston_compositor *ec,
1951 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001952 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001953 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001954{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001955 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001956 struct wl_event_loop *loop = NULL;
1957
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001958 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001959 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001960 return -1;
1961 }
1962
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001963 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001964
1965 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001966 if (hmi_ctrl == NULL)
1967 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001968
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001969 if (!initialize(hmi_ctrl)) {
1970 return -1;
1971 }
1972
1973 if (wl_global_create(ec->wl_display,
1974 &ivi_hmi_controller_interface, 1,
1975 hmi_ctrl, bind_hmi_controller) == NULL) {
1976 return -1;
1977 }
1978
1979 loop = wl_display_get_event_loop(ec->wl_display);
1980 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1981
1982 return 0;
1983}