blob: b27f87b25fd8fc3ecb184ddfe5eb16bb54e6f0b7 [file] [log] [blame]
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001/*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090011 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090024 */
25
26/**
27 * A reference implementation how to use ivi-layout APIs in order to manage
28 * layout of ivi_surfaces/ivi_layers. Layout change is triggered by
29 * ivi-hmi-controller protocol, ivi-hmi-controller.xml. A reference how to
30 * use the protocol, see hmi-controller-homescreen.
31 *
32 * In-Vehicle Infotainment system usually manage properties of
33 * ivi_surfaces/ivi_layers by only a central component which decide where
34 * ivi_surfaces/ivi_layers shall be. This reference show examples to
35 * implement the central component as a module of weston.
36 *
37 * Default Scene graph of UI is defined in hmi_controller_create. It
38 * consists of
39 * - In the bottom, a base ivi_layer to group ivi_surfaces of background,
40 * panel, and buttons
41 * - Next, a application ivi_layer to show application ivi_surfaces.
42 * - Workspace background ivi_layer to show a ivi_surface of background image.
43 * - Workspace ivi_layer to show launcher to launch application with icons.
44 * Paths to binary and icon are defined in weston.ini. The width of this
45 * ivi_layer is longer than the size of ivi_screen because a workspace has
46 * several pages and is controlled by motion of input.
47 *
48 * TODO: animation method shall be refined
49 * TODO: support fade-in when UI is ready
50 */
51
52#include <sys/wait.h>
53#include <unistd.h>
54#include <stdlib.h>
55#include <stdio.h>
56#include <string.h>
57#include <linux/input.h>
58#include <assert.h>
59#include <time.h>
60
61#include "ivi-layout-export.h"
62#include "ivi-hmi-controller-server-protocol.h"
Jon Cruz867d50e2015-06-15 15:37:10 -070063#include "shared/helpers.h"
Bryce Harringtone99e4bf2016-03-16 14:15:18 -070064#include "shared/xalloc.h"
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090065
66/*****************************************************************************
67 * structure, globals
68 ****************************************************************************/
69struct hmi_controller_layer {
70 struct ivi_layout_layer *ivilayer;
71 uint32_t id_layer;
72 int32_t x;
73 int32_t y;
74 int32_t width;
75 int32_t height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090076 struct wl_list link;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090077};
78
79struct link_layer {
80 struct ivi_layout_layer *layout_layer;
81 struct wl_list link;
82};
83
84struct hmi_controller_fade {
85 uint32_t is_fade_in;
86 struct wl_list layer_list;
87};
88
89struct hmi_server_setting {
90 uint32_t base_layer_id;
91 uint32_t application_layer_id;
92 uint32_t workspace_background_layer_id;
93 uint32_t workspace_layer_id;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +090094 uint32_t base_layer_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +090095 int32_t panel_height;
96 uint32_t transition_duration;
97 char *ivi_homescreen;
98};
99
100struct ui_setting {
101 uint32_t background_id;
102 uint32_t panel_id;
103 uint32_t tiling_id;
104 uint32_t sidebyside_id;
105 uint32_t fullscreen_id;
106 uint32_t random_id;
107 uint32_t home_id;
108 uint32_t workspace_background_id;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900109 uint32_t surface_id_offset;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900110};
111
112struct hmi_controller {
113 struct hmi_server_setting *hmi_setting;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900114 /* List of struct hmi_controller_layer */
115 struct wl_list base_layer_list;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900116 struct wl_list application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900117 struct hmi_controller_layer workspace_background_layer;
118 struct hmi_controller_layer workspace_layer;
119 enum ivi_hmi_controller_layout_mode layout_mode;
120
121 struct hmi_controller_fade workspace_fade;
122
123 int32_t workspace_count;
124 struct wl_array ui_widgets;
125 int32_t is_initialized;
126
127 struct weston_compositor *compositor;
128 struct wl_listener destroy_listener;
129
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000130 struct wl_listener surface_created;
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000131 struct wl_listener surface_removed;
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000132
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900133 struct wl_client *user_interface;
134 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900135
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000136 struct weston_output * workspace_background_output;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900137 int32_t screen_num;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900138};
139
140struct launcher_info {
141 uint32_t surface_id;
142 uint32_t workspace_id;
143 int32_t index;
144};
145
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000146const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900147
148int
149controller_module_init(struct weston_compositor *ec,
150 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000151 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900152 size_t interface_version);
153
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900154/*****************************************************************************
155 * local functions
156 ****************************************************************************/
157static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900158mem_alloc(size_t size, char *file, int32_t line)
159{
160 return fail_on_null(calloc(1, size), size, file, line);
161}
162
163#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
164
165static int32_t
166is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
167 struct ivi_layout_surface *ivisurf)
168{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000169 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900170
171 uint32_t *ui_widget_id = NULL;
172 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
173 if (*ui_widget_id == id)
174 return 1;
175 }
176
177 return 0;
178}
179
180static int
181compare_launcher_info(const void *lhs, const void *rhs)
182{
183 const struct launcher_info *left = lhs;
184 const struct launcher_info *right = rhs;
185
186 if (left->workspace_id < right->workspace_id)
187 return -1;
188
189 if (left->workspace_id > right->workspace_id)
190 return 1;
191
192 if (left->index < right->index)
193 return -1;
194
195 if (left->index > right->index)
196 return 1;
197
198 return 0;
199}
200
201/**
202 * Internal methods called by mainly ivi_hmi_controller_switch_mode
203 * This reference shows 4 examples how to use ivi_layout APIs.
204 */
205static void
206mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
207 struct ivi_layout_surface **pp_surface,
208 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900209 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900210{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900211 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900212 const float surface_width = (float)layer->width * 0.25;
213 const float surface_height = (float)layer->height * 0.5;
214 int32_t surface_x = 0;
215 int32_t surface_y = 0;
216 struct ivi_layout_surface *ivisurf = NULL;
217 struct ivi_layout_surface **surfaces;
218 struct ivi_layout_surface **new_order;
219 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900220 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900221
222 int32_t i = 0;
223 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900224 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900225
226 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
227 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
228
229 for (i = 0; i < surface_length; i++) {
230 ivisurf = pp_surface[i];
231
232 /* skip ui widgets */
233 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
234 continue;
235
236 surfaces[surf_num++] = ivisurf;
237 }
238
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900239 wl_list_for_each_reverse(layer, layer_list, link) {
240 if (idx >= surf_num)
241 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900242
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900243 ivilayer = layer->ivilayer;
244
245 for (i = 0; i < 8; i++, idx++) {
246 if (idx >= surf_num)
247 break;
248
249 ivisurf = surfaces[idx];
250 new_order[i] = ivisurf;
251 if (i < 4) {
252 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900253 surface_y = 0;
254 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900255 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900256 surface_y = (int32_t)surface_height;
257 }
258
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000259 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900260 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
261 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000262 ivi_layout_interface->surface_set_visibility(ivisurf, true);
263 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900264 surface_x, surface_y,
265 (int32_t)surface_width,
266 (int32_t)surface_height);
267
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900268 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900269 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900270
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900271 ivi_layout_interface->layer_set_transition(ivilayer,
272 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
273 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900274 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900275 for (i = idx; i < surf_num; i++)
276 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900277
278 free(surfaces);
279 free(new_order);
280}
281
282static void
283mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
284 struct ivi_layout_surface **pp_surface,
285 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900286 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900287{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900288 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900289 int32_t surface_width = layer->width / 2;
290 int32_t surface_height = layer->height;
291 struct ivi_layout_surface *ivisurf = NULL;
292
293 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
294 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900295 struct ivi_layout_surface **surfaces;
296 struct ivi_layout_surface **new_order;
297 struct ivi_layout_layer *ivilayer = NULL;
298 int32_t surf_num = 0;
299 int32_t idx = 0;
300
301 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
302 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900303
304 for (i = 0; i < surface_length; i++) {
305 ivisurf = pp_surface[i];
306
307 /* skip ui widgets */
308 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
309 continue;
310
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900311 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900312 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900313
314 wl_list_for_each_reverse(layer, layer_list, link) {
315 if (idx >= surf_num)
316 break;
317
318 ivilayer = layer->ivilayer;
319
320 for (i = 0; i < 2; i++, idx++) {
321 if (idx >= surf_num)
322 break;
323
324 ivisurf = surfaces[idx];
325 new_order[i] = ivisurf;
326
327 ivi_layout_interface->surface_set_transition(ivisurf,
328 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
329 duration);
330 ivi_layout_interface->surface_set_visibility(ivisurf, true);
331
332 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
333 i * surface_width, 0,
334 surface_width,
335 surface_height);
336 }
337 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
338 }
339
340 for (i = idx; i < surf_num; i++) {
341 ivi_layout_interface->surface_set_transition(surfaces[i],
342 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
343 duration);
344 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
345 }
346
347 free(surfaces);
348 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900349}
350
351static void
352mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
353 struct ivi_layout_surface **pp_surface,
354 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900355 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900356{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900357 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900358 const int32_t surface_width = layer->width;
359 const int32_t surface_height = layer->height;
360 struct ivi_layout_surface *ivisurf = NULL;
361 int32_t i = 0;
362 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900363 int32_t surf_num = 0;
364 struct ivi_layout_surface **surfaces;
365
366 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900367
368 for (i = 0; i < surface_length; i++) {
369 ivisurf = pp_surface[i];
370
371 /* skip ui widgets */
372 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
373 continue;
374
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900375 surfaces[surf_num++] = ivisurf;
376 }
377 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
378
379 for (i = 0; i < surf_num; i++) {
380 ivisurf = surfaces[i];
381
382 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
383 layer = wl_container_of(layer->link.prev, layer, link);
384 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
385 }
386
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000387 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900388 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
389 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000390 ivi_layout_interface->surface_set_visibility(ivisurf, true);
391 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900392 surface_width,
393 surface_height);
394 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900395
396 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900397}
398
399static void
400mode_random_replace(struct hmi_controller *hmi_ctrl,
401 struct ivi_layout_surface **pp_surface,
402 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900403 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900404{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900405 struct hmi_controller_layer *application_layer = NULL;
406 struct hmi_controller_layer **layers = NULL;
407 int32_t surface_width = 0;
408 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900409 int32_t surface_x = 0;
410 int32_t surface_y = 0;
411 struct ivi_layout_surface *ivisurf = NULL;
412 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
413 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900414 int32_t layer_idx = 0;
415
416 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
417
418 wl_list_for_each(application_layer, layer_list, link) {
419 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900420 layer_idx++;
421 }
422
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900423 for (i = 0; i < surface_length; i++) {
424 ivisurf = pp_surface[i];
425
426 /* skip ui widgets */
427 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
428 continue;
429
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900430 /* surface determined at random a layer that belongs */
431 layer_idx = rand() % hmi_ctrl->screen_num;
432
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000433 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900434 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
435 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900436
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000437 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900438
439 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
440 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
441 surface_x = rand() % (layers[layer_idx]->width - surface_width);
442 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900443
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000444 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900445 surface_x,
446 surface_y,
447 surface_width,
448 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900449
450 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900451 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900452
453 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900454}
455
456static int32_t
457has_application_surface(struct hmi_controller *hmi_ctrl,
458 struct ivi_layout_surface **pp_surface,
459 int32_t surface_length)
460{
461 struct ivi_layout_surface *ivisurf = NULL;
462 int32_t i = 0;
463
464 for (i = 0; i < surface_length; i++) {
465 ivisurf = pp_surface[i];
466
467 /* skip ui widgets */
468 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
469 continue;
470
471 return 1;
472 }
473
474 return 0;
475}
476
477/**
478 * Supports 4 example to layout of application ivi_surfaces;
479 * tiling, side by side, fullscreen, and random.
480 */
481static void
482switch_mode(struct hmi_controller *hmi_ctrl,
483 enum ivi_hmi_controller_layout_mode layout_mode)
484{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900485 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900486 struct ivi_layout_surface **pp_surface = NULL;
487 int32_t surface_length = 0;
488 int32_t ret = 0;
489
490 if (!hmi_ctrl->is_initialized)
491 return;
492
493 hmi_ctrl->layout_mode = layout_mode;
494
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000495 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900496 assert(!ret);
497
498 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
499 free(pp_surface);
500 pp_surface = NULL;
501 return;
502 }
503
504 switch (layout_mode) {
505 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
506 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
507 layer);
508 break;
509 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
510 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
511 surface_length, layer);
512 break;
513 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
514 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
515 layer);
516 break;
517 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
518 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
519 layer);
520 break;
521 }
522
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000523 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900524 free(pp_surface);
525}
526
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900527/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900528 * Internal method for transition
529 */
530static void
531hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
532 struct hmi_controller_fade *fade)
533{
534 double tint = is_fade_in ? 1.0 : 0.0;
535 struct link_layer *linklayer = NULL;
536 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
537
538 fade->is_fade_in = is_fade_in;
539
540 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000541 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900542 IVI_LAYOUT_TRANSITION_LAYER_FADE,
543 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000544 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900545 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900546 }
547}
548
549/**
550 * Internal method to create ivi_layer with hmi_controller_layer and
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000551 * add to a weston_output
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900552 */
553static void
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000554create_layer(struct weston_output *output,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900555 struct hmi_controller_layer *layer)
556{
557 int32_t ret = 0;
558
559 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000560 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900561 layer->width,
562 layer->height);
563 assert(layer->ivilayer != NULL);
564
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000565 ret = ivi_layout_interface->screen_add_layer(output, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900566 assert(!ret);
567
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000568 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900569 layer->x, layer->y,
570 layer->width,
571 layer->height);
572 assert(!ret);
573
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000574 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900575 assert(!ret);
576}
577
578/**
579 * Internal set notification
580 */
581static void
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000582set_notification_create_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900583{
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000584 struct hmi_controller *hmi_ctrl =
585 wl_container_of(listener, hmi_ctrl,
586 surface_created);
587 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900588 struct hmi_controller_layer *layer_link =
589 wl_container_of(hmi_ctrl->application_layer_list.prev,
590 layer_link,
591 link);
592 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900593 int32_t ret = 0;
594
595 /* skip ui widgets */
596 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
597 return;
598
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000599 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900600 assert(!ret);
601}
602
603static void
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000604set_notification_remove_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900605{
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000606 struct hmi_controller *hmi_ctrl =
607 wl_container_of(listener, hmi_ctrl,
608 surface_removed);
609 (void)data;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900610
611 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
612}
613
614static void
615set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
616 void *userdata)
617{
618 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900619 struct hmi_controller_layer *layer_link = NULL;
620 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900621 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900622 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900623 int32_t length = 0;
624 int32_t i;
625
626 /* return if the surface is not application content */
627 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
628 return;
629 }
630
631 /*
632 * if application changes size of wl_buffer. The source rectangle shall be
633 * fit to the size.
634 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000635 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900636 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000637 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900638 ivisurf, 0, 0, surface->width,
639 surface->height);
640 }
641
642 /*
643 * search if the surface is already added to layer.
644 * If not yet, it is newly invoded application to go to switch_mode.
645 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900646 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
647 application_layer = layer_link->ivilayer;
648 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900649 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900650 for (i = 0; i < length; i++) {
651 if (ivisurf == ivisurfs[i]) {
652 /*
653 * if it is non new invoked application, just call
654 * commit_changes to apply source_rectangle.
655 */
656 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900657 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900658 return;
659 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900660 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900661 free(ivisurfs);
662 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900663 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900664
665 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
666}
667
668/**
669 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
670 * corresponding ivi_layer are defined in weston.ini. Default scene graph
671 * of ivi_layers are initialized in hmi_controller_create
672 */
673static struct hmi_server_setting *
674hmi_server_setting_create(struct weston_compositor *ec)
675{
676 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
677 struct weston_config *config = ec->config;
678 struct weston_config_section *shell_section = NULL;
679
680 shell_section = weston_config_get_section(config, "ivi-shell",
681 NULL, NULL);
682
683 weston_config_section_get_uint(shell_section, "base-layer-id",
684 &setting->base_layer_id, 1000);
685
686 weston_config_section_get_uint(shell_section,
687 "workspace-background-layer-id",
688 &setting->workspace_background_layer_id,
689 2000);
690
691 weston_config_section_get_uint(shell_section, "workspace-layer-id",
692 &setting->workspace_layer_id, 3000);
693
694 weston_config_section_get_uint(shell_section, "application-layer-id",
695 &setting->application_layer_id, 4000);
696
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900697 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
698 &setting->base_layer_id_offset, 10000);
699
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900700 weston_config_section_get_uint(shell_section, "transition-duration",
701 &setting->transition_duration, 300);
702
703 setting->panel_height = 70;
704
705 weston_config_section_get_string(shell_section,
706 "ivi-shell-user-interface",
707 &setting->ivi_homescreen, NULL);
708
709 return setting;
710}
711
712static void
713hmi_controller_destroy(struct wl_listener *listener, void *data)
714{
715 struct link_layer *link = NULL;
716 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900717 struct hmi_controller_layer *ctrl_layer_link = NULL;
718 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900719 struct hmi_controller *hmi_ctrl =
720 container_of(listener, struct hmi_controller, destroy_listener);
721
722 wl_list_for_each_safe(link, next,
723 &hmi_ctrl->workspace_fade.layer_list, link) {
724 wl_list_remove(&link->link);
725 free(link);
726 }
727
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900728 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900729 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
730 &hmi_ctrl->base_layer_list, link) {
731 wl_list_remove(&ctrl_layer_link->link);
732 free(ctrl_layer_link);
733 }
734
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900735 /* clear application_layer_list */
736 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
737 &hmi_ctrl->application_layer_list, link) {
738 wl_list_remove(&ctrl_layer_link->link);
739 free(ctrl_layer_link);
740 }
741
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900742 wl_array_release(&hmi_ctrl->ui_widgets);
743 free(hmi_ctrl->hmi_setting);
744 free(hmi_ctrl);
745}
746
747/**
748 * This is a starting method called from module_init.
749 * This sets up scene graph of ivi_layers; base, application, workspace
750 * background, and workspace. These ivi_layers are created/added to
751 * ivi_screen in create_layer
752 *
753 * base: to group ivi_surfaces of panel and background
754 * application: to group ivi_surfaces of ivi_applications
755 * workspace background: to group a ivi_surface of background in workspace
756 * workspace: to group ivi_surfaces for launching ivi_applications
757 *
758 * ivi_layers of workspace background and workspace is set to invisible at
759 * first. The properties of it is updated with animation when
760 * ivi_hmi_controller_home is requested.
761 */
762static struct hmi_controller *
763hmi_controller_create(struct weston_compositor *ec)
764{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900765 struct link_layer *tmp_link_layer = NULL;
766 int32_t panel_height = 0;
767 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900768 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900769 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000770 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900771
772 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900773
774 wl_array_init(&hmi_ctrl->ui_widgets);
775 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
776 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
777 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000778 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900779
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900780 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900781 wl_list_init(&hmi_ctrl->base_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000782 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900783 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
784 base_layer->x = 0;
785 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000786 base_layer->width = output->current_mode->width;
787 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900788 base_layer->id_layer =
789 hmi_ctrl->hmi_setting->base_layer_id +
790 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
791 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900792
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000793 create_layer(output, base_layer);
794 i++;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900795 }
796
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000797 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900798 panel_height = hmi_ctrl->hmi_setting->panel_height;
799
800 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900801 wl_list_init(&hmi_ctrl->application_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000802 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900803 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
804 application_layer->x = 0;
805 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000806 application_layer->width = output->current_mode->width;
807 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900808 application_layer->id_layer =
809 hmi_ctrl->hmi_setting->application_layer_id +
810 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
811 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
812
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000813 create_layer(output, application_layer);
814 i++;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900815 }
816
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900817 /* init workspace background ivi_layer */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000818 output = wl_container_of(ec->output_list.next, output, link);
819 hmi_ctrl->workspace_background_output = output;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900820 hmi_ctrl->workspace_background_layer.x = 0;
821 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000822 hmi_ctrl->workspace_background_layer.width =
823 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900824 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000825 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900826
827 hmi_ctrl->workspace_background_layer.id_layer =
828 hmi_ctrl->hmi_setting->workspace_background_layer_id;
829
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000830 create_layer(output, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000831 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900832 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000833 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900834 hmi_ctrl->workspace_background_layer.ivilayer, false);
835
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900836
837 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
838 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900839 tmp_link_layer->layout_layer =
840 hmi_ctrl->workspace_background_layer.ivilayer;
841 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
842 &tmp_link_layer->link);
843
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000844 hmi_ctrl->surface_created.notify = set_notification_create_surface;
845 ivi_layout_interface->add_listener_create_surface(&hmi_ctrl->surface_created);
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000846
847 hmi_ctrl->surface_removed.notify = set_notification_remove_surface;
848 ivi_layout_interface->add_listener_remove_surface(&hmi_ctrl->surface_removed);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000849 ivi_layout_interface->add_notification_configure_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900850 set_notification_configure_surface, hmi_ctrl);
851
852 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
853 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
854 &hmi_ctrl->destroy_listener);
855
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900856 return hmi_ctrl;
857}
858
859/**
860 * Implementations of ivi-hmi-controller.xml
861 */
862
863/**
864 * A ivi_surface drawing background is identified by id_surface.
865 * Properties of the ivi_surface is set by using ivi_layout APIs according to
866 * the scene graph of UI defined in hmi_controller_create.
867 *
868 * UI ivi_layer is used to add this ivi_surface.
869 */
870static void
871ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
872 uint32_t id_surface)
873{
874 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900875 struct hmi_controller_layer *base_layer = NULL;
876 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000877 int32_t dstx;
878 int32_t dsty;
879 int32_t width;
880 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900881 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900882 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900883
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900884 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
885 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
886 sizeof(*add_surface_id));
887 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000888 dstx = base_layer->x;
889 dsty = base_layer->y;
890 width = base_layer->width;
891 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900892 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900893
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900894 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
895 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900896
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900897 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
898 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900899
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900900 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
901 dstx, dsty, width, height);
902 assert(!ret);
903
904 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
905 assert(!ret);
906
907 i++;
908 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900909}
910
911/**
912 * A ivi_surface drawing panel is identified by id_surface.
913 * Properties of the ivi_surface is set by using ivi_layout APIs according to
914 * the scene graph of UI defined in hmi_controller_create.
915 *
916 * UI ivi_layer is used to add this ivi_surface.
917 */
918static void
919ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
920 uint32_t id_surface)
921{
922 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000923 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900924 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000925 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900926 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900927 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900928 const int32_t dstx = 0;
929 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900930 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900931
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900932 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
933 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
934 sizeof(*add_surface_id));
935 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900936
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900937 ivilayer = base_layer->ivilayer;
938 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
939 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900940
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900941 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
942 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900943
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900944 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000945 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900946
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900947 ret = ivi_layout_interface->surface_set_destination_rectangle(
948 ivisurf, dstx, dsty, width, panel_height);
949 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900950
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900951 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
952 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900953
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900954 i++;
955 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900956}
957
958/**
959 * A ivi_surface drawing buttons in panel is identified by id_surface.
960 * It can set several buttons. Properties of the ivi_surface is set by
961 * using ivi_layout APIs according to the scene graph of UI defined in
962 * hmi_controller_create. Additionally, the position of it is shifted to
963 * right when new one is requested.
964 *
965 * UI ivi_layer is used to add these ivi_surfaces.
966 */
967static void
968ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
969 uint32_t id_surface, int32_t number)
970{
971 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900972 struct hmi_controller_layer *base_layer =
973 wl_container_of(hmi_ctrl->base_layer_list.prev,
974 base_layer,
975 link);
976 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900977 const int32_t width = 48;
978 const int32_t height = 48;
979 int32_t ret = 0;
980 int32_t panel_height = 0;
981 int32_t dstx = 0;
982 int32_t dsty = 0;
983 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
984 sizeof(*add_surface_id));
985 *add_surface_id = id_surface;
986
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000987 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900988 assert(ivisurf != NULL);
989
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000990 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900991 assert(!ret);
992
993 panel_height = hmi_ctrl->hmi_setting->panel_height;
994
995 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900996 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900997
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000998 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900999 ivisurf,dstx, dsty, width, height);
1000 assert(!ret);
1001
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001002 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001003 assert(!ret);
1004}
1005
1006/**
1007 * A ivi_surface drawing home button in panel is identified by id_surface.
1008 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1009 * the scene graph of UI defined in hmi_controller_create.
1010 *
1011 * UI ivi_layer is used to add these ivi_surfaces.
1012 */
1013static void
1014ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1015 uint32_t id_surface)
1016{
1017 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001018 struct hmi_controller_layer *base_layer =
1019 wl_container_of(hmi_ctrl->base_layer_list.prev,
1020 base_layer,
1021 link);
1022 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001023 int32_t ret = 0;
1024 int32_t size = 48;
1025 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001026 const int32_t dstx = (base_layer->width - size) / 2;
1027 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001028
1029 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1030 sizeof(*add_surface_id));
1031 *add_surface_id = id_surface;
1032
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001033 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001034 assert(ivisurf != NULL);
1035
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001036 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001037 assert(!ret);
1038
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001039 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001040 ivisurf, dstx, dsty, size, size);
1041 assert(!ret);
1042
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001043 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001044 assert(!ret);
1045}
1046
1047/**
1048 * A ivi_surface drawing background of workspace is identified by id_surface.
1049 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1050 * the scene graph of UI defined in hmi_controller_create.
1051 *
1052 * A ivi_layer of workspace_background is used to add this ivi_surface.
1053 */
1054static void
1055ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1056 uint32_t id_surface)
1057{
1058 struct ivi_layout_surface *ivisurf = NULL;
1059 struct ivi_layout_layer *ivilayer = NULL;
1060 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1061 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1062 int32_t ret = 0;
1063
1064 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1065 sizeof(*add_surface_id));
1066 *add_surface_id = id_surface;
1067 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1068
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001069 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001070 assert(ivisurf != NULL);
1071
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001072 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001073 assert(!ret);
1074
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001075 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001076 0, 0, width, height);
1077 assert(!ret);
1078
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001079 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001080 assert(!ret);
1081}
1082
1083/**
1084 * A list of ivi_surfaces drawing launchers in workspace is identified by
1085 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1086 * APIs according to the scene graph of UI defined in hmi_controller_create.
1087 *
1088 * The workspace can have several pages to group ivi_surfaces of launcher.
1089 * Each call of this interface increments a number of page to add a group
1090 * of ivi_surfaces
1091 */
1092static void
1093ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1094 int32_t icon_size)
1095{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001096 int32_t minspace_x = 10;
1097 int32_t minspace_y = minspace_x;
1098
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001099 int32_t width = hmi_ctrl->workspace_background_layer.width;
1100 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001101
1102 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1103 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1104 float fcell_size_x = icon_size + space_x;
1105
1106 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1107 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1108 float fcell_size_y = icon_size + space_y;
1109
1110 struct weston_config *config = NULL;
1111 struct weston_config_section *section = NULL;
1112 const char *name = NULL;
1113 int launcher_count = 0;
1114 struct wl_array launchers;
1115 int32_t nx = 0;
1116 int32_t ny = 0;
1117 int32_t prev = -1;
1118 struct launcher_info *data = NULL;
1119
1120 uint32_t surfaceid = 0;
1121 uint32_t workspaceid = 0;
1122 struct launcher_info *info = NULL;
1123
1124 int32_t x = 0;
1125 int32_t y = 0;
1126 int32_t ret = 0;
1127 struct ivi_layout_surface* layout_surface = NULL;
1128 uint32_t *add_surface_id = NULL;
1129
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001130 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001131
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001132 if (0 == x_count)
1133 x_count = 1;
1134
1135 if (0 == y_count)
1136 y_count = 1;
1137
1138 config = hmi_ctrl->compositor->config;
1139 if (!config)
1140 return;
1141
1142 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1143 if (!section)
1144 return;
1145
1146 wl_array_init(&launchers);
1147
1148 while (weston_config_next_section(config, &section, &name)) {
1149 surfaceid = 0;
1150 workspaceid = 0;
1151 info = NULL;
1152 if (0 != strcmp(name, "ivi-launcher"))
1153 continue;
1154
1155 if (0 != weston_config_section_get_uint(section, "icon-id",
1156 &surfaceid, 0))
1157 continue;
1158
1159 if (0 != weston_config_section_get_uint(section,
1160 "workspace-id",
1161 &workspaceid, 0))
1162 continue;
1163
1164 info = wl_array_add(&launchers, sizeof(*info));
1165
1166 if (info) {
1167 info->surface_id = surfaceid;
1168 info->workspace_id = workspaceid;
1169 info->index = launcher_count;
1170 ++launcher_count;
1171 }
1172 }
1173
1174 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1175 compare_launcher_info);
1176
1177 wl_array_for_each(data, &launchers) {
1178 x = 0;
1179 y = 0;
1180 ret = 0;
1181 layout_surface = NULL;
1182 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1183 sizeof(*add_surface_id));
1184
1185 *add_surface_id = data->surface_id;
1186
1187 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1188 nx = 0;
1189 ny = 0;
1190 prev = data->workspace_id;
1191
1192 if (0 <= prev)
1193 hmi_ctrl->workspace_count++;
1194 }
1195
1196 if (y_count == ny) {
1197 ny = 0;
1198 hmi_ctrl->workspace_count++;
1199 }
1200
1201 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1202 y = ny * fcell_size_y + space_y;
1203
1204 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001205 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001206 assert(layout_surface);
1207
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001208 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001209 layout_surface, x, y, icon_size, icon_size);
1210 assert(!ret);
1211
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001212 nx++;
1213
1214 if (x_count == nx) {
1215 ny++;
1216 nx = 0;
1217 }
1218 }
1219
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001220 /* init workspace ivi_layer */
1221 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1222 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1223 hmi_ctrl->workspace_layer.width =
1224 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1225 hmi_ctrl->workspace_layer.height =
1226 hmi_ctrl->workspace_background_layer.height;
1227 hmi_ctrl->workspace_layer.id_layer =
1228 hmi_ctrl->hmi_setting->workspace_layer_id;
1229
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001230 create_layer(hmi_ctrl->workspace_background_output, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001231 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1232 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001233 false);
1234
1235 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1236 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1237 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1238 &tmp_link_layer->link);
1239
1240 /* Add surface to layer */
1241 wl_array_for_each(data, &launchers) {
1242 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001243 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001244 assert(layout_surface);
1245
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001246 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001247 layout_surface);
1248 assert(!ret);
1249
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001250 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001251 assert(!ret);
1252 }
1253
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001254 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001255 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001256}
1257
1258static void
1259ivi_hmi_controller_UI_ready(struct wl_client *client,
1260 struct wl_resource *resource)
1261{
1262 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1263
1264 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1265 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1266 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1267 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1268 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1269 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1270 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1271 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001272 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001273
1274 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1275 hmi_ctrl->is_initialized = 1;
1276}
1277
1278/**
1279 * Implementation of request and event of ivi_hmi_controller_workspace_control
1280 * and controlling workspace.
1281 *
1282 * When motion of input is detected in a ivi_surface of workspace background,
1283 * ivi_hmi_controller_workspace_control shall be invoked and to start
1284 * controlling of workspace. The workspace has several pages to show several
1285 * groups of applications.
1286 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1287 * according to motion. When motion finished, e.g. touch up detected, control is
1288 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1289 */
1290struct pointer_grab {
1291 struct weston_pointer_grab grab;
1292 struct ivi_layout_layer *layer;
1293 struct wl_resource *resource;
1294};
1295
1296struct touch_grab {
1297 struct weston_touch_grab grab;
1298 struct ivi_layout_layer *layer;
1299 struct wl_resource *resource;
1300};
1301
1302struct move_grab {
1303 wl_fixed_t dst[2];
1304 wl_fixed_t rgn[2][2];
1305 double v[2];
1306 struct timespec start_time;
1307 struct timespec pre_time;
1308 wl_fixed_t start_pos[2];
1309 wl_fixed_t pos[2];
1310 int32_t is_moved;
1311};
1312
1313struct pointer_move_grab {
1314 struct pointer_grab base;
1315 struct move_grab move;
1316};
1317
1318struct touch_move_grab {
1319 struct touch_grab base;
1320 struct move_grab move;
1321 int32_t is_active;
1322};
1323
1324static void
1325pointer_grab_start(struct pointer_grab *grab,
1326 struct ivi_layout_layer *layer,
1327 const struct weston_pointer_grab_interface *interface,
1328 struct weston_pointer *pointer)
1329{
1330 grab->grab.interface = interface;
1331 grab->layer = layer;
1332 weston_pointer_start_grab(pointer, &grab->grab);
1333}
1334
1335static void
1336touch_grab_start(struct touch_grab *grab,
1337 struct ivi_layout_layer *layer,
1338 const struct weston_touch_grab_interface *interface,
1339 struct weston_touch* touch)
1340{
1341 grab->grab.interface = interface;
1342 grab->layer = layer;
1343 weston_touch_start_grab(touch, &grab->grab);
1344}
1345
1346static int32_t
1347clamp(int32_t val, int32_t min, int32_t max)
1348{
1349 if (val < min)
1350 return min;
1351
1352 if (max < val)
1353 return max;
1354
1355 return val;
1356}
1357
1358static void
1359move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1360 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1361{
1362 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1363 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001364 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001365
1366 struct timespec time = {0};
1367 double grab_time = 0.0;
1368 double from_motion_time = 0.0;
1369 double pointer_v = 0.0;
1370 int32_t is_flick = 0;
1371 int32_t pos_x = 0;
1372 int32_t pos_y = 0;
1373 int page_no = 0;
1374 double end_pos = 0.0;
1375 uint32_t duration = 0;
1376
1377 clock_gettime(CLOCK_MONOTONIC, &time);
1378
1379 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1380 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1381
1382 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1383 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1384
1385 pointer_v = move->v[0];
1386
1387 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1388 if (200 < from_motion_time)
1389 pointer_v = 0.0;
1390
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001391 prop = ivi_layout_interface->get_properties_of_layer(layer);
1392 pos_x = prop->dest_x;
1393 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001394
1395 if (is_flick) {
1396 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1397 page_no = (-orgx + width / 2) / width;
1398
1399 if (pointer_v < 0.0)
1400 page_no++;
1401 else
1402 page_no--;
1403 } else {
1404 page_no = (-pos_x + width / 2) / width;
1405 }
1406
1407 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1408 end_pos = -page_no * width;
1409
1410 duration = hmi_ctrl->hmi_setting->transition_duration;
1411 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001412 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001413 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1414 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001415 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001416 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001417 hmi_ctrl->workspace_layer.width,
1418 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001419 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001420}
1421
1422static void
1423pointer_move_workspace_grab_end(struct pointer_grab *grab)
1424{
1425 struct pointer_move_grab *pnt_move_grab =
1426 (struct pointer_move_grab *)grab;
1427 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1428
1429 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1430 grab->grab.pointer->grab_x, layer);
1431
1432 weston_pointer_end_grab(grab->grab.pointer);
1433}
1434
1435static void
1436touch_move_workspace_grab_end(struct touch_grab *grab)
1437{
1438 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1439 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1440
1441 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1442 grab->grab.touch->grab_x, layer);
1443
1444 weston_touch_end_grab(grab->grab.touch);
1445}
1446
1447static void
1448pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1449{
1450}
1451
1452static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001453pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001454 uint32_t time,
1455 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001456{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001457 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001458}
1459
1460static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001461pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1462 uint32_t source)
1463{
1464 weston_pointer_send_axis_source(grab->pointer, source);
1465}
1466
1467static void
1468pointer_default_grab_frame(struct weston_pointer_grab *grab)
1469{
1470 weston_pointer_send_frame(grab->pointer);
1471}
1472
1473static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001474move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1475{
1476 struct timespec timestamp = {0};
1477 int32_t ii = 0;
1478 double dt = 0.0;
1479
1480 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1481 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1482 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1483
1484 if (dt < 1e-6)
1485 dt = 1e-6;
1486
1487 move->pre_time = timestamp;
1488
1489 for (ii = 0; ii < 2; ii++) {
1490 wl_fixed_t prepos = move->pos[ii];
1491 move->pos[ii] = pointer[ii] + move->dst[ii];
1492
1493 if (move->pos[ii] < move->rgn[0][ii]) {
1494 move->pos[ii] = move->rgn[0][ii];
1495 move->dst[ii] = move->pos[ii] - pointer[ii];
1496 } else if (move->rgn[1][ii] < move->pos[ii]) {
1497 move->pos[ii] = move->rgn[1][ii];
1498 move->dst[ii] = move->pos[ii] - pointer[ii];
1499 }
1500
1501 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1502
1503 if (!move->is_moved &&
1504 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1505 move->is_moved = 1;
1506 }
1507}
1508
1509static void
1510layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1511 wl_fixed_t pos_y)
1512{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001513 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001514 int32_t layout_pos_x = 0;
1515 int32_t layout_pos_y = 0;
1516
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001517 prop = ivi_layout_interface->get_properties_of_layer(layer);
1518
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001519 layout_pos_x = wl_fixed_to_int(pos_x);
1520 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001521 ivi_layout_interface->layer_set_destination_rectangle(layer,
1522 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001523 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001524}
1525
1526static void
1527pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001528 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001529{
1530 struct pointer_move_grab *pnt_move_grab =
1531 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001532 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001533
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001534 weston_pointer_motion_to_abs(grab->pointer, event,
1535 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001536 move_grab_update(&pnt_move_grab->move, pointer_pos);
1537 layer_set_pos(pnt_move_grab->base.layer,
1538 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001539 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001540}
1541
1542static void
1543touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1544 int touch_id, wl_fixed_t x, wl_fixed_t y)
1545{
1546 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1547
1548 if (!tch_move_grab->is_active)
1549 return;
1550
1551 wl_fixed_t pointer_pos[2] = {
1552 grab->touch->grab_x,
1553 grab->touch->grab_y
1554 };
1555
1556 move_grab_update(&tch_move_grab->move, pointer_pos);
1557 layer_set_pos(tch_move_grab->base.layer,
1558 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1559}
1560
1561static void
1562pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1563 uint32_t time, uint32_t button,
1564 uint32_t state_w)
1565{
1566 if (BTN_LEFT == button &&
1567 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1568 struct pointer_grab *pg = (struct pointer_grab *)grab;
1569
1570 pointer_move_workspace_grab_end(pg);
1571 free(grab);
1572 }
1573}
1574
1575static void
1576touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1577 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1578{
1579}
1580
1581static void
1582touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1583 int touch_id)
1584{
1585 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1586
1587 if (0 == touch_id)
1588 tch_move_grab->is_active = 0;
1589
1590 if (0 == grab->touch->num_tp) {
1591 touch_move_workspace_grab_end(&tch_move_grab->base);
1592 free(grab);
1593 }
1594}
1595
1596static void
1597pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1598{
1599 struct pointer_grab *pg = (struct pointer_grab *)grab;
1600
1601 pointer_move_workspace_grab_end(pg);
1602 free(grab);
1603}
1604
1605static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001606touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1607{
1608}
1609
1610static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001611touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1612{
1613 struct touch_grab *tg = (struct touch_grab *)grab;
1614
1615 touch_move_workspace_grab_end(tg);
1616 free(grab);
1617}
1618
1619static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1620 pointer_noop_grab_focus,
1621 pointer_move_grab_motion,
1622 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001623 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001624 pointer_default_grab_axis_source,
1625 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001626 pointer_move_workspace_grab_cancel
1627};
1628
1629static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1630 touch_nope_grab_down,
1631 touch_move_workspace_grab_up,
1632 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001633 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001634 touch_move_workspace_grab_cancel
1635};
1636
1637enum HMI_GRAB_DEVICE {
1638 HMI_GRAB_DEVICE_NONE,
1639 HMI_GRAB_DEVICE_POINTER,
1640 HMI_GRAB_DEVICE_TOUCH
1641};
1642
1643static enum HMI_GRAB_DEVICE
1644get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1645{
Derek Foreman1281a362015-07-31 16:55:32 -05001646 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1647 struct weston_touch *touch = weston_seat_get_touch(seat);
1648
1649 if (pointer &&
1650 pointer->focus &&
1651 pointer->button_count &&
1652 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001653 return HMI_GRAB_DEVICE_POINTER;
1654
Derek Foreman1281a362015-07-31 16:55:32 -05001655 if (touch &&
1656 touch->focus &&
1657 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001658 return HMI_GRAB_DEVICE_TOUCH;
1659
1660 return HMI_GRAB_DEVICE_NONE;
1661}
1662
1663static void
1664move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1665 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1666 struct wl_resource* resource)
1667{
1668 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1669 move->pre_time = move->start_time;
1670 move->pos[0] = start_pos[0];
1671 move->pos[1] = start_pos[1];
1672 move->start_pos[0] = start_pos[0];
1673 move->start_pos[1] = start_pos[1];
1674 move->dst[0] = start_pos[0] - grab_pos[0];
1675 move->dst[1] = start_pos[1] - grab_pos[1];
1676 memcpy(move->rgn, rgn, sizeof(move->rgn));
1677}
1678
1679static void
1680move_grab_init_workspace(struct move_grab* move,
1681 wl_fixed_t grab_x, wl_fixed_t grab_y,
1682 struct wl_resource *resource)
1683{
1684 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1685 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001686 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001687 int32_t workspace_count = hmi_ctrl->workspace_count;
1688 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1689 int32_t layer_pos_x = 0;
1690 int32_t layer_pos_y = 0;
1691 wl_fixed_t start_pos[2] = {0};
1692 wl_fixed_t rgn[2][2] = {{0}};
1693 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1694
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001695 prop = ivi_layout_interface->get_properties_of_layer(layer);
1696 layer_pos_x = prop->dest_x;
1697 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001698
1699 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1700 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1701
1702 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1703
1704 rgn[0][1] = wl_fixed_from_int(0);
1705 rgn[1][0] = wl_fixed_from_int(0);
1706 rgn[1][1] = wl_fixed_from_int(0);
1707
1708 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1709}
1710
1711static struct pointer_move_grab *
1712create_workspace_pointer_move(struct weston_pointer *pointer,
1713 struct wl_resource* resource)
1714{
1715 struct pointer_move_grab *pnt_move_grab =
1716 MEM_ALLOC(sizeof(*pnt_move_grab));
1717
1718 pnt_move_grab->base.resource = resource;
1719 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1720 pointer->grab_y, resource);
1721
1722 return pnt_move_grab;
1723}
1724
1725static struct touch_move_grab *
1726create_workspace_touch_move(struct weston_touch *touch,
1727 struct wl_resource* resource)
1728{
1729 struct touch_move_grab *tch_move_grab =
1730 MEM_ALLOC(sizeof(*tch_move_grab));
1731
1732 tch_move_grab->base.resource = resource;
1733 tch_move_grab->is_active = 1;
1734 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1735 touch->grab_y, resource);
1736
1737 return tch_move_grab;
1738}
1739
1740static void
1741ivi_hmi_controller_workspace_control(struct wl_client *client,
1742 struct wl_resource *resource,
1743 struct wl_resource *seat_resource,
1744 uint32_t serial)
1745{
1746 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1747 struct ivi_layout_layer *layer = NULL;
1748 struct pointer_move_grab *pnt_move_grab = NULL;
1749 struct touch_move_grab *tch_move_grab = NULL;
1750 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001751 struct weston_pointer *pointer;
1752 struct weston_touch *touch;
1753
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001754 enum HMI_GRAB_DEVICE device;
1755
1756 if (hmi_ctrl->workspace_count < 2)
1757 return;
1758
1759 seat = wl_resource_get_user_data(seat_resource);
1760 device = get_hmi_grab_device(seat, serial);
1761
1762 if (HMI_GRAB_DEVICE_POINTER != device &&
1763 HMI_GRAB_DEVICE_TOUCH != device)
1764 return;
1765
1766 layer = hmi_ctrl->workspace_layer.ivilayer;
1767
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001768 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001769
1770 switch (device) {
1771 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001772 pointer = weston_seat_get_pointer(seat);
1773 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001774 resource);
1775
1776 pointer_grab_start(&pnt_move_grab->base, layer,
1777 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001778 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001779 break;
1780
1781 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001782 touch = weston_seat_get_touch(seat);
1783 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001784 resource);
1785
1786 touch_grab_start(&tch_move_grab->base, layer,
1787 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001788 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001789 break;
1790
1791 default:
1792 break;
1793 }
1794}
1795
1796/**
1797 * Implementation of switch_mode
1798 */
1799static void
1800ivi_hmi_controller_switch_mode(struct wl_client *client,
1801 struct wl_resource *resource,
1802 uint32_t layout_mode)
1803{
1804 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1805
1806 switch_mode(hmi_ctrl, layout_mode);
1807}
1808
1809/**
1810 * Implementation of on/off displaying workspace and workspace background
1811 * ivi_layers.
1812 */
1813static void
1814ivi_hmi_controller_home(struct wl_client *client,
1815 struct wl_resource *resource,
1816 uint32_t home)
1817{
1818 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1819 uint32_t is_fade_in;
1820
1821 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1822 !hmi_ctrl->workspace_fade.is_fade_in) ||
1823 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1824 hmi_ctrl->workspace_fade.is_fade_in)) {
1825 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1826 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1827 &hmi_ctrl->workspace_fade);
1828 }
1829
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001830 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001831}
1832
1833/**
1834 * binding ivi-hmi-controller implementation
1835 */
1836static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1837 ivi_hmi_controller_UI_ready,
1838 ivi_hmi_controller_workspace_control,
1839 ivi_hmi_controller_switch_mode,
1840 ivi_hmi_controller_home
1841};
1842
1843static void
1844unbind_hmi_controller(struct wl_resource *resource)
1845{
1846}
1847
1848static void
1849bind_hmi_controller(struct wl_client *client,
1850 void *data, uint32_t version, uint32_t id)
1851{
1852 struct wl_resource *resource = NULL;
1853 struct hmi_controller *hmi_ctrl = data;
1854
1855 if (hmi_ctrl->user_interface != client) {
1856 struct wl_resource *res = wl_client_get_object(client, 1);
1857 wl_resource_post_error(res,
1858 WL_DISPLAY_ERROR_INVALID_OBJECT,
1859 "hmi-controller failed: permission denied");
1860 return;
1861 }
1862
1863 resource = wl_resource_create(
1864 client, &ivi_hmi_controller_interface, 1, id);
1865
1866 wl_resource_set_implementation(
1867 resource, &ivi_hmi_controller_implementation,
1868 hmi_ctrl, unbind_hmi_controller);
1869}
1870
1871static int32_t
1872initialize(struct hmi_controller *hmi_ctrl)
1873{
1874 struct config_command {
1875 char *key;
1876 uint32_t *dest;
1877 };
1878
1879 struct weston_config *config = hmi_ctrl->compositor->config;
1880 struct weston_config_section *section = NULL;
1881 int result = 0;
1882 int i = 0;
1883
1884 const struct config_command uint_commands[] = {
1885 { "background-id", &hmi_ctrl->ui_setting.background_id },
1886 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1887 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1888 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1889 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1890 { "random-id", &hmi_ctrl->ui_setting.random_id },
1891 { "home-id", &hmi_ctrl->ui_setting.home_id },
1892 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001893 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001894 { NULL, NULL }
1895 };
1896
1897 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1898
1899 for (i = 0; -1 != result; ++i) {
1900 const struct config_command *command = &uint_commands[i];
1901
1902 if (!command->key)
1903 break;
1904
1905 if (weston_config_section_get_uint(
1906 section, command->key, command->dest, 0) != 0)
1907 result = -1;
1908 }
1909
1910 if (-1 == result) {
1911 weston_log("Failed to initialize hmi-controller\n");
1912 return 0;
1913 }
1914
1915 return 1;
1916}
1917
1918static void
1919launch_hmi_client_process(void *data)
1920{
1921 struct hmi_controller *hmi_ctrl =
1922 (struct hmi_controller *)data;
1923
1924 hmi_ctrl->user_interface =
1925 weston_client_start(hmi_ctrl->compositor,
1926 hmi_ctrl->hmi_setting->ivi_homescreen);
1927
1928 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1929}
1930
1931/*****************************************************************************
1932 * exported functions
1933 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001934WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001935controller_module_init(struct weston_compositor *ec,
1936 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001937 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001938 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001939{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001940 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001941 struct wl_event_loop *loop = NULL;
1942
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001943 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001944 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001945 return -1;
1946 }
1947
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001948 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001949
1950 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001951 if (hmi_ctrl == NULL)
1952 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001953
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001954 if (!initialize(hmi_ctrl)) {
1955 return -1;
1956 }
1957
1958 if (wl_global_create(ec->wl_display,
1959 &ivi_hmi_controller_interface, 1,
1960 hmi_ctrl, bind_hmi_controller) == NULL) {
1961 return -1;
1962 }
1963
1964 loop = wl_display_get_event_loop(ec->wl_display);
1965 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1966
1967 return 0;
1968}