blob: f3a88308f961b536e2c4b2bfb23ceed19b5ffc56 [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>
Jussi Kukkonen649bbce2016-07-19 14:16:27 +030055#include <stdint.h>
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090056#include <stdio.h>
57#include <string.h>
58#include <linux/input.h>
59#include <assert.h>
60#include <time.h>
61
62#include "ivi-layout-export.h"
63#include "ivi-hmi-controller-server-protocol.h"
Jon Cruz867d50e2015-06-15 15:37:10 -070064#include "shared/helpers.h"
Bryce Harringtone99e4bf2016-03-16 14:15:18 -070065#include "shared/xalloc.h"
Pekka Paalanen58f98c92016-06-03 16:45:21 +030066#include "compositor/weston.h"
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090067
68/*****************************************************************************
69 * structure, globals
70 ****************************************************************************/
71struct hmi_controller_layer {
72 struct ivi_layout_layer *ivilayer;
73 uint32_t id_layer;
74 int32_t x;
75 int32_t y;
76 int32_t width;
77 int32_t height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090078 struct wl_list link;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090079};
80
81struct link_layer {
82 struct ivi_layout_layer *layout_layer;
83 struct wl_list link;
84};
85
86struct hmi_controller_fade {
87 uint32_t is_fade_in;
88 struct wl_list layer_list;
89};
90
91struct hmi_server_setting {
92 uint32_t base_layer_id;
93 uint32_t application_layer_id;
94 uint32_t workspace_background_layer_id;
95 uint32_t workspace_layer_id;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090096 uint32_t base_layer_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090097 int32_t panel_height;
98 uint32_t transition_duration;
99 char *ivi_homescreen;
100};
101
102struct ui_setting {
103 uint32_t background_id;
104 uint32_t panel_id;
105 uint32_t tiling_id;
106 uint32_t sidebyside_id;
107 uint32_t fullscreen_id;
108 uint32_t random_id;
109 uint32_t home_id;
110 uint32_t workspace_background_id;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900111 uint32_t surface_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900112};
113
114struct hmi_controller {
115 struct hmi_server_setting *hmi_setting;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900116 /* List of struct hmi_controller_layer */
117 struct wl_list base_layer_list;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900118 struct wl_list application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900119 struct hmi_controller_layer workspace_background_layer;
120 struct hmi_controller_layer workspace_layer;
121 enum ivi_hmi_controller_layout_mode layout_mode;
122
123 struct hmi_controller_fade workspace_fade;
124
125 int32_t workspace_count;
126 struct wl_array ui_widgets;
127 int32_t is_initialized;
128
129 struct weston_compositor *compositor;
130 struct wl_listener destroy_listener;
131
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000132 struct wl_listener surface_created;
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000133 struct wl_listener surface_removed;
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000134 struct wl_listener surface_configured;
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000135
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900136 struct wl_client *user_interface;
137 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900138
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000139 struct weston_output * workspace_background_output;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900140 int32_t screen_num;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900141};
142
143struct launcher_info {
144 uint32_t surface_id;
145 uint32_t workspace_id;
146 int32_t index;
147};
148
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000149const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900150
151int
152controller_module_init(struct weston_compositor *ec,
153 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000154 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900155 size_t interface_version);
156
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900157/*****************************************************************************
158 * local functions
159 ****************************************************************************/
160static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900161mem_alloc(size_t size, char *file, int32_t line)
162{
163 return fail_on_null(calloc(1, size), size, file, line);
164}
165
166#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
167
168static int32_t
169is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
170 struct ivi_layout_surface *ivisurf)
171{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000172 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900173
174 uint32_t *ui_widget_id = NULL;
175 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
176 if (*ui_widget_id == id)
177 return 1;
178 }
179
180 return 0;
181}
182
183static int
184compare_launcher_info(const void *lhs, const void *rhs)
185{
186 const struct launcher_info *left = lhs;
187 const struct launcher_info *right = rhs;
188
189 if (left->workspace_id < right->workspace_id)
190 return -1;
191
192 if (left->workspace_id > right->workspace_id)
193 return 1;
194
195 if (left->index < right->index)
196 return -1;
197
198 if (left->index > right->index)
199 return 1;
200
201 return 0;
202}
203
204/**
205 * Internal methods called by mainly ivi_hmi_controller_switch_mode
206 * This reference shows 4 examples how to use ivi_layout APIs.
207 */
208static void
209mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
210 struct ivi_layout_surface **pp_surface,
211 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900212 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900213{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900214 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900215 const float surface_width = (float)layer->width * 0.25;
216 const float surface_height = (float)layer->height * 0.5;
217 int32_t surface_x = 0;
218 int32_t surface_y = 0;
219 struct ivi_layout_surface *ivisurf = NULL;
220 struct ivi_layout_surface **surfaces;
221 struct ivi_layout_surface **new_order;
222 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900223 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900224
225 int32_t i = 0;
226 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900227 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900228
229 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
230 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
231
232 for (i = 0; i < surface_length; i++) {
233 ivisurf = pp_surface[i];
234
235 /* skip ui widgets */
236 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
237 continue;
238
239 surfaces[surf_num++] = ivisurf;
240 }
241
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900242 wl_list_for_each_reverse(layer, layer_list, link) {
243 if (idx >= surf_num)
244 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900245
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900246 ivilayer = layer->ivilayer;
247
248 for (i = 0; i < 8; i++, idx++) {
249 if (idx >= surf_num)
250 break;
251
252 ivisurf = surfaces[idx];
253 new_order[i] = ivisurf;
254 if (i < 4) {
255 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900256 surface_y = 0;
257 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900258 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900259 surface_y = (int32_t)surface_height;
260 }
261
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000262 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900263 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
264 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000265 ivi_layout_interface->surface_set_visibility(ivisurf, true);
266 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900267 surface_x, surface_y,
268 (int32_t)surface_width,
269 (int32_t)surface_height);
270
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900271 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900272 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900273
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900274 ivi_layout_interface->layer_set_transition(ivilayer,
275 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
276 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900277 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900278 for (i = idx; i < surf_num; i++)
279 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900280
281 free(surfaces);
282 free(new_order);
283}
284
285static void
286mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
287 struct ivi_layout_surface **pp_surface,
288 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900289 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900290{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900291 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900292 int32_t surface_width = layer->width / 2;
293 int32_t surface_height = layer->height;
294 struct ivi_layout_surface *ivisurf = NULL;
295
296 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
297 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900298 struct ivi_layout_surface **surfaces;
299 struct ivi_layout_surface **new_order;
300 struct ivi_layout_layer *ivilayer = NULL;
301 int32_t surf_num = 0;
302 int32_t idx = 0;
303
304 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
305 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900306
307 for (i = 0; i < surface_length; i++) {
308 ivisurf = pp_surface[i];
309
310 /* skip ui widgets */
311 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
312 continue;
313
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900314 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900315 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900316
317 wl_list_for_each_reverse(layer, layer_list, link) {
318 if (idx >= surf_num)
319 break;
320
321 ivilayer = layer->ivilayer;
322
323 for (i = 0; i < 2; i++, idx++) {
324 if (idx >= surf_num)
325 break;
326
327 ivisurf = surfaces[idx];
328 new_order[i] = ivisurf;
329
330 ivi_layout_interface->surface_set_transition(ivisurf,
331 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
332 duration);
333 ivi_layout_interface->surface_set_visibility(ivisurf, true);
334
335 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
336 i * surface_width, 0,
337 surface_width,
338 surface_height);
339 }
340 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
341 }
342
343 for (i = idx; i < surf_num; i++) {
344 ivi_layout_interface->surface_set_transition(surfaces[i],
345 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
346 duration);
347 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
348 }
349
350 free(surfaces);
351 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900352}
353
354static void
355mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
356 struct ivi_layout_surface **pp_surface,
357 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900358 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900359{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900360 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900361 const int32_t surface_width = layer->width;
362 const int32_t surface_height = layer->height;
363 struct ivi_layout_surface *ivisurf = NULL;
364 int32_t i = 0;
365 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900366 int32_t surf_num = 0;
367 struct ivi_layout_surface **surfaces;
368
369 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900370
371 for (i = 0; i < surface_length; i++) {
372 ivisurf = pp_surface[i];
373
374 /* skip ui widgets */
375 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
376 continue;
377
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900378 surfaces[surf_num++] = ivisurf;
379 }
380 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
381
382 for (i = 0; i < surf_num; i++) {
383 ivisurf = surfaces[i];
384
385 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
386 layer = wl_container_of(layer->link.prev, layer, link);
387 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
388 }
389
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000390 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900391 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
392 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000393 ivi_layout_interface->surface_set_visibility(ivisurf, true);
394 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900395 surface_width,
396 surface_height);
397 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900398
399 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900400}
401
402static void
403mode_random_replace(struct hmi_controller *hmi_ctrl,
404 struct ivi_layout_surface **pp_surface,
405 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900406 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900407{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900408 struct hmi_controller_layer *application_layer = NULL;
409 struct hmi_controller_layer **layers = NULL;
410 int32_t surface_width = 0;
411 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900412 int32_t surface_x = 0;
413 int32_t surface_y = 0;
414 struct ivi_layout_surface *ivisurf = NULL;
415 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
416 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900417 int32_t layer_idx = 0;
418
419 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
420
421 wl_list_for_each(application_layer, layer_list, link) {
422 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900423 layer_idx++;
424 }
425
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900426 for (i = 0; i < surface_length; i++) {
427 ivisurf = pp_surface[i];
428
429 /* skip ui widgets */
430 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
431 continue;
432
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900433 /* surface determined at random a layer that belongs */
434 layer_idx = rand() % hmi_ctrl->screen_num;
435
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000436 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900437 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
438 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900439
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000440 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900441
442 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
443 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
444 surface_x = rand() % (layers[layer_idx]->width - surface_width);
445 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900446
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000447 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900448 surface_x,
449 surface_y,
450 surface_width,
451 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900452
453 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900454 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900455
456 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900457}
458
459static int32_t
460has_application_surface(struct hmi_controller *hmi_ctrl,
461 struct ivi_layout_surface **pp_surface,
462 int32_t surface_length)
463{
464 struct ivi_layout_surface *ivisurf = NULL;
465 int32_t i = 0;
466
467 for (i = 0; i < surface_length; i++) {
468 ivisurf = pp_surface[i];
469
470 /* skip ui widgets */
471 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
472 continue;
473
474 return 1;
475 }
476
477 return 0;
478}
479
480/**
481 * Supports 4 example to layout of application ivi_surfaces;
482 * tiling, side by side, fullscreen, and random.
483 */
484static void
485switch_mode(struct hmi_controller *hmi_ctrl,
486 enum ivi_hmi_controller_layout_mode layout_mode)
487{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900488 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900489 struct ivi_layout_surface **pp_surface = NULL;
490 int32_t surface_length = 0;
491 int32_t ret = 0;
492
493 if (!hmi_ctrl->is_initialized)
494 return;
495
496 hmi_ctrl->layout_mode = layout_mode;
497
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000498 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900499 assert(!ret);
500
501 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
502 free(pp_surface);
503 pp_surface = NULL;
504 return;
505 }
506
507 switch (layout_mode) {
508 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
509 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
510 layer);
511 break;
512 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
513 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
514 surface_length, layer);
515 break;
516 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
517 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
518 layer);
519 break;
520 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
521 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
522 layer);
523 break;
524 }
525
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000526 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900527 free(pp_surface);
528}
529
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900530/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900531 * Internal method for transition
532 */
533static void
534hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
535 struct hmi_controller_fade *fade)
536{
537 double tint = is_fade_in ? 1.0 : 0.0;
538 struct link_layer *linklayer = NULL;
539 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
540
541 fade->is_fade_in = is_fade_in;
542
543 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000544 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900545 IVI_LAYOUT_TRANSITION_LAYER_FADE,
546 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000547 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900548 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900549 }
550}
551
552/**
553 * Internal method to create ivi_layer with hmi_controller_layer and
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000554 * add to a weston_output
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900555 */
556static void
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000557create_layer(struct weston_output *output,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900558 struct hmi_controller_layer *layer)
559{
560 int32_t ret = 0;
561
562 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000563 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900564 layer->width,
565 layer->height);
566 assert(layer->ivilayer != NULL);
567
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000568 ret = ivi_layout_interface->screen_add_layer(output, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900569 assert(!ret);
570
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000571 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900572 layer->x, layer->y,
573 layer->width,
574 layer->height);
575 assert(!ret);
576
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000577 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900578 assert(!ret);
579}
580
581/**
582 * Internal set notification
583 */
584static void
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000585set_notification_create_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900586{
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000587 struct hmi_controller *hmi_ctrl =
588 wl_container_of(listener, hmi_ctrl,
589 surface_created);
590 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900591 struct hmi_controller_layer *layer_link =
592 wl_container_of(hmi_ctrl->application_layer_list.prev,
593 layer_link,
594 link);
595 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900596 int32_t ret = 0;
597
598 /* skip ui widgets */
599 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
600 return;
601
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000602 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900603 assert(!ret);
604}
605
606static void
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000607set_notification_remove_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900608{
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000609 struct hmi_controller *hmi_ctrl =
610 wl_container_of(listener, hmi_ctrl,
611 surface_removed);
612 (void)data;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900613
614 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
615}
616
617static void
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000618set_notification_configure_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900619{
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000620 struct hmi_controller *hmi_ctrl =
621 wl_container_of(listener, hmi_ctrl,
622 surface_configured);
623 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900624 struct hmi_controller_layer *layer_link = NULL;
625 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900626 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900627 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900628 int32_t length = 0;
629 int32_t i;
630
631 /* return if the surface is not application content */
632 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
633 return;
634 }
635
636 /*
637 * if application changes size of wl_buffer. The source rectangle shall be
638 * fit to the size.
639 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000640 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900641 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000642 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900643 ivisurf, 0, 0, surface->width,
644 surface->height);
645 }
646
647 /*
648 * search if the surface is already added to layer.
649 * If not yet, it is newly invoded application to go to switch_mode.
650 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900651 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
652 application_layer = layer_link->ivilayer;
653 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900654 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900655 for (i = 0; i < length; i++) {
656 if (ivisurf == ivisurfs[i]) {
657 /*
658 * if it is non new invoked application, just call
659 * commit_changes to apply source_rectangle.
660 */
661 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900662 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900663 return;
664 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900665 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900666 free(ivisurfs);
667 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900668 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900669
670 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
671}
672
673/**
674 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
675 * corresponding ivi_layer are defined in weston.ini. Default scene graph
676 * of ivi_layers are initialized in hmi_controller_create
677 */
678static struct hmi_server_setting *
679hmi_server_setting_create(struct weston_compositor *ec)
680{
681 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
Giulio Camuffod52f3b72016-06-02 21:48:11 +0300682 struct weston_config *config = wet_get_config(ec);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900683 struct weston_config_section *shell_section = NULL;
684
685 shell_section = weston_config_get_section(config, "ivi-shell",
686 NULL, NULL);
687
688 weston_config_section_get_uint(shell_section, "base-layer-id",
689 &setting->base_layer_id, 1000);
690
691 weston_config_section_get_uint(shell_section,
692 "workspace-background-layer-id",
693 &setting->workspace_background_layer_id,
694 2000);
695
696 weston_config_section_get_uint(shell_section, "workspace-layer-id",
697 &setting->workspace_layer_id, 3000);
698
699 weston_config_section_get_uint(shell_section, "application-layer-id",
700 &setting->application_layer_id, 4000);
701
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900702 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
703 &setting->base_layer_id_offset, 10000);
704
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900705 weston_config_section_get_uint(shell_section, "transition-duration",
706 &setting->transition_duration, 300);
707
708 setting->panel_height = 70;
709
710 weston_config_section_get_string(shell_section,
711 "ivi-shell-user-interface",
712 &setting->ivi_homescreen, NULL);
713
714 return setting;
715}
716
717static void
718hmi_controller_destroy(struct wl_listener *listener, void *data)
719{
720 struct link_layer *link = NULL;
721 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900722 struct hmi_controller_layer *ctrl_layer_link = NULL;
723 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900724 struct hmi_controller *hmi_ctrl =
725 container_of(listener, struct hmi_controller, destroy_listener);
726
727 wl_list_for_each_safe(link, next,
728 &hmi_ctrl->workspace_fade.layer_list, link) {
729 wl_list_remove(&link->link);
730 free(link);
731 }
732
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900733 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900734 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
735 &hmi_ctrl->base_layer_list, link) {
736 wl_list_remove(&ctrl_layer_link->link);
737 free(ctrl_layer_link);
738 }
739
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900740 /* clear application_layer_list */
741 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
742 &hmi_ctrl->application_layer_list, link) {
743 wl_list_remove(&ctrl_layer_link->link);
744 free(ctrl_layer_link);
745 }
746
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900747 wl_array_release(&hmi_ctrl->ui_widgets);
748 free(hmi_ctrl->hmi_setting);
749 free(hmi_ctrl);
750}
751
752/**
753 * This is a starting method called from module_init.
754 * This sets up scene graph of ivi_layers; base, application, workspace
755 * background, and workspace. These ivi_layers are created/added to
756 * ivi_screen in create_layer
757 *
758 * base: to group ivi_surfaces of panel and background
759 * application: to group ivi_surfaces of ivi_applications
760 * workspace background: to group a ivi_surface of background in workspace
761 * workspace: to group ivi_surfaces for launching ivi_applications
762 *
763 * ivi_layers of workspace background and workspace is set to invisible at
764 * first. The properties of it is updated with animation when
765 * ivi_hmi_controller_home is requested.
766 */
767static struct hmi_controller *
768hmi_controller_create(struct weston_compositor *ec)
769{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900770 struct link_layer *tmp_link_layer = NULL;
771 int32_t panel_height = 0;
772 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900773 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900774 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000775 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900776
777 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900778
779 wl_array_init(&hmi_ctrl->ui_widgets);
780 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
781 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
782 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000783 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900784
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900785 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900786 wl_list_init(&hmi_ctrl->base_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000787 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900788 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
789 base_layer->x = 0;
790 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000791 base_layer->width = output->current_mode->width;
792 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900793 base_layer->id_layer =
794 hmi_ctrl->hmi_setting->base_layer_id +
795 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
796 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900797
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000798 create_layer(output, base_layer);
799 i++;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900800 }
801
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000802 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900803 panel_height = hmi_ctrl->hmi_setting->panel_height;
804
805 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900806 wl_list_init(&hmi_ctrl->application_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000807 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900808 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
809 application_layer->x = 0;
810 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000811 application_layer->width = output->current_mode->width;
812 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900813 application_layer->id_layer =
814 hmi_ctrl->hmi_setting->application_layer_id +
815 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
816 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
817
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000818 create_layer(output, application_layer);
819 i++;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900820 }
821
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900822 /* init workspace background ivi_layer */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000823 output = wl_container_of(ec->output_list.next, output, link);
824 hmi_ctrl->workspace_background_output = output;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900825 hmi_ctrl->workspace_background_layer.x = 0;
826 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000827 hmi_ctrl->workspace_background_layer.width =
828 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900829 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000830 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900831
832 hmi_ctrl->workspace_background_layer.id_layer =
833 hmi_ctrl->hmi_setting->workspace_background_layer_id;
834
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000835 create_layer(output, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000836 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900837 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000838 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900839 hmi_ctrl->workspace_background_layer.ivilayer, false);
840
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900841
842 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
843 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900844 tmp_link_layer->layout_layer =
845 hmi_ctrl->workspace_background_layer.ivilayer;
846 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
847 &tmp_link_layer->link);
848
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000849 hmi_ctrl->surface_removed.notify = set_notification_remove_surface;
850 ivi_layout_interface->add_listener_remove_surface(&hmi_ctrl->surface_removed);
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000851
852 hmi_ctrl->surface_configured.notify = set_notification_configure_surface;
853 ivi_layout_interface->add_listener_configure_surface(&hmi_ctrl->surface_configured);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900854
855 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
856 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
857 &hmi_ctrl->destroy_listener);
858
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900859 return hmi_ctrl;
860}
861
862/**
863 * Implementations of ivi-hmi-controller.xml
864 */
865
866/**
867 * A ivi_surface drawing background is identified by id_surface.
868 * Properties of the ivi_surface is set by using ivi_layout APIs according to
869 * the scene graph of UI defined in hmi_controller_create.
870 *
871 * UI ivi_layer is used to add this ivi_surface.
872 */
873static void
874ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
875 uint32_t id_surface)
876{
877 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900878 struct hmi_controller_layer *base_layer = NULL;
879 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000880 int32_t dstx;
881 int32_t dsty;
882 int32_t width;
883 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900884 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900885 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900886
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900887 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
888 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
889 sizeof(*add_surface_id));
890 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000891 dstx = base_layer->x;
892 dsty = base_layer->y;
893 width = base_layer->width;
894 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900895 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900896
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900897 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
898 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900899
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900900 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
901 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900902
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900903 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
904 dstx, dsty, width, height);
905 assert(!ret);
906
907 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
908 assert(!ret);
909
910 i++;
911 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900912}
913
914/**
915 * A ivi_surface drawing panel 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_panel(struct hmi_controller *hmi_ctrl,
923 uint32_t id_surface)
924{
925 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000926 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900927 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000928 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900929 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900930 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900931 const int32_t dstx = 0;
932 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900933 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900934
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900935 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
936 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
937 sizeof(*add_surface_id));
938 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900939
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900940 ivilayer = base_layer->ivilayer;
941 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
942 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900943
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900944 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
945 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900946
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900947 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000948 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900949
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900950 ret = ivi_layout_interface->surface_set_destination_rectangle(
951 ivisurf, dstx, dsty, width, panel_height);
952 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900953
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900954 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
955 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900956
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900957 i++;
958 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900959}
960
961/**
962 * A ivi_surface drawing buttons in panel is identified by id_surface.
963 * It can set several buttons. Properties of the ivi_surface is set by
964 * using ivi_layout APIs according to the scene graph of UI defined in
965 * hmi_controller_create. Additionally, the position of it is shifted to
966 * right when new one is requested.
967 *
968 * UI ivi_layer is used to add these ivi_surfaces.
969 */
970static void
971ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
972 uint32_t id_surface, int32_t number)
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);
979 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900980 const int32_t width = 48;
981 const int32_t height = 48;
982 int32_t ret = 0;
983 int32_t panel_height = 0;
984 int32_t dstx = 0;
985 int32_t dsty = 0;
986 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
987 sizeof(*add_surface_id));
988 *add_surface_id = id_surface;
989
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000990 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900991 assert(ivisurf != NULL);
992
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000993 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900994 assert(!ret);
995
996 panel_height = hmi_ctrl->hmi_setting->panel_height;
997
998 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900999 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001000
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001001 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001002 ivisurf,dstx, dsty, width, height);
1003 assert(!ret);
1004
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001005 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001006 assert(!ret);
1007}
1008
1009/**
1010 * A ivi_surface drawing home button in panel is identified by id_surface.
1011 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1012 * the scene graph of UI defined in hmi_controller_create.
1013 *
1014 * UI ivi_layer is used to add these ivi_surfaces.
1015 */
1016static void
1017ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1018 uint32_t id_surface)
1019{
1020 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001021 struct hmi_controller_layer *base_layer =
1022 wl_container_of(hmi_ctrl->base_layer_list.prev,
1023 base_layer,
1024 link);
1025 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001026 int32_t ret = 0;
1027 int32_t size = 48;
1028 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001029 const int32_t dstx = (base_layer->width - size) / 2;
1030 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001031
1032 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1033 sizeof(*add_surface_id));
1034 *add_surface_id = id_surface;
1035
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001036 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001037 assert(ivisurf != NULL);
1038
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001039 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001040 assert(!ret);
1041
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001042 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001043 ivisurf, dstx, dsty, size, size);
1044 assert(!ret);
1045
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001046 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001047 assert(!ret);
1048}
1049
1050/**
1051 * A ivi_surface drawing background of workspace is identified by id_surface.
1052 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1053 * the scene graph of UI defined in hmi_controller_create.
1054 *
1055 * A ivi_layer of workspace_background is used to add this ivi_surface.
1056 */
1057static void
1058ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1059 uint32_t id_surface)
1060{
1061 struct ivi_layout_surface *ivisurf = NULL;
1062 struct ivi_layout_layer *ivilayer = NULL;
1063 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1064 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1065 int32_t ret = 0;
1066
1067 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1068 sizeof(*add_surface_id));
1069 *add_surface_id = id_surface;
1070 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1071
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001072 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001073 assert(ivisurf != NULL);
1074
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001075 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001076 assert(!ret);
1077
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001078 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001079 0, 0, width, height);
1080 assert(!ret);
1081
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001082 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001083 assert(!ret);
1084}
1085
1086/**
1087 * A list of ivi_surfaces drawing launchers in workspace is identified by
1088 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1089 * APIs according to the scene graph of UI defined in hmi_controller_create.
1090 *
1091 * The workspace can have several pages to group ivi_surfaces of launcher.
1092 * Each call of this interface increments a number of page to add a group
1093 * of ivi_surfaces
1094 */
1095static void
1096ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1097 int32_t icon_size)
1098{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001099 int32_t minspace_x = 10;
1100 int32_t minspace_y = minspace_x;
1101
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001102 int32_t width = hmi_ctrl->workspace_background_layer.width;
1103 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001104
1105 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1106 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1107 float fcell_size_x = icon_size + space_x;
1108
1109 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1110 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1111 float fcell_size_y = icon_size + space_y;
1112
1113 struct weston_config *config = NULL;
1114 struct weston_config_section *section = NULL;
1115 const char *name = NULL;
1116 int launcher_count = 0;
1117 struct wl_array launchers;
1118 int32_t nx = 0;
1119 int32_t ny = 0;
1120 int32_t prev = -1;
1121 struct launcher_info *data = NULL;
1122
1123 uint32_t surfaceid = 0;
1124 uint32_t workspaceid = 0;
1125 struct launcher_info *info = NULL;
1126
1127 int32_t x = 0;
1128 int32_t y = 0;
1129 int32_t ret = 0;
1130 struct ivi_layout_surface* layout_surface = NULL;
1131 uint32_t *add_surface_id = NULL;
1132
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001133 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001134
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001135 if (0 == x_count)
1136 x_count = 1;
1137
1138 if (0 == y_count)
1139 y_count = 1;
1140
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001141 config = wet_get_config(hmi_ctrl->compositor);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001142 if (!config)
1143 return;
1144
1145 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1146 if (!section)
1147 return;
1148
1149 wl_array_init(&launchers);
1150
1151 while (weston_config_next_section(config, &section, &name)) {
1152 surfaceid = 0;
1153 workspaceid = 0;
1154 info = NULL;
1155 if (0 != strcmp(name, "ivi-launcher"))
1156 continue;
1157
1158 if (0 != weston_config_section_get_uint(section, "icon-id",
1159 &surfaceid, 0))
1160 continue;
1161
1162 if (0 != weston_config_section_get_uint(section,
1163 "workspace-id",
1164 &workspaceid, 0))
1165 continue;
1166
1167 info = wl_array_add(&launchers, sizeof(*info));
1168
1169 if (info) {
1170 info->surface_id = surfaceid;
1171 info->workspace_id = workspaceid;
1172 info->index = launcher_count;
1173 ++launcher_count;
1174 }
1175 }
1176
1177 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1178 compare_launcher_info);
1179
1180 wl_array_for_each(data, &launchers) {
1181 x = 0;
1182 y = 0;
1183 ret = 0;
1184 layout_surface = NULL;
1185 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1186 sizeof(*add_surface_id));
1187
1188 *add_surface_id = data->surface_id;
1189
1190 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1191 nx = 0;
1192 ny = 0;
1193 prev = data->workspace_id;
1194
1195 if (0 <= prev)
1196 hmi_ctrl->workspace_count++;
1197 }
1198
1199 if (y_count == ny) {
1200 ny = 0;
1201 hmi_ctrl->workspace_count++;
1202 }
1203
1204 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1205 y = ny * fcell_size_y + space_y;
1206
1207 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001208 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001209 assert(layout_surface);
1210
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001211 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001212 layout_surface, x, y, icon_size, icon_size);
1213 assert(!ret);
1214
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001215 nx++;
1216
1217 if (x_count == nx) {
1218 ny++;
1219 nx = 0;
1220 }
1221 }
1222
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001223 /* init workspace ivi_layer */
1224 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1225 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1226 hmi_ctrl->workspace_layer.width =
1227 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1228 hmi_ctrl->workspace_layer.height =
1229 hmi_ctrl->workspace_background_layer.height;
1230 hmi_ctrl->workspace_layer.id_layer =
1231 hmi_ctrl->hmi_setting->workspace_layer_id;
1232
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001233 create_layer(hmi_ctrl->workspace_background_output, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001234 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1235 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001236 false);
1237
1238 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1239 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1240 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1241 &tmp_link_layer->link);
1242
1243 /* Add surface to layer */
1244 wl_array_for_each(data, &launchers) {
1245 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001246 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001247 assert(layout_surface);
1248
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001249 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001250 layout_surface);
1251 assert(!ret);
1252
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001253 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001254 assert(!ret);
1255 }
1256
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001257 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001258 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001259}
1260
1261static void
1262ivi_hmi_controller_UI_ready(struct wl_client *client,
1263 struct wl_resource *resource)
1264{
1265 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1266
1267 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1268 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1269 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1270 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1271 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1272 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1273 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1274 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001275 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001276
1277 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
Ucan, Emre (ADITG/SW1)d97f1002016-06-17 13:50:16 +00001278
1279 /* Add surface_created listener after the initialization of launchers.
1280 * Otherwise, surfaces of the launchers will be added to application
1281 * layer too.*/
1282 hmi_ctrl->surface_created.notify = set_notification_create_surface;
1283 ivi_layout_interface->add_listener_create_surface(&hmi_ctrl->surface_created);
1284
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001285 hmi_ctrl->is_initialized = 1;
1286}
1287
1288/**
1289 * Implementation of request and event of ivi_hmi_controller_workspace_control
1290 * and controlling workspace.
1291 *
1292 * When motion of input is detected in a ivi_surface of workspace background,
1293 * ivi_hmi_controller_workspace_control shall be invoked and to start
1294 * controlling of workspace. The workspace has several pages to show several
1295 * groups of applications.
1296 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1297 * according to motion. When motion finished, e.g. touch up detected, control is
1298 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1299 */
1300struct pointer_grab {
1301 struct weston_pointer_grab grab;
1302 struct ivi_layout_layer *layer;
1303 struct wl_resource *resource;
1304};
1305
1306struct touch_grab {
1307 struct weston_touch_grab grab;
1308 struct ivi_layout_layer *layer;
1309 struct wl_resource *resource;
1310};
1311
1312struct move_grab {
1313 wl_fixed_t dst[2];
1314 wl_fixed_t rgn[2][2];
1315 double v[2];
1316 struct timespec start_time;
1317 struct timespec pre_time;
1318 wl_fixed_t start_pos[2];
1319 wl_fixed_t pos[2];
1320 int32_t is_moved;
1321};
1322
1323struct pointer_move_grab {
1324 struct pointer_grab base;
1325 struct move_grab move;
1326};
1327
1328struct touch_move_grab {
1329 struct touch_grab base;
1330 struct move_grab move;
1331 int32_t is_active;
1332};
1333
1334static void
1335pointer_grab_start(struct pointer_grab *grab,
1336 struct ivi_layout_layer *layer,
1337 const struct weston_pointer_grab_interface *interface,
1338 struct weston_pointer *pointer)
1339{
1340 grab->grab.interface = interface;
1341 grab->layer = layer;
1342 weston_pointer_start_grab(pointer, &grab->grab);
1343}
1344
1345static void
1346touch_grab_start(struct touch_grab *grab,
1347 struct ivi_layout_layer *layer,
1348 const struct weston_touch_grab_interface *interface,
1349 struct weston_touch* touch)
1350{
1351 grab->grab.interface = interface;
1352 grab->layer = layer;
1353 weston_touch_start_grab(touch, &grab->grab);
1354}
1355
1356static int32_t
1357clamp(int32_t val, int32_t min, int32_t max)
1358{
1359 if (val < min)
1360 return min;
1361
1362 if (max < val)
1363 return max;
1364
1365 return val;
1366}
1367
1368static void
1369move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1370 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1371{
1372 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1373 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001374 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001375
1376 struct timespec time = {0};
1377 double grab_time = 0.0;
1378 double from_motion_time = 0.0;
1379 double pointer_v = 0.0;
1380 int32_t is_flick = 0;
1381 int32_t pos_x = 0;
1382 int32_t pos_y = 0;
1383 int page_no = 0;
1384 double end_pos = 0.0;
1385 uint32_t duration = 0;
1386
1387 clock_gettime(CLOCK_MONOTONIC, &time);
1388
1389 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1390 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1391
1392 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1393 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1394
1395 pointer_v = move->v[0];
1396
1397 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1398 if (200 < from_motion_time)
1399 pointer_v = 0.0;
1400
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001401 prop = ivi_layout_interface->get_properties_of_layer(layer);
1402 pos_x = prop->dest_x;
1403 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001404
1405 if (is_flick) {
1406 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1407 page_no = (-orgx + width / 2) / width;
1408
1409 if (pointer_v < 0.0)
1410 page_no++;
1411 else
1412 page_no--;
1413 } else {
1414 page_no = (-pos_x + width / 2) / width;
1415 }
1416
1417 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1418 end_pos = -page_no * width;
1419
1420 duration = hmi_ctrl->hmi_setting->transition_duration;
1421 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001422 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001423 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1424 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001425 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001426 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001427 hmi_ctrl->workspace_layer.width,
1428 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001429 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001430}
1431
1432static void
1433pointer_move_workspace_grab_end(struct pointer_grab *grab)
1434{
1435 struct pointer_move_grab *pnt_move_grab =
1436 (struct pointer_move_grab *)grab;
1437 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1438
1439 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1440 grab->grab.pointer->grab_x, layer);
1441
1442 weston_pointer_end_grab(grab->grab.pointer);
1443}
1444
1445static void
1446touch_move_workspace_grab_end(struct touch_grab *grab)
1447{
1448 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1449 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1450
1451 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1452 grab->grab.touch->grab_x, layer);
1453
1454 weston_touch_end_grab(grab->grab.touch);
1455}
1456
1457static void
1458pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1459{
1460}
1461
1462static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001463pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001464 uint32_t time,
1465 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001466{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001467 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001468}
1469
1470static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001471pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1472 uint32_t source)
1473{
1474 weston_pointer_send_axis_source(grab->pointer, source);
1475}
1476
1477static void
1478pointer_default_grab_frame(struct weston_pointer_grab *grab)
1479{
1480 weston_pointer_send_frame(grab->pointer);
1481}
1482
1483static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001484move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1485{
1486 struct timespec timestamp = {0};
1487 int32_t ii = 0;
1488 double dt = 0.0;
1489
1490 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1491 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1492 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1493
1494 if (dt < 1e-6)
1495 dt = 1e-6;
1496
1497 move->pre_time = timestamp;
1498
1499 for (ii = 0; ii < 2; ii++) {
1500 wl_fixed_t prepos = move->pos[ii];
1501 move->pos[ii] = pointer[ii] + move->dst[ii];
1502
1503 if (move->pos[ii] < move->rgn[0][ii]) {
1504 move->pos[ii] = move->rgn[0][ii];
1505 move->dst[ii] = move->pos[ii] - pointer[ii];
1506 } else if (move->rgn[1][ii] < move->pos[ii]) {
1507 move->pos[ii] = move->rgn[1][ii];
1508 move->dst[ii] = move->pos[ii] - pointer[ii];
1509 }
1510
1511 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1512
1513 if (!move->is_moved &&
1514 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1515 move->is_moved = 1;
1516 }
1517}
1518
1519static void
1520layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1521 wl_fixed_t pos_y)
1522{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001523 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001524 int32_t layout_pos_x = 0;
1525 int32_t layout_pos_y = 0;
1526
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001527 prop = ivi_layout_interface->get_properties_of_layer(layer);
1528
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001529 layout_pos_x = wl_fixed_to_int(pos_x);
1530 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001531 ivi_layout_interface->layer_set_destination_rectangle(layer,
1532 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001533 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001534}
1535
1536static void
1537pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001538 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001539{
1540 struct pointer_move_grab *pnt_move_grab =
1541 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001542 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001543
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001544 weston_pointer_motion_to_abs(grab->pointer, event,
1545 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001546 move_grab_update(&pnt_move_grab->move, pointer_pos);
1547 layer_set_pos(pnt_move_grab->base.layer,
1548 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001549 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001550}
1551
1552static void
1553touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1554 int touch_id, wl_fixed_t x, wl_fixed_t y)
1555{
1556 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1557
1558 if (!tch_move_grab->is_active)
1559 return;
1560
1561 wl_fixed_t pointer_pos[2] = {
1562 grab->touch->grab_x,
1563 grab->touch->grab_y
1564 };
1565
1566 move_grab_update(&tch_move_grab->move, pointer_pos);
1567 layer_set_pos(tch_move_grab->base.layer,
1568 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1569}
1570
1571static void
1572pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1573 uint32_t time, uint32_t button,
1574 uint32_t state_w)
1575{
1576 if (BTN_LEFT == button &&
1577 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1578 struct pointer_grab *pg = (struct pointer_grab *)grab;
1579
1580 pointer_move_workspace_grab_end(pg);
1581 free(grab);
1582 }
1583}
1584
1585static void
1586touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1587 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1588{
1589}
1590
1591static void
1592touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1593 int touch_id)
1594{
1595 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1596
1597 if (0 == touch_id)
1598 tch_move_grab->is_active = 0;
1599
1600 if (0 == grab->touch->num_tp) {
1601 touch_move_workspace_grab_end(&tch_move_grab->base);
1602 free(grab);
1603 }
1604}
1605
1606static void
1607pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1608{
1609 struct pointer_grab *pg = (struct pointer_grab *)grab;
1610
1611 pointer_move_workspace_grab_end(pg);
1612 free(grab);
1613}
1614
1615static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001616touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1617{
1618}
1619
1620static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001621touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1622{
1623 struct touch_grab *tg = (struct touch_grab *)grab;
1624
1625 touch_move_workspace_grab_end(tg);
1626 free(grab);
1627}
1628
1629static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1630 pointer_noop_grab_focus,
1631 pointer_move_grab_motion,
1632 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001633 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001634 pointer_default_grab_axis_source,
1635 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001636 pointer_move_workspace_grab_cancel
1637};
1638
1639static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1640 touch_nope_grab_down,
1641 touch_move_workspace_grab_up,
1642 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001643 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001644 touch_move_workspace_grab_cancel
1645};
1646
1647enum HMI_GRAB_DEVICE {
1648 HMI_GRAB_DEVICE_NONE,
1649 HMI_GRAB_DEVICE_POINTER,
1650 HMI_GRAB_DEVICE_TOUCH
1651};
1652
1653static enum HMI_GRAB_DEVICE
1654get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1655{
Derek Foreman1281a362015-07-31 16:55:32 -05001656 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1657 struct weston_touch *touch = weston_seat_get_touch(seat);
1658
1659 if (pointer &&
1660 pointer->focus &&
1661 pointer->button_count &&
1662 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001663 return HMI_GRAB_DEVICE_POINTER;
1664
Derek Foreman1281a362015-07-31 16:55:32 -05001665 if (touch &&
1666 touch->focus &&
1667 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001668 return HMI_GRAB_DEVICE_TOUCH;
1669
1670 return HMI_GRAB_DEVICE_NONE;
1671}
1672
1673static void
1674move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1675 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1676 struct wl_resource* resource)
1677{
1678 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1679 move->pre_time = move->start_time;
1680 move->pos[0] = start_pos[0];
1681 move->pos[1] = start_pos[1];
1682 move->start_pos[0] = start_pos[0];
1683 move->start_pos[1] = start_pos[1];
1684 move->dst[0] = start_pos[0] - grab_pos[0];
1685 move->dst[1] = start_pos[1] - grab_pos[1];
1686 memcpy(move->rgn, rgn, sizeof(move->rgn));
1687}
1688
1689static void
1690move_grab_init_workspace(struct move_grab* move,
1691 wl_fixed_t grab_x, wl_fixed_t grab_y,
1692 struct wl_resource *resource)
1693{
1694 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1695 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001696 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001697 int32_t workspace_count = hmi_ctrl->workspace_count;
1698 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1699 int32_t layer_pos_x = 0;
1700 int32_t layer_pos_y = 0;
1701 wl_fixed_t start_pos[2] = {0};
1702 wl_fixed_t rgn[2][2] = {{0}};
1703 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1704
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001705 prop = ivi_layout_interface->get_properties_of_layer(layer);
1706 layer_pos_x = prop->dest_x;
1707 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001708
1709 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1710 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1711
1712 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1713
1714 rgn[0][1] = wl_fixed_from_int(0);
1715 rgn[1][0] = wl_fixed_from_int(0);
1716 rgn[1][1] = wl_fixed_from_int(0);
1717
1718 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1719}
1720
1721static struct pointer_move_grab *
1722create_workspace_pointer_move(struct weston_pointer *pointer,
1723 struct wl_resource* resource)
1724{
1725 struct pointer_move_grab *pnt_move_grab =
1726 MEM_ALLOC(sizeof(*pnt_move_grab));
1727
1728 pnt_move_grab->base.resource = resource;
1729 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1730 pointer->grab_y, resource);
1731
1732 return pnt_move_grab;
1733}
1734
1735static struct touch_move_grab *
1736create_workspace_touch_move(struct weston_touch *touch,
1737 struct wl_resource* resource)
1738{
1739 struct touch_move_grab *tch_move_grab =
1740 MEM_ALLOC(sizeof(*tch_move_grab));
1741
1742 tch_move_grab->base.resource = resource;
1743 tch_move_grab->is_active = 1;
1744 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1745 touch->grab_y, resource);
1746
1747 return tch_move_grab;
1748}
1749
1750static void
1751ivi_hmi_controller_workspace_control(struct wl_client *client,
1752 struct wl_resource *resource,
1753 struct wl_resource *seat_resource,
1754 uint32_t serial)
1755{
1756 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1757 struct ivi_layout_layer *layer = NULL;
1758 struct pointer_move_grab *pnt_move_grab = NULL;
1759 struct touch_move_grab *tch_move_grab = NULL;
1760 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001761 struct weston_pointer *pointer;
1762 struct weston_touch *touch;
1763
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001764 enum HMI_GRAB_DEVICE device;
1765
1766 if (hmi_ctrl->workspace_count < 2)
1767 return;
1768
1769 seat = wl_resource_get_user_data(seat_resource);
1770 device = get_hmi_grab_device(seat, serial);
1771
1772 if (HMI_GRAB_DEVICE_POINTER != device &&
1773 HMI_GRAB_DEVICE_TOUCH != device)
1774 return;
1775
1776 layer = hmi_ctrl->workspace_layer.ivilayer;
1777
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001778 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001779
1780 switch (device) {
1781 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001782 pointer = weston_seat_get_pointer(seat);
1783 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001784 resource);
1785
1786 pointer_grab_start(&pnt_move_grab->base, layer,
1787 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001788 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001789 break;
1790
1791 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001792 touch = weston_seat_get_touch(seat);
1793 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001794 resource);
1795
1796 touch_grab_start(&tch_move_grab->base, layer,
1797 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001798 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001799 break;
1800
1801 default:
1802 break;
1803 }
1804}
1805
1806/**
1807 * Implementation of switch_mode
1808 */
1809static void
1810ivi_hmi_controller_switch_mode(struct wl_client *client,
1811 struct wl_resource *resource,
1812 uint32_t layout_mode)
1813{
1814 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1815
1816 switch_mode(hmi_ctrl, layout_mode);
1817}
1818
1819/**
1820 * Implementation of on/off displaying workspace and workspace background
1821 * ivi_layers.
1822 */
1823static void
1824ivi_hmi_controller_home(struct wl_client *client,
1825 struct wl_resource *resource,
1826 uint32_t home)
1827{
1828 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1829 uint32_t is_fade_in;
1830
1831 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1832 !hmi_ctrl->workspace_fade.is_fade_in) ||
1833 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1834 hmi_ctrl->workspace_fade.is_fade_in)) {
1835 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1836 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1837 &hmi_ctrl->workspace_fade);
1838 }
1839
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001840 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001841}
1842
1843/**
1844 * binding ivi-hmi-controller implementation
1845 */
1846static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1847 ivi_hmi_controller_UI_ready,
1848 ivi_hmi_controller_workspace_control,
1849 ivi_hmi_controller_switch_mode,
1850 ivi_hmi_controller_home
1851};
1852
1853static void
1854unbind_hmi_controller(struct wl_resource *resource)
1855{
1856}
1857
1858static void
1859bind_hmi_controller(struct wl_client *client,
1860 void *data, uint32_t version, uint32_t id)
1861{
1862 struct wl_resource *resource = NULL;
1863 struct hmi_controller *hmi_ctrl = data;
1864
1865 if (hmi_ctrl->user_interface != client) {
1866 struct wl_resource *res = wl_client_get_object(client, 1);
1867 wl_resource_post_error(res,
1868 WL_DISPLAY_ERROR_INVALID_OBJECT,
1869 "hmi-controller failed: permission denied");
1870 return;
1871 }
1872
1873 resource = wl_resource_create(
1874 client, &ivi_hmi_controller_interface, 1, id);
1875
1876 wl_resource_set_implementation(
1877 resource, &ivi_hmi_controller_implementation,
1878 hmi_ctrl, unbind_hmi_controller);
1879}
1880
1881static int32_t
1882initialize(struct hmi_controller *hmi_ctrl)
1883{
1884 struct config_command {
1885 char *key;
1886 uint32_t *dest;
1887 };
1888
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001889 struct weston_config *config = wet_get_config(hmi_ctrl->compositor);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001890 struct weston_config_section *section = NULL;
1891 int result = 0;
1892 int i = 0;
1893
1894 const struct config_command uint_commands[] = {
1895 { "background-id", &hmi_ctrl->ui_setting.background_id },
1896 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1897 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1898 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1899 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1900 { "random-id", &hmi_ctrl->ui_setting.random_id },
1901 { "home-id", &hmi_ctrl->ui_setting.home_id },
1902 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001903 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001904 { NULL, NULL }
1905 };
1906
1907 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1908
1909 for (i = 0; -1 != result; ++i) {
1910 const struct config_command *command = &uint_commands[i];
1911
1912 if (!command->key)
1913 break;
1914
1915 if (weston_config_section_get_uint(
1916 section, command->key, command->dest, 0) != 0)
1917 result = -1;
1918 }
1919
1920 if (-1 == result) {
1921 weston_log("Failed to initialize hmi-controller\n");
1922 return 0;
1923 }
1924
1925 return 1;
1926}
1927
1928static void
1929launch_hmi_client_process(void *data)
1930{
1931 struct hmi_controller *hmi_ctrl =
1932 (struct hmi_controller *)data;
1933
1934 hmi_ctrl->user_interface =
1935 weston_client_start(hmi_ctrl->compositor,
1936 hmi_ctrl->hmi_setting->ivi_homescreen);
1937
1938 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1939}
1940
1941/*****************************************************************************
1942 * exported functions
1943 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001944WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001945controller_module_init(struct weston_compositor *ec,
1946 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001947 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001948 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001949{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001950 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001951 struct wl_event_loop *loop = NULL;
1952
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001953 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001954 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001955 return -1;
1956 }
1957
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001958 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001959
1960 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001961 if (hmi_ctrl == NULL)
1962 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001963
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001964 if (!initialize(hmi_ctrl)) {
1965 return -1;
1966 }
1967
1968 if (wl_global_create(ec->wl_display,
1969 &ivi_hmi_controller_interface, 1,
1970 hmi_ctrl, bind_hmi_controller) == NULL) {
1971 return -1;
1972 }
1973
1974 loop = wl_display_get_event_loop(ec->wl_display);
1975 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1976
1977 return 0;
1978}