1 /*
2 * Copyright (C) 2013 DENSO CORPORATION
3 * Copyright (C) 2016 Advanced Driver Information Technology Joint Venture GmbH
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of the copyright holders not be used in
10 * advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission. The copyright holders make
12 * no representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23 /*
24 * This is implementation of ivi-controller.xml. This implementation uses
25 * ivi-extension APIs, which uses ivi_controller_interface pvoided by
26 * ivi-layout.c in weston.
27 */
28
29 #include "config.h"
30
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include <sys/mman.h>
37
38 #include "ivi-controller.h"
39 #include "ivi-wm-server-protocol.h"
40 #include "wayland-util.h"
41 #include "screen-info.h"
42 #include "weston.h"
43 #include "libweston-internal.h"
44 #include "backend.h"
45
46 #define IVI_CLIENT_SURFACE_ID_ENV_NAME "IVI_CLIENT_SURFACE_ID"
47 #define IVI_CLIENT_DEBUG_SCOPES_ENV_NAME "IVI_CLIENT_DEBUG_STREAM_NAMES"
48 #define IVI_CLIENT_ENABLE_CURSOR_ENV_NAME "IVI_CLIENT_ENABLE_CURSOR"
49
50 struct ivilayer;
51 struct iviscreen;
52
53 struct notification {
54 struct wl_list link;
55 struct wl_resource *resource;
56 struct wl_list layout_link;
57 };
58
59 struct ivilayer {
60 struct wl_list link;
61 struct ivishell *shell;
62 struct ivi_layout_layer *layout_layer;
63 const struct ivi_layout_layer_properties *prop;
64 struct wl_listener property_changed;
65 struct wl_list notification_list;
66 };
67
68 struct iviscreen {
69 struct wl_list link;
70 struct ivishell *shell;
71 uint32_t id_screen;
72 struct weston_output *output;
73 struct wl_list resource_list;
74 };
75
76 struct ivicontroller {
77 struct wl_resource *resource;
78 uint32_t id;
79 struct wl_client *client;
80 struct wl_list link;
81 struct ivishell *shell;
82
83 struct wl_list layer_notifications;
84 struct wl_list surface_notifications;
85 };
86
87 struct screenshot_frame_listener {
88 struct wl_listener frame_listener;
89 struct wl_listener output_destroyed;
90 struct wl_resource *screenshot;
91 struct weston_output *output;
92 };
93
94 struct screen_id_info {
95 char *screen_name;
96 uint32_t screen_id;
97 };
98
99 screen_listener_t screen_info_property_change_callback_listener = NULL;
100
101 static int
check_surface_id(struct wl_client * client,uint32_t surface_id)102 check_surface_id(struct wl_client *client, uint32_t surface_id)
103 {
104 //for dummy output screen debug(USE_DUMMY_SCREEN)
105 #ifdef USE_DUMMY_SCREEN
106 return 0;
107 #endif
108
109 pid_t pid;
110 const int windowIdBitNum = 5;
111
112 wl_client_get_credentials(client, &pid, NULL, NULL);
113 if ((surface_id >> windowIdBitNum) == pid) {
114 return 0;
115 }
116
117 return 1;
118 }
119
120 static void
clear_notification_list(struct wl_list * notification_list)121 clear_notification_list(struct wl_list* notification_list)
122 {
123 struct notification *not, *next;
124
125 wl_list_for_each_safe(not, next, notification_list, link) {
126 wl_list_remove(¬->layout_link);
127 wl_list_remove(¬->link);
128 free(not);
129 }
130 }
131
132 static void
destroy_ivicontroller_screen(struct wl_resource * resource)133 destroy_ivicontroller_screen(struct wl_resource *resource)
134 {
135 wl_list_remove(wl_resource_get_link(resource));
136 }
137
138 static void
unbind_resource_controller(struct wl_resource * resource)139 unbind_resource_controller(struct wl_resource *resource)
140 {
141 struct ivicontroller *controller = wl_resource_get_user_data(resource);
142
143 wl_list_remove(&controller->link);
144
145 clear_notification_list(&controller->layer_notifications);
146 clear_notification_list(&controller->surface_notifications);
147
148 free(controller);
149 controller = NULL;
150 }
151
152 static struct ivisurface*
get_surface(struct wl_list * list_surf,struct ivi_layout_surface * layout_surface)153 get_surface(struct wl_list *list_surf, struct ivi_layout_surface *layout_surface)
154 {
155 struct ivisurface *ivisurf = NULL;
156
157 wl_list_for_each(ivisurf, list_surf, link) {
158 if (layout_surface == ivisurf->layout_surface) {
159 return ivisurf;
160 }
161 }
162
163 return NULL;
164 }
165
166 static struct ivilayer*
get_layer(struct wl_list * list_layer,struct ivi_layout_layer * layout_layer)167 get_layer(struct wl_list *list_layer, struct ivi_layout_layer *layout_layer)
168 {
169 struct ivilayer *ivilayer = NULL;
170
171 wl_list_for_each(ivilayer, list_layer, link) {
172 if (layout_layer == ivilayer->layout_layer) {
173 return ivilayer;
174 }
175 }
176
177 return NULL;
178 }
179
180 static void
send_surface_configure_event(struct ivicontroller * ctrl,struct ivi_layout_surface * layout_surface,uint32_t surface_id)181 send_surface_configure_event(struct ivicontroller * ctrl,
182 struct ivi_layout_surface *layout_surface,
183 uint32_t surface_id)
184 {
185 struct weston_surface *surface;
186 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
187
188
189 surface = lyt->surface_get_weston_surface(layout_surface);
190
191 if (!surface)
192 return;
193
194 if ((surface->width == 0) || (surface->height == 0))
195 return;
196
197 ivi_wm_send_surface_size(ctrl->resource, surface_id,
198 surface->width, surface->height);
199 }
200
201 static void
send_surface_event(struct ivicontroller * ctrl,struct ivi_layout_surface * layout_surface,uint32_t surface_id,const struct ivi_layout_surface_properties * prop,uint32_t mask)202 send_surface_event(struct ivicontroller * ctrl,
203 struct ivi_layout_surface *layout_surface,
204 uint32_t surface_id,
205 const struct ivi_layout_surface_properties *prop,
206 uint32_t mask)
207 {
208 if (mask & IVI_NOTIFICATION_OPACITY) {
209 ivi_wm_send_surface_opacity(ctrl->resource, surface_id, prop->opacity);
210 }
211 if (mask & IVI_NOTIFICATION_SOURCE_RECT) {
212 ivi_wm_send_surface_source_rectangle(ctrl->resource, surface_id,
213 prop->source_x, prop->source_y,
214 prop->source_width, prop->source_height);
215 }
216 if (mask & IVI_NOTIFICATION_DEST_RECT) {
217 ivi_wm_send_surface_destination_rectangle(ctrl->resource, surface_id,
218 prop->dest_x, prop->dest_y,
219 prop->dest_width, prop->dest_height);
220 }
221 if (mask & IVI_NOTIFICATION_VISIBILITY) {
222 ivi_wm_send_surface_visibility(ctrl->resource, surface_id, prop->visibility);
223 }
224 if (mask & IVI_NOTIFICATION_CONFIGURE) {
225 send_surface_configure_event(ctrl, layout_surface, surface_id);
226 }
227 }
228
229 static void
send_surface_prop(struct wl_listener * listener,void * data)230 send_surface_prop(struct wl_listener *listener, void *data)
231 {
232 struct ivisurface *ivisurf =
233 wl_container_of(listener, ivisurf,
234 property_changed);
235 (void)data;
236 enum ivi_layout_notification_mask mask;
237 struct ivicontroller *ctrl;
238 const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
239 struct notification *not;
240 uint32_t surface_id;
241
242 mask = ivisurf->prop->event_mask;
243
244 surface_id = lyt->get_id_of_surface(ivisurf->layout_surface);
245
246 wl_list_for_each(not, &ivisurf->notification_list, layout_link) {
247 ctrl = wl_resource_get_user_data(not->resource);
248 send_surface_event(ctrl, ivisurf->layout_surface, surface_id, ivisurf->prop, mask);
249 }
250
251 if (screen_info_property_change_callback_listener) {
252 screen_info_property_change_callback_listener();
253 }
254 }
255
256 static void
send_layer_event(struct ivicontroller * ctrl,struct ivi_layout_layer * layout_layer,uint32_t layer_id,const struct ivi_layout_layer_properties * prop,uint32_t mask)257 send_layer_event(struct ivicontroller * ctrl,
258 struct ivi_layout_layer *layout_layer,
259 uint32_t layer_id,
260 const struct ivi_layout_layer_properties *prop,
261 uint32_t mask)
262 {
263 if (mask & IVI_NOTIFICATION_OPACITY) {
264 ivi_wm_send_layer_opacity(ctrl->resource, layer_id, prop->opacity);
265 }
266 if (mask & IVI_NOTIFICATION_SOURCE_RECT) {
267 ivi_wm_send_layer_source_rectangle(ctrl->resource, layer_id,
268 prop->source_x, prop->source_y,
269 prop->source_width, prop->source_height);
270 }
271 if (mask & IVI_NOTIFICATION_DEST_RECT) {
272 ivi_wm_send_layer_destination_rectangle(ctrl->resource, layer_id,
273 prop->dest_x, prop->dest_y,
274 prop->dest_width, prop->dest_height);
275 }
276 if (mask & IVI_NOTIFICATION_VISIBILITY) {
277 ivi_wm_send_layer_visibility(ctrl->resource, layer_id, prop->visibility);
278 }
279 }
280
281 static void
send_layer_prop(struct wl_listener * listener,void * data)282 send_layer_prop(struct wl_listener *listener, void *data)
283 {
284 struct ivilayer *ivilayer =
285 wl_container_of(listener, ivilayer, property_changed);
286 (void)data;
287 enum ivi_layout_notification_mask mask;
288 struct ivicontroller *ctrl;
289 const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
290 struct notification *not;
291 uint32_t layer_id;
292
293 mask = ivilayer->prop->event_mask;
294
295 layer_id = lyt->get_id_of_layer(ivilayer->layout_layer);
296
297 wl_list_for_each(not, &ivilayer->notification_list, layout_link) {
298 ctrl = wl_resource_get_user_data(not->resource);
299 send_layer_event(ctrl, ivilayer->layout_layer, layer_id, ivilayer->prop, mask);
300 }
301
302 if (screen_info_property_change_callback_listener) {
303 screen_info_property_change_callback_listener();
304 }
305 }
306
307 static void
controller_set_surface_opacity(struct wl_client * client,struct wl_resource * resource,uint32_t surface_id,wl_fixed_t opacity)308 controller_set_surface_opacity(struct wl_client *client,
309 struct wl_resource *resource,
310 uint32_t surface_id,
311 wl_fixed_t opacity)
312 {
313 if (check_surface_id(client, surface_id)) {
314 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
315 return;
316 }
317
318 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
319 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
320 (void)client;
321 struct ivi_layout_surface *layout_surface;
322
323 layout_surface = lyt->get_surface_from_id(surface_id);
324 if (!layout_surface) {
325 ivi_wm_send_surface_error(resource, surface_id,
326 IVI_WM_SURFACE_ERROR_NO_SURFACE,
327 "surface_set_opacity: the surface with given id does not exist");
328 return;
329 }
330
331 lyt->surface_set_opacity(layout_surface, opacity);
332 }
333
334 static void
controller_set_surface_source_rectangle(struct wl_client * client,struct wl_resource * resource,uint32_t surface_id,int32_t x,int32_t y,int32_t width,int32_t height)335 controller_set_surface_source_rectangle(struct wl_client *client,
336 struct wl_resource *resource,
337 uint32_t surface_id,
338 int32_t x,
339 int32_t y,
340 int32_t width,
341 int32_t height)
342 {
343 if (check_surface_id(client, surface_id)) {
344 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
345 return;
346 }
347
348 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
349 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
350 (void)client;
351 struct ivi_layout_surface *layout_surface;
352 const struct ivi_layout_surface_properties *prop;
353
354 layout_surface = lyt->get_surface_from_id(surface_id);
355 if (!layout_surface) {
356 ivi_wm_send_surface_error(resource, surface_id,
357 IVI_WM_SURFACE_ERROR_NO_SURFACE,
358 "surface_set_source_rectangle: the surface with given id does not exist");
359 return;
360 }
361
362 prop = lyt->get_properties_of_surface(layout_surface);
363
364 if (x < 0)
365 x = prop->source_x;
366 if (y < 0)
367 y = prop->source_y;
368 if (width < 0)
369 width = prop->source_width;
370 if (height < 0)
371 height = prop->source_height;
372
373 lyt->surface_set_source_rectangle(layout_surface,
374 (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
375 }
376
377 static void
controller_set_surface_destination_rectangle(struct wl_client * client,struct wl_resource * resource,uint32_t surface_id,int32_t x,int32_t y,int32_t width,int32_t height)378 controller_set_surface_destination_rectangle(struct wl_client *client,
379 struct wl_resource *resource,
380 uint32_t surface_id,
381 int32_t x,
382 int32_t y,
383 int32_t width,
384 int32_t height)
385 {
386 if (check_surface_id(client, surface_id)) {
387 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
388 return;
389 }
390
391 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
392 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
393 (void)client;
394 struct ivi_layout_surface *layout_surface;
395 const struct ivi_layout_surface_properties *prop;
396
397 layout_surface = lyt->get_surface_from_id(surface_id);
398 if (!layout_surface) {
399 ivi_wm_send_surface_error(resource, surface_id,
400 IVI_WM_SURFACE_ERROR_NO_SURFACE,
401 "surface_set_destination_rectangle: the surface with given id does not exist");
402 return;
403 }
404
405 prop = lyt->get_properties_of_surface(layout_surface);
406
407 // TODO: create set transition type protocol
408 lyt->surface_set_transition(layout_surface,
409 IVI_LAYOUT_TRANSITION_NONE,
410 300); // ms
411
412 if (x < 0)
413 x = prop->dest_x;
414 if (y < 0)
415 y = prop->dest_y;
416 if (width < 0)
417 width = prop->dest_width;
418 if (height < 0)
419 height = prop->dest_height;
420
421
422 lyt->surface_set_destination_rectangle(layout_surface,
423 (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
424 }
425
426 static void
controller_set_surface_visibility(struct wl_client * client,struct wl_resource * resource,uint32_t surface_id,uint32_t visibility)427 controller_set_surface_visibility(struct wl_client *client,
428 struct wl_resource *resource,
429 uint32_t surface_id,
430 uint32_t visibility)
431 {
432 if (check_surface_id(client, surface_id)) {
433 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
434 return;
435 }
436
437 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
438 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
439 (void)client;
440 struct ivi_layout_surface *layout_surface;
441
442 layout_surface = lyt->get_surface_from_id(surface_id);
443 if (!layout_surface) {
444 ivi_wm_send_surface_error(resource, surface_id,
445 IVI_WM_SURFACE_ERROR_NO_SURFACE,
446 "surface_set_visibility: the surface with given id does not exist");
447 return;
448 }
449
450 lyt->surface_set_visibility(layout_surface, visibility);
451 }
452
453 static int
create_screenshot_file(off_t size)454 create_screenshot_file(off_t size) {
455 const char template[] = "/ivi-shell-screenshot-XXXXXX";
456 const char *runtimedir;
457 char *tmpname;
458 int fd;
459
460 runtimedir = getenv("XDG_RUNTIME_DIR");
461 if (runtimedir == NULL)
462 return -1;
463
464 tmpname = malloc(strlen(runtimedir) + sizeof(template));
465 if (tmpname == NULL)
466 return -1;
467
468 fd = mkstemp(strcat(strcpy(tmpname, runtimedir), template));
469
470 if (fd < 0) {
471 free(tmpname);
472 return -1;
473 }
474
475 unlink(tmpname);
476 free(tmpname);
477
478 #ifdef HAVE_POSIX_FALLOCATE
479 if (posix_fallocate(fd, 0, size)) {
480 #else
481 if (ftruncate(fd, size) < 0) {
482 #endif
483 close(fd);
484 return -1;
485 }
486
487 return fd;
488 }
489
490 static void
491 controller_surface_screenshot(struct wl_client *client,
492 struct wl_resource *resource,
493 uint32_t screenshot_id,
494 uint32_t surface_id)
495 {
496 int32_t result = IVI_FAILED;
497 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
498 struct weston_surface *weston_surface = NULL;
499 int32_t width = 0;
500 int32_t height = 0;
501 int32_t stride = 0;
502 int32_t size = 0;
503 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
504 struct ivi_layout_surface *layout_surface;
505 char *buffer = NULL;
506 struct weston_compositor *compositor = ctrl->shell->compositor;
507 // assuming ABGR32 is always written by surface_dump
508 uint32_t format = WL_SHM_FORMAT_ABGR8888;
509 struct wl_resource *screenshot;
510 struct timespec stamp;
511 uint32_t stamp_ms;
512 int fd;
513
514 screenshot =
515 wl_resource_create(client, &ivi_screenshot_interface, 1, screenshot_id);
516
517 ivi_screenshot_send_error(screenshot, 0, "screenshot disabled");
518 return;
519
520 if (screenshot == NULL) {
521 wl_client_post_no_memory(client);
522 return;
523 }
524
525 layout_surface = lyt->get_surface_from_id(surface_id);
526 if (!layout_surface) {
527 ivi_screenshot_send_error(
528 screenshot, IVI_SCREENSHOT_ERROR_NO_SURFACE,
529 "surface_screenshot: the surface with given id does not exist");
530 goto err;
531 }
532
533 result = lyt->surface_get_size(layout_surface, &width,
534 &height, &stride);
535 if ((result != IVI_SUCCEEDED) || !width || !height || !stride) {
536 ivi_screenshot_send_error(
537 screenshot, IVI_SCREENSHOT_ERROR_NO_CONTENT,
538 "surface_screenshot: surface does not have content");
539 goto err;
540 }
541
542 size = stride * height;
543
544 fd = create_screenshot_file(size);
545 if (fd < 0) {
546 weston_log(
547 "surface_screenshot: failed to create file of %d bytes: %m\n",
548 size);
549 ivi_screenshot_send_error(
550 screenshot, IVI_SCREENSHOT_ERROR_IO_ERROR,
551 "failed to create screenshot file");
552 goto err;
553 }
554
555 buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
556 if (buffer == MAP_FAILED) {
557 weston_log("surface_screenshot: failed to mmap %d bytes: %m\n", size);
558 ivi_screenshot_send_error(screenshot, IVI_SCREENSHOT_ERROR_IO_ERROR,
559 "failed to create screenshot");
560 goto err_mmap;
561 }
562
563 weston_surface = lyt->surface_get_weston_surface(layout_surface);
564
565 result = lyt->surface_dump(weston_surface, buffer, size, 0, 0,
566 width, height);
567
568 if (result != IVI_SUCCEEDED) {
569 ivi_screenshot_send_error(
570 resource, IVI_SCREENSHOT_ERROR_NOT_SUPPORTED,
571 "surface_screenshot: surface dumping is not supported by renderer");
572 goto err_readpix;
573 }
574
575 // get current timestamp
576 weston_compositor_read_presentation_clock(compositor, &stamp);
577 stamp_ms = stamp.tv_sec * 1000 + stamp.tv_nsec / 1000000;
578
579 ivi_screenshot_send_done(screenshot, fd, width, height, stride, format,
580 stamp_ms);
581
582 err_readpix:
583 munmap(buffer, size);
584 err_mmap:
585 close(fd);
586 err:
587 wl_resource_destroy(screenshot);
588 }
589
590
591 static void
592 send_surface_stats(struct ivicontroller *ctrl,
593 struct ivi_layout_surface *layout_surface,
594 uint32_t surface_id)
595 {
596 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
597 struct ivisurface *ivisurf;
598 struct weston_surface *surface;
599 struct wl_client* target_client;
600 pid_t pid;
601 uid_t uid;
602 gid_t gid;
603
604 ivisurf = get_surface(&ctrl->shell->list_surface, layout_surface);
605
606 /* Get pid that creates surface */
607 surface = lyt->surface_get_weston_surface(layout_surface);
608
609 target_client = wl_resource_get_client(surface->resource);
610
611 wl_client_get_credentials(target_client, &pid, &uid, &gid);
612
613 ivi_wm_send_surface_stats(ctrl->resource, surface_id, ivisurf->frame_count, pid);
614 }
615
616 static void
617 controller_surface_sync(struct wl_client *client,
618 struct wl_resource *resource,
619 uint32_t surface_id,
620 int32_t sync_state)
621 {
622 if (check_surface_id(client, surface_id)) {
623 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
624 return;
625 }
626
627 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
628 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
629 struct ivi_layout_surface *layout_surface;
630 struct ivisurface *ivisurf;
631 (void)client;
632 struct notification *not;
633
634 layout_surface = lyt->get_surface_from_id(surface_id);
635 if (!layout_surface) {
636 ivi_wm_send_surface_error(resource, surface_id,
637 IVI_WM_SURFACE_ERROR_NO_SURFACE,
638 "surface_sync: the surface with given id does not exist");
639 return;
640 }
641
642 ivisurf = get_surface(&ctrl->shell->list_surface, layout_surface);
643
644 switch (sync_state) {
645 case IVI_WM_SYNC_ADD:
646 /*Check if a notification for the surface is already initialized*/
647 not= calloc(1, sizeof *not);
648 if (not == NULL) {
649 wl_resource_post_no_memory(resource);
650 return;
651 }
652
653 wl_list_insert(&ctrl->surface_notifications, ¬->link);
654 wl_list_insert(&ivisurf->notification_list, ¬->layout_link);
655 not->resource = resource;
656 break;
657 case IVI_WM_SYNC_REMOVE:
658 wl_list_for_each(not, &ivisurf->notification_list, layout_link)
659 {
660 if (not->resource == resource) {
661 wl_list_remove(¬->link);
662 wl_list_remove(¬->layout_link);
663 free(not);
664 break;
665 }
666 }
667 break;
668 default:
669 ivi_wm_send_surface_error(resource, surface_id,
670 IVI_WM_SURFACE_ERROR_BAD_PARAM,
671 "surface_sync: invalid sync_state parameter");
672 }
673 }
674
675 static void
676 controller_set_surface_type(struct wl_client *client, struct wl_resource *resource,
677 uint32_t surface_id, int32_t type)
678 {
679 if (check_surface_id(client, surface_id)) {
680 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
681 return;
682 }
683
684 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
685 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
686 (void)client;
687 struct ivi_layout_surface *layout_surface;
688 struct ivisurface *ivisurf;
689
690 layout_surface = lyt->get_surface_from_id(surface_id);
691 if (!layout_surface) {
692 ivi_wm_send_surface_error(resource, surface_id,
693 IVI_WM_SURFACE_ERROR_NO_SURFACE,
694 "surface_set_type: the surface with given id does not exist");
695 return;
696 }
697
698 ivisurf = get_surface(&ctrl->shell->list_surface, layout_surface);
699 ivisurf->type = type;
700 }
701
702 static int32_t
703 convert_protocol_enum(int32_t param)
704 {
705 int32_t mask = 0;
706
707 if (param & IVI_WM_PARAM_OPACITY)
708 mask |= IVI_NOTIFICATION_OPACITY;
709
710 if (param & IVI_WM_PARAM_VISIBILITY)
711 mask |= IVI_NOTIFICATION_VISIBILITY;
712
713 if (param & IVI_WM_PARAM_SIZE) {
714 mask |= IVI_NOTIFICATION_SOURCE_RECT;
715 mask |= IVI_NOTIFICATION_DEST_RECT;
716 mask |= IVI_NOTIFICATION_CONFIGURE;
717 }
718
719 return mask;
720 }
721
722 static void
723 controller_surface_get(struct wl_client *client, struct wl_resource *resource,
724 uint32_t surface_id, int32_t param)
725 {
726 if (check_surface_id(client, surface_id)) {
727 ivi_wm_send_surface_error(resource, surface_id, 0, "pid check falied!!!");
728 return;
729 }
730
731 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
732 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
733 (void)client;
734 struct ivi_layout_surface *layout_surface;
735 enum ivi_layout_notification_mask mask;
736 const struct ivi_layout_surface_properties *prop;
737
738 mask = convert_protocol_enum(param);
739
740 layout_surface = lyt->get_surface_from_id(surface_id);
741 if (!layout_surface) {
742 ivi_wm_send_surface_error(resource, surface_id,
743 IVI_WM_SURFACE_ERROR_NO_SURFACE,
744 "surface_get: the surface with given id does not exist");
745 return;
746 }
747
748 prop = lyt->get_properties_of_surface(layout_surface);
749
750 send_surface_event(ctrl, layout_surface, surface_id, prop, mask);
751 send_surface_stats(ctrl, layout_surface, surface_id);
752 }
753
754 static void
755 controller_set_layer_source_rectangle(struct wl_client *client,
756 struct wl_resource *resource,
757 uint32_t layer_id,
758 int32_t x,
759 int32_t y,
760 int32_t width,
761 int32_t height)
762 {
763 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
764 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
765 (void)client;
766 struct ivi_layout_layer *layout_layer;
767 const struct ivi_layout_layer_properties *prop;
768
769 layout_layer = lyt->get_layer_from_id(layer_id);
770 if (!layout_layer) {
771 ivi_wm_send_layer_error(resource, layer_id,
772 IVI_WM_LAYER_ERROR_NO_LAYER,
773 "set_layer_source_rectangle: the layer with given id does not exist");
774 return;
775 }
776
777 prop = lyt->get_properties_of_layer(layout_layer);
778
779 if (x < 0)
780 x = prop->source_x;
781 if (y < 0)
782 y = prop->source_y;
783 if (width < 0)
784 width = prop->source_width;
785 if (height < 0)
786 height = prop->source_height;
787
788 lyt->layer_set_source_rectangle(layout_layer,
789 (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
790 }
791
792 static void
793 controller_set_layer_destination_rectangle(struct wl_client *client,
794 struct wl_resource *resource,
795 uint32_t layer_id,
796 int32_t x,
797 int32_t y,
798 int32_t width,
799 int32_t height)
800 {
801 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
802 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
803 (void)client;
804 struct ivi_layout_layer *layout_layer;
805 const struct ivi_layout_layer_properties *prop;
806
807 layout_layer = lyt->get_layer_from_id(layer_id);
808 if (!layout_layer) {
809 ivi_wm_send_layer_error(resource, layer_id,
810 IVI_WM_LAYER_ERROR_NO_LAYER,
811 "set_layer_destination_rectangle: the layer with given id does not exist");
812 return;
813 }
814
815 prop = lyt->get_properties_of_layer(layout_layer);
816
817 if (x < 0)
818 x = prop->dest_x;
819 if (y < 0)
820 y = prop->dest_y;
821 if (width < 0)
822 width = prop->dest_width;
823 if (height < 0)
824 height = prop->dest_height;
825
826 lyt->layer_set_destination_rectangle(layout_layer,
827 (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
828 }
829
830 static void
831 controller_set_layer_visibility(struct wl_client *client,
832 struct wl_resource *resource,
833 uint32_t layer_id,
834 uint32_t visibility)
835 {
836 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
837 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
838 (void)client;
839 struct ivi_layout_layer *layout_layer;
840
841 layout_layer = lyt->get_layer_from_id(layer_id);
842 if (!layout_layer) {
843 ivi_wm_send_layer_error(resource, layer_id,
844 IVI_WM_LAYER_ERROR_NO_LAYER,
845 "layer_set_visibility: the layer with given id does not exist");
846 return;
847 }
848
849 lyt->layer_set_visibility(layout_layer, visibility);
850 }
851
852 static void
853 controller_set_layer_opacity(struct wl_client *client,
854 struct wl_resource *resource,
855 uint32_t layer_id,
856 wl_fixed_t opacity)
857 {
858 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
859 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
860 (void)client;
861 struct ivi_layout_layer *layout_layer;
862
863 layout_layer = lyt->get_layer_from_id(layer_id);
864 if (!layout_layer) {
865 ivi_wm_send_layer_error(resource, layer_id,
866 IVI_WM_LAYER_ERROR_NO_LAYER,
867 "layer_set_opacity: the layer with given id does not exist");
868 return;
869 }
870
871 lyt->layer_set_opacity(layout_layer, opacity);
872 }
873
874 static void
875 controller_layer_clear(struct wl_client *client,
876 struct wl_resource *resource,
877 uint32_t layer_id)
878 {
879 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
880 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
881 (void)client;
882 struct ivi_layout_layer *layout_layer;
883
884 layout_layer = lyt->get_layer_from_id(layer_id);
885 if (!layout_layer) {
886 ivi_wm_send_layer_error(resource, layer_id,
887 IVI_WM_LAYER_ERROR_NO_LAYER,
888 "layer_clear: the layer with given id does not exist");
889 return;
890 }
891
892 lyt->layer_set_render_order(layout_layer, NULL, 0);
893 }
894
895 static void
896 calc_trans_matrix(struct weston_geometry *source_rect,
897 struct weston_geometry *dest_rect,
898 struct weston_matrix *m)
899 {
900 float source_center_x;
901 float source_center_y;
902 float scale_x;
903 float scale_y;
904 float translate_x;
905 float translate_y;
906
907 source_center_x = source_rect->x + source_rect->width * 0.5f;
908 source_center_y = source_rect->y + source_rect->height * 0.5f;
909 weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
910
911 if ((dest_rect->width != source_rect->width) ||
912 (dest_rect->height != source_rect->height))
913 {
914 scale_x = ((float)dest_rect->width) / source_rect->width;
915 scale_y = ((float)dest_rect->height) / source_rect->height;
916
917 weston_matrix_scale(m, scale_x, scale_y, 1.0f);
918 }
919
920 translate_x = dest_rect->width * 0.5f + dest_rect->x;
921 translate_y = dest_rect->height * 0.5f + dest_rect->y;
922 weston_matrix_translate(m, translate_x, translate_y, 0.0f);
923 }
924
925 void
926 set_bkgnd_surface_prop(struct ivishell *shell)
927 {
928 struct weston_view *view;
929 struct weston_compositor *compositor;
930 struct weston_output *output;
931 struct weston_surface *w_surface;
932 struct weston_geometry source_rect = {0};
933 struct weston_geometry dest_rect = {0};
934 int32_t src_width = 0;
935 int32_t src_height = 0;
936 int32_t dest_width = 0;
937 int32_t dest_height = 0;
938 uint32_t count = 0;
939 int32_t x = 0;
940 int32_t y = 0;
941
942 view = shell->bkgnd_view;
943 compositor = shell->compositor;
944
945 wl_list_remove(&shell->bkgnd_transform.link);
946 weston_matrix_init(&shell->bkgnd_transform.matrix);
947
948 /*find the available screen's resolution*/
949 wl_list_for_each(output, &compositor->output_list, link) {
950 if (!count)
951 {
952 x = output->x;
953 y = output->y;
954 count++;
955 }
956 dest_width = output->x + output->width;
957 if (output->height > dest_height)
958 dest_height = output->height;
959 weston_log("set_bkgnd_surface_prop: o_name:%s x:%d y:%d o_width:%d o_height:%d\n",
960 output->name, output->x, output->y, output->width, output->height);
961 }
962
963 w_surface = view->surface;
964 src_width = w_surface->width;
965 src_height = w_surface->height;
966
967 source_rect.width = src_width;
968 source_rect.height = src_height;
969 dest_rect.width = dest_width;
970 dest_rect.height = dest_height;
971
972 calc_trans_matrix(&source_rect, &dest_rect,
973 &shell->bkgnd_transform.matrix);
974 weston_matrix_translate(&shell->bkgnd_transform.matrix, x, y, 0.0f);
975
976 weston_log("set_bkgnd_surface_prop: x:%d y:%d s_width:%d s_height:%d d_width:%d d_height:%d\n",
977 x, y, src_width, src_height, dest_width, dest_height);
978
979 wl_list_insert(&view->geometry.transformation_list,
980 &shell->bkgnd_transform.link);
981 weston_view_update_transform(view);
982 weston_surface_schedule_repaint(w_surface);
983 }
984
985 static void
986 controller_layer_add_surface(struct wl_client *client,
987 struct wl_resource *resource,
988 uint32_t layer_id,
989 uint32_t surface_id)
990 {
991 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
992 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
993 (void)client;
994 struct ivi_layout_layer *layout_layer;
995 struct ivi_layout_surface *layout_surface;
996
997 layout_layer = lyt->get_layer_from_id(layer_id);
998 if (!layout_layer) {
999 ivi_wm_send_layer_error(resource, layer_id,
1000 IVI_WM_LAYER_ERROR_NO_LAYER,
1001 "layer_add_surface: the layer with given id does not exist");
1002 return;
1003 }
1004
1005 layout_surface = lyt->get_surface_from_id(surface_id);
1006 if (!layout_surface) {
1007 ivi_wm_send_layer_error(resource, surface_id,
1008 IVI_WM_LAYER_ERROR_NO_SURFACE,
1009 "layer_add_surface: the surface with given id does not exist");
1010 return;
1011 }
1012
1013 lyt->layer_add_surface(layout_layer, layout_surface);
1014 }
1015
1016 static void
1017 controller_layer_remove_surface(struct wl_client *client,
1018 struct wl_resource *resource,
1019 uint32_t layer_id,
1020 uint32_t surface_id)
1021 {
1022 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1023 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
1024 (void)client;
1025 struct ivi_layout_layer *layout_layer;
1026 struct ivi_layout_surface *layout_surface;
1027
1028 layout_layer = lyt->get_layer_from_id(layer_id);
1029 if (!layout_layer) {
1030 ivi_wm_send_layer_error(resource, layer_id,
1031 IVI_WM_LAYER_ERROR_NO_LAYER,
1032 "layer_remove_surface: the layer with given id does not exist");
1033 return;
1034 }
1035
1036 layout_surface = lyt->get_surface_from_id(surface_id);
1037 if (!layout_surface) {
1038 ivi_wm_send_layer_error(resource, surface_id,
1039 IVI_WM_LAYER_ERROR_NO_SURFACE,
1040 "layer_remove_surface: the surface with given id does not exist");
1041 return;
1042 }
1043
1044 lyt->layer_remove_surface(layout_layer, layout_surface);
1045 }
1046
1047 static void
1048 controller_layer_sync(struct wl_client *client,
1049 struct wl_resource *resource,
1050 uint32_t layer_id,
1051 int32_t sync_state)
1052 {
1053 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1054 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
1055 struct ivi_layout_layer *layout_layer;
1056 struct ivilayer *ivilayer;
1057 (void)client;
1058 struct notification *not;
1059
1060 layout_layer = lyt->get_layer_from_id(layer_id);
1061 if (!layout_layer) {
1062 ivi_wm_send_layer_error(resource, layer_id,
1063 IVI_WM_LAYER_ERROR_NO_LAYER,
1064 "layer sync: the layer with given id does not exist");
1065 return;
1066 }
1067
1068 ivilayer = get_layer(&ctrl->shell->list_layer, layout_layer);
1069
1070 switch (sync_state) {
1071 case IVI_WM_SYNC_ADD:
1072 /*Check if a notification for the surface is already initialized*/
1073 not= calloc(1, sizeof *not);
1074 if (not == NULL) {
1075 wl_resource_post_no_memory(resource);
1076 return;
1077 }
1078
1079 wl_list_insert(&ctrl->layer_notifications, ¬->link);
1080 wl_list_insert(&ivilayer->notification_list, ¬->layout_link);
1081 not->resource = resource;
1082 break;
1083 case IVI_WM_SYNC_REMOVE:
1084 ivilayer = get_layer(&ctrl->shell->list_layer, layout_layer);
1085
1086 wl_list_for_each(not, &ivilayer->notification_list, layout_link)
1087 {
1088 if (not->resource == resource) {
1089 wl_list_remove(¬->link);
1090 wl_list_remove(¬->layout_link);
1091 free(not);
1092 break;
1093 }
1094 }
1095 break;
1096 default:
1097 ivi_wm_send_layer_error(resource, layer_id,
1098 IVI_WM_LAYER_ERROR_BAD_PARAM,
1099 "layer sync: invalid sync_state param");
1100 return;
1101 }
1102 }
1103
1104 static void
1105 controller_create_layout_layer(struct wl_client *client,
1106 struct wl_resource *resource, uint32_t layer_id,
1107 int width, int height)
1108 {
1109 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1110 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
1111 (void)client;
1112
1113 if(lyt->layer_create_with_dimension(layer_id, width, height) == NULL) {
1114 wl_resource_post_no_memory(resource);
1115 }
1116 }
1117
1118 static void
1119 controller_destroy_layout_layer(struct wl_client *client,
1120 struct wl_resource *resource, uint32_t layer_id)
1121 {
1122 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1123 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
1124 (void)client;
1125 struct ivi_layout_layer *layout_layer;
1126
1127 layout_layer = lyt->get_layer_from_id(layer_id);
1128 if (!layout_layer) {
1129 ivi_wm_send_layer_error(resource, layer_id,
1130 IVI_WM_LAYER_ERROR_NO_LAYER,
1131 "destroy_layout_layer: the layer with given id does not exist");
1132 return;
1133 }
1134
1135 lyt->layer_destroy(layout_layer);
1136 }
1137
1138 static void
1139 controller_layer_get(struct wl_client *client, struct wl_resource *resource,
1140 uint32_t layer_id, int32_t param)
1141 {
1142 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1143 const struct ivi_layout_interface *lyt = ctrl->shell->interface;
1144 (void)client;
1145 struct ivi_layout_layer *layout_layer;
1146 const struct ivi_layout_layer_properties *prop;
1147 enum ivi_layout_notification_mask mask;
1148 struct ivi_layout_surface **surf_list = NULL;
1149 int32_t surface_count, i;
1150 uint32_t id;
1151
1152 layout_layer = lyt->get_layer_from_id(layer_id);
1153 if (!layout_layer) {
1154 ivi_wm_send_layer_error(resource, layer_id,
1155 IVI_WM_LAYER_ERROR_NO_LAYER,
1156 "layer_get: the layer with given id does not exist");
1157 return;
1158 }
1159
1160 mask = convert_protocol_enum(param);
1161 prop = lyt->get_properties_of_layer(layout_layer);
1162 send_layer_event(ctrl, layout_layer, layer_id, prop, mask);
1163
1164 if (param & IVI_WM_PARAM_RENDER_ORDER) {
1165 lyt->get_surfaces_on_layer(layout_layer, &surface_count, &surf_list);
1166 for (i = 0; i < surface_count; i++) {
1167 id = lyt->get_id_of_surface(surf_list[i]);
1168 ivi_wm_send_layer_surface_added(ctrl->resource, layer_id, id);
1169 }
1170
1171 free(surf_list);
1172 }
1173 }
1174
1175 static void
1176 controller_screen_destroy(struct wl_client *client,
1177 struct wl_resource *resource)
1178 {
1179 (void)client;
1180 wl_resource_destroy(resource);
1181 }
1182
1183 static void
1184 controller_screen_clear(struct wl_client *client,
1185 struct wl_resource *resource)
1186 {
1187 struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
1188 const struct ivi_layout_interface *lyt;
1189 (void)client;
1190
1191 if (!iviscrn) {
1192 ivi_wm_screen_send_error(resource, IVI_WM_SCREEN_ERROR_NO_SCREEN,
1193 "the output is already destroyed");
1194 return;
1195 }
1196
1197 lyt = iviscrn->shell->interface;
1198 lyt->screen_set_render_order(iviscrn->output, NULL, 0);
1199 }
1200
1201 static void
1202 controller_screen_add_layer(struct wl_client *client,
1203 struct wl_resource *resource,
1204 uint32_t layer_id)
1205 {
1206 struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
1207 const struct ivi_layout_interface *lyt;
1208 (void)client;
1209 struct ivi_layout_layer *layout_layer;
1210
1211 if (!iviscrn) {
1212 ivi_wm_screen_send_error(resource, IVI_WM_SCREEN_ERROR_NO_SCREEN,
1213 "the output is already destroyed");
1214 return;
1215 }
1216
1217 lyt = iviscrn->shell->interface;
1218 layout_layer = lyt->get_layer_from_id(layer_id);
1219 if (!layout_layer) {
1220 ivi_wm_screen_send_error(resource, IVI_WM_SCREEN_ERROR_NO_LAYER,
1221 "the layer with given id does not exist");
1222 weston_log("ivi-controller: an ivi-layer with id: %d does not exist\n", layer_id);
1223 return;
1224 }
1225
1226 lyt->screen_add_layer(iviscrn->output, layout_layer);
1227 }
1228
1229 static void
1230 controller_screen_remove_layer(struct wl_client *client,
1231 struct wl_resource *resource,
1232 uint32_t layer_id)
1233 {
1234 struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
1235 const struct ivi_layout_interface *lyt;
1236 (void)client;
1237 struct ivi_layout_layer *layout_layer;
1238
1239 if (!iviscrn) {
1240 ivi_wm_screen_send_error(resource, IVI_WM_SCREEN_ERROR_NO_SCREEN,
1241 "the output is already destroyed");
1242 return;
1243 }
1244
1245 lyt = iviscrn->shell->interface;
1246 layout_layer = lyt->get_layer_from_id(layer_id);
1247 if (!layout_layer) {
1248 ivi_wm_screen_send_error(resource, IVI_WM_SCREEN_ERROR_NO_LAYER,
1249 "the layer with given id does not exist");
1250 weston_log("ivi-controller: an ivi-layer with id: %d does not exist\n", layer_id);
1251 return;
1252 }
1253
1254 lyt->screen_remove_layer(iviscrn->output, layout_layer);
1255 }
1256
1257 static void
1258 flip_y(int32_t stride, int32_t height, uint32_t *data) {
1259 int i, y, p, q;
1260 // assuming stride aligned to 4 bytes
1261 int pitch = stride / sizeof(*data);
1262 for (y = 0; y < height / 2; ++y) {
1263 p = y * pitch;
1264 q = (height - y - 1) * pitch;
1265 for (i = 0; i < pitch; ++i) {
1266 uint32_t tmp = data[p + i];
1267 data[p + i] = data[q + i];
1268 data[q + i] = tmp;
1269 }
1270 }
1271 }
1272
1273 static void
1274 controller_screenshot_notify(struct wl_listener *listener, void *data)
1275 {
1276 struct screenshot_frame_listener *l =
1277 wl_container_of(listener, l, frame_listener);
1278
1279 struct weston_output *output = l->output;
1280 int32_t width = 0;
1281 int32_t height = 0;
1282 int32_t stride = 0;
1283 uint32_t *readpixs = NULL;
1284 uint32_t shm_format;
1285 int fd;
1286 size_t size;
1287 pixman_format_code_t format = output->compositor->read_format;
1288
1289 --output->disable_planes;
1290
1291 // map to shm buffer format
1292 switch (format) {
1293 case PIXMAN_a8r8g8b8:
1294 shm_format = WL_SHM_FORMAT_ARGB8888;
1295 break;
1296 case PIXMAN_x8r8g8b8:
1297 shm_format = WL_SHM_FORMAT_XRGB8888;
1298 break;
1299 case PIXMAN_a8b8g8r8:
1300 shm_format = WL_SHM_FORMAT_ABGR8888;
1301 break;
1302 case PIXMAN_x8b8g8r8:
1303 shm_format = WL_SHM_FORMAT_XBGR8888;
1304 break;
1305 default:
1306 ivi_screenshot_send_error(l->screenshot,
1307 IVI_SCREENSHOT_ERROR_NOT_SUPPORTED,
1308 "unsupported pixel format");
1309 goto err_fd;
1310 }
1311
1312 width = output->current_mode->width;
1313 height = output->current_mode->height;
1314 stride = width * (PIXMAN_FORMAT_BPP(format) / 8);
1315 size = stride * height;
1316
1317 fd = create_screenshot_file(size);
1318 if (fd < 0) {
1319 weston_log("screenshot: failed to create file of %zu bytes: %m\n",
1320 size);
1321 ivi_screenshot_send_error(l->screenshot, IVI_SCREENSHOT_ERROR_IO_ERROR,
1322 "failed to create screenshot file");
1323 goto err_fd;
1324 }
1325
1326 readpixs = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1327 if (readpixs == MAP_FAILED) {
1328 weston_log("screenshot: failed to mmap %zu bytes: %m\n", size);
1329 ivi_screenshot_send_error(l->screenshot, IVI_SCREENSHOT_ERROR_IO_ERROR,
1330 "failed to create screenshot");
1331 goto err_mmap;
1332 }
1333
1334 if (output->compositor->renderer->read_pixels(output, format, readpixs,
1335 0, 0, width, height) < 0) {
1336 ivi_screenshot_send_error(
1337 l->screenshot, IVI_SCREENSHOT_ERROR_NOT_SUPPORTED,
1338 "screenshot of given output is not supported by renderer");
1339 goto err_readpix;
1340 }
1341
1342 if (output->compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP)
1343 flip_y(stride, height, readpixs);
1344
1345 ivi_screenshot_send_done(l->screenshot, fd, width, height, stride,
1346 shm_format, timespec_to_msec(&output->frame_time));
1347
1348 err_readpix:
1349 munmap(readpixs, size);
1350 err_mmap:
1351 close(fd);
1352 err_fd:
1353 wl_resource_destroy(l->screenshot);
1354 }
1355
1356 static void
1357 screenshot_output_destroyed(struct wl_listener *listener, void *data)
1358 {
1359 struct screenshot_frame_listener *l =
1360 wl_container_of(listener, l, output_destroyed);
1361
1362 ivi_screenshot_send_error(l->screenshot, IVI_SCREENSHOT_ERROR_NO_OUTPUT,
1363 "the output has been destroyed");
1364 wl_resource_destroy(l->screenshot);
1365 }
1366
1367 static void
1368 screenshot_frame_listener_destroy(struct wl_resource *resource)
1369 {
1370 struct screenshot_frame_listener *l = wl_resource_get_user_data(resource);
1371
1372 wl_list_remove(&l->frame_listener.link);
1373 wl_list_remove(&l->output_destroyed.link);
1374 free(l);
1375 }
1376
1377 static void
1378 controller_screen_screenshot(struct wl_client *client,
1379 struct wl_resource *resource,
1380 uint32_t id)
1381 {
1382 struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
1383 struct screenshot_frame_listener *l;
1384 (void)client;
1385
1386 l = malloc(sizeof *l);
1387 if(l == NULL) {
1388 wl_resource_post_no_memory(resource);
1389 return;
1390 }
1391
1392 l->screenshot =
1393 wl_resource_create(client, &ivi_screenshot_interface, 1, id);
1394
1395 if (l->screenshot == NULL) {
1396 wl_resource_post_no_memory(resource);
1397 free(l);
1398 return;
1399 }
1400
1401 if (!iviscrn) {
1402 ivi_screenshot_send_error(l->screenshot, IVI_SCREENSHOT_ERROR_NO_OUTPUT,
1403 "the output is already destroyed");
1404 wl_resource_destroy(l->screenshot);
1405 free(l);
1406 return;
1407 }
1408
1409 l->output = iviscrn->output;
1410
1411 wl_resource_set_implementation(l->screenshot, NULL, l,
1412 screenshot_frame_listener_destroy);
1413 l->output_destroyed.notify = screenshot_output_destroyed;
1414 wl_signal_add(&iviscrn->output->destroy_signal, &l->output_destroyed);
1415 l->frame_listener.notify = controller_screenshot_notify;
1416 wl_signal_add(&iviscrn->output->frame_signal, &l->frame_listener);
1417 iviscrn->output->disable_planes++;
1418 weston_output_damage(iviscrn->output);
1419 }
1420
1421 static void
1422 controller_screen_get(struct wl_client *client,
1423 struct wl_resource *resource,
1424 int32_t param)
1425 {
1426 struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
1427 const struct ivi_layout_interface *lyt;
1428 (void)client;
1429 struct ivi_layout_layer **layer_list = NULL;
1430 int32_t layer_count, i;
1431 uint32_t id;
1432
1433 lyt = iviscrn->shell->interface;
1434
1435 if (!iviscrn) {
1436 ivi_wm_screen_send_error(resource, IVI_WM_SCREEN_ERROR_NO_SCREEN,
1437 "the output is already destroyed");
1438 return;
1439 }
1440
1441 if (param & IVI_WM_PARAM_RENDER_ORDER) {
1442 lyt->get_layers_on_screen(iviscrn->output, &layer_count, &layer_list);
1443
1444 for (i = 0; i < layer_count; i++) {
1445 id = lyt->get_id_of_layer(layer_list[i]);
1446 ivi_wm_screen_send_layer_added(resource, id);
1447 }
1448
1449 free(layer_list);
1450 }
1451 }
1452
1453 static const
1454 struct ivi_wm_screen_interface controller_screen_implementation = {
1455 controller_screen_destroy,
1456 controller_screen_clear,
1457 controller_screen_add_layer,
1458 controller_screen_remove_layer,
1459 controller_screen_screenshot,
1460 controller_screen_get
1461 };
1462
1463 static void
1464 controller_commit_changes(struct wl_client *client,
1465 struct wl_resource *resource)
1466 {
1467 int32_t ans = 0;
1468 (void)client;
1469 struct ivicontroller *controller = wl_resource_get_user_data(resource);
1470
1471 ans = controller->shell->interface->commit_changes();
1472 if (ans < 0) {
1473 weston_log("Failed to commit changes at controller_commit_changes\n");
1474 }
1475 }
1476
1477 static void
1478 controller_create_screen(struct wl_client *client,
1479 struct wl_resource *resource,
1480 struct wl_resource *output_resource,
1481 uint32_t id)
1482 {
1483 struct weston_head *weston_head =
1484 wl_resource_get_user_data(output_resource);
1485 struct wl_resource *screen_resource;
1486 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1487 struct iviscreen* iviscrn = NULL;
1488
1489
1490 wl_list_for_each(iviscrn, &ctrl->shell->list_screen, link) {
1491 if (weston_head->output != iviscrn->output) {
1492 continue;
1493 }
1494
1495 screen_resource = wl_resource_create(client, &ivi_wm_screen_interface, 1, id);
1496 if (screen_resource == NULL) {
1497 wl_resource_post_no_memory(resource);
1498 return;
1499 }
1500
1501 wl_resource_set_implementation(screen_resource,
1502 &controller_screen_implementation,
1503 iviscrn, destroy_ivicontroller_screen);
1504
1505 wl_list_insert(&iviscrn->resource_list, wl_resource_get_link(screen_resource));
1506
1507 ivi_wm_screen_send_screen_id(screen_resource, iviscrn->id_screen);
1508 ivi_wm_screen_send_connector_name(screen_resource, iviscrn->output->name);
1509 }
1510 }
1511
1512 //for dummy output screen(USE_DUMMY_SCREEN)
1513 static void
1514 controller_create_screen2(struct wl_client *client,
1515 struct wl_resource *resource,
1516 uint32_t screen_id,
1517 uint32_t id)
1518 {
1519 struct wl_resource *screen_resource;
1520 struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
1521 struct iviscreen* iviscrn = NULL;
1522 weston_log("######controller_create_screen2: screen_id = %d\n", screen_id);
1523
1524 wl_list_for_each(iviscrn, &ctrl->shell->list_screen, link) {
1525 weston_log("######controller_create_screen2: iviscrn->id_screen = %d\n", iviscrn->id_screen);
1526 if (screen_id != iviscrn->id_screen) {
1527 continue;
1528 }
1529
1530 screen_resource = wl_resource_create(client, &ivi_wm_screen_interface, 1, id);
1531 if (screen_resource == NULL) {
1532 wl_resource_post_no_memory(resource);
1533 return;
1534 }
1535
1536 wl_resource_set_implementation(screen_resource,
1537 &controller_screen_implementation,
1538 iviscrn, destroy_ivicontroller_screen);
1539
1540 wl_list_insert(&iviscrn->resource_list, wl_resource_get_link(screen_resource));
1541
1542 ivi_wm_screen_send_screen_id(screen_resource, iviscrn->id_screen);
1543 ivi_wm_screen_send_connector_name(screen_resource, iviscrn->output->name);
1544 }
1545 }
1546
1547 static const struct ivi_wm_interface controller_implementation = {
1548 controller_commit_changes,
1549 controller_create_screen,
1550 //for dummy output screen(USE_DUMMY_SCREEN)
1551 controller_create_screen2,
1552 controller_set_surface_visibility,
1553 controller_set_layer_visibility,
1554 controller_set_surface_opacity,
1555 controller_set_layer_opacity,
1556 controller_set_surface_source_rectangle,
1557 controller_set_layer_source_rectangle,
1558 controller_set_surface_destination_rectangle,
1559 controller_set_layer_destination_rectangle,
1560 controller_surface_sync,
1561 controller_layer_sync,
1562 controller_surface_get,
1563 controller_layer_get,
1564 controller_surface_screenshot,
1565 controller_set_surface_type,
1566 controller_layer_clear,
1567 controller_layer_add_surface,
1568 controller_layer_remove_surface,
1569 controller_create_layout_layer,
1570 controller_destroy_layout_layer
1571 };
1572
1573 static void
1574 bind_ivi_controller(struct wl_client *client, void *data,
1575 uint32_t version, uint32_t id)
1576 {
1577 struct ivishell *shell = data;
1578 struct ivicontroller *controller;
1579 (void)version;
1580 uint32_t surface_id, layer_id;
1581 struct ivisurface *ivisurf;
1582 struct ivilayer *ivilayer;
1583
1584 controller = calloc(1, sizeof *controller);
1585 if (controller == NULL) {
1586 wl_client_post_no_memory(client);
1587 return;
1588 }
1589
1590 controller->resource =
1591 wl_resource_create(client, &ivi_wm_interface, 1, id);
1592 if (controller->resource == NULL) {
1593 wl_client_post_no_memory(client);
1594 free(controller);
1595 return;
1596 }
1597
1598 wl_resource_set_implementation(controller->resource,
1599 &controller_implementation,
1600 controller, unbind_resource_controller);
1601
1602 controller->shell = shell;
1603 controller->client = client;
1604 controller->id = id;
1605
1606 wl_list_insert(&shell->list_controller, &controller->link);
1607 wl_list_init(&controller->surface_notifications);
1608 wl_list_init(&controller->layer_notifications);
1609
1610 wl_list_for_each_reverse(ivisurf, &shell->list_surface, link) {
1611 surface_id = shell->interface->get_id_of_surface(ivisurf->layout_surface);
1612 ivi_wm_send_surface_created(controller->resource, surface_id);
1613 }
1614
1615 wl_list_for_each_reverse(ivilayer, &shell->list_layer, link) {
1616 layer_id = shell->interface->get_id_of_layer(ivilayer->layout_layer);
1617 ivi_wm_send_layer_created(controller->resource, layer_id);
1618 }
1619 }
1620
1621 static void
1622 create_screen(struct ivishell *shell, struct weston_output *output)
1623 {
1624 struct iviscreen *iviscrn;
1625 struct screen_id_info *screen_info;
1626 uint32_t id;
1627
1628 iviscrn = calloc(1, sizeof *iviscrn);
1629 if (iviscrn == NULL) {
1630 weston_log("no memory to allocate client screen\n");
1631 return;
1632 }
1633
1634 id = output->id + shell->screen_id_offset;
1635
1636 wl_array_for_each(screen_info, &shell->screen_ids) {
1637 if(!strcmp(screen_info->screen_name, output->name))
1638 {
1639 id = screen_info->screen_id;
1640 break;
1641 }
1642 }
1643
1644 iviscrn->shell = shell;
1645 iviscrn->output = output;
1646
1647 iviscrn->id_screen = id;
1648
1649 wl_list_insert(&shell->list_screen, &iviscrn->link);
1650 wl_list_init(&iviscrn->resource_list);
1651
1652 return;
1653 }
1654
1655 static void
1656 destroy_screen(struct iviscreen *iviscrn)
1657 {
1658 struct wl_resource *resource, *next;
1659
1660 wl_resource_for_each_safe(resource, next, &iviscrn->resource_list) {
1661 wl_resource_set_destructor(resource, NULL);
1662 wl_resource_destroy(resource);
1663 }
1664
1665 wl_list_remove(&iviscrn->link);
1666 free(iviscrn);
1667 }
1668
1669 static void
1670 output_destroyed_event(struct wl_listener *listener, void *data)
1671 {
1672 struct ivishell *shell = wl_container_of(listener, shell, output_destroyed);
1673 struct iviscreen *iviscrn = NULL;
1674 struct iviscreen *next = NULL;
1675 struct weston_output *destroyed_output = (struct weston_output*)data;
1676
1677 wl_list_for_each_safe(iviscrn, next, &shell->list_screen, link) {
1678 if (iviscrn->output == destroyed_output)
1679 destroy_screen(iviscrn);
1680 }
1681
1682 if (shell->bkgnd_view && shell->client)
1683 set_bkgnd_surface_prop(shell);
1684 else
1685 weston_compositor_schedule_repaint(shell->compositor);
1686 }
1687
1688 static void
1689 output_resized_event(struct wl_listener *listener, void *data)
1690 {
1691 struct ivishell *shell = wl_container_of(listener, shell, output_destroyed);
1692
1693 if (shell->bkgnd_view && shell->client)
1694 set_bkgnd_surface_prop(shell);
1695 }
1696
1697 static void
1698 output_created_event(struct wl_listener *listener, void *data)
1699 {
1700 struct ivishell *shell = wl_container_of(listener, shell, output_created);
1701 struct weston_output *created_output = (struct weston_output*)data;
1702
1703 create_screen(shell, created_output);
1704
1705 if (shell->bkgnd_view && shell->client)
1706 set_bkgnd_surface_prop(shell);
1707 else
1708 weston_compositor_schedule_repaint(shell->compositor);
1709 }
1710
1711 static struct ivilayer*
1712 create_layer(struct ivishell *shell,
1713 struct ivi_layout_layer *layout_layer,
1714 uint32_t id_layer)
1715 {
1716 const struct ivi_layout_interface *lyt = shell->interface;
1717 struct ivilayer *ivilayer = NULL;
1718 struct ivicontroller *controller = NULL;
1719
1720 ivilayer = calloc(1, sizeof *ivilayer);
1721 if (NULL == ivilayer) {
1722 weston_log("no memory to allocate client layer\n");
1723 return NULL;
1724 }
1725
1726 ivilayer->shell = shell;
1727 wl_list_insert(&shell->list_layer, &ivilayer->link);
1728 wl_list_init(&ivilayer->notification_list);
1729 ivilayer->layout_layer = layout_layer;
1730 ivilayer->prop = lyt->get_properties_of_layer(layout_layer);
1731
1732 ivilayer->property_changed.notify = send_layer_prop;
1733 lyt->layer_add_listener(layout_layer, &ivilayer->property_changed);
1734
1735 wl_list_for_each(controller, &shell->list_controller, link) {
1736 if (controller->resource)
1737 ivi_wm_send_layer_created(controller->resource, id_layer);
1738 }
1739
1740 return ivilayer;
1741 }
1742
1743 static void
1744 surface_committed(struct wl_listener *listener, void *data)
1745 {
1746 struct ivisurface *ivisurf = wl_container_of(listener, ivisurf, committed);
1747 (void)data;
1748
1749 ivisurf->frame_count++;
1750 }
1751
1752 static struct ivisurface*
1753 create_surface(struct ivishell *shell,
1754 struct ivi_layout_surface *layout_surface,
1755 uint32_t id_surface)
1756 {
1757 const struct ivi_layout_interface *lyt = shell->interface;
1758 struct ivisurface *ivisurf = NULL;
1759 struct ivicontroller *controller = NULL;
1760 struct weston_surface *surface;
1761
1762 ivisurf = calloc(1, sizeof *ivisurf);
1763 if (ivisurf == NULL) {
1764 weston_log("no memory to allocate client surface\n");
1765 return NULL;
1766 }
1767
1768 ivisurf->shell = shell;
1769 ivisurf->layout_surface = layout_surface;
1770 ivisurf->prop = lyt->get_properties_of_surface(layout_surface);
1771 wl_list_init(&ivisurf->notification_list);
1772
1773 ivisurf->committed.notify = surface_committed;
1774 surface = lyt->surface_get_weston_surface(layout_surface);
1775 wl_signal_add(&surface->commit_signal, &ivisurf->committed);
1776
1777 if (shell->bkgnd_surface_id != (int32_t)id_surface) {
1778 wl_list_insert(&shell->list_surface, &ivisurf->link);
1779
1780 wl_list_for_each(controller, &shell->list_controller, link) {
1781 if (controller->resource)
1782 ivi_wm_send_surface_created(controller->resource, id_surface);
1783 }
1784
1785 ivisurf->property_changed.notify = send_surface_prop;
1786 lyt->surface_add_listener(layout_surface, &ivisurf->property_changed);
1787 }
1788 else {
1789 shell->bkgnd_surface = ivisurf;
1790 }
1791
1792 return ivisurf;
1793 }
1794
1795 static void
1796 layer_event_create(struct wl_listener *listener, void *data)
1797 {
1798 struct ivishell *shell = wl_container_of(listener, shell, layer_created);
1799 const struct ivi_layout_interface *lyt = shell->interface;
1800 struct ivilayer *ivilayer = NULL;
1801 struct ivi_layout_layer *layout_layer =
1802 (struct ivi_layout_layer *) data;
1803 uint32_t id_layer = 0;
1804
1805 id_layer = lyt->get_id_of_layer(layout_layer);
1806
1807 ivilayer = create_layer(shell, layout_layer, id_layer);
1808 if (ivilayer == NULL) {
1809 weston_log("failed to create layer");
1810 return;
1811 }
1812 }
1813
1814 static void
1815 layer_event_remove(struct wl_listener *listener, void *data)
1816 {
1817 struct ivishell *shell = wl_container_of(listener, shell, layer_removed);
1818 struct ivilayer *ivilayer = NULL;
1819 struct ivicontroller *controller = NULL;
1820 struct ivi_layout_layer *layout_layer =
1821 (struct ivi_layout_layer *) data;
1822 uint32_t id_layer = 0;
1823 struct notification *not, *next;
1824
1825 ivilayer = get_layer(&shell->list_layer, layout_layer);
1826 if (ivilayer == NULL) {
1827 weston_log("id_surface is not created yet\n");
1828 return;
1829 }
1830
1831 wl_list_for_each_safe(not, next, &ivilayer->notification_list, layout_link)
1832 {
1833 wl_list_remove(¬->link);
1834 wl_list_remove(¬->layout_link);
1835 free(not);
1836 }
1837
1838 wl_list_remove(&ivilayer->link);
1839 wl_list_remove(&ivilayer->property_changed.link);
1840 free(ivilayer);
1841
1842 id_layer = shell->interface->get_id_of_layer(layout_layer);
1843
1844 wl_list_for_each(controller, &shell->list_controller, link) {
1845 if (controller->resource)
1846 ivi_wm_send_layer_destroyed(controller->resource, id_layer);
1847 }
1848 }
1849
1850
1851 static void
1852 surface_event_create(struct wl_listener *listener, void *data)
1853 {
1854 struct ivishell *shell = wl_container_of(listener, shell, surface_created);
1855 const struct ivi_layout_interface *lyt = shell->interface;
1856 struct ivisurface *ivisurf = NULL;
1857 struct ivi_layout_surface *layout_surface =
1858 (struct ivi_layout_surface *) data;
1859 uint32_t id_surface = 0;
1860
1861 id_surface = lyt->get_id_of_surface(layout_surface);
1862
1863 ivisurf = create_surface(shell, layout_surface, id_surface);
1864 if (ivisurf == NULL) {
1865 weston_log("failed to create surface");
1866 return;
1867 }
1868
1869 if (shell->bkgnd_surface_id != (int32_t)id_surface)
1870 wl_signal_emit(&shell->ivisurface_created_signal, ivisurf);
1871 }
1872
1873 static void
1874 surface_event_remove(struct wl_listener *listener, void *data)
1875 {
1876 struct ivishell *shell = wl_container_of(listener, shell, surface_removed);
1877 struct ivicontroller *controller = NULL;
1878 struct ivisurface *ivisurf = NULL;
1879 struct ivi_layout_surface *layout_surface =
1880 (struct ivi_layout_surface *) data;
1881 uint32_t id_surface = 0;
1882 struct notification *not, *next;
1883
1884 ivisurf = get_surface(&shell->list_surface, layout_surface);
1885 if (ivisurf == NULL) {
1886 weston_log("id_surface is not created yet\n");
1887 return;
1888 }
1889
1890 wl_signal_emit(&shell->ivisurface_removed_signal, ivisurf);
1891 wl_list_for_each_safe(not, next, &ivisurf->notification_list, layout_link)
1892 {
1893 wl_list_remove(¬->link);
1894 wl_list_remove(¬->layout_link);
1895 free(not);
1896 }
1897
1898 wl_list_remove(&ivisurf->link);
1899 wl_list_remove(&ivisurf->property_changed.link);
1900 wl_list_remove(&ivisurf->committed.link);
1901 free(ivisurf);
1902
1903 id_surface = shell->interface->get_id_of_surface(layout_surface);
1904
1905 if ((shell->bkgnd_surface_id == (int32_t)id_surface) &&
1906 shell->bkgnd_view) {
1907 weston_layer_entry_remove(&shell->bkgnd_view->layer_link);
1908 weston_view_destroy(shell->bkgnd_view);
1909 }
1910
1911 wl_list_for_each(controller, &shell->list_controller, link) {
1912 if (controller->resource)
1913 ivi_wm_send_surface_destroyed(controller->resource, id_surface);
1914 }
1915 }
1916
1917 static void
1918 surface_event_configure(struct wl_listener *listener, void *data)
1919 {
1920 struct ivishell *shell = wl_container_of(listener, shell, surface_configured);
1921 const struct ivi_layout_interface *lyt = shell->interface;
1922 struct ivisurface *ivisurf = NULL;
1923 struct ivi_layout_surface *layout_surface =
1924 (struct ivi_layout_surface *) data;
1925 struct ivicontroller *ctrl;
1926 struct notification *not;
1927 uint32_t surface_id;
1928 struct weston_surface *w_surface;
1929
1930 surface_id = lyt->get_id_of_surface(layout_surface);
1931 if (shell->bkgnd_surface_id == (int32_t)surface_id) {
1932 float red, green, blue, alpha;
1933
1934 if (!shell->bkgnd_view) {
1935 w_surface = lyt->surface_get_weston_surface(layout_surface);
1936
1937 alpha = ((shell->bkgnd_color >> 24) & 0xFF) / 255.0F;
1938 red = ((shell->bkgnd_color >> 16) & 0xFF) / 255.0F;
1939 green = ((shell->bkgnd_color >> 8) & 0xFF) / 255.0F;
1940 blue = (shell->bkgnd_color & 0xFF) / 255.0F;
1941
1942 weston_surface_set_color(w_surface, red, green, blue, alpha);
1943
1944 wl_list_init(&shell->bkgnd_transform.link);
1945 shell->bkgnd_view = weston_view_create(w_surface);
1946 weston_layer_entry_insert(&shell->bkgnd_layer.view_list,
1947 &shell->bkgnd_view->layer_link);
1948 }
1949
1950 set_bkgnd_surface_prop(shell);
1951 return;
1952 }
1953
1954 ivisurf = get_surface(&shell->list_surface, layout_surface);
1955 if (ivisurf == NULL) {
1956 weston_log("id_surface is not created yet\n");
1957 return;
1958 }
1959
1960 if (ivisurf->type == IVI_WM_SURFACE_TYPE_DESKTOP) {
1961 w_surface = lyt->surface_get_weston_surface(layout_surface);
1962 lyt->surface_set_destination_rectangle(layout_surface,
1963 ivisurf->prop->dest_x,
1964 ivisurf->prop->dest_y,
1965 w_surface->width,
1966 w_surface->height);
1967 lyt->surface_set_source_rectangle(layout_surface,
1968 0,
1969 0,
1970 w_surface->width,
1971 w_surface->height);
1972 lyt->commit_changes();
1973 }
1974
1975 wl_list_for_each(not, &ivisurf->notification_list, layout_link) {
1976 ctrl = wl_resource_get_user_data(not->resource);
1977 send_surface_event(ctrl, ivisurf->layout_surface, surface_id, ivisurf->prop,
1978 IVI_NOTIFICATION_CONFIGURE);
1979 }
1980 }
1981
1982 static int32_t
1983 check_layout_layers(struct ivishell *shell)
1984 {
1985 struct ivi_layout_layer **pArray = NULL;
1986 struct ivilayer *ivilayer = NULL;
1987 const struct ivi_layout_interface *lyt = shell->interface;
1988 uint32_t id_layer = 0;
1989 int32_t length = 0;
1990 int32_t i = 0;
1991 int32_t ret = 0;
1992
1993 ret = lyt->get_layers(&length, &pArray);
1994 if(ret != 0) {
1995 weston_log("failed to get layers at check_layout_layers\n");
1996 return -1;
1997 }
1998
1999 if (length == 0) {
2000 /* if length is 0, pArray doesn't need to free.*/
2001 return 0;
2002 }
2003
2004 for (i = 0; i < length; i++) {
2005 id_layer = lyt->get_id_of_layer(pArray[i]);
2006 ivilayer = create_layer(shell, pArray[i], id_layer);
2007 if (ivilayer == NULL) {
2008 weston_log("failed to create layer");
2009 }
2010 }
2011
2012 free(pArray);
2013 pArray = NULL;
2014
2015 return 0;
2016 }
2017
2018 static int32_t
2019 check_layout_surfaces(struct ivishell *shell)
2020 {
2021 struct ivi_layout_surface **pArray = NULL;
2022 struct ivisurface *ivisurf = NULL;
2023 const struct ivi_layout_interface *lyt = shell->interface;
2024 uint32_t id_surface = 0;
2025 int32_t length = 0;
2026 int32_t i = 0;
2027 int32_t ret = 0;
2028
2029 ret = lyt->get_surfaces(&length, &pArray);
2030 if(ret != 0) {
2031 weston_log("failed to get surfaces at check_layout_surfaces\n");
2032 return -1;
2033 }
2034
2035 if (length == 0) {
2036 /* if length is 0, pArray doesn't need to free.*/
2037 return 0;
2038 }
2039
2040 for (i = 0; i < length; i++) {
2041 id_surface = lyt->get_id_of_surface(pArray[i]);
2042 ivisurf = create_surface(shell, pArray[i], id_surface);
2043 if (ivisurf == NULL) {
2044 weston_log("failed to create surface");
2045 }
2046 }
2047
2048 free(pArray);
2049 pArray = NULL;
2050
2051 return 0;
2052 }
2053
2054 static void
2055 destroy_screen_ids(struct ivishell *shell)
2056 {
2057 struct screen_id_info *screen_info = NULL;
2058
2059 wl_array_for_each(screen_info, &shell->screen_ids) {
2060 free(screen_info->screen_name);
2061 }
2062
2063 wl_array_release(&shell->screen_ids);
2064 }
2065
2066 static void
2067 get_config(struct weston_compositor *compositor, struct ivishell *shell)
2068 {
2069 struct weston_config_section *section = NULL;
2070 struct weston_config *config = NULL;
2071 struct screen_id_info *screen_info = NULL;
2072 const char *name = NULL;
2073
2074 config = wet_get_config(compositor);
2075 if (!config)
2076 return;
2077
2078 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
2079 if (!section)
2080 return;
2081
2082 weston_config_section_get_uint(section,
2083 "screen-id-offset",
2084 &shell->screen_id_offset, 0);
2085
2086 weston_config_section_get_string(section,
2087 "ivi-client-name",
2088 &shell->ivi_client_name, NULL);
2089
2090 weston_config_section_get_int(section,
2091 "bkgnd-surface-id",
2092 &shell->bkgnd_surface_id, -1);
2093
2094 weston_config_section_get_string(section,
2095 "debug-scopes",
2096 &shell->debug_scopes, NULL);
2097
2098 weston_config_section_get_color(section,
2099 "bkgnd-color",
2100 &shell->bkgnd_color, 0xFF000000);
2101
2102 weston_config_section_get_bool(section,
2103 "enable-cursor",
2104 &shell->enable_cursor, 0);
2105
2106 wl_array_init(&shell->screen_ids);
2107
2108 while (weston_config_next_section(config, §ion, &name)) {
2109 char *screen_name = NULL;
2110 uint32_t screen_id = 0;
2111
2112 if (0 != strcmp(name, "ivi-screen"))
2113 continue;
2114
2115 if (0 != weston_config_section_get_string(section, "screen-name",
2116 &screen_name, NULL))
2117 continue;
2118
2119 if (0 != weston_config_section_get_uint(section,
2120 "screen-id",
2121 &screen_id, 0))
2122 {
2123 free(screen_name);
2124 continue;
2125 }
2126
2127 screen_info = wl_array_add(&shell->screen_ids,
2128 sizeof(*screen_info));
2129 if(screen_info)
2130 {
2131 screen_info->screen_name = screen_name;
2132 screen_info->screen_id = screen_id;
2133 }
2134 }
2135 }
2136
2137 static void
2138 ivi_shell_destroy(struct wl_listener *listener, void *data)
2139 {
2140 struct ivisurface *ivisurf;
2141 struct ivisurface *ivisurf_next;
2142 struct ivilayer *ivilayer;
2143 struct ivilayer *ivilayer_next;
2144 struct iviscreen *iviscrn;
2145 struct iviscreen *iviscrn_next;
2146 struct ivishell *shell =
2147 wl_container_of(listener, shell, destroy_listener);
2148
2149 if (shell->client) {
2150 wl_list_remove(&shell->client_destroy_listener.link);
2151 wl_client_destroy(shell->client);
2152 }
2153
2154 wl_list_remove(&shell->destroy_listener.link);
2155
2156 wl_list_remove(&shell->output_created.link);
2157 wl_list_remove(&shell->output_destroyed.link);
2158 wl_list_remove(&shell->output_resized.link);
2159
2160 wl_list_remove(&shell->surface_configured.link);
2161 wl_list_remove(&shell->surface_removed.link);
2162 wl_list_remove(&shell->surface_created.link);
2163
2164 wl_list_remove(&shell->layer_removed.link);
2165 wl_list_remove(&shell->layer_created.link);
2166
2167 wl_list_for_each_safe(ivisurf, ivisurf_next,
2168 &shell->list_surface, link) {
2169 wl_list_remove(&ivisurf->link);
2170 free(ivisurf);
2171 }
2172
2173 wl_list_for_each_safe(ivilayer, ivilayer_next,
2174 &shell->list_layer, link) {
2175 wl_list_remove(&ivilayer->link);
2176 free(ivilayer);
2177 }
2178
2179 wl_list_for_each_safe(iviscrn, iviscrn_next,
2180 &shell->list_screen, link) {
2181 destroy_screen(iviscrn);
2182 }
2183
2184 destroy_screen_ids(shell);
2185 free(shell);
2186 }
2187
2188 void
2189 init_ivi_shell(struct weston_compositor *ec, struct ivishell *shell)
2190 {
2191 const struct ivi_layout_interface *lyt = shell->interface;
2192 struct weston_output *output = NULL;
2193 int32_t ret = 0;
2194
2195 shell->compositor = ec;
2196
2197 wl_list_init(&shell->list_surface);
2198 wl_list_init(&shell->list_layer);
2199 wl_list_init(&shell->list_screen);
2200 wl_list_init(&shell->list_controller);
2201
2202 wl_list_for_each(output, &ec->output_list, link)
2203 create_screen(shell, output);
2204 #ifdef USE_DUMMY_SCREEN
2205 output = lyt->get_dummy_output();
2206 create_screen(shell, output);
2207 #endif /* USE_DUMMY_SCREEN */
2208
2209 ret = check_layout_layers(shell);
2210 if (ret != 0) {
2211 weston_log("failed to check_layout_layers");
2212 }
2213
2214 ret = check_layout_surfaces(shell);
2215 if (ret != 0) {
2216 weston_log("failed to check_layout_surfaces");
2217 }
2218
2219 shell->layer_created.notify = layer_event_create;
2220 shell->layer_removed.notify = layer_event_remove;
2221
2222 lyt->add_listener_create_layer(&shell->layer_created);
2223 lyt->add_listener_remove_layer(&shell->layer_removed);
2224
2225 shell->surface_created.notify = surface_event_create;
2226 shell->surface_removed.notify = surface_event_remove;
2227 shell->surface_configured.notify = surface_event_configure;
2228
2229 lyt->add_listener_create_surface(&shell->surface_created);
2230 lyt->add_listener_remove_surface(&shell->surface_removed);
2231 lyt->add_listener_configure_surface(&shell->surface_configured);
2232
2233 shell->output_created.notify = output_created_event;
2234 shell->output_destroyed.notify = output_destroyed_event;
2235 shell->output_resized.notify = output_resized_event;
2236
2237 wl_signal_add(&ec->output_created_signal, &shell->output_created);
2238 wl_signal_add(&ec->output_destroyed_signal, &shell->output_destroyed);
2239 wl_signal_add(&ec->output_resized_signal, &shell->output_resized);
2240
2241 wl_signal_init(&shell->ivisurface_created_signal);
2242 wl_signal_init(&shell->ivisurface_removed_signal);
2243 }
2244
2245 int
2246 setup_ivi_controller_server(struct weston_compositor *compositor,
2247 struct ivishell *shell)
2248 {
2249 if (wl_global_create(compositor->wl_display, &ivi_wm_interface, 1,
2250 shell, bind_ivi_controller) == NULL) {
2251 return -1;
2252 }
2253
2254 return 0;
2255 }
2256
2257 static int
2258 load_input_module(struct ivishell *shell)
2259 {
2260 struct weston_config *config = wet_get_config(shell->compositor);
2261 struct weston_config_section *section;
2262 char *input_module = NULL;
2263
2264 int (*input_module_init)(struct ivishell *shell);
2265
2266 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
2267
2268 if (weston_config_section_get_string(section, "ivi-input-module",
2269 &input_module, NULL) < 0) {
2270 /* input events are handled by weston's default grabs */
2271 weston_log("ivi-controller: No ivi-input-module set\n");
2272 return 0;
2273 }
2274
2275 input_module_init = wet_load_module_entrypoint(input_module, "input_controller_module_init");
2276 if (!input_module_init)
2277 return -1;
2278
2279 if (input_module_init(shell) != 0) {
2280 weston_log("ivi-controller: Initialization of input module fails");
2281 return -1;
2282 }
2283
2284 free(input_module);
2285
2286 return 0;
2287 }
2288
2289 static int
2290 load_screen_info_module(struct ivishell *shell)
2291 {
2292 struct weston_config *config = wet_get_config(shell->compositor);
2293 struct weston_config_section *section;
2294 char *screen_info_module = NULL;
2295
2296 int (*screen_info_module_init)(struct ivishell *shell);
2297
2298 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
2299
2300 if (weston_config_section_get_string(section, "screen-info-module",
2301 &screen_info_module, NULL) < 0) {
2302 /* input events are handled by weston's default grabs */
2303 weston_log("ivi-controller: No screen-info-module set\n");
2304 return 0;
2305 }
2306
2307 screen_info_module_init = wet_load_module_entrypoint(screen_info_module, "ivishell_module_init");
2308 if (!screen_info_module_init)
2309 return -1;
2310
2311 if (screen_info_module_init(shell) != 0) {
2312 weston_log("ivi-controller: Initialization of screen-info-module fails");
2313 return -1;
2314 }
2315
2316 free(screen_info_module);
2317
2318 return 0;
2319 }
2320
2321 static void
2322 ivi_shell_client_destroy(struct wl_listener *listener, void *data)
2323 {
2324 struct ivishell *shell = wl_container_of(listener, shell,
2325 client_destroy_listener);
2326
2327 weston_log("ivi shell client %p destroyed \n", shell->client);
2328
2329 wl_list_remove(&shell->client_destroy_listener.link);
2330 shell->client = NULL;
2331 }
2332
2333 static void
2334 launch_client_process(void *data)
2335 {
2336 struct ivishell *shell =
2337 (struct ivishell *)data;
2338 char option[128] = {0};
2339
2340 sprintf(option, "%d", shell->bkgnd_surface_id);
2341 setenv(IVI_CLIENT_SURFACE_ID_ENV_NAME, option, 0x1);
2342 if (shell->debug_scopes) {
2343 setenv(IVI_CLIENT_DEBUG_SCOPES_ENV_NAME, shell->debug_scopes, 0x1);
2344 free(shell->debug_scopes);
2345 }
2346 if(shell->enable_cursor) {
2347 sprintf(option, "%d", shell->enable_cursor);
2348 setenv(IVI_CLIENT_ENABLE_CURSOR_ENV_NAME, option, 0x1);
2349 }
2350
2351 shell->client = weston_client_start(shell->compositor,
2352 shell->ivi_client_name);
2353
2354 shell->client_destroy_listener.notify = ivi_shell_client_destroy;
2355 wl_client_add_destroy_listener(shell->client,
2356 &shell->client_destroy_listener);
2357
2358 free(shell->ivi_client_name);
2359 }
2360
2361 static int load_id_agent_module(struct ivishell *shell)
2362 {
2363 struct weston_config *config = wet_get_config(shell->compositor);
2364 struct weston_config_section *section;
2365 char *id_agent_module = NULL;
2366
2367 int (*id_agent_module_init)(struct weston_compositor *compositor,
2368 const struct ivi_layout_interface *interface);
2369
2370 section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
2371
2372 if (weston_config_section_get_string(section, "ivi-id-agent-module",
2373 &id_agent_module, NULL) < 0) {
2374 /* input events are handled by weston's default grabs */
2375 weston_log("ivi-controller: No ivi-id-agent-module set\n");
2376 return 0;
2377 }
2378
2379 id_agent_module_init = wet_load_module_entrypoint(id_agent_module, "id_agent_module_init");
2380 if (!id_agent_module_init)
2381 return -1;
2382
2383 if (id_agent_module_init(shell->compositor, shell->interface) != 0) {
2384 weston_log("ivi-controller: Initialization of id-agent module failed\n");
2385 return -1;
2386 }
2387
2388 free(id_agent_module);
2389
2390 return 0;
2391 }
2392
2393 void
2394 set_screen_listener(screen_listener_t listener)
2395 {
2396 screen_info_property_change_callback_listener = listener;
2397 }
2398
2399 WL_EXPORT int
2400 wet_module_init(struct weston_compositor *compositor,
2401 int *argc, char *argv[])
2402 {
2403 struct ivishell *shell;
2404 struct wl_event_loop *loop = NULL;
2405 (void)argc;
2406 (void)argv;
2407
2408 shell = malloc(sizeof *shell);
2409 if (shell == NULL)
2410 return -1;
2411
2412 memset(shell, 0, sizeof *shell);
2413
2414 shell->interface = ivi_layout_get_api(compositor);
2415 if (!shell->interface) {
2416 free(shell);
2417 weston_log("Cannot use ivi_layout_interface.\n");
2418 return -1;
2419 }
2420
2421 get_config(compositor, shell);
2422
2423 /* Add background layer*/
2424 if (shell->bkgnd_surface_id && shell->ivi_client_name) {
2425 weston_layer_init(&shell->bkgnd_layer, compositor);
2426 weston_layer_set_position(&shell->bkgnd_layer,
2427 WESTON_LAYER_POSITION_BACKGROUND);
2428 }
2429
2430 init_ivi_shell(compositor, shell);
2431
2432 if (setup_ivi_controller_server(compositor, shell)) {
2433 destroy_screen_ids(shell);
2434 free(shell);
2435 return -1;
2436 }
2437
2438 if (load_input_module(shell) < 0) {
2439 destroy_screen_ids(shell);
2440 free(shell);
2441 return -1;
2442 }
2443
2444 if (load_screen_info_module(shell) < 0) {
2445 destroy_screen_ids(shell);
2446 free(shell);
2447 return -1;
2448 }
2449
2450 /* add compositor destroy signal after loading input
2451 * modules, to ensure input module is the first one to
2452 * de-initialize
2453 */
2454 shell->destroy_listener.notify = ivi_shell_destroy;
2455 wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener);
2456
2457 if (shell->bkgnd_surface_id && shell->ivi_client_name) {
2458 loop = wl_display_get_event_loop(compositor->wl_display);
2459 wl_event_loop_add_idle(loop, launch_client_process, shell);
2460 }
2461
2462 if (load_id_agent_module(shell) < 0) {
2463 weston_log("ivi-controller: id-agent module not loaded\n");
2464 }
2465
2466 return 0;
2467 }
2468