blob: b6716f3f0e968bd239de9851e564983f5e098340 [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;
131
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900132 struct wl_client *user_interface;
133 struct ui_setting ui_setting;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900134
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000135 struct weston_output * workspace_background_output;
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900136 int32_t screen_num;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900137};
138
139struct launcher_info {
140 uint32_t surface_id;
141 uint32_t workspace_id;
142 int32_t index;
143};
144
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000145const struct ivi_layout_interface *ivi_layout_interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900146
147int
148controller_module_init(struct weston_compositor *ec,
149 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000150 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900151 size_t interface_version);
152
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900153/*****************************************************************************
154 * local functions
155 ****************************************************************************/
156static void *
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900157mem_alloc(size_t size, char *file, int32_t line)
158{
159 return fail_on_null(calloc(1, size), size, file, line);
160}
161
162#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
163
164static int32_t
165is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
166 struct ivi_layout_surface *ivisurf)
167{
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000168 uint32_t id = ivi_layout_interface->get_id_of_surface(ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900169
170 uint32_t *ui_widget_id = NULL;
171 wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
172 if (*ui_widget_id == id)
173 return 1;
174 }
175
176 return 0;
177}
178
179static int
180compare_launcher_info(const void *lhs, const void *rhs)
181{
182 const struct launcher_info *left = lhs;
183 const struct launcher_info *right = rhs;
184
185 if (left->workspace_id < right->workspace_id)
186 return -1;
187
188 if (left->workspace_id > right->workspace_id)
189 return 1;
190
191 if (left->index < right->index)
192 return -1;
193
194 if (left->index > right->index)
195 return 1;
196
197 return 0;
198}
199
200/**
201 * Internal methods called by mainly ivi_hmi_controller_switch_mode
202 * This reference shows 4 examples how to use ivi_layout APIs.
203 */
204static void
205mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
206 struct ivi_layout_surface **pp_surface,
207 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900208 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900209{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900210 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900211 const float surface_width = (float)layer->width * 0.25;
212 const float surface_height = (float)layer->height * 0.5;
213 int32_t surface_x = 0;
214 int32_t surface_y = 0;
215 struct ivi_layout_surface *ivisurf = NULL;
216 struct ivi_layout_surface **surfaces;
217 struct ivi_layout_surface **new_order;
218 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900219 struct ivi_layout_layer *ivilayer = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900220
221 int32_t i = 0;
222 int32_t surf_num = 0;
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900223 int32_t idx = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900224
225 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
226 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
227
228 for (i = 0; i < surface_length; i++) {
229 ivisurf = pp_surface[i];
230
231 /* skip ui widgets */
232 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
233 continue;
234
235 surfaces[surf_num++] = ivisurf;
236 }
237
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900238 wl_list_for_each_reverse(layer, layer_list, link) {
239 if (idx >= surf_num)
240 break;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900241
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900242 ivilayer = layer->ivilayer;
243
244 for (i = 0; i < 8; i++, idx++) {
245 if (idx >= surf_num)
246 break;
247
248 ivisurf = surfaces[idx];
249 new_order[i] = ivisurf;
250 if (i < 4) {
251 surface_x = (int32_t)(i * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900252 surface_y = 0;
253 } else {
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900254 surface_x = (int32_t)((i - 4) * (surface_width));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900255 surface_y = (int32_t)surface_height;
256 }
257
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000258 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900259 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
260 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000261 ivi_layout_interface->surface_set_visibility(ivisurf, true);
262 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900263 surface_x, surface_y,
264 (int32_t)surface_width,
265 (int32_t)surface_height);
266
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900267 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900268 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900269
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900270 ivi_layout_interface->layer_set_transition(ivilayer,
271 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
272 duration);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900273 }
Nobuhiko Tanibataa8aa91c2015-12-09 15:43:30 +0900274 for (i = idx; i < surf_num; i++)
275 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900276
277 free(surfaces);
278 free(new_order);
279}
280
281static void
282mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
283 struct ivi_layout_surface **pp_surface,
284 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900285 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900286{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900287 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900288 int32_t surface_width = layer->width / 2;
289 int32_t surface_height = layer->height;
290 struct ivi_layout_surface *ivisurf = NULL;
291
292 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
293 int32_t i = 0;
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900294 struct ivi_layout_surface **surfaces;
295 struct ivi_layout_surface **new_order;
296 struct ivi_layout_layer *ivilayer = NULL;
297 int32_t surf_num = 0;
298 int32_t idx = 0;
299
300 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
301 new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900302
303 for (i = 0; i < surface_length; i++) {
304 ivisurf = pp_surface[i];
305
306 /* skip ui widgets */
307 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
308 continue;
309
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900310 surfaces[surf_num++] = ivisurf;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900311 }
Nobuhiko Tanibatad156d9c2015-12-09 15:44:07 +0900312
313 wl_list_for_each_reverse(layer, layer_list, link) {
314 if (idx >= surf_num)
315 break;
316
317 ivilayer = layer->ivilayer;
318
319 for (i = 0; i < 2; i++, idx++) {
320 if (idx >= surf_num)
321 break;
322
323 ivisurf = surfaces[idx];
324 new_order[i] = ivisurf;
325
326 ivi_layout_interface->surface_set_transition(ivisurf,
327 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
328 duration);
329 ivi_layout_interface->surface_set_visibility(ivisurf, true);
330
331 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
332 i * surface_width, 0,
333 surface_width,
334 surface_height);
335 }
336 ivi_layout_interface->layer_set_render_order(ivilayer, new_order, i);
337 }
338
339 for (i = idx; i < surf_num; i++) {
340 ivi_layout_interface->surface_set_transition(surfaces[i],
341 IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
342 duration);
343 ivi_layout_interface->surface_set_visibility(surfaces[i], false);
344 }
345
346 free(surfaces);
347 free(new_order);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900348}
349
350static void
351mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
352 struct ivi_layout_surface **pp_surface,
353 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900354 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900355{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900356 struct hmi_controller_layer *layer = wl_container_of(layer_list->prev, layer, link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900357 const int32_t surface_width = layer->width;
358 const int32_t surface_height = layer->height;
359 struct ivi_layout_surface *ivisurf = NULL;
360 int32_t i = 0;
361 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900362 int32_t surf_num = 0;
363 struct ivi_layout_surface **surfaces;
364
365 surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900366
367 for (i = 0; i < surface_length; i++) {
368 ivisurf = pp_surface[i];
369
370 /* skip ui widgets */
371 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
372 continue;
373
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900374 surfaces[surf_num++] = ivisurf;
375 }
376 ivi_layout_interface->layer_set_render_order(layer->ivilayer, surfaces, surf_num);
377
378 for (i = 0; i < surf_num; i++) {
379 ivisurf = surfaces[i];
380
381 if ((i > 0) && (i < hmi_ctrl->screen_num)) {
382 layer = wl_container_of(layer->link.prev, layer, link);
383 ivi_layout_interface->layer_set_render_order(layer->ivilayer, &ivisurf, 1);
384 }
385
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000386 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900387 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
388 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000389 ivi_layout_interface->surface_set_visibility(ivisurf, true);
390 ivi_layout_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900391 surface_width,
392 surface_height);
393 }
Nobuhiko Tanibataa7ffa682015-12-09 15:45:20 +0900394
395 free(surfaces);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900396}
397
398static void
399mode_random_replace(struct hmi_controller *hmi_ctrl,
400 struct ivi_layout_surface **pp_surface,
401 int32_t surface_length,
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900402 struct wl_list *layer_list)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900403{
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900404 struct hmi_controller_layer *application_layer = NULL;
405 struct hmi_controller_layer **layers = NULL;
406 int32_t surface_width = 0;
407 int32_t surface_height = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900408 int32_t surface_x = 0;
409 int32_t surface_y = 0;
410 struct ivi_layout_surface *ivisurf = NULL;
411 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
412 int32_t i = 0;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900413 int32_t layer_idx = 0;
414
415 layers = MEM_ALLOC(sizeof(*layers) * hmi_ctrl->screen_num);
416
417 wl_list_for_each(application_layer, layer_list, link) {
418 layers[layer_idx] = application_layer;
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900419 layer_idx++;
420 }
421
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900422 for (i = 0; i < surface_length; i++) {
423 ivisurf = pp_surface[i];
424
425 /* skip ui widgets */
426 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
427 continue;
428
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900429 /* surface determined at random a layer that belongs */
430 layer_idx = rand() % hmi_ctrl->screen_num;
431
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000432 ivi_layout_interface->surface_set_transition(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900433 IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
434 duration);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900435
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000436 ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900437
438 surface_width = (int32_t)(layers[layer_idx]->width * 0.25f);
439 surface_height = (int32_t)(layers[layer_idx]->height * 0.25f);
440 surface_x = rand() % (layers[layer_idx]->width - surface_width);
441 surface_y = rand() % (layers[layer_idx]->height - surface_height);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900442
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000443 ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900444 surface_x,
445 surface_y,
446 surface_width,
447 surface_height);
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900448
449 ivi_layout_interface->layer_add_surface(layers[layer_idx]->ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900450 }
Nobuhiko Tanibata1c2201b2015-12-09 15:45:52 +0900451
452 free(layers);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900453}
454
455static int32_t
456has_application_surface(struct hmi_controller *hmi_ctrl,
457 struct ivi_layout_surface **pp_surface,
458 int32_t surface_length)
459{
460 struct ivi_layout_surface *ivisurf = NULL;
461 int32_t i = 0;
462
463 for (i = 0; i < surface_length; i++) {
464 ivisurf = pp_surface[i];
465
466 /* skip ui widgets */
467 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
468 continue;
469
470 return 1;
471 }
472
473 return 0;
474}
475
476/**
477 * Supports 4 example to layout of application ivi_surfaces;
478 * tiling, side by side, fullscreen, and random.
479 */
480static void
481switch_mode(struct hmi_controller *hmi_ctrl,
482 enum ivi_hmi_controller_layout_mode layout_mode)
483{
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900484 struct wl_list *layer = &hmi_ctrl->application_layer_list;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900485 struct ivi_layout_surface **pp_surface = NULL;
486 int32_t surface_length = 0;
487 int32_t ret = 0;
488
489 if (!hmi_ctrl->is_initialized)
490 return;
491
492 hmi_ctrl->layout_mode = layout_mode;
493
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000494 ret = ivi_layout_interface->get_surfaces(&surface_length, &pp_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900495 assert(!ret);
496
497 if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
498 free(pp_surface);
499 pp_surface = NULL;
500 return;
501 }
502
503 switch (layout_mode) {
504 case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
505 mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
506 layer);
507 break;
508 case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
509 mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
510 surface_length, layer);
511 break;
512 case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
513 mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
514 layer);
515 break;
516 case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
517 mode_random_replace(hmi_ctrl, pp_surface, surface_length,
518 layer);
519 break;
520 }
521
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000522 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900523 free(pp_surface);
524}
525
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +0900526/**
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900527 * Internal method for transition
528 */
529static void
530hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
531 struct hmi_controller_fade *fade)
532{
533 double tint = is_fade_in ? 1.0 : 0.0;
534 struct link_layer *linklayer = NULL;
535 const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
536
537 fade->is_fade_in = is_fade_in;
538
539 wl_list_for_each(linklayer, &fade->layer_list, link) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000540 ivi_layout_interface->layer_set_transition(linklayer->layout_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900541 IVI_LAYOUT_TRANSITION_LAYER_FADE,
542 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000543 ivi_layout_interface->layer_set_fade_info(linklayer->layout_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900544 is_fade_in, 1.0 - tint, tint);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900545 }
546}
547
548/**
549 * Internal method to create ivi_layer with hmi_controller_layer and
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000550 * add to a weston_output
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900551 */
552static void
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000553create_layer(struct weston_output *output,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900554 struct hmi_controller_layer *layer)
555{
556 int32_t ret = 0;
557
558 layer->ivilayer =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000559 ivi_layout_interface->layer_create_with_dimension(layer->id_layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900560 layer->width,
561 layer->height);
562 assert(layer->ivilayer != NULL);
563
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000564 ret = ivi_layout_interface->screen_add_layer(output, layer->ivilayer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900565 assert(!ret);
566
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000567 ret = ivi_layout_interface->layer_set_destination_rectangle(layer->ivilayer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900568 layer->x, layer->y,
569 layer->width,
570 layer->height);
571 assert(!ret);
572
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000573 ret = ivi_layout_interface->layer_set_visibility(layer->ivilayer, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900574 assert(!ret);
575}
576
577/**
578 * Internal set notification
579 */
580static void
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000581set_notification_create_surface(struct wl_listener *listener, void *data)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900582{
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000583 struct hmi_controller *hmi_ctrl =
584 wl_container_of(listener, hmi_ctrl,
585 surface_created);
586 struct ivi_layout_surface *ivisurf = data;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900587 struct hmi_controller_layer *layer_link =
588 wl_container_of(hmi_ctrl->application_layer_list.prev,
589 layer_link,
590 link);
591 struct ivi_layout_layer *application_layer = layer_link->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900592 int32_t ret = 0;
593
594 /* skip ui widgets */
595 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
596 return;
597
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000598 ret = ivi_layout_interface->layer_add_surface(application_layer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900599 assert(!ret);
600}
601
602static void
603set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
604 void *userdata)
605{
606 struct hmi_controller *hmi_ctrl = userdata;
607
608 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
609}
610
611static void
612set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
613 void *userdata)
614{
615 struct hmi_controller *hmi_ctrl = userdata;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900616 struct hmi_controller_layer *layer_link = NULL;
617 struct ivi_layout_layer *application_layer = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900618 struct weston_surface *surface;
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900619 struct ivi_layout_surface **ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900620 int32_t length = 0;
621 int32_t i;
622
623 /* return if the surface is not application content */
624 if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
625 return;
626 }
627
628 /*
629 * if application changes size of wl_buffer. The source rectangle shall be
630 * fit to the size.
631 */
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000632 surface = ivi_layout_interface->surface_get_weston_surface(ivisurf);
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900633 if (surface) {
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000634 ivi_layout_interface->surface_set_source_rectangle(
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900635 ivisurf, 0, 0, surface->width,
636 surface->height);
637 }
638
639 /*
640 * search if the surface is already added to layer.
641 * If not yet, it is newly invoded application to go to switch_mode.
642 */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900643 wl_list_for_each_reverse(layer_link, &hmi_ctrl->application_layer_list, link) {
644 application_layer = layer_link->ivilayer;
645 ivi_layout_interface->get_surfaces_on_layer(application_layer,
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900646 &length, &ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900647 for (i = 0; i < length; i++) {
648 if (ivisurf == ivisurfs[i]) {
649 /*
650 * if it is non new invoked application, just call
651 * commit_changes to apply source_rectangle.
652 */
653 ivi_layout_interface->commit_changes();
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900654 free(ivisurfs);
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900655 return;
656 }
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900657 }
Wataru Natsume9d8b4412016-03-03 19:56:52 +0900658 free(ivisurfs);
659 ivisurfs = NULL;
Nobuhiko Tanibata65160dc2015-04-27 17:00:25 +0900660 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900661
662 switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
663}
664
665/**
666 * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
667 * corresponding ivi_layer are defined in weston.ini. Default scene graph
668 * of ivi_layers are initialized in hmi_controller_create
669 */
670static struct hmi_server_setting *
671hmi_server_setting_create(struct weston_compositor *ec)
672{
673 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
674 struct weston_config *config = ec->config;
675 struct weston_config_section *shell_section = NULL;
676
677 shell_section = weston_config_get_section(config, "ivi-shell",
678 NULL, NULL);
679
680 weston_config_section_get_uint(shell_section, "base-layer-id",
681 &setting->base_layer_id, 1000);
682
683 weston_config_section_get_uint(shell_section,
684 "workspace-background-layer-id",
685 &setting->workspace_background_layer_id,
686 2000);
687
688 weston_config_section_get_uint(shell_section, "workspace-layer-id",
689 &setting->workspace_layer_id, 3000);
690
691 weston_config_section_get_uint(shell_section, "application-layer-id",
692 &setting->application_layer_id, 4000);
693
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900694 weston_config_section_get_uint(shell_section, "base-layer-id-offset",
695 &setting->base_layer_id_offset, 10000);
696
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900697 weston_config_section_get_uint(shell_section, "transition-duration",
698 &setting->transition_duration, 300);
699
700 setting->panel_height = 70;
701
702 weston_config_section_get_string(shell_section,
703 "ivi-shell-user-interface",
704 &setting->ivi_homescreen, NULL);
705
706 return setting;
707}
708
709static void
710hmi_controller_destroy(struct wl_listener *listener, void *data)
711{
712 struct link_layer *link = NULL;
713 struct link_layer *next = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900714 struct hmi_controller_layer *ctrl_layer_link = NULL;
715 struct hmi_controller_layer *ctrl_layer_next = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900716 struct hmi_controller *hmi_ctrl =
717 container_of(listener, struct hmi_controller, destroy_listener);
718
719 wl_list_for_each_safe(link, next,
720 &hmi_ctrl->workspace_fade.layer_list, link) {
721 wl_list_remove(&link->link);
722 free(link);
723 }
724
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900725 /* clear base_layer_list */
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900726 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
727 &hmi_ctrl->base_layer_list, link) {
728 wl_list_remove(&ctrl_layer_link->link);
729 free(ctrl_layer_link);
730 }
731
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900732 /* clear application_layer_list */
733 wl_list_for_each_safe(ctrl_layer_link, ctrl_layer_next,
734 &hmi_ctrl->application_layer_list, link) {
735 wl_list_remove(&ctrl_layer_link->link);
736 free(ctrl_layer_link);
737 }
738
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900739 wl_array_release(&hmi_ctrl->ui_widgets);
740 free(hmi_ctrl->hmi_setting);
741 free(hmi_ctrl);
742}
743
744/**
745 * This is a starting method called from module_init.
746 * This sets up scene graph of ivi_layers; base, application, workspace
747 * background, and workspace. These ivi_layers are created/added to
748 * ivi_screen in create_layer
749 *
750 * base: to group ivi_surfaces of panel and background
751 * application: to group ivi_surfaces of ivi_applications
752 * workspace background: to group a ivi_surface of background in workspace
753 * workspace: to group ivi_surfaces for launching ivi_applications
754 *
755 * ivi_layers of workspace background and workspace is set to invisible at
756 * first. The properties of it is updated with animation when
757 * ivi_hmi_controller_home is requested.
758 */
759static struct hmi_controller *
760hmi_controller_create(struct weston_compositor *ec)
761{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900762 struct link_layer *tmp_link_layer = NULL;
763 int32_t panel_height = 0;
764 struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900765 struct hmi_controller_layer *base_layer = NULL;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900766 struct hmi_controller_layer *application_layer = NULL;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000767 struct weston_output *output;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900768
769 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900770
771 wl_array_init(&hmi_ctrl->ui_widgets);
772 hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
773 hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
774 hmi_ctrl->compositor = ec;
Ucan, Emre (ADITG/SW1)3a8521e2016-03-17 15:30:39 +0000775 hmi_ctrl->screen_num = wl_list_length(&ec->output_list);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900776
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900777 /* init base ivi_layer*/
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900778 wl_list_init(&hmi_ctrl->base_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000779 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900780 base_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
781 base_layer->x = 0;
782 base_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000783 base_layer->width = output->current_mode->width;
784 base_layer->height = output->current_mode->height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900785 base_layer->id_layer =
786 hmi_ctrl->hmi_setting->base_layer_id +
787 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
788 wl_list_insert(&hmi_ctrl->base_layer_list, &base_layer->link);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900789
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000790 create_layer(output, base_layer);
791 i++;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900792 }
793
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000794 i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900795 panel_height = hmi_ctrl->hmi_setting->panel_height;
796
797 /* init application ivi_layer */
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900798 wl_list_init(&hmi_ctrl->application_layer_list);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000799 wl_list_for_each(output, &ec->output_list, link) {
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900800 application_layer = MEM_ALLOC(1 * sizeof(struct hmi_controller_layer));
801 application_layer->x = 0;
802 application_layer->y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000803 application_layer->width = output->current_mode->width;
804 application_layer->height = output->current_mode->height - panel_height;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900805 application_layer->id_layer =
806 hmi_ctrl->hmi_setting->application_layer_id +
807 (i * hmi_ctrl->hmi_setting->base_layer_id_offset);
808 wl_list_insert(&hmi_ctrl->application_layer_list, &application_layer->link);
809
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000810 create_layer(output, application_layer);
811 i++;
Nobuhiko Tanibatad789c662015-12-09 15:42:46 +0900812 }
813
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900814 /* init workspace background ivi_layer */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000815 output = wl_container_of(ec->output_list.next, output, link);
816 hmi_ctrl->workspace_background_output = output;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900817 hmi_ctrl->workspace_background_layer.x = 0;
818 hmi_ctrl->workspace_background_layer.y = 0;
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000819 hmi_ctrl->workspace_background_layer.width =
820 output->current_mode->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900821 hmi_ctrl->workspace_background_layer.height =
Ucan, Emre (ADITG/SW1)ff6a9f82016-03-17 15:30:35 +0000822 output->current_mode->height - panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900823
824 hmi_ctrl->workspace_background_layer.id_layer =
825 hmi_ctrl->hmi_setting->workspace_background_layer_id;
826
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +0000827 create_layer(output, &hmi_ctrl->workspace_background_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000828 ivi_layout_interface->layer_set_opacity(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900829 hmi_ctrl->workspace_background_layer.ivilayer, 0);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000830 ivi_layout_interface->layer_set_visibility(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900831 hmi_ctrl->workspace_background_layer.ivilayer, false);
832
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900833
834 wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
835 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900836 tmp_link_layer->layout_layer =
837 hmi_ctrl->workspace_background_layer.ivilayer;
838 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
839 &tmp_link_layer->link);
840
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000841 hmi_ctrl->surface_created.notify = set_notification_create_surface;
842 ivi_layout_interface->add_listener_create_surface(&hmi_ctrl->surface_created);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000843 ivi_layout_interface->add_notification_remove_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900844 set_notification_remove_surface, hmi_ctrl);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000845 ivi_layout_interface->add_notification_configure_surface(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900846 set_notification_configure_surface, hmi_ctrl);
847
848 hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
849 wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
850 &hmi_ctrl->destroy_listener);
851
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900852 return hmi_ctrl;
853}
854
855/**
856 * Implementations of ivi-hmi-controller.xml
857 */
858
859/**
860 * A ivi_surface drawing background is identified by id_surface.
861 * Properties of the ivi_surface is set by using ivi_layout APIs according to
862 * the scene graph of UI defined in hmi_controller_create.
863 *
864 * UI ivi_layer is used to add this ivi_surface.
865 */
866static void
867ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
868 uint32_t id_surface)
869{
870 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900871 struct hmi_controller_layer *base_layer = NULL;
872 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000873 int32_t dstx;
874 int32_t dsty;
875 int32_t width;
876 int32_t height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900877 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900878 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900879
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900880 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
881 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
882 sizeof(*add_surface_id));
883 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Ucan, Emre (ADITG/SW1)783cb4d2016-03-17 14:36:51 +0000884 dstx = base_layer->x;
885 dsty = base_layer->y;
886 width = base_layer->width;
887 height = base_layer->height;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900888 ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900889
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900890 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
891 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900892
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900893 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
894 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900895
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900896 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
897 dstx, dsty, width, height);
898 assert(!ret);
899
900 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
901 assert(!ret);
902
903 i++;
904 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900905}
906
907/**
908 * A ivi_surface drawing panel is identified by id_surface.
909 * Properties of the ivi_surface is set by using ivi_layout APIs according to
910 * the scene graph of UI defined in hmi_controller_create.
911 *
912 * UI ivi_layer is used to add this ivi_surface.
913 */
914static void
915ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
916 uint32_t id_surface)
917{
918 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000919 struct hmi_controller_layer *base_layer;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900920 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000921 int32_t width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900922 int32_t ret = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900923 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900924 const int32_t dstx = 0;
925 int32_t dsty = 0;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900926 int32_t i = 0;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900927
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900928 wl_list_for_each_reverse(base_layer, &hmi_ctrl->base_layer_list, link) {
929 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
930 sizeof(*add_surface_id));
931 *add_surface_id = id_surface + (i * hmi_ctrl->ui_setting.surface_id_offset);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900932
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900933 ivilayer = base_layer->ivilayer;
934 ivisurf = ivi_layout_interface->get_surface_from_id(*add_surface_id);
935 assert(ivisurf != NULL);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900936
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900937 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
938 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900939
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900940 dsty = base_layer->height - panel_height;
Ucan, Emre (ADITG/SW1)c6459c492016-03-17 14:36:52 +0000941 width = base_layer->width;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900942
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900943 ret = ivi_layout_interface->surface_set_destination_rectangle(
944 ivisurf, dstx, dsty, width, panel_height);
945 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900946
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900947 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
948 assert(!ret);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900949
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900950 i++;
951 }
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900952}
953
954/**
955 * A ivi_surface drawing buttons in panel is identified by id_surface.
956 * It can set several buttons. Properties of the ivi_surface is set by
957 * using ivi_layout APIs according to the scene graph of UI defined in
958 * hmi_controller_create. Additionally, the position of it is shifted to
959 * right when new one is requested.
960 *
961 * UI ivi_layer is used to add these ivi_surfaces.
962 */
963static void
964ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
965 uint32_t id_surface, int32_t number)
966{
967 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900968 struct hmi_controller_layer *base_layer =
969 wl_container_of(hmi_ctrl->base_layer_list.prev,
970 base_layer,
971 link);
972 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900973 const int32_t width = 48;
974 const int32_t height = 48;
975 int32_t ret = 0;
976 int32_t panel_height = 0;
977 int32_t dstx = 0;
978 int32_t dsty = 0;
979 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
980 sizeof(*add_surface_id));
981 *add_surface_id = id_surface;
982
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000983 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900984 assert(ivisurf != NULL);
985
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000986 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900987 assert(!ret);
988
989 panel_height = hmi_ctrl->hmi_setting->panel_height;
990
991 dstx = (60 * number) + 15;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +0900992 dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900993
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000994 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900995 ivisurf,dstx, dsty, width, height);
996 assert(!ret);
997
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +0000998 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +0900999 assert(!ret);
1000}
1001
1002/**
1003 * A ivi_surface drawing home button in panel is identified by id_surface.
1004 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1005 * the scene graph of UI defined in hmi_controller_create.
1006 *
1007 * UI ivi_layer is used to add these ivi_surfaces.
1008 */
1009static void
1010ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
1011 uint32_t id_surface)
1012{
1013 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001014 struct hmi_controller_layer *base_layer =
1015 wl_container_of(hmi_ctrl->base_layer_list.prev,
1016 base_layer,
1017 link);
1018 struct ivi_layout_layer *ivilayer = base_layer->ivilayer;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001019 int32_t ret = 0;
1020 int32_t size = 48;
1021 int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
Nobuhiko Tanibata744b0302015-12-09 15:41:00 +09001022 const int32_t dstx = (base_layer->width - size) / 2;
1023 const int32_t dsty = (base_layer->height - panel_height) + 5;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001024
1025 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1026 sizeof(*add_surface_id));
1027 *add_surface_id = id_surface;
1028
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001029 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001030 assert(ivisurf != NULL);
1031
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001032 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001033 assert(!ret);
1034
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001035 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001036 ivisurf, dstx, dsty, size, size);
1037 assert(!ret);
1038
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001039 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001040 assert(!ret);
1041}
1042
1043/**
1044 * A ivi_surface drawing background of workspace is identified by id_surface.
1045 * Properties of the ivi_surface is set by using ivi_layout APIs according to
1046 * the scene graph of UI defined in hmi_controller_create.
1047 *
1048 * A ivi_layer of workspace_background is used to add this ivi_surface.
1049 */
1050static void
1051ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
1052 uint32_t id_surface)
1053{
1054 struct ivi_layout_surface *ivisurf = NULL;
1055 struct ivi_layout_layer *ivilayer = NULL;
1056 const int32_t width = hmi_ctrl->workspace_background_layer.width;
1057 const int32_t height = hmi_ctrl->workspace_background_layer.height;
1058 int32_t ret = 0;
1059
1060 uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1061 sizeof(*add_surface_id));
1062 *add_surface_id = id_surface;
1063 ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
1064
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001065 ivisurf = ivi_layout_interface->get_surface_from_id(id_surface);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001066 assert(ivisurf != NULL);
1067
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001068 ret = ivi_layout_interface->layer_add_surface(ivilayer, ivisurf);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001069 assert(!ret);
1070
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001071 ret = ivi_layout_interface->surface_set_destination_rectangle(ivisurf,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001072 0, 0, width, height);
1073 assert(!ret);
1074
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001075 ret = ivi_layout_interface->surface_set_visibility(ivisurf, true);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001076 assert(!ret);
1077}
1078
1079/**
1080 * A list of ivi_surfaces drawing launchers in workspace is identified by
1081 * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
1082 * APIs according to the scene graph of UI defined in hmi_controller_create.
1083 *
1084 * The workspace can have several pages to group ivi_surfaces of launcher.
1085 * Each call of this interface increments a number of page to add a group
1086 * of ivi_surfaces
1087 */
1088static void
1089ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
1090 int32_t icon_size)
1091{
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001092 int32_t minspace_x = 10;
1093 int32_t minspace_y = minspace_x;
1094
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001095 int32_t width = hmi_ctrl->workspace_background_layer.width;
1096 int32_t height = hmi_ctrl->workspace_background_layer.height;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001097
1098 int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
1099 int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
1100 float fcell_size_x = icon_size + space_x;
1101
1102 int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
1103 int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
1104 float fcell_size_y = icon_size + space_y;
1105
1106 struct weston_config *config = NULL;
1107 struct weston_config_section *section = NULL;
1108 const char *name = NULL;
1109 int launcher_count = 0;
1110 struct wl_array launchers;
1111 int32_t nx = 0;
1112 int32_t ny = 0;
1113 int32_t prev = -1;
1114 struct launcher_info *data = NULL;
1115
1116 uint32_t surfaceid = 0;
1117 uint32_t workspaceid = 0;
1118 struct launcher_info *info = NULL;
1119
1120 int32_t x = 0;
1121 int32_t y = 0;
1122 int32_t ret = 0;
1123 struct ivi_layout_surface* layout_surface = NULL;
1124 uint32_t *add_surface_id = NULL;
1125
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001126 struct link_layer *tmp_link_layer = NULL;
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001127
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001128 if (0 == x_count)
1129 x_count = 1;
1130
1131 if (0 == y_count)
1132 y_count = 1;
1133
1134 config = hmi_ctrl->compositor->config;
1135 if (!config)
1136 return;
1137
1138 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1139 if (!section)
1140 return;
1141
1142 wl_array_init(&launchers);
1143
1144 while (weston_config_next_section(config, &section, &name)) {
1145 surfaceid = 0;
1146 workspaceid = 0;
1147 info = NULL;
1148 if (0 != strcmp(name, "ivi-launcher"))
1149 continue;
1150
1151 if (0 != weston_config_section_get_uint(section, "icon-id",
1152 &surfaceid, 0))
1153 continue;
1154
1155 if (0 != weston_config_section_get_uint(section,
1156 "workspace-id",
1157 &workspaceid, 0))
1158 continue;
1159
1160 info = wl_array_add(&launchers, sizeof(*info));
1161
1162 if (info) {
1163 info->surface_id = surfaceid;
1164 info->workspace_id = workspaceid;
1165 info->index = launcher_count;
1166 ++launcher_count;
1167 }
1168 }
1169
1170 qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
1171 compare_launcher_info);
1172
1173 wl_array_for_each(data, &launchers) {
1174 x = 0;
1175 y = 0;
1176 ret = 0;
1177 layout_surface = NULL;
1178 add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
1179 sizeof(*add_surface_id));
1180
1181 *add_surface_id = data->surface_id;
1182
1183 if (0 > prev || (uint32_t)prev != data->workspace_id) {
1184 nx = 0;
1185 ny = 0;
1186 prev = data->workspace_id;
1187
1188 if (0 <= prev)
1189 hmi_ctrl->workspace_count++;
1190 }
1191
1192 if (y_count == ny) {
1193 ny = 0;
1194 hmi_ctrl->workspace_count++;
1195 }
1196
1197 x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
1198 y = ny * fcell_size_y + space_y;
1199
1200 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001201 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001202 assert(layout_surface);
1203
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001204 ret = ivi_layout_interface->surface_set_destination_rectangle(
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001205 layout_surface, x, y, icon_size, icon_size);
1206 assert(!ret);
1207
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001208 nx++;
1209
1210 if (x_count == nx) {
1211 ny++;
1212 nx = 0;
1213 }
1214 }
1215
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001216 /* init workspace ivi_layer */
1217 hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
1218 hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
1219 hmi_ctrl->workspace_layer.width =
1220 hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
1221 hmi_ctrl->workspace_layer.height =
1222 hmi_ctrl->workspace_background_layer.height;
1223 hmi_ctrl->workspace_layer.id_layer =
1224 hmi_ctrl->hmi_setting->workspace_layer_id;
1225
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001226 create_layer(hmi_ctrl->workspace_background_output, &hmi_ctrl->workspace_layer);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001227 ivi_layout_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
1228 ivi_layout_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001229 false);
1230
1231 tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
1232 tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
1233 wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
1234 &tmp_link_layer->link);
1235
1236 /* Add surface to layer */
1237 wl_array_for_each(data, &launchers) {
1238 layout_surface =
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001239 ivi_layout_interface->get_surface_from_id(data->surface_id);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001240 assert(layout_surface);
1241
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001242 ret = ivi_layout_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001243 layout_surface);
1244 assert(!ret);
1245
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001246 ret = ivi_layout_interface->surface_set_visibility(layout_surface, true);
Nobuhiko Tanibatad290f882015-08-24 09:12:23 +09001247 assert(!ret);
1248 }
1249
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001250 wl_array_release(&launchers);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001251 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001252}
1253
1254static void
1255ivi_hmi_controller_UI_ready(struct wl_client *client,
1256 struct wl_resource *resource)
1257{
1258 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1259
1260 ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
1261 ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
1262 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
1263 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
1264 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
1265 ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
1266 ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
1267 ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001268 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001269
1270 ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
1271 hmi_ctrl->is_initialized = 1;
1272}
1273
1274/**
1275 * Implementation of request and event of ivi_hmi_controller_workspace_control
1276 * and controlling workspace.
1277 *
1278 * When motion of input is detected in a ivi_surface of workspace background,
1279 * ivi_hmi_controller_workspace_control shall be invoked and to start
1280 * controlling of workspace. The workspace has several pages to show several
1281 * groups of applications.
1282 * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
1283 * according to motion. When motion finished, e.g. touch up detected, control is
1284 * terminated and event:ivi_hmi_controller_workspace_control is notified.
1285 */
1286struct pointer_grab {
1287 struct weston_pointer_grab grab;
1288 struct ivi_layout_layer *layer;
1289 struct wl_resource *resource;
1290};
1291
1292struct touch_grab {
1293 struct weston_touch_grab grab;
1294 struct ivi_layout_layer *layer;
1295 struct wl_resource *resource;
1296};
1297
1298struct move_grab {
1299 wl_fixed_t dst[2];
1300 wl_fixed_t rgn[2][2];
1301 double v[2];
1302 struct timespec start_time;
1303 struct timespec pre_time;
1304 wl_fixed_t start_pos[2];
1305 wl_fixed_t pos[2];
1306 int32_t is_moved;
1307};
1308
1309struct pointer_move_grab {
1310 struct pointer_grab base;
1311 struct move_grab move;
1312};
1313
1314struct touch_move_grab {
1315 struct touch_grab base;
1316 struct move_grab move;
1317 int32_t is_active;
1318};
1319
1320static void
1321pointer_grab_start(struct pointer_grab *grab,
1322 struct ivi_layout_layer *layer,
1323 const struct weston_pointer_grab_interface *interface,
1324 struct weston_pointer *pointer)
1325{
1326 grab->grab.interface = interface;
1327 grab->layer = layer;
1328 weston_pointer_start_grab(pointer, &grab->grab);
1329}
1330
1331static void
1332touch_grab_start(struct touch_grab *grab,
1333 struct ivi_layout_layer *layer,
1334 const struct weston_touch_grab_interface *interface,
1335 struct weston_touch* touch)
1336{
1337 grab->grab.interface = interface;
1338 grab->layer = layer;
1339 weston_touch_start_grab(touch, &grab->grab);
1340}
1341
1342static int32_t
1343clamp(int32_t val, int32_t min, int32_t max)
1344{
1345 if (val < min)
1346 return min;
1347
1348 if (max < val)
1349 return max;
1350
1351 return val;
1352}
1353
1354static void
1355move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
1356 wl_fixed_t grab_x, struct ivi_layout_layer *layer)
1357{
1358 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1359 int32_t width = hmi_ctrl->workspace_background_layer.width;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001360 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001361
1362 struct timespec time = {0};
1363 double grab_time = 0.0;
1364 double from_motion_time = 0.0;
1365 double pointer_v = 0.0;
1366 int32_t is_flick = 0;
1367 int32_t pos_x = 0;
1368 int32_t pos_y = 0;
1369 int page_no = 0;
1370 double end_pos = 0.0;
1371 uint32_t duration = 0;
1372
1373 clock_gettime(CLOCK_MONOTONIC, &time);
1374
1375 grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
1376 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
1377
1378 from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
1379 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
1380
1381 pointer_v = move->v[0];
1382
1383 is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
1384 if (200 < from_motion_time)
1385 pointer_v = 0.0;
1386
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001387 prop = ivi_layout_interface->get_properties_of_layer(layer);
1388 pos_x = prop->dest_x;
1389 pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001390
1391 if (is_flick) {
1392 int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
1393 page_no = (-orgx + width / 2) / width;
1394
1395 if (pointer_v < 0.0)
1396 page_no++;
1397 else
1398 page_no--;
1399 } else {
1400 page_no = (-pos_x + width / 2) / width;
1401 }
1402
1403 page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
1404 end_pos = -page_no * width;
1405
1406 duration = hmi_ctrl->hmi_setting->transition_duration;
1407 ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001408 ivi_layout_interface->layer_set_transition(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001409 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
1410 duration);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001411 ivi_layout_interface->layer_set_destination_rectangle(layer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001412 end_pos, pos_y,
Nobuhiko Tanibata4412cd12015-08-24 09:12:37 +09001413 hmi_ctrl->workspace_layer.width,
1414 hmi_ctrl->workspace_layer.height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001415 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001416}
1417
1418static void
1419pointer_move_workspace_grab_end(struct pointer_grab *grab)
1420{
1421 struct pointer_move_grab *pnt_move_grab =
1422 (struct pointer_move_grab *)grab;
1423 struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
1424
1425 move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
1426 grab->grab.pointer->grab_x, layer);
1427
1428 weston_pointer_end_grab(grab->grab.pointer);
1429}
1430
1431static void
1432touch_move_workspace_grab_end(struct touch_grab *grab)
1433{
1434 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1435 struct ivi_layout_layer *layer = tch_move_grab->base.layer;
1436
1437 move_workspace_grab_end(&tch_move_grab->move, grab->resource,
1438 grab->grab.touch->grab_x, layer);
1439
1440 weston_touch_end_grab(grab->grab.touch);
1441}
1442
1443static void
1444pointer_noop_grab_focus(struct weston_pointer_grab *grab)
1445{
1446}
1447
1448static void
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001449pointer_default_grab_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001450 uint32_t time,
1451 struct weston_pointer_axis_event *event)
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001452{
Peter Hutterer89b6a492016-01-18 15:58:17 +10001453 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001454}
1455
1456static void
Peter Hutterer87743e92016-01-18 16:38:22 +10001457pointer_default_grab_axis_source(struct weston_pointer_grab *grab,
1458 uint32_t source)
1459{
1460 weston_pointer_send_axis_source(grab->pointer, source);
1461}
1462
1463static void
1464pointer_default_grab_frame(struct weston_pointer_grab *grab)
1465{
1466 weston_pointer_send_frame(grab->pointer);
1467}
1468
1469static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001470move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
1471{
1472 struct timespec timestamp = {0};
1473 int32_t ii = 0;
1474 double dt = 0.0;
1475
1476 clock_gettime(CLOCK_MONOTONIC, &timestamp); //FIXME
1477 dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
1478 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
1479
1480 if (dt < 1e-6)
1481 dt = 1e-6;
1482
1483 move->pre_time = timestamp;
1484
1485 for (ii = 0; ii < 2; ii++) {
1486 wl_fixed_t prepos = move->pos[ii];
1487 move->pos[ii] = pointer[ii] + move->dst[ii];
1488
1489 if (move->pos[ii] < move->rgn[0][ii]) {
1490 move->pos[ii] = move->rgn[0][ii];
1491 move->dst[ii] = move->pos[ii] - pointer[ii];
1492 } else if (move->rgn[1][ii] < move->pos[ii]) {
1493 move->pos[ii] = move->rgn[1][ii];
1494 move->dst[ii] = move->pos[ii] - pointer[ii];
1495 }
1496
1497 move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
1498
1499 if (!move->is_moved &&
1500 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
1501 move->is_moved = 1;
1502 }
1503}
1504
1505static void
1506layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
1507 wl_fixed_t pos_y)
1508{
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001509 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001510 int32_t layout_pos_x = 0;
1511 int32_t layout_pos_y = 0;
1512
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001513 prop = ivi_layout_interface->get_properties_of_layer(layer);
1514
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001515 layout_pos_x = wl_fixed_to_int(pos_x);
1516 layout_pos_y = wl_fixed_to_int(pos_y);
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001517 ivi_layout_interface->layer_set_destination_rectangle(layer,
1518 layout_pos_x, layout_pos_y, prop->dest_width, prop->dest_height);
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001519 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001520}
1521
1522static void
1523pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001524 struct weston_pointer_motion_event *event)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001525{
1526 struct pointer_move_grab *pnt_move_grab =
1527 (struct pointer_move_grab *)grab;
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001528 wl_fixed_t pointer_pos[2];
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001529
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001530 weston_pointer_motion_to_abs(grab->pointer, event,
1531 &pointer_pos[0], &pointer_pos[1]);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001532 move_grab_update(&pnt_move_grab->move, pointer_pos);
1533 layer_set_pos(pnt_move_grab->base.layer,
1534 pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
Jonas Ã…dahld2510102014-10-05 21:39:14 +02001535 weston_pointer_move(pnt_move_grab->base.grab.pointer, event);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001536}
1537
1538static void
1539touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1540 int touch_id, wl_fixed_t x, wl_fixed_t y)
1541{
1542 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1543
1544 if (!tch_move_grab->is_active)
1545 return;
1546
1547 wl_fixed_t pointer_pos[2] = {
1548 grab->touch->grab_x,
1549 grab->touch->grab_y
1550 };
1551
1552 move_grab_update(&tch_move_grab->move, pointer_pos);
1553 layer_set_pos(tch_move_grab->base.layer,
1554 tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
1555}
1556
1557static void
1558pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
1559 uint32_t time, uint32_t button,
1560 uint32_t state_w)
1561{
1562 if (BTN_LEFT == button &&
1563 WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
1564 struct pointer_grab *pg = (struct pointer_grab *)grab;
1565
1566 pointer_move_workspace_grab_end(pg);
1567 free(grab);
1568 }
1569}
1570
1571static void
1572touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
1573 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1574{
1575}
1576
1577static void
1578touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
1579 int touch_id)
1580{
1581 struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
1582
1583 if (0 == touch_id)
1584 tch_move_grab->is_active = 0;
1585
1586 if (0 == grab->touch->num_tp) {
1587 touch_move_workspace_grab_end(&tch_move_grab->base);
1588 free(grab);
1589 }
1590}
1591
1592static void
1593pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
1594{
1595 struct pointer_grab *pg = (struct pointer_grab *)grab;
1596
1597 pointer_move_workspace_grab_end(pg);
1598 free(grab);
1599}
1600
1601static void
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001602touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
1603{
1604}
1605
1606static void
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001607touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
1608{
1609 struct touch_grab *tg = (struct touch_grab *)grab;
1610
1611 touch_move_workspace_grab_end(tg);
1612 free(grab);
1613}
1614
1615static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
1616 pointer_noop_grab_focus,
1617 pointer_move_grab_motion,
1618 pointer_move_workspace_grab_button,
Jonas Ã…dahl0336ca02014-10-04 16:28:29 +02001619 pointer_default_grab_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +10001620 pointer_default_grab_axis_source,
1621 pointer_default_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001622 pointer_move_workspace_grab_cancel
1623};
1624
1625static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
1626 touch_nope_grab_down,
1627 touch_move_workspace_grab_up,
1628 touch_move_grab_motion,
Nobuhiko Tanibata82cc25b2015-02-06 16:08:52 +09001629 touch_move_workspace_grab_frame,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001630 touch_move_workspace_grab_cancel
1631};
1632
1633enum HMI_GRAB_DEVICE {
1634 HMI_GRAB_DEVICE_NONE,
1635 HMI_GRAB_DEVICE_POINTER,
1636 HMI_GRAB_DEVICE_TOUCH
1637};
1638
1639static enum HMI_GRAB_DEVICE
1640get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
1641{
Derek Foreman1281a362015-07-31 16:55:32 -05001642 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1643 struct weston_touch *touch = weston_seat_get_touch(seat);
1644
1645 if (pointer &&
1646 pointer->focus &&
1647 pointer->button_count &&
1648 pointer->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001649 return HMI_GRAB_DEVICE_POINTER;
1650
Derek Foreman1281a362015-07-31 16:55:32 -05001651 if (touch &&
1652 touch->focus &&
1653 touch->grab_serial == serial)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001654 return HMI_GRAB_DEVICE_TOUCH;
1655
1656 return HMI_GRAB_DEVICE_NONE;
1657}
1658
1659static void
1660move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
1661 wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
1662 struct wl_resource* resource)
1663{
1664 clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
1665 move->pre_time = move->start_time;
1666 move->pos[0] = start_pos[0];
1667 move->pos[1] = start_pos[1];
1668 move->start_pos[0] = start_pos[0];
1669 move->start_pos[1] = start_pos[1];
1670 move->dst[0] = start_pos[0] - grab_pos[0];
1671 move->dst[1] = start_pos[1] - grab_pos[1];
1672 memcpy(move->rgn, rgn, sizeof(move->rgn));
1673}
1674
1675static void
1676move_grab_init_workspace(struct move_grab* move,
1677 wl_fixed_t grab_x, wl_fixed_t grab_y,
1678 struct wl_resource *resource)
1679{
1680 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1681 struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001682 const struct ivi_layout_layer_properties *prop;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001683 int32_t workspace_count = hmi_ctrl->workspace_count;
1684 int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
1685 int32_t layer_pos_x = 0;
1686 int32_t layer_pos_y = 0;
1687 wl_fixed_t start_pos[2] = {0};
1688 wl_fixed_t rgn[2][2] = {{0}};
1689 wl_fixed_t grab_pos[2] = { grab_x, grab_y };
1690
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +00001691 prop = ivi_layout_interface->get_properties_of_layer(layer);
1692 layer_pos_x = prop->dest_x;
1693 layer_pos_y = prop->dest_y;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001694
1695 start_pos[0] = wl_fixed_from_int(layer_pos_x);
1696 start_pos[1] = wl_fixed_from_int(layer_pos_y);
1697
1698 rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
1699
1700 rgn[0][1] = wl_fixed_from_int(0);
1701 rgn[1][0] = wl_fixed_from_int(0);
1702 rgn[1][1] = wl_fixed_from_int(0);
1703
1704 move_grab_init(move, start_pos, grab_pos, rgn, resource);
1705}
1706
1707static struct pointer_move_grab *
1708create_workspace_pointer_move(struct weston_pointer *pointer,
1709 struct wl_resource* resource)
1710{
1711 struct pointer_move_grab *pnt_move_grab =
1712 MEM_ALLOC(sizeof(*pnt_move_grab));
1713
1714 pnt_move_grab->base.resource = resource;
1715 move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
1716 pointer->grab_y, resource);
1717
1718 return pnt_move_grab;
1719}
1720
1721static struct touch_move_grab *
1722create_workspace_touch_move(struct weston_touch *touch,
1723 struct wl_resource* resource)
1724{
1725 struct touch_move_grab *tch_move_grab =
1726 MEM_ALLOC(sizeof(*tch_move_grab));
1727
1728 tch_move_grab->base.resource = resource;
1729 tch_move_grab->is_active = 1;
1730 move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
1731 touch->grab_y, resource);
1732
1733 return tch_move_grab;
1734}
1735
1736static void
1737ivi_hmi_controller_workspace_control(struct wl_client *client,
1738 struct wl_resource *resource,
1739 struct wl_resource *seat_resource,
1740 uint32_t serial)
1741{
1742 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1743 struct ivi_layout_layer *layer = NULL;
1744 struct pointer_move_grab *pnt_move_grab = NULL;
1745 struct touch_move_grab *tch_move_grab = NULL;
1746 struct weston_seat *seat = NULL;
Derek Foreman1281a362015-07-31 16:55:32 -05001747 struct weston_pointer *pointer;
1748 struct weston_touch *touch;
1749
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001750 enum HMI_GRAB_DEVICE device;
1751
1752 if (hmi_ctrl->workspace_count < 2)
1753 return;
1754
1755 seat = wl_resource_get_user_data(seat_resource);
1756 device = get_hmi_grab_device(seat, serial);
1757
1758 if (HMI_GRAB_DEVICE_POINTER != device &&
1759 HMI_GRAB_DEVICE_TOUCH != device)
1760 return;
1761
1762 layer = hmi_ctrl->workspace_layer.ivilayer;
1763
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001764 ivi_layout_interface->transition_move_layer_cancel(layer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001765
1766 switch (device) {
1767 case HMI_GRAB_DEVICE_POINTER:
Derek Foreman1281a362015-07-31 16:55:32 -05001768 pointer = weston_seat_get_pointer(seat);
1769 pnt_move_grab = create_workspace_pointer_move(pointer,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001770 resource);
1771
1772 pointer_grab_start(&pnt_move_grab->base, layer,
1773 &pointer_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001774 pointer);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001775 break;
1776
1777 case HMI_GRAB_DEVICE_TOUCH:
Derek Foreman1281a362015-07-31 16:55:32 -05001778 touch = weston_seat_get_touch(seat);
1779 tch_move_grab = create_workspace_touch_move(touch,
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001780 resource);
1781
1782 touch_grab_start(&tch_move_grab->base, layer,
1783 &touch_move_grab_workspace_interface,
Derek Foreman1281a362015-07-31 16:55:32 -05001784 touch);
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001785 break;
1786
1787 default:
1788 break;
1789 }
1790}
1791
1792/**
1793 * Implementation of switch_mode
1794 */
1795static void
1796ivi_hmi_controller_switch_mode(struct wl_client *client,
1797 struct wl_resource *resource,
1798 uint32_t layout_mode)
1799{
1800 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1801
1802 switch_mode(hmi_ctrl, layout_mode);
1803}
1804
1805/**
1806 * Implementation of on/off displaying workspace and workspace background
1807 * ivi_layers.
1808 */
1809static void
1810ivi_hmi_controller_home(struct wl_client *client,
1811 struct wl_resource *resource,
1812 uint32_t home)
1813{
1814 struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
1815 uint32_t is_fade_in;
1816
1817 if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
1818 !hmi_ctrl->workspace_fade.is_fade_in) ||
1819 (IVI_HMI_CONTROLLER_HOME_OFF == home &&
1820 hmi_ctrl->workspace_fade.is_fade_in)) {
1821 is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
1822 hmi_controller_fade_run(hmi_ctrl, is_fade_in,
1823 &hmi_ctrl->workspace_fade);
1824 }
1825
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001826 ivi_layout_interface->commit_changes();
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001827}
1828
1829/**
1830 * binding ivi-hmi-controller implementation
1831 */
1832static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
1833 ivi_hmi_controller_UI_ready,
1834 ivi_hmi_controller_workspace_control,
1835 ivi_hmi_controller_switch_mode,
1836 ivi_hmi_controller_home
1837};
1838
1839static void
1840unbind_hmi_controller(struct wl_resource *resource)
1841{
1842}
1843
1844static void
1845bind_hmi_controller(struct wl_client *client,
1846 void *data, uint32_t version, uint32_t id)
1847{
1848 struct wl_resource *resource = NULL;
1849 struct hmi_controller *hmi_ctrl = data;
1850
1851 if (hmi_ctrl->user_interface != client) {
1852 struct wl_resource *res = wl_client_get_object(client, 1);
1853 wl_resource_post_error(res,
1854 WL_DISPLAY_ERROR_INVALID_OBJECT,
1855 "hmi-controller failed: permission denied");
1856 return;
1857 }
1858
1859 resource = wl_resource_create(
1860 client, &ivi_hmi_controller_interface, 1, id);
1861
1862 wl_resource_set_implementation(
1863 resource, &ivi_hmi_controller_implementation,
1864 hmi_ctrl, unbind_hmi_controller);
1865}
1866
1867static int32_t
1868initialize(struct hmi_controller *hmi_ctrl)
1869{
1870 struct config_command {
1871 char *key;
1872 uint32_t *dest;
1873 };
1874
1875 struct weston_config *config = hmi_ctrl->compositor->config;
1876 struct weston_config_section *section = NULL;
1877 int result = 0;
1878 int i = 0;
1879
1880 const struct config_command uint_commands[] = {
1881 { "background-id", &hmi_ctrl->ui_setting.background_id },
1882 { "panel-id", &hmi_ctrl->ui_setting.panel_id },
1883 { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
1884 { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
1885 { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
1886 { "random-id", &hmi_ctrl->ui_setting.random_id },
1887 { "home-id", &hmi_ctrl->ui_setting.home_id },
1888 { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001889 { "surface-id-offset", &hmi_ctrl->ui_setting.surface_id_offset },
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001890 { NULL, NULL }
1891 };
1892
1893 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
1894
1895 for (i = 0; -1 != result; ++i) {
1896 const struct config_command *command = &uint_commands[i];
1897
1898 if (!command->key)
1899 break;
1900
1901 if (weston_config_section_get_uint(
1902 section, command->key, command->dest, 0) != 0)
1903 result = -1;
1904 }
1905
1906 if (-1 == result) {
1907 weston_log("Failed to initialize hmi-controller\n");
1908 return 0;
1909 }
1910
1911 return 1;
1912}
1913
1914static void
1915launch_hmi_client_process(void *data)
1916{
1917 struct hmi_controller *hmi_ctrl =
1918 (struct hmi_controller *)data;
1919
1920 hmi_ctrl->user_interface =
1921 weston_client_start(hmi_ctrl->compositor,
1922 hmi_ctrl->hmi_setting->ivi_homescreen);
1923
1924 free(hmi_ctrl->hmi_setting->ivi_homescreen);
1925}
1926
1927/*****************************************************************************
1928 * exported functions
1929 ****************************************************************************/
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001930WL_EXPORT int
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001931controller_module_init(struct weston_compositor *ec,
1932 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001933 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001934 size_t interface_version)
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001935{
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001936 struct hmi_controller *hmi_ctrl = NULL;
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001937 struct wl_event_loop *loop = NULL;
1938
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001939 if (interface_version < sizeof(struct ivi_layout_interface)) {
Chris Michaelc083af92015-10-01 10:51:29 -04001940 weston_log("ivi-shell: version mismatch of controller interface\n");
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001941 return -1;
1942 }
1943
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001944 ivi_layout_interface = interface;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001945
1946 hmi_ctrl = hmi_controller_create(ec);
Nobuhiko Tanibata35711df2015-12-09 15:40:13 +09001947 if (hmi_ctrl == NULL)
1948 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001949
Nobuhiko Tanibata4f6853b2014-11-27 13:23:12 +09001950 if (!initialize(hmi_ctrl)) {
1951 return -1;
1952 }
1953
1954 if (wl_global_create(ec->wl_display,
1955 &ivi_hmi_controller_interface, 1,
1956 hmi_ctrl, bind_hmi_controller) == NULL) {
1957 return -1;
1958 }
1959
1960 loop = wl_display_get_event_loop(ec->wl_display);
1961 wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
1962
1963 return 0;
1964}