blob: 0c28e817f9646e34980f5c61758270d5205ebc63 [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"
Pekka Paalanen58f98c92016-06-03 16:45:21 +030065#include "compositor/weston.h"
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090066
67/*****************************************************************************
68 * structure, globals
69 ****************************************************************************/
70struct hmi_controller_layer {
71 struct ivi_layout_layer *ivilayer;
72 uint32_t id_layer;
73 int32_t x;
74 int32_t y;
75 int32_t width;
76 int32_t height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090077 struct wl_list link;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090078};
79
80struct link_layer {
81 struct ivi_layout_layer *layout_layer;
82 struct wl_list link;
83};
84
85struct hmi_controller_fade {
86 uint32_t is_fade_in;
87 struct wl_list layer_list;
88};
89
90struct hmi_server_setting {
91 uint32_t base_layer_id;
92 uint32_t application_layer_id;
93 uint32_t workspace_background_layer_id;
94 uint32_t workspace_layer_id;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090095 uint32_t base_layer_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090096 int32_t panel_height;
97 uint32_t transition_duration;
98 char *ivi_homescreen;
99};
100
101struct ui_setting {
102 uint32_t background_id;
103 uint32_t panel_id;
104 uint32_t tiling_id;
105 uint32_t sidebyside_id;
106 uint32_t fullscreen_id;
107 uint32_t random_id;
108 uint32_t home_id;
109 uint32_t workspace_background_id;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900110 uint32_t surface_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900111};
112
113struct hmi_controller {
114 struct hmi_server_setting *hmi_setting;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900115 /* List of struct hmi_controller_layer */
116 struct wl_list base_layer_list;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900117 struct wl_list application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900118 struct hmi_controller_layer workspace_background_layer;
119 struct hmi_controller_layer workspace_layer;
120 enum ivi_hmi_controller_layout_mode layout_mode;
121
122 struct hmi_controller_fade workspace_fade;
123
124 int32_t workspace_count;
125 struct wl_array ui_widgets;
126 int32_t is_initialized;
127
128 struct weston_compositor *compositor;
129 struct wl_listener destroy_listener;
130
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000131 struct wl_listener surface_created;
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000132 struct wl_listener surface_removed;
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000133 struct wl_listener surface_configured;
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000134
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900135 struct wl_client *user_interface;
136 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900137
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000138 struct weston_output * workspace_background_output;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900139 int32_t screen_num;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900140};
141
142struct launcher_info {
143 uint32_t surface_id;
144 uint32_t workspace_id;
145 int32_t index;
146};
147
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000148const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900149
150int
151controller_module_init(struct weston_compositor *ec,
152 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000153 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900154 size_t interface_version);
155
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900156/*****************************************************************************
157 * local functions
158 ****************************************************************************/
159static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900160mem_alloc(size_t size, char *file, int32_t line)
161{
162 return fail_on_null(calloc(1, size), size, file, line);
163}
164
165#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
166
167static int32_t
168is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
169 struct ivi_layout_surface *ivisurf)
170{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000171 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900172
173 uint32_t *ui_widget_id = NULL;
174 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
175 if (*ui_widget_id == id)
176 return 1;
177 }
178
179 return 0;
180}
181
182static int
183compare_launcher_info(const void *lhs, const void *rhs)
184{
185 const struct launcher_info *left = lhs;
186 const struct launcher_info *right = rhs;
187
188 if (left->workspace_id < right->workspace_id)
189 return -1;
190
191 if (left->workspace_id > right->workspace_id)
192 return 1;
193
194 if (left->index < right->index)
195 return -1;
196
197 if (left->index > right->index)
198 return 1;
199
200 return 0;
201}
202
203/**
204 * Internal methods called by mainly ivi_hmi_controller_switch_mode
205 * This reference shows 4 examples how to use ivi_layout APIs.
206 */
207static void
208mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
209 struct ivi_layout_surface **pp_surface,
210 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900211 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900212{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900213 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900214 const float surface_width = (float)layer->width * 0.25;
215 const float surface_height = (float)layer->height * 0.5;
216 int32_t surface_x = 0;
217 int32_t surface_y = 0;
218 struct ivi_layout_surface *ivisurf = NULL;
219 struct ivi_layout_surface **surfaces;
220 struct ivi_layout_surface **new_order;
221 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900222 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900223
224 int32_t i = 0;
225 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900226 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900227
228 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
229 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
230
231 for (i = 0; i < surface_length; i++) {
232 ivisurf = pp_surface[i];
233
234 /* skip ui widgets */
235 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
236 continue;
237
238 surfaces[surf_num++] = ivisurf;
239 }
240
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900241 wl_list_for_each_reverse(layer, layer_list, link) {
242 if (idx >= surf_num)
243 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900244
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900245 ivilayer = layer->ivilayer;
246
247 for (i = 0; i < 8; i++, idx++) {
248 if (idx >= surf_num)
249 break;
250
251 ivisurf = surfaces[idx];
252 new_order[i] = ivisurf;
253 if (i < 4) {
254 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900255 surface_y = 0;
256 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900257 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900258 surface_y = (int32_t)surface_height;
259 }
260
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000261 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900262 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
263 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000264 ivi_layout_interface->surface_set_visibility(ivisurf, true);
265 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900266 surface_x, surface_y,
267 (int32_t)surface_width,
268 (int32_t)surface_height);
269
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900270 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900271 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900272
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900273 ivi_layout_interface->layer_set_transition(ivilayer,
274 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
275 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900276 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900277 for (i = idx; i < surf_num; i++)
278 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900279
280 free(surfaces);
281 free(new_order);
282}
283
284static void
285mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
286 struct ivi_layout_surface **pp_surface,
287 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900288 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900289{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900290 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900291 int32_t surface_width = layer->width / 2;
292 int32_t surface_height = layer->height;
293 struct ivi_layout_surface *ivisurf = NULL;
294
295 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
296 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900297 struct ivi_layout_surface **surfaces;
298 struct ivi_layout_surface **new_order;
299 struct ivi_layout_layer *ivilayer = NULL;
300 int32_t surf_num = 0;
301 int32_t idx = 0;
302
303 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
304 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900305
306 for (i = 0; i < surface_length; i++) {
307 ivisurf = pp_surface[i];
308
309 /* skip ui widgets */
310 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
311 continue;
312
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900313 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900314 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900315
316 wl_list_for_each_reverse(layer, layer_list, link) {
317 if (idx >= surf_num)
318 break;
319
320 ivilayer = layer->ivilayer;
321
322 for (i = 0; i < 2; i++, idx++) {
323 if (idx >= surf_num)
324 break;
325
326 ivisurf = surfaces[idx];
327 new_order[i] = ivisurf;
328
329 ivi_layout_interface->surface_set_transition(ivisurf,
330 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
331 duration);
332 ivi_layout_interface->surface_set_visibility(ivisurf, true);
333
334 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
335 i * surface_width, 0,
336 surface_width,
337 surface_height);
338 }
339 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
340 }
341
342 for (i = idx; i < surf_num; i++) {
343 ivi_layout_interface->surface_set_transition(surfaces[i],
344 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
345 duration);
346 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
347 }
348
349 free(surfaces);
350 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900351}
352
353static void
354mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
355 struct ivi_layout_surface **pp_surface,
356 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900357 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900358{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900359 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900360 const int32_t surface_width = layer->width;
361 const int32_t surface_height = layer->height;
362 struct ivi_layout_surface *ivisurf = NULL;
363 int32_t i = 0;
364 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900365 int32_t surf_num = 0;
366 struct ivi_layout_surface **surfaces;
367
368 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900369
370 for (i = 0; i < surface_length; i++) {
371 ivisurf = pp_surface[i];
372
373 /* skip ui widgets */
374 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
375 continue;
376
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900377 surfaces[surf_num++] = ivisurf;
378 }
379 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
380
381 for (i = 0; i < surf_num; i++) {
382 ivisurf = surfaces[i];
383
384 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
385 layer = wl_container_of(layer->link.prev, layer, link);
386 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
387 }
388
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000389 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900390 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
391 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000392 ivi_layout_interface->surface_set_visibility(ivisurf, true);
393 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900394 surface_width,
395 surface_height);
396 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900397
398 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900399}
400
401static void
402mode_random_replace(struct hmi_controller *hmi_ctrl,
403 struct ivi_layout_surface **pp_surface,
404 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900405 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900406{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900407 struct hmi_controller_layer *application_layer = NULL;
408 struct hmi_controller_layer **layers = NULL;
409 int32_t surface_width = 0;
410 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900411 int32_t surface_x = 0;
412 int32_t surface_y = 0;
413 struct ivi_layout_surface *ivisurf = NULL;
414 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
415 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900416 int32_t layer_idx = 0;
417
418 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
419
420 wl_list_for_each(application_layer, layer_list, link) {
421 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900422 layer_idx++;
423 }
424
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900425 for (i = 0; i < surface_length; i++) {
426 ivisurf = pp_surface[i];
427
428 /* skip ui widgets */
429 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
430 continue;
431
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900432 /* surface determined at random a layer that belongs */
433 layer_idx = rand() % hmi_ctrl->screen_num;
434
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000435 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900436 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
437 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900438
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000439 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900440
441 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
442 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
443 surface_x = rand() % (layers[layer_idx]->width - surface_width);
444 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900445
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000446 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900447 surface_x,
448 surface_y,
449 surface_width,
450 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900451
452 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900453 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900454
455 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900456}
457
458static int32_t
459has_application_surface(struct hmi_controller *hmi_ctrl,
460 struct ivi_layout_surface **pp_surface,
461 int32_t surface_length)
462{
463 struct ivi_layout_surface *ivisurf = NULL;
464 int32_t i = 0;
465
466 for (i = 0; i < surface_length; i++) {
467 ivisurf = pp_surface[i];
468
469 /* skip ui widgets */
470 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
471 continue;
472
473 return 1;
474 }
475
476 return 0;
477}
478
479/**
480 * Supports 4 example to layout of application ivi_surfaces;
481 * tiling, side by side, fullscreen, and random.
482 */
483static void
484switch_mode(struct hmi_controller *hmi_ctrl,
485 enum ivi_hmi_controller_layout_mode layout_mode)
486{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900487 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900488 struct ivi_layout_surface **pp_surface = NULL;
489 int32_t surface_length = 0;
490 int32_t ret = 0;
491
492 if (!hmi_ctrl->is_initialized)
493 return;
494
495 hmi_ctrl->layout_mode = layout_mode;
496
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000497 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900498 assert(!ret);
499
500 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
501 free(pp_surface);
502 pp_surface = NULL;
503 return;
504 }
505
506 switch (layout_mode) {
507 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
508 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
509 layer);
510 break;
511 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
512 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
513 surface_length, layer);
514 break;
515 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
516 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
517 layer);
518 break;
519 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
520 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
521 layer);
522 break;
523 }
524
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000525 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900526 free(pp_surface);
527}
528
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900529/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900530 * Internal method for transition
531 */
532static void
533hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
534 struct hmi_controller_fade *fade)
535{
536 double tint = is_fade_in ? 1.0 : 0.0;
537 struct link_layer *linklayer = NULL;
538 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
539
540 fade->is_fade_in = is_fade_in;
541
542 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000543 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900544 IVI_LAYOUT_TRANSITION_LAYER_FADE,
545 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000546 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900547 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900548 }
549}
550
551/**
552 * Internal method to create ivi_layer with hmi_controller_layer and
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000553 * add to a weston_output
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900554 */
555static void
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000556create_layer(struct weston_output *output,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900557 struct hmi_controller_layer *layer)
558{
559 int32_t ret = 0;
560
561 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000562 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900563 layer->width,
564 layer->height);
565 assert(layer->ivilayer != NULL);
566
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000567 ret = ivi_layout_interface->screen_add_layer(output, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900568 assert(!ret);
569
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000570 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900571 layer->x, layer->y,
572 layer->width,
573 layer->height);
574 assert(!ret);
575
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000576 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900577 assert(!ret);
578}
579
580/**
581 * Internal set notification
582 */
583static void
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000584set_notification_create_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900585{
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000586 struct hmi_controller *hmi_ctrl =
587 wl_container_of(listener, hmi_ctrl,
588 surface_created);
589 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900590 struct hmi_controller_layer *layer_link =
591 wl_container_of(hmi_ctrl->application_layer_list.prev,
592 layer_link,
593 link);
594 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900595 int32_t ret = 0;
596
597 /* skip ui widgets */
598 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
599 return;
600
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000601 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900602 assert(!ret);
603}
604
605static void
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000606set_notification_remove_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900607{
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000608 struct hmi_controller *hmi_ctrl =
609 wl_container_of(listener, hmi_ctrl,
610 surface_removed);
611 (void)data;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900612
613 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
614}
615
616static void
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000617set_notification_configure_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900618{
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000619 struct hmi_controller *hmi_ctrl =
620 wl_container_of(listener, hmi_ctrl,
621 surface_configured);
622 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900623 struct hmi_controller_layer *layer_link = NULL;
624 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900625 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900626 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900627 int32_t length = 0;
628 int32_t i;
629
630 /* return if the surface is not application content */
631 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
632 return;
633 }
634
635 /*
636 * if application changes size of wl_buffer. The source rectangle shall be
637 * fit to the size.
638 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000639 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900640 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000641 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900642 ivisurf, 0, 0, surface->width,
643 surface->height);
644 }
645
646 /*
647 * search if the surface is already added to layer.
648 * If not yet, it is newly invoded application to go to switch_mode.
649 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900650 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
651 application_layer = layer_link->ivilayer;
652 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900653 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900654 for (i = 0; i < length; i++) {
655 if (ivisurf == ivisurfs[i]) {
656 /*
657 * if it is non new invoked application, just call
658 * commit_changes to apply source_rectangle.
659 */
660 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900661 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900662 return;
663 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900664 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900665 free(ivisurfs);
666 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900667 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900668
669 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
670}
671
672/**
673 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
674 * corresponding ivi_layer are defined in weston.ini. Default scene graph
675 * of ivi_layers are initialized in hmi_controller_create
676 */
677static struct hmi_server_setting *
678hmi_server_setting_create(struct weston_compositor *ec)
679{
680 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
Giulio Camuffod52f3b72016-06-02 21:48:11 +0300681 struct weston_config *config = wet_get_config(ec);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900682 struct weston_config_section *shell_section = NULL;
683
684 shell_section = weston_config_get_section(config, "ivi-shell",
685 NULL, NULL);
686
687 weston_config_section_get_uint(shell_section, "base-layer-id",
688 &setting->base_layer_id, 1000);
689
690 weston_config_section_get_uint(shell_section,
691 "workspace-background-layer-id",
692 &setting->workspace_background_layer_id,
693 2000);
694
695 weston_config_section_get_uint(shell_section, "workspace-layer-id",
696 &setting->workspace_layer_id, 3000);
697
698 weston_config_section_get_uint(shell_section, "application-layer-id",
699 &setting->application_layer_id, 4000);
700
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900701 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
702 &setting->base_layer_id_offset, 10000);
703
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900704 weston_config_section_get_uint(shell_section, "transition-duration",
705 &setting->transition_duration, 300);
706
707 setting->panel_height = 70;
708
709 weston_config_section_get_string(shell_section,
710 "ivi-shell-user-interface",
711 &setting->ivi_homescreen, NULL);
712
713 return setting;
714}
715
716static void
717hmi_controller_destroy(struct wl_listener *listener, void *data)
718{
719 struct link_layer *link = NULL;
720 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900721 struct hmi_controller_layer *ctrl_layer_link = NULL;
722 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900723 struct hmi_controller *hmi_ctrl =
724 container_of(listener, struct hmi_controller, destroy_listener);
725
726 wl_list_for_each_safe(link, next,
727 &hmi_ctrl->workspace_fade.layer_list, link) {
728 wl_list_remove(&link->link);
729 free(link);
730 }
731
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900732 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900733 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
734 &hmi_ctrl->base_layer_list, link) {
735 wl_list_remove(&ctrl_layer_link->link);
736 free(ctrl_layer_link);
737 }
738
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900739 /* clear application_layer_list */
740 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
741 &hmi_ctrl->application_layer_list, link) {
742 wl_list_remove(&ctrl_layer_link->link);
743 free(ctrl_layer_link);
744 }
745
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900746 wl_array_release(&hmi_ctrl->ui_widgets);
747 free(hmi_ctrl->hmi_setting);
748 free(hmi_ctrl);
749}
750
751/**
752 * This is a starting method called from module_init.
753 * This sets up scene graph of ivi_layers; base, application, workspace
754 * background, and workspace. These ivi_layers are created/added to
755 * ivi_screen in create_layer
756 *
757 * base: to group ivi_surfaces of panel and background
758 * application: to group ivi_surfaces of ivi_applications
759 * workspace background: to group a ivi_surface of background in workspace
760 * workspace: to group ivi_surfaces for launching ivi_applications
761 *
762 * ivi_layers of workspace background and workspace is set to invisible at
763 * first. The properties of it is updated with animation when
764 * ivi_hmi_controller_home is requested.
765 */
766static struct hmi_controller *
767hmi_controller_create(struct weston_compositor *ec)
768{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900769 struct link_layer *tmp_link_layer = NULL;
770 int32_t panel_height = 0;
771 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900772 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900773 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000774 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900775
776 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900777
778 wl_array_init(&hmi_ctrl->ui_widgets);
779 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
780 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
781 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000782 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900783
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900784 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900785 wl_list_init(&hmi_ctrl->base_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000786 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900787 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
788 base_layer->x = 0;
789 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000790 base_layer->width = output->current_mode->width;
791 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900792 base_layer->id_layer =
793 hmi_ctrl->hmi_setting->base_layer_id +
794 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
795 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900796
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000797 create_layer(output, base_layer);
798 i++;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900799 }
800
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000801 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900802 panel_height = hmi_ctrl->hmi_setting->panel_height;
803
804 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900805 wl_list_init(&hmi_ctrl->application_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000806 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900807 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
808 application_layer->x = 0;
809 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000810 application_layer->width = output->current_mode->width;
811 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900812 application_layer->id_layer =
813 hmi_ctrl->hmi_setting->application_layer_id +
814 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
815 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
816
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000817 create_layer(output, application_layer);
818 i++;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900819 }
820
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900821 /* init workspace background ivi_layer */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000822 output = wl_container_of(ec->output_list.next, output, link);
823 hmi_ctrl->workspace_background_output = output;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900824 hmi_ctrl->workspace_background_layer.x = 0;
825 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000826 hmi_ctrl->workspace_background_layer.width =
827 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900828 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000829 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900830
831 hmi_ctrl->workspace_background_layer.id_layer =
832 hmi_ctrl->hmi_setting->workspace_background_layer_id;
833
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000834 create_layer(output, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000835 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900836 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000837 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900838 hmi_ctrl->workspace_background_layer.ivilayer, false);
839
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900840
841 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
842 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900843 tmp_link_layer->layout_layer =
844 hmi_ctrl->workspace_background_layer.ivilayer;
845 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
846 &tmp_link_layer->link);
847
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000848 hmi_ctrl->surface_removed.notify = set_notification_remove_surface;
849 ivi_layout_interface->add_listener_remove_surface(&hmi_ctrl->surface_removed);
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000850
851 hmi_ctrl->surface_configured.notify = set_notification_configure_surface;
852 ivi_layout_interface->add_listener_configure_surface(&hmi_ctrl->surface_configured);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900853
854 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
855 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
856 &hmi_ctrl->destroy_listener);
857
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900858 return hmi_ctrl;
859}
860
861/**
862 * Implementations of ivi-hmi-controller.xml
863 */
864
865/**
866 * A ivi_surface drawing background is identified by id_surface.
867 * Properties of the ivi_surface is set by using ivi_layout APIs according to
868 * the scene graph of UI defined in hmi_controller_create.
869 *
870 * UI ivi_layer is used to add this ivi_surface.
871 */
872static void
873ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
874 uint32_t id_surface)
875{
876 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900877 struct hmi_controller_layer *base_layer = NULL;
878 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000879 int32_t dstx;
880 int32_t dsty;
881 int32_t width;
882 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900883 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900884 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900885
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900886 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
887 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
888 sizeof(*add_surface_id));
889 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000890 dstx = base_layer->x;
891 dsty = base_layer->y;
892 width = base_layer->width;
893 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900894 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900895
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900896 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
897 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900898
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900899 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
900 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900901
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900902 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
903 dstx, dsty, width, height);
904 assert(!ret);
905
906 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
907 assert(!ret);
908
909 i++;
910 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900911}
912
913/**
914 * A ivi_surface drawing panel is identified by id_surface.
915 * Properties of the ivi_surface is set by using ivi_layout APIs according to
916 * the scene graph of UI defined in hmi_controller_create.
917 *
918 * UI ivi_layer is used to add this ivi_surface.
919 */
920static void
921ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
922 uint32_t id_surface)
923{
924 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000925 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900926 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000927 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900928 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900929 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900930 const int32_t dstx = 0;
931 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900932 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900933
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900934 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
935 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
936 sizeof(*add_surface_id));
937 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900938
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900939 ivilayer = base_layer->ivilayer;
940 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
941 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900942
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900943 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
944 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900945
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900946 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000947 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900948
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900949 ret = ivi_layout_interface->surface_set_destination_rectangle(
950 ivisurf, dstx, dsty, width, panel_height);
951 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900952
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900953 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
954 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900955
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900956 i++;
957 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900958}
959
960/**
961 * A ivi_surface drawing buttons in panel is identified by id_surface.
962 * It can set several buttons. Properties of the ivi_surface is set by
963 * using ivi_layout APIs according to the scene graph of UI defined in
964 * hmi_controller_create. Additionally, the position of it is shifted to
965 * right when new one is requested.
966 *
967 * UI ivi_layer is used to add these ivi_surfaces.
968 */
969static void
970ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
971 uint32_t id_surface, int32_t number)
972{
973 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900974 struct hmi_controller_layer *base_layer =
975 wl_container_of(hmi_ctrl->base_layer_list.prev,
976 base_layer,
977 link);
978 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900979 const int32_t width = 48;
980 const int32_t height = 48;
981 int32_t ret = 0;
982 int32_t panel_height = 0;
983 int32_t dstx = 0;
984 int32_t dsty = 0;
985 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
986 sizeof(*add_surface_id));
987 *add_surface_id = id_surface;
988
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000989 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900990 assert(ivisurf != NULL);
991
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000992 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900993 assert(!ret);
994
995 panel_height = hmi_ctrl->hmi_setting->panel_height;
996
997 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900998 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900999
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001000 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001001 ivisurf,dstx, dsty, width, height);
1002 assert(!ret);
1003
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001004 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001005 assert(!ret);
1006}
1007
1008/**
1009 * A ivi_surface drawing home button in panel is identified by id_surface.
1010 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1011 * the scene graph of UI defined in hmi_controller_create.
1012 *
1013 * UI ivi_layer is used to add these ivi_surfaces.
1014 */
1015static void
1016ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1017 uint32_t id_surface)
1018{
1019 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001020 struct hmi_controller_layer *base_layer =
1021 wl_container_of(hmi_ctrl->base_layer_list.prev,
1022 base_layer,
1023 link);
1024 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001025 int32_t ret = 0;
1026 int32_t size = 48;
1027 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001028 const int32_t dstx = (base_layer->width - size) / 2;
1029 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001030
1031 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1032 sizeof(*add_surface_id));
1033 *add_surface_id = id_surface;
1034
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001035 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001036 assert(ivisurf != NULL);
1037
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001038 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001039 assert(!ret);
1040
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001041 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001042 ivisurf, dstx, dsty, size, size);
1043 assert(!ret);
1044
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001045 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001046 assert(!ret);
1047}
1048
1049/**
1050 * A ivi_surface drawing background of workspace is identified by id_surface.
1051 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1052 * the scene graph of UI defined in hmi_controller_create.
1053 *
1054 * A ivi_layer of workspace_background is used to add this ivi_surface.
1055 */
1056static void
1057ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1058 uint32_t id_surface)
1059{
1060 struct ivi_layout_surface *ivisurf = NULL;
1061 struct ivi_layout_layer *ivilayer = NULL;
1062 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1063 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1064 int32_t ret = 0;
1065
1066 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1067 sizeof(*add_surface_id));
1068 *add_surface_id = id_surface;
1069 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1070
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001071 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001072 assert(ivisurf != NULL);
1073
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001074 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001075 assert(!ret);
1076
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001077 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001078 0, 0, width, height);
1079 assert(!ret);
1080
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001081 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001082 assert(!ret);
1083}
1084
1085/**
1086 * A list of ivi_surfaces drawing launchers in workspace is identified by
1087 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1088 * APIs according to the scene graph of UI defined in hmi_controller_create.
1089 *
1090 * The workspace can have several pages to group ivi_surfaces of launcher.
1091 * Each call of this interface increments a number of page to add a group
1092 * of ivi_surfaces
1093 */
1094static void
1095ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1096 int32_t icon_size)
1097{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001098 int32_t minspace_x = 10;
1099 int32_t minspace_y = minspace_x;
1100
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001101 int32_t width = hmi_ctrl->workspace_background_layer.width;
1102 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001103
1104 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1105 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1106 float fcell_size_x = icon_size + space_x;
1107
1108 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1109 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1110 float fcell_size_y = icon_size + space_y;
1111
1112 struct weston_config *config = NULL;
1113 struct weston_config_section *section = NULL;
1114 const char *name = NULL;
1115 int launcher_count = 0;
1116 struct wl_array launchers;
1117 int32_t nx = 0;
1118 int32_t ny = 0;
1119 int32_t prev = -1;
1120 struct launcher_info *data = NULL;
1121
1122 uint32_t surfaceid = 0;
1123 uint32_t workspaceid = 0;
1124 struct launcher_info *info = NULL;
1125
1126 int32_t x = 0;
1127 int32_t y = 0;
1128 int32_t ret = 0;
1129 struct ivi_layout_surface* layout_surface = NULL;
1130 uint32_t *add_surface_id = NULL;
1131
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001132 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001133
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001134 if (0 == x_count)
1135 x_count = 1;
1136
1137 if (0 == y_count)
1138 y_count = 1;
1139
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001140 config = wet_get_config(hmi_ctrl->compositor);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001141 if (!config)
1142 return;
1143
1144 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1145 if (!section)
1146 return;
1147
1148 wl_array_init(&launchers);
1149
1150 while (weston_config_next_section(config, &section, &name)) {
1151 surfaceid = 0;
1152 workspaceid = 0;
1153 info = NULL;
1154 if (0 != strcmp(name, "ivi-launcher"))
1155 continue;
1156
1157 if (0 != weston_config_section_get_uint(section, "icon-id",
1158 &surfaceid, 0))
1159 continue;
1160
1161 if (0 != weston_config_section_get_uint(section,
1162 "workspace-id",
1163 &workspaceid, 0))
1164 continue;
1165
1166 info = wl_array_add(&launchers, sizeof(*info));
1167
1168 if (info) {
1169 info->surface_id = surfaceid;
1170 info->workspace_id = workspaceid;
1171 info->index = launcher_count;
1172 ++launcher_count;
1173 }
1174 }
1175
1176 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1177 compare_launcher_info);
1178
1179 wl_array_for_each(data, &launchers) {
1180 x = 0;
1181 y = 0;
1182 ret = 0;
1183 layout_surface = NULL;
1184 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1185 sizeof(*add_surface_id));
1186
1187 *add_surface_id = data->surface_id;
1188
1189 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1190 nx = 0;
1191 ny = 0;
1192 prev = data->workspace_id;
1193
1194 if (0 <= prev)
1195 hmi_ctrl->workspace_count++;
1196 }
1197
1198 if (y_count == ny) {
1199 ny = 0;
1200 hmi_ctrl->workspace_count++;
1201 }
1202
1203 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1204 y = ny * fcell_size_y + space_y;
1205
1206 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001207 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001208 assert(layout_surface);
1209
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001210 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001211 layout_surface, x, y, icon_size, icon_size);
1212 assert(!ret);
1213
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001214 nx++;
1215
1216 if (x_count == nx) {
1217 ny++;
1218 nx = 0;
1219 }
1220 }
1221
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001222 /* init workspace ivi_layer */
1223 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1224 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1225 hmi_ctrl->workspace_layer.width =
1226 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1227 hmi_ctrl->workspace_layer.height =
1228 hmi_ctrl->workspace_background_layer.height;
1229 hmi_ctrl->workspace_layer.id_layer =
1230 hmi_ctrl->hmi_setting->workspace_layer_id;
1231
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001232 create_layer(hmi_ctrl->workspace_background_output, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001233 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1234 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001235 false);
1236
1237 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1238 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1239 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1240 &tmp_link_layer->link);
1241
1242 /* Add surface to layer */
1243 wl_array_for_each(data, &launchers) {
1244 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001245 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001246 assert(layout_surface);
1247
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001248 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001249 layout_surface);
1250 assert(!ret);
1251
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001252 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001253 assert(!ret);
1254 }
1255
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001256 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001257 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001258}
1259
1260static void
1261ivi_hmi_controller_UI_ready(struct wl_client *client,
1262 struct wl_resource *resource)
1263{
1264 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1265
1266 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1267 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1268 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1269 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1270 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1271 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1272 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1273 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001274 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001275
1276 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
Ucan, Emre (ADITG/SW1)d97f1002016-06-17 13:50:16 +00001277
1278 /* Add surface_created listener after the initialization of launchers.
1279 * Otherwise, surfaces of the launchers will be added to application
1280 * layer too.*/
1281 hmi_ctrl->surface_created.notify = set_notification_create_surface;
1282 ivi_layout_interface->add_listener_create_surface(&hmi_ctrl->surface_created);
1283
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001284 hmi_ctrl->is_initialized = 1;
1285}
1286
1287/**
1288 * Implementation of request and event of ivi_hmi_controller_workspace_control
1289 * and controlling workspace.
1290 *
1291 * When motion of input is detected in a ivi_surface of workspace background,
1292 * ivi_hmi_controller_workspace_control shall be invoked and to start
1293 * controlling of workspace. The workspace has several pages to show several
1294 * groups of applications.
1295 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1296 * according to motion. When motion finished, e.g. touch up detected, control is
1297 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1298 */
1299struct pointer_grab {
1300 struct weston_pointer_grab grab;
1301 struct ivi_layout_layer *layer;
1302 struct wl_resource *resource;
1303};
1304
1305struct touch_grab {
1306 struct weston_touch_grab grab;
1307 struct ivi_layout_layer *layer;
1308 struct wl_resource *resource;
1309};
1310
1311struct move_grab {
1312 wl_fixed_t dst[2];
1313 wl_fixed_t rgn[2][2];
1314 double v[2];
1315 struct timespec start_time;
1316 struct timespec pre_time;
1317 wl_fixed_t start_pos[2];
1318 wl_fixed_t pos[2];
1319 int32_t is_moved;
1320};
1321
1322struct pointer_move_grab {
1323 struct pointer_grab base;
1324 struct move_grab move;
1325};
1326
1327struct touch_move_grab {
1328 struct touch_grab base;
1329 struct move_grab move;
1330 int32_t is_active;
1331};
1332
1333static void
1334pointer_grab_start(struct pointer_grab *grab,
1335 struct ivi_layout_layer *layer,
1336 const struct weston_pointer_grab_interface *interface,
1337 struct weston_pointer *pointer)
1338{
1339 grab->grab.interface = interface;
1340 grab->layer = layer;
1341 weston_pointer_start_grab(pointer, &grab->grab);
1342}
1343
1344static void
1345touch_grab_start(struct touch_grab *grab,
1346 struct ivi_layout_layer *layer,
1347 const struct weston_touch_grab_interface *interface,
1348 struct weston_touch* touch)
1349{
1350 grab->grab.interface = interface;
1351 grab->layer = layer;
1352 weston_touch_start_grab(touch, &grab->grab);
1353}
1354
1355static int32_t
1356clamp(int32_t val, int32_t min, int32_t max)
1357{
1358 if (val < min)
1359 return min;
1360
1361 if (max < val)
1362 return max;
1363
1364 return val;
1365}
1366
1367static void
1368move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1369 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1370{
1371 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1372 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001373 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001374
1375 struct timespec time = {0};
1376 double grab_time = 0.0;
1377 double from_motion_time = 0.0;
1378 double pointer_v = 0.0;
1379 int32_t is_flick = 0;
1380 int32_t pos_x = 0;
1381 int32_t pos_y = 0;
1382 int page_no = 0;
1383 double end_pos = 0.0;
1384 uint32_t duration = 0;
1385
1386 clock_gettime(CLOCK_MONOTONIC, &time);
1387
1388 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1389 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1390
1391 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1392 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1393
1394 pointer_v = move->v[0];
1395
1396 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1397 if (200 < from_motion_time)
1398 pointer_v = 0.0;
1399
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001400 prop = ivi_layout_interface->get_properties_of_layer(layer);
1401 pos_x = prop->dest_x;
1402 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001403
1404 if (is_flick) {
1405 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1406 page_no = (-orgx + width / 2) / width;
1407
1408 if (pointer_v < 0.0)
1409 page_no++;
1410 else
1411 page_no--;
1412 } else {
1413 page_no = (-pos_x + width / 2) / width;
1414 }
1415
1416 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1417 end_pos = -page_no * width;
1418
1419 duration = hmi_ctrl->hmi_setting->transition_duration;
1420 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001421 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001422 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1423 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001424 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001425 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001426 hmi_ctrl->workspace_layer.width,
1427 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001428 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001429}
1430
1431static void
1432pointer_move_workspace_grab_end(struct pointer_grab *grab)
1433{
1434 struct pointer_move_grab *pnt_move_grab =
1435 (struct pointer_move_grab *)grab;
1436 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1437
1438 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1439 grab->grab.pointer->grab_x, layer);
1440
1441 weston_pointer_end_grab(grab->grab.pointer);
1442}
1443
1444static void
1445touch_move_workspace_grab_end(struct touch_grab *grab)
1446{
1447 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1448 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1449
1450 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1451 grab->grab.touch->grab_x, layer);
1452
1453 weston_touch_end_grab(grab->grab.touch);
1454}
1455
1456static void
1457pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1458{
1459}
1460
1461static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001462pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001463 uint32_t time,
1464 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001465{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001466 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001467}
1468
1469static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001470pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1471 uint32_t source)
1472{
1473 weston_pointer_send_axis_source(grab->pointer, source);
1474}
1475
1476static void
1477pointer_default_grab_frame(struct weston_pointer_grab *grab)
1478{
1479 weston_pointer_send_frame(grab->pointer);
1480}
1481
1482static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001483move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1484{
1485 struct timespec timestamp = {0};
1486 int32_t ii = 0;
1487 double dt = 0.0;
1488
1489 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1490 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1491 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1492
1493 if (dt < 1e-6)
1494 dt = 1e-6;
1495
1496 move->pre_time = timestamp;
1497
1498 for (ii = 0; ii < 2; ii++) {
1499 wl_fixed_t prepos = move->pos[ii];
1500 move->pos[ii] = pointer[ii] + move->dst[ii];
1501
1502 if (move->pos[ii] < move->rgn[0][ii]) {
1503 move->pos[ii] = move->rgn[0][ii];
1504 move->dst[ii] = move->pos[ii] - pointer[ii];
1505 } else if (move->rgn[1][ii] < move->pos[ii]) {
1506 move->pos[ii] = move->rgn[1][ii];
1507 move->dst[ii] = move->pos[ii] - pointer[ii];
1508 }
1509
1510 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1511
1512 if (!move->is_moved &&
1513 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1514 move->is_moved = 1;
1515 }
1516}
1517
1518static void
1519layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1520 wl_fixed_t pos_y)
1521{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001522 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001523 int32_t layout_pos_x = 0;
1524 int32_t layout_pos_y = 0;
1525
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001526 prop = ivi_layout_interface->get_properties_of_layer(layer);
1527
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001528 layout_pos_x = wl_fixed_to_int(pos_x);
1529 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001530 ivi_layout_interface->layer_set_destination_rectangle(layer,
1531 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001532 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001533}
1534
1535static void
1536pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001537 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001538{
1539 struct pointer_move_grab *pnt_move_grab =
1540 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001541 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001542
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001543 weston_pointer_motion_to_abs(grab->pointer, event,
1544 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001545 move_grab_update(&pnt_move_grab->move, pointer_pos);
1546 layer_set_pos(pnt_move_grab->base.layer,
1547 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001548 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001549}
1550
1551static void
1552touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1553 int touch_id, wl_fixed_t x, wl_fixed_t y)
1554{
1555 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1556
1557 if (!tch_move_grab->is_active)
1558 return;
1559
1560 wl_fixed_t pointer_pos[2] = {
1561 grab->touch->grab_x,
1562 grab->touch->grab_y
1563 };
1564
1565 move_grab_update(&tch_move_grab->move, pointer_pos);
1566 layer_set_pos(tch_move_grab->base.layer,
1567 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1568}
1569
1570static void
1571pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1572 uint32_t time, uint32_t button,
1573 uint32_t state_w)
1574{
1575 if (BTN_LEFT == button &&
1576 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1577 struct pointer_grab *pg = (struct pointer_grab *)grab;
1578
1579 pointer_move_workspace_grab_end(pg);
1580 free(grab);
1581 }
1582}
1583
1584static void
1585touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1586 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1587{
1588}
1589
1590static void
1591touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1592 int touch_id)
1593{
1594 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1595
1596 if (0 == touch_id)
1597 tch_move_grab->is_active = 0;
1598
1599 if (0 == grab->touch->num_tp) {
1600 touch_move_workspace_grab_end(&tch_move_grab->base);
1601 free(grab);
1602 }
1603}
1604
1605static void
1606pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1607{
1608 struct pointer_grab *pg = (struct pointer_grab *)grab;
1609
1610 pointer_move_workspace_grab_end(pg);
1611 free(grab);
1612}
1613
1614static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001615touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1616{
1617}
1618
1619static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001620touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1621{
1622 struct touch_grab *tg = (struct touch_grab *)grab;
1623
1624 touch_move_workspace_grab_end(tg);
1625 free(grab);
1626}
1627
1628static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1629 pointer_noop_grab_focus,
1630 pointer_move_grab_motion,
1631 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001632 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001633 pointer_default_grab_axis_source,
1634 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001635 pointer_move_workspace_grab_cancel
1636};
1637
1638static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1639 touch_nope_grab_down,
1640 touch_move_workspace_grab_up,
1641 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001642 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001643 touch_move_workspace_grab_cancel
1644};
1645
1646enum HMI_GRAB_DEVICE {
1647 HMI_GRAB_DEVICE_NONE,
1648 HMI_GRAB_DEVICE_POINTER,
1649 HMI_GRAB_DEVICE_TOUCH
1650};
1651
1652static enum HMI_GRAB_DEVICE
1653get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1654{
Derek Foreman1281a362015-07-31 16:55:32 -05001655 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1656 struct weston_touch *touch = weston_seat_get_touch(seat);
1657
1658 if (pointer &&
1659 pointer->focus &&
1660 pointer->button_count &&
1661 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001662 return HMI_GRAB_DEVICE_POINTER;
1663
Derek Foreman1281a362015-07-31 16:55:32 -05001664 if (touch &&
1665 touch->focus &&
1666 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001667 return HMI_GRAB_DEVICE_TOUCH;
1668
1669 return HMI_GRAB_DEVICE_NONE;
1670}
1671
1672static void
1673move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1674 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1675 struct wl_resource* resource)
1676{
1677 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1678 move->pre_time = move->start_time;
1679 move->pos[0] = start_pos[0];
1680 move->pos[1] = start_pos[1];
1681 move->start_pos[0] = start_pos[0];
1682 move->start_pos[1] = start_pos[1];
1683 move->dst[0] = start_pos[0] - grab_pos[0];
1684 move->dst[1] = start_pos[1] - grab_pos[1];
1685 memcpy(move->rgn, rgn, sizeof(move->rgn));
1686}
1687
1688static void
1689move_grab_init_workspace(struct move_grab* move,
1690 wl_fixed_t grab_x, wl_fixed_t grab_y,
1691 struct wl_resource *resource)
1692{
1693 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1694 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001695 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001696 int32_t workspace_count = hmi_ctrl->workspace_count;
1697 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1698 int32_t layer_pos_x = 0;
1699 int32_t layer_pos_y = 0;
1700 wl_fixed_t start_pos[2] = {0};
1701 wl_fixed_t rgn[2][2] = {{0}};
1702 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1703
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001704 prop = ivi_layout_interface->get_properties_of_layer(layer);
1705 layer_pos_x = prop->dest_x;
1706 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001707
1708 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1709 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1710
1711 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1712
1713 rgn[0][1] = wl_fixed_from_int(0);
1714 rgn[1][0] = wl_fixed_from_int(0);
1715 rgn[1][1] = wl_fixed_from_int(0);
1716
1717 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1718}
1719
1720static struct pointer_move_grab *
1721create_workspace_pointer_move(struct weston_pointer *pointer,
1722 struct wl_resource* resource)
1723{
1724 struct pointer_move_grab *pnt_move_grab =
1725 MEM_ALLOC(sizeof(*pnt_move_grab));
1726
1727 pnt_move_grab->base.resource = resource;
1728 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1729 pointer->grab_y, resource);
1730
1731 return pnt_move_grab;
1732}
1733
1734static struct touch_move_grab *
1735create_workspace_touch_move(struct weston_touch *touch,
1736 struct wl_resource* resource)
1737{
1738 struct touch_move_grab *tch_move_grab =
1739 MEM_ALLOC(sizeof(*tch_move_grab));
1740
1741 tch_move_grab->base.resource = resource;
1742 tch_move_grab->is_active = 1;
1743 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1744 touch->grab_y, resource);
1745
1746 return tch_move_grab;
1747}
1748
1749static void
1750ivi_hmi_controller_workspace_control(struct wl_client *client,
1751 struct wl_resource *resource,
1752 struct wl_resource *seat_resource,
1753 uint32_t serial)
1754{
1755 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1756 struct ivi_layout_layer *layer = NULL;
1757 struct pointer_move_grab *pnt_move_grab = NULL;
1758 struct touch_move_grab *tch_move_grab = NULL;
1759 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001760 struct weston_pointer *pointer;
1761 struct weston_touch *touch;
1762
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001763 enum HMI_GRAB_DEVICE device;
1764
1765 if (hmi_ctrl->workspace_count < 2)
1766 return;
1767
1768 seat = wl_resource_get_user_data(seat_resource);
1769 device = get_hmi_grab_device(seat, serial);
1770
1771 if (HMI_GRAB_DEVICE_POINTER != device &&
1772 HMI_GRAB_DEVICE_TOUCH != device)
1773 return;
1774
1775 layer = hmi_ctrl->workspace_layer.ivilayer;
1776
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001777 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001778
1779 switch (device) {
1780 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001781 pointer = weston_seat_get_pointer(seat);
1782 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001783 resource);
1784
1785 pointer_grab_start(&pnt_move_grab->base, layer,
1786 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001787 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001788 break;
1789
1790 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001791 touch = weston_seat_get_touch(seat);
1792 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001793 resource);
1794
1795 touch_grab_start(&tch_move_grab->base, layer,
1796 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001797 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001798 break;
1799
1800 default:
1801 break;
1802 }
1803}
1804
1805/**
1806 * Implementation of switch_mode
1807 */
1808static void
1809ivi_hmi_controller_switch_mode(struct wl_client *client,
1810 struct wl_resource *resource,
1811 uint32_t layout_mode)
1812{
1813 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1814
1815 switch_mode(hmi_ctrl, layout_mode);
1816}
1817
1818/**
1819 * Implementation of on/off displaying workspace and workspace background
1820 * ivi_layers.
1821 */
1822static void
1823ivi_hmi_controller_home(struct wl_client *client,
1824 struct wl_resource *resource,
1825 uint32_t home)
1826{
1827 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1828 uint32_t is_fade_in;
1829
1830 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1831 !hmi_ctrl->workspace_fade.is_fade_in) ||
1832 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1833 hmi_ctrl->workspace_fade.is_fade_in)) {
1834 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1835 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1836 &hmi_ctrl->workspace_fade);
1837 }
1838
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001839 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001840}
1841
1842/**
1843 * binding ivi-hmi-controller implementation
1844 */
1845static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1846 ivi_hmi_controller_UI_ready,
1847 ivi_hmi_controller_workspace_control,
1848 ivi_hmi_controller_switch_mode,
1849 ivi_hmi_controller_home
1850};
1851
1852static void
1853unbind_hmi_controller(struct wl_resource *resource)
1854{
1855}
1856
1857static void
1858bind_hmi_controller(struct wl_client *client,
1859 void *data, uint32_t version, uint32_t id)
1860{
1861 struct wl_resource *resource = NULL;
1862 struct hmi_controller *hmi_ctrl = data;
1863
1864 if (hmi_ctrl->user_interface != client) {
1865 struct wl_resource *res = wl_client_get_object(client, 1);
1866 wl_resource_post_error(res,
1867 WL_DISPLAY_ERROR_INVALID_OBJECT,
1868 "hmi-controller failed: permission denied");
1869 return;
1870 }
1871
1872 resource = wl_resource_create(
1873 client, &ivi_hmi_controller_interface, 1, id);
1874
1875 wl_resource_set_implementation(
1876 resource, &ivi_hmi_controller_implementation,
1877 hmi_ctrl, unbind_hmi_controller);
1878}
1879
1880static int32_t
1881initialize(struct hmi_controller *hmi_ctrl)
1882{
1883 struct config_command {
1884 char *key;
1885 uint32_t *dest;
1886 };
1887
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001888 struct weston_config *config = wet_get_config(hmi_ctrl->compositor);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001889 struct weston_config_section *section = NULL;
1890 int result = 0;
1891 int i = 0;
1892
1893 const struct config_command uint_commands[] = {
1894 { "background-id", &hmi_ctrl->ui_setting.background_id },
1895 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1896 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1897 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1898 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1899 { "random-id", &hmi_ctrl->ui_setting.random_id },
1900 { "home-id", &hmi_ctrl->ui_setting.home_id },
1901 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001902 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001903 { NULL, NULL }
1904 };
1905
1906 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1907
1908 for (i = 0; -1 != result; ++i) {
1909 const struct config_command *command = &uint_commands[i];
1910
1911 if (!command->key)
1912 break;
1913
1914 if (weston_config_section_get_uint(
1915 section, command->key, command->dest, 0) != 0)
1916 result = -1;
1917 }
1918
1919 if (-1 == result) {
1920 weston_log("Failed to initialize hmi-controller\n");
1921 return 0;
1922 }
1923
1924 return 1;
1925}
1926
1927static void
1928launch_hmi_client_process(void *data)
1929{
1930 struct hmi_controller *hmi_ctrl =
1931 (struct hmi_controller *)data;
1932
1933 hmi_ctrl->user_interface =
1934 weston_client_start(hmi_ctrl->compositor,
1935 hmi_ctrl->hmi_setting->ivi_homescreen);
1936
1937 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1938}
1939
1940/*****************************************************************************
1941 * exported functions
1942 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001943WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001944controller_module_init(struct weston_compositor *ec,
1945 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001946 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001947 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001948{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001949 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001950 struct wl_event_loop *loop = NULL;
1951
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001952 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001953 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001954 return -1;
1955 }
1956
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001957 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001958
1959 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001960 if (hmi_ctrl == NULL)
1961 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001962
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001963 if (!initialize(hmi_ctrl)) {
1964 return -1;
1965 }
1966
1967 if (wl_global_create(ec->wl_display,
1968 &ivi_hmi_controller_interface, 1,
1969 hmi_ctrl, bind_hmi_controller) == NULL) {
1970 return -1;
1971 }
1972
1973 loop = wl_display_get_event_loop(ec->wl_display);
1974 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1975
1976 return 0;
1977}