1 From 0d114839f299b6a9e3f504e75c22d636222c3b20 Mon Sep 17 00:00:00 2001
2 From: Wataru Mizuno <wmizuno@jp.adit-jv.com>
3 Date: Tue, 10 Apr 2018 15:23:02 +0900
4 Subject: [PATCH 3/3] transmitter: transmitter plugin for waltham protocol
6 The transmitter plugin enables weston to communicate with
7 remote site compositor over the ethernet.
8 Communication is done with waltham protocol which is the
9 wayland like IPC protocol.
11 Signed-off-by: Wataru Mizuno <wmizuno@jp.adit-jv.com>
15 transmitter/README | 108 +++--
16 transmitter/input.c | 783 ++++++++++++++++++++++++++++++++-
17 transmitter/output.c | 139 +++++-
18 transmitter/plugin.c | 875 ++++++++++++++++++++++++++-----------
19 transmitter/plugin.h | 140 +++++-
20 transmitter/transmitter_api.h | 26 +-
21 transmitter/weston.ini.transmitter | 21 +
22 9 files changed, 1763 insertions(+), 352 deletions(-)
23 create mode 100644 transmitter/weston.ini.transmitter
25 diff --git a/Makefile.am b/Makefile.am
26 index 6cca875..2cb1920 100644
29 @@ -306,6 +306,11 @@ westoninclude_HEADERS += \
30 ivi-shell/ivi-layout-export.h
33 +if ENABLE_SURFACE_REMOTING
34 +westoninclude_HEADERS += \
35 + transmitter/transmitter_api.h
39 libweston_module_LTLIBRARIES += gl-renderer.la
40 gl_renderer_la_LDFLAGS = -module -avoid-version
41 @@ -507,8 +512,10 @@ module_LTLIBRARIES += transmitter.la
42 transmitter_la_LDFLAGS = -module -avoid-version
43 transmitter_la_CFLAGS = \
44 $(COMPOSITOR_CFLAGS) \
46 -transmitter_la_LIBADD = $(COMPOSITOR_LIBS)
49 +transmitter_la_LIBADD = $(COMPOSITOR_LIBS) \
51 transmitter_la_SOURCES = \
52 transmitter/plugin.c \
53 transmitter/plugin.h \
54 diff --git a/configure.ac b/configure.ac
55 index 6cf2883..4819e08 100644
58 @@ -543,6 +543,18 @@ AC_ARG_ENABLE(surface-remoting,
59 AS_HELP_STRING([--enable-surface-remoting],
60 [support for surface remoting over network]),,
61 enable_surface_remoting=no)
62 +if test "x$enable_surface_remoting" != "xno"; then
63 + PKG_CHECK_MODULES(WALTHAM,
67 + if test "x$have_waltham" = "xno" -a "x$enable_surface_remoting" = "xyes"; then
68 + AC_MSG_ERROR([surface_remoting support explicitly requested, but waltham couldn't be found])
70 + if test "x$have_waltham" = "xyes"; then
71 + enable_surface_remoting=yes
74 AM_CONDITIONAL(ENABLE_SURFACE_REMOTING, test "x$enable_surface_remoting" = "xyes")
77 diff --git a/transmitter/README b/transmitter/README
78 index a7977ba..af80574 100644
79 --- a/transmitter/README
80 +++ b/transmitter/README
82 -Testing Transmitter with ivi-shell
85 The current implementation of Transmitter is a stub which interfaces to
86 other Weston parts appropriately, but all networking is just a mockup.
88 +Sections in this file describe:
90 +- How to write weston.ini
95 Configure Weston with --enable-surface-remoting to build the Transmitter
98 -In weston.ini, add 'transmitter.so' to the 'modules' key under '[core]', and
99 -make sure the 'shell' is 'ivi-shell.so'. Follow the ivi-shell example
100 -weston.ini for everything else.
102 -When you start weston, the log should contain something like this:
104 -[13:13:54.799] Loading module '/home/pq/local/lib/weston/ivi-shell.so'
105 -[13:13:54.799] launching '/home/pq/local/libexec/weston-keyboard'
106 -[13:13:54.799] Loading module '/home/pq/local/lib/weston/hmi-controller.so'
107 -[13:13:54.799] Loading module '/home/pq/local/lib/weston/transmitter.so'
108 -[13:13:54.799] Registered plugin API 'transmitter_v1' of size 48
109 -[13:13:54.799] Registered plugin API 'transmitter_ivi_v1' of size 16
110 -[13:13:54.799] Transmitter initialized.
111 -[13:13:54.799] ivi-layout: Transmitter enabled.
112 -[13:13:54.799] launching '/home/pq/build/weston/weston-ivi-shell-user-interface'
113 -[13:13:54.799] hmi-controller: Transmitter enabled.
114 -[13:13:54.799] Transmitter connecting to 0.0.0.0:66...
115 -[13:13:55.800] Transmitter connected to 0.0.0.0:66.
116 -[13:13:55.800] hmi-controller: connection status 0
117 -[13:13:55.800] Transmitter created output 'transmitter-0.0.0.0:66-1': Weston-Transmitter, transmitter-0.0.0.0:66-1, 0
118 -[13:13:55.800] Transmitter created seat=0x1c37bd0 'transmitter-0.0.0.0:66-default'
119 -[13:13:55.800] Transmitter created pointer=0x1c38430 for seat 0x1c37bd0
120 -[13:13:55.800] transmitter_start_repaint_loop(transmitter-0.0.0.0:66-1)
123 -If you have edited a client to have ivi-id >= 0xfaa01000, when you start that
124 -client it should be "remoted" automatically and not appear on screen.
126 -You can also manually start remoting:
127 +How to write weston.ini
128 +=======================
129 +To load transmitter plugin to weston, add 'transmitter.so' to the 'modules'
130 +key under '[core]', and make sure the 'shell' is 'ivi-shell.so'.
132 +The destination of remoting is configured in weston.ini.
133 +Add output name, server address, port number, output's width and height key
134 +under '[remote-output]'.
135 +You can speficy multiple [remote-output].
137 +In details, see 'weston.ini.transmitter'.
141 +You can use server side test application in waltham repository.
143 +If you set 'WALTHAM_DEBUG=1' to your environment valuable, you can
144 +see the log like this:
146 + [06:12:41.238] Loading module '/usr/lib64/weston/ivi-shell.so'
147 + [06:12:41.245] launching '/usr/libexec/weston-keyboard'
148 + [06:12:41.247] Loading module '/usr/lib64/weston/ivi-controller.so'
149 + [06:12:41.252] Loading module '/usr/lib64/weston/ivi-input-controller.so'
150 + [06:12:41.253] ivi-input-controller module loaded successfully!
151 + [06:12:41.255] Loading module '/usr/lib64/weston/transmitter.so'
152 + [06:12:41.260] Registered plugin API 'transmitter_v1' of size 88
153 + [06:12:41.260] Registered plugin API 'transmitter_ivi_v1' of size 16
154 + [06:12:41.260] Transmitter initialized.
155 + [06:12:41.260] ivi-layout: Transmitter enabled.
156 + [06:12:41.260] Transmitter weston_seat 0x14f8010
157 + [06:12:41.260] Transmitter created pointer=0x139a440 for seat 0x14f8010
158 + [06:12:41.261] Transmitter created keyboard=0x14f8160 for seat 0x14f8010
159 + [06:12:41.261] Transmitter created touch=0x1508750 for seat 0x14f8010
161 +The connection is established, you can see following debug messages:
163 + root@gr-mrb-64:~# debug: wth_connection_insert_new_object: new object id: 1
164 + debug: wth_connection_insert_new_object: new object id: 2
165 + 2017-07-19T06:14:31Z 00001000030000000100000002000000 wth_display_get_registry
166 + debug: wth_connection_insert_new_object: new object id: 3
167 + 2017-07-19T06:14:31Z 00001000020000000100000003000000 wth_display_sync
168 + debug: Message received on conn 0x1560340: (9) 40 bytes
169 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
170 + debug: wth_connection_insert_new_object: new object id: 4
171 + 2017-07-19T06:14:31Z 00002c000800000002000000010000000400000010000000777468705f636f6d706f7369746f720001000000 wthp_registry_bind
172 + debug: Message received on conn 0x1560340: (9) 44 bytes
173 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
174 + debug: wth_connection_insert_new_object: new object id: 5
175 + 2017-07-19T06:14:31Z 000030000800000002000000010000000500000012000000777468705f626c6f625f666163746f72790001000000 wthp_registry_bind
176 + debug: Message received on conn 0x1560340: (9) 48 bytes
177 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 1) (opcode 9) called.
178 + debug: wth_connection_insert_new_object: new object id: 6
179 + 2017-07-19T06:14:31Z 000034000800000002000000010000000600000015000000777468705f6976695f6170706c69636174696f6e0001000000 wthp_registry_bind
180 + debug: Message received on conn 0x1560340: (11) 16 bytes
181 + debug: wthp_callback_send_done(3, 0) (opcode 11) called.
182 + sending wth_display.sync...
183 + debug: wth_connection_insert_new_object: new object id: 7
184 + 2017-07-19T06:14:31Z 00001000020000000100000007000000 wth_display_sync
185 + debug: Message received on conn 0x1560340: (11) 16 bytes
186 + debug: wthp_callback_send_done(7, 0) (opcode 11) called.
190 - Start an IVI application.
191 -- Move pointer onto the application window.
192 -- Press Mod+Shift+space, and then 'k'.
193 -- The window should disappear.
194 +- Put surface on backend output
195 +- Put surface on transmitter output
197 Weston log will indicate remoting has started:
199 @@ -48,6 +87,3 @@ Weston log will indicate remoting has started:
200 [13:18:24.572] transmitter_surface_set_ivi_id(0x1c3dad0, 0x9ff6)
201 [13:18:24.972] Transmitter: surface 0x1c3dad0 entered output transmitter-0.0.0.0:66-1
203 -Once remoting has started, the mockup code will generate fake pointer input for
204 -the window. This can be seen with e.g. weston-eventdemo, or running an
205 -application with WAYLAND_DEBUG=client.
206 diff --git a/transmitter/input.c b/transmitter/input.c
207 index 0ba04d4..eeb7452 100644
208 --- a/transmitter/input.c
209 +++ b/transmitter/input.c
212 * Copyright (C) 2016 DENSO CORPORATION
213 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
215 * Permission is hereby granted, free of charge, to any person obtaining
216 * a copy of this software and associated documentation files (the
217 @@ -129,6 +130,79 @@ static const struct weston_pointer_grab_interface pointer_grab_impl = {
218 pointer_cancel_grab_handler,
222 +keyboard_grab_key(struct weston_keyboard_grab *grab,
230 +keyboard_grab_modifiers(struct weston_keyboard_grab *grab,
232 + uint32_t mods_depressed,
233 + uint32_t mods_latched,
234 + uint32_t mods_locked,
240 +keyboard_grab_cancel(struct weston_keyboard_grab *grab)
244 +static const struct weston_keyboard_grab_interface keyborad_grab_impl = {
246 + keyboard_grab_modifiers,
247 + keyboard_grab_cancel
251 +touch_grab_down_handler(struct weston_touch_grab *grab,
260 +touch_grab_up_handler(struct weston_touch_grab *grab,
267 +touch_grab_motion_handler(struct weston_touch_grab *grab,
276 +touch_grab_frame_handler(struct weston_touch_grab *grab)
281 +touch_grab_cancel_handler(struct weston_touch_grab *grab)
285 +static const struct weston_touch_grab_interface touch_grab_impl = {
286 + touch_grab_down_handler,
287 + touch_grab_up_handler,
288 + touch_grab_motion_handler,
289 + touch_grab_frame_handler,
290 + touch_grab_cancel_handler,
294 /* The different ways to get pointer focus on a remoted surface:
296 * 1. Transmitter seat has pointer. The client has wl_pointer. Transmitter
297 @@ -207,7 +281,7 @@ seat_get_pointer_handler(struct wl_listener *listener, void *data)
298 if (wl_resource_get_client(surface) != client)
301 - pointer = weston_seat_get_pointer(&seat->base);
302 + pointer = weston_seat_get_pointer(seat->base);
303 assert(pointer); /* guaranteed by having pointer_focus */
304 pointer_client = weston_pointer_get_pointer_client(pointer, client);
306 @@ -235,13 +309,9 @@ transmitter_seat_create_pointer(struct weston_transmitter_seat *seat)
307 seat->pointer_focus = NULL;
308 wl_list_init(&seat->pointer_focus_destroy_listener.link);
310 - weston_seat_init_pointer(&seat->base);
312 - seat->get_pointer_listener.notify = seat_get_pointer_handler;
313 - wl_signal_add(&seat->base.get_pointer_signal,
314 - &seat->get_pointer_listener);
315 + weston_seat_init_pointer(seat->base);
317 - pointer = weston_seat_get_pointer(&seat->base);
318 + pointer = weston_seat_get_pointer(seat->base);
321 * weston_pointer_set_default_grab(pointer, &pointer_grab_impl); */
322 @@ -252,7 +322,7 @@ transmitter_seat_create_pointer(struct weston_transmitter_seat *seat)
323 wl_list_init(&pointer->output_destroy_listener.link);
325 weston_log("Transmitter created pointer=%p for seat %p\n",
326 - pointer, &seat->base);
327 + pointer, seat->base);
331 @@ -279,7 +349,7 @@ transmitter_seat_pointer_enter(struct weston_transmitter_seat *seat,
332 struct wl_list *focus_resource_list;
333 struct wl_resource *resource;
335 - pointer = weston_seat_get_pointer(&seat->base);
336 + pointer = weston_seat_get_pointer(seat->base);
339 assert(txs->surface);
340 @@ -299,8 +369,6 @@ transmitter_seat_pointer_enter(struct weston_transmitter_seat *seat,
341 seat->pointer_surface_x = surface_x;
342 seat->pointer_surface_y = surface_y;
344 - pointer->focus_client = weston_pointer_get_pointer_client(pointer,
346 pointer->focus_serial = serial;
348 /* pointer->focus is not used, because it is a weston_view, while
349 @@ -347,7 +415,7 @@ transmitter_seat_pointer_leave(struct weston_transmitter_seat *seat,
350 assert(txs->surface);
351 surface_resource = txs->surface->resource;
353 - pointer = weston_seat_get_pointer(&seat->base);
354 + pointer = weston_seat_get_pointer(seat->base);
356 if (!pointer->focus_client)
358 @@ -373,7 +441,7 @@ transmitter_seat_pointer_motion(struct weston_transmitter_seat *seat,
359 struct wl_resource *resource;
360 struct weston_transmitter_surface *txs;
362 - pointer = weston_seat_get_pointer(&seat->base);
363 + pointer = weston_seat_get_pointer(seat->base);
366 seat->pointer_surface_x = surface_x;
367 @@ -401,7 +469,27 @@ transmitter_seat_pointer_button(struct weston_transmitter_seat *seat,
372 + struct weston_pointer *pointer;
373 + struct wl_list *focus_resource_list;
374 + struct wl_resource *resource;
375 + struct weston_transmitter_surface *txs;
377 + pointer = weston_seat_get_pointer(seat->base);
380 + if (!pointer->focus_client)
383 + txs = seat->pointer_focus;
385 + assert(wl_resource_get_client(txs->surface->resource) ==
386 + pointer->focus_client->client);
388 + focus_resource_list = &pointer->focus_client->pointer_resources;
389 + wl_resource_for_each(resource, focus_resource_list) {
390 + wl_pointer_send_button(resource, serial, time,
396 @@ -410,7 +498,27 @@ transmitter_seat_pointer_axis(struct weston_transmitter_seat *seat,
401 + struct weston_pointer *pointer;
402 + struct wl_list *focus_resource_list;
403 + struct wl_resource *resource;
404 + struct weston_transmitter_surface *txs;
406 + pointer = weston_seat_get_pointer(seat->base);
409 + if (!pointer->focus_client)
412 + txs = seat->pointer_focus;
414 + assert(wl_resource_get_client(txs->surface->resource) ==
415 + pointer->focus_client->client);
417 + focus_resource_list = &pointer->focus_client->pointer_resources;
418 + wl_resource_for_each(resource, focus_resource_list) {
419 + wl_pointer_send_axis(resource, time,
425 @@ -418,7 +526,7 @@ transmitter_seat_pointer_frame(struct weston_transmitter_seat *seat)
427 struct weston_pointer *pointer;
429 - pointer = weston_seat_get_pointer(&seat->base);
430 + pointer = weston_seat_get_pointer(seat->base);
432 weston_pointer_send_frame(pointer);
434 @@ -427,7 +535,7 @@ void
435 transmitter_seat_pointer_axis_source(struct weston_transmitter_seat *seat,
436 uint32_t axis_source)
439 + /* ToDo : implement axis event handling */
443 @@ -435,7 +543,7 @@ transmitter_seat_pointer_axis_stop(struct weston_transmitter_seat *seat,
448 + /* ToDo : implement axis event handling */
452 @@ -443,7 +551,222 @@ transmitter_seat_pointer_axis_discrete(struct weston_transmitter_seat *seat,
457 + /* ToDo : implement axis event handling */
461 +transmitter_seat_create_keyboard(struct weston_transmitter_seat *seat)
463 + struct weston_keyboard *keyboard;
465 + seat->keyboard_focus = NULL;
466 + weston_seat_init_keyboard(seat->base, NULL);
468 + keyboard = weston_seat_get_keyboard(seat->base);
470 + keyboard->default_grab.interface = &keyborad_grab_impl;
472 + weston_log("Transmitter created keyboard=%p for seat %p\n",
473 + keyboard, seat->base);
477 +transmitter_seat_keyboard_enter(struct weston_transmitter_seat *seat,
479 + struct weston_transmitter_surface *txs,
480 + struct wl_array *keys)
482 + struct weston_keyboard *keyboard;
483 + struct wl_resource *resource = NULL;
484 + struct wl_resource *surface_resource;
486 + keyboard = weston_seat_get_keyboard(seat->base);
489 + assert(txs->surface);
490 + surface_resource = txs->surface->resource;
492 + seat->keyboard_focus = txs;
493 + wl_array_copy(&keyboard->keys, keys);
495 + wl_resource_for_each(resource, &keyboard->resource_list) {
496 + if (wl_resource_get_client(resource) == wl_resource_get_client(surface_resource)) {
497 + wl_keyboard_send_enter(resource,
506 +transmitter_seat_keyboard_leave(struct weston_transmitter_seat *seat,
508 + struct weston_transmitter_surface *txs)
510 + struct weston_keyboard *keyboard;
511 + struct wl_resource *resource = NULL;
512 + struct wl_resource *surface_resource;
514 + keyboard = weston_seat_get_keyboard(seat->base);
517 + assert(txs->surface);
518 + surface_resource = txs->surface->resource;
520 + wl_resource_for_each(resource, &keyboard->resource_list) {
521 + if (wl_resource_get_client(resource) == wl_resource_get_client(surface_resource)) {
522 + wl_keyboard_send_leave(resource,
530 +transmitter_seat_keyboard_key(struct weston_transmitter_seat *seat,
536 + struct weston_keyboard *keyboard;
537 + struct wl_resource *resource = NULL;
539 + keyboard = weston_seat_get_keyboard(seat->base);
542 + wl_resource_for_each(resource, &keyboard->resource_list) {
543 + if (wl_resource_get_client(resource) ==
544 + wl_resource_get_client(seat->keyboard_focus->surface->resource)) {
545 + wl_keyboard_send_key(resource,
555 +transmitter_seat_create_touch(struct weston_transmitter_seat *seat)
557 + struct weston_touch *touch;
559 + seat->touch_focus = NULL;
560 + weston_seat_init_touch(seat->base);
562 + touch = weston_seat_get_touch(seat->base);
564 + touch->default_grab.interface = &touch_grab_impl;
566 + weston_log("Transmitter created touch=%p for seat %p\n",
567 + touch, seat->base);
571 +transmitter_seat_touch_down (struct weston_transmitter_seat *seat,
574 + struct weston_transmitter_surface *txs,
579 + struct weston_touch *touch;
580 + struct wl_resource *resource = NULL;
581 + struct wl_resource *surface_resource;
583 + touch = weston_seat_get_touch(seat->base);
586 + assert(txs->surface);
587 + surface_resource = txs->surface->resource;
589 + seat->touch_focus = txs;
591 + wl_resource_for_each(resource, &touch->resource_list) {
592 + if (wl_resource_get_client(resource) == wl_resource_get_client(surface_resource)) {
593 + wl_touch_send_down(resource, serial, time,
601 +transmitter_seat_touch_up (struct weston_transmitter_seat *seat,
606 + struct weston_touch *touch;
607 + struct wl_resource *resource = NULL;
609 + touch = weston_seat_get_touch(seat->base);
612 + wl_resource_for_each(resource, &touch->resource_list) {
613 + if (wl_resource_get_client(resource) ==
614 + wl_resource_get_client(seat->touch_focus->surface->resource)) {
615 + wl_touch_send_up(resource, serial, time, touch_id);
621 +transmitter_seat_touch_motion (struct weston_transmitter_seat *seat,
627 + struct weston_touch *touch;
628 + struct wl_resource *resource = NULL;
630 + touch = weston_seat_get_touch(seat->base);
633 + wl_resource_for_each(resource, &touch->resource_list) {
634 + if (wl_resource_get_client(resource) ==
635 + wl_resource_get_client(seat->touch_focus->surface->resource)) {
636 + wl_touch_send_motion(resource, time, touch_id, x, y);
642 +transmitter_seat_touch_frame (struct weston_transmitter_seat *seat)
644 + struct weston_touch *touch;
645 + struct wl_resource *resource = NULL;
647 + touch = weston_seat_get_touch(seat->base);
650 + wl_resource_for_each(resource, &touch->resource_list) {
651 + if (wl_resource_get_client(resource) ==
652 + wl_resource_get_client(seat->touch_focus->surface->resource)) {
653 + wl_touch_send_frame(resource);
659 +transmitter_seat_touch_cancel (struct weston_transmitter_seat *seat)
661 + struct weston_touch *touch;
662 + struct wl_resource *resource = NULL;
664 + touch = weston_seat_get_touch(seat->base);
667 + wl_resource_for_each(resource, &touch->resource_list) {
668 + if (wl_resource_get_client(resource) ==
669 + wl_resource_get_client(seat->touch_focus->surface->resource)) {
670 + wl_touch_send_cancel(resource);
676 @@ -462,9 +785,7 @@ transmitter_seat_destroy(struct weston_transmitter_seat *seat)
678 wl_list_remove(&seat->link);
680 - weston_log("Transmitter destroy seat=%p\n", &seat->base);
682 - weston_seat_release(&seat->base);
683 + weston_log("Transmitter destroy seat=%p\n", seat->base);
685 wl_list_remove(&seat->get_pointer_listener.link);
686 wl_list_remove(&seat->pointer_focus_destroy_listener.link);
687 @@ -475,11 +796,406 @@ transmitter_seat_destroy(struct weston_transmitter_seat *seat)
692 +pointer_handle_enter(struct wthp_pointer *wthp_pointer,
694 + struct wthp_surface *surface,
695 + wth_fixed_t surface_x,
696 + wth_fixed_t surface_y)
698 + struct waltham_display *dpy =
699 + wth_object_get_user_data((struct wth_object *)wthp_pointer);
700 + struct weston_transmitter_remote *remote = dpy->remote;
701 + struct wl_list *seat_list = &remote->seat_list;
702 + struct weston_transmitter_seat *seat;
703 + struct weston_transmitter_surface *txs;
705 + seat = container_of(seat_list->next,
706 + struct weston_transmitter_seat, link);
708 + wl_list_for_each(txs, &remote->surface_list, link)
710 + if (txs->wthp_surf == surface) {
711 + if (txs != seat->pointer_focus)
712 + transmitter_seat_pointer_leave(seat, serial, seat->pointer_focus);
713 + transmitter_seat_pointer_enter(seat, serial, txs,
714 + surface_x, surface_y);
720 +pointer_handle_leave(struct wthp_pointer *wthp_pointer,
722 + struct wthp_surface *surface)
724 + struct waltham_display *dpy =
725 + wth_object_get_user_data((struct wth_object *)wthp_pointer);
726 + struct weston_transmitter_remote *remote = dpy->remote;
727 + struct wl_list *seat_list = &remote->seat_list;
728 + struct weston_transmitter_seat *seat;
729 + struct weston_transmitter_surface *txs;
731 + seat = container_of(seat_list->next,
732 + struct weston_transmitter_seat, link);
734 + wl_list_for_each(txs, &remote->surface_list, link)
736 + if (txs->wthp_surf == surface) {
737 + transmitter_seat_pointer_leave(seat, serial, txs);
743 +pointer_handle_motion(struct wthp_pointer *wthp_pointer,
745 + wth_fixed_t surface_x,
746 + wth_fixed_t surface_y)
748 + struct waltham_display *dpy =
749 + wth_object_get_user_data((struct wth_object *)wthp_pointer);
750 + struct weston_transmitter_remote *remote = dpy->remote;
751 + struct wl_list *seat_list = &remote->seat_list;
752 + struct weston_transmitter_seat *seat;
754 + seat = container_of(seat_list->next,
755 + struct weston_transmitter_seat, link);
757 + transmitter_seat_pointer_motion(seat, time,
763 +pointer_handle_button(struct wthp_pointer *wthp_pointer,
769 + struct waltham_display *dpy =
770 + wth_object_get_user_data((struct wth_object *)wthp_pointer);
771 + struct weston_transmitter_remote *remote = dpy->remote;
772 + struct wl_list *seat_list = &remote->seat_list;
773 + struct weston_transmitter_seat *seat;
775 + seat = container_of(seat_list->next,
776 + struct weston_transmitter_seat, link);
778 + transmitter_seat_pointer_button(seat, serial,
784 +pointer_handle_axis(struct wthp_pointer *wthp_pointer,
786 + uint32_t axis, wth_fixed_t value)
788 + struct waltham_display *dpy =
789 + wth_object_get_user_data((struct wth_object *)wthp_pointer);
790 + struct weston_transmitter_remote *remote = dpy->remote;
791 + struct wl_list *seat_list = &remote->seat_list;
792 + struct weston_transmitter_seat *seat;
794 + seat = container_of(seat_list->next,
795 + struct weston_transmitter_seat, link);
797 + transmitter_seat_pointer_axis(seat, time,
802 +pointer_handle_frame(struct wthp_pointer *wthp_pointer)
804 + /* ToDo : implement pointer handle frame */
808 +pointer_handle_axis_source(struct wthp_pointer *wthp_pointer,
809 + uint32_t axis_source)
811 + /* ToDo : implement pointer handle axis source */
815 +pointer_handle_axis_stop(struct wthp_pointer *wthp_pointer,
819 + /* ToDo : implement pointer handle axis stop */
823 +pointer_handle_axis_discrete(struct wthp_pointer *wthp_pointer,
827 + /* ToDo : implement pointer handle axis discrete */
830 +static const struct wthp_pointer_listener pointer_listener = {
831 + pointer_handle_enter,
832 + pointer_handle_leave,
833 + pointer_handle_motion,
834 + pointer_handle_button,
835 + pointer_handle_axis,
836 + pointer_handle_frame,
837 + pointer_handle_axis_source,
838 + pointer_handle_axis_stop,
839 + pointer_handle_axis_discrete
843 +keyboard_handle_keymap(struct wthp_keyboard * wthp_keyboard,
845 + uint32_t keymap_sz,
848 + /* ToDo : implement keyboard handle keymap */
852 +keyboard_handle_enter(struct wthp_keyboard *wthp_keyboard,
854 + struct wthp_surface *surface,
855 + struct wth_array *keys)
857 + struct waltham_display *dpy =
858 + wth_object_get_user_data((struct wth_object *)wthp_keyboard);
859 + struct weston_transmitter_remote *remote = dpy->remote;
860 + struct wl_list *seat_list = &remote->seat_list;
861 + struct weston_transmitter_seat *seat;
862 + struct weston_transmitter_surface *txs;
863 + struct wl_array *wl_key = (struct wl_array *)malloc(sizeof(struct wl_array));
865 + wl_key->size = keys->size;
866 + wl_key->alloc = keys->alloc;
867 + wl_key->data = keys->data;
869 + seat = container_of(seat_list->next,
870 + struct weston_transmitter_seat, link);
872 + wl_list_for_each(txs, &remote->surface_list, link)
874 + if (txs->wthp_surf == surface) {
875 + //transmitter_seat_keyboard_enter(seat, serial, txs, keys);
876 + transmitter_seat_keyboard_enter(seat, serial, txs, wl_key);
883 +keyboard_handle_leave(struct wthp_keyboard *wthp_keyboard,
885 + struct wthp_surface *surface)
887 + struct waltham_display *dpy =
888 + wth_object_get_user_data((struct wth_object *)wthp_keyboard);
889 + struct weston_transmitter_remote *remote = dpy->remote;
890 + struct wl_list *seat_list = &remote->seat_list;
891 + struct weston_transmitter_seat *seat;
892 + struct weston_transmitter_surface *txs;
894 + seat = container_of(seat_list->next,
895 + struct weston_transmitter_seat, link);
897 + wl_list_for_each(txs, &remote->surface_list, link)
899 + if (txs->wthp_surf == surface) {
900 + transmitter_seat_keyboard_leave(seat, serial, txs);
906 +keyboard_handle_key(struct wthp_keyboard *wthp_keyboard,
912 + struct waltham_display *dpy =
913 + wth_object_get_user_data((struct wth_object *)wthp_keyboard);
914 + struct weston_transmitter_remote *remote = dpy->remote;
915 + struct wl_list *seat_list = &remote->seat_list;
916 + struct weston_transmitter_seat *seat;
918 + seat = container_of(seat_list->next,
919 + struct weston_transmitter_seat, link);
921 + transmitter_seat_keyboard_key(seat, serial, time, key, state);
925 +keyboard_handle_modifiers(struct wthp_keyboard *wthp_keyboard,
927 + uint32_t mods_depressed,
928 + uint32_t mods_latched,
929 + uint32_t mods_locked,
932 + weston_log("keyboard_handle_modifiers\n");
936 +keyboard_handle_repeat_info(struct wthp_keyboard *wthp_keyboard,
940 + weston_log("keyboard_handle_repeat_info\n");
943 +static const struct wthp_keyboard_listener keyboard_listener = {
944 + keyboard_handle_keymap,
945 + keyboard_handle_enter,
946 + keyboard_handle_leave,
947 + keyboard_handle_key,
948 + keyboard_handle_modifiers,
949 + keyboard_handle_repeat_info
953 +touch_handle_down (struct wthp_touch * wthp_touch,
956 + struct wthp_surface * surface,
961 + struct waltham_display *dpy =
962 + wth_object_get_user_data((struct wth_object *)wthp_touch);
963 + struct weston_transmitter_remote *remote = dpy->remote;
964 + struct wl_list *seat_list = &remote->seat_list;
965 + struct weston_transmitter_seat *seat;
966 + struct weston_transmitter_surface *txs;
968 + seat = container_of(seat_list->next,
969 + struct weston_transmitter_seat, link);
971 + wl_list_for_each(txs, &remote->surface_list, link)
973 + if (txs->wthp_surf == surface) {
974 + transmitter_seat_touch_down(seat, serial, time,
981 +touch_handle_up (struct wthp_touch * wthp_touch,
986 + struct waltham_display *dpy =
987 + wth_object_get_user_data((struct wth_object *)wthp_touch);
988 + struct weston_transmitter_remote *remote = dpy->remote;
989 + struct wl_list *seat_list = &remote->seat_list;
990 + struct weston_transmitter_seat *seat;
992 + seat = container_of(seat_list->next,
993 + struct weston_transmitter_seat, link);
995 + transmitter_seat_touch_up(seat, serial, time, id);
999 +touch_handle_motion (struct wthp_touch * wthp_touch,
1005 + struct waltham_display *dpy =
1006 + wth_object_get_user_data((struct wth_object *)wthp_touch);
1007 + struct weston_transmitter_remote *remote = dpy->remote;
1008 + struct wl_list *seat_list = &remote->seat_list;
1009 + struct weston_transmitter_seat *seat;
1011 + seat = container_of(seat_list->next,
1012 + struct weston_transmitter_seat, link);
1014 + transmitter_seat_touch_motion(seat, time, id, x, y);
1019 +touch_handle_frame (struct wthp_touch * wthp_touch)
1021 + struct waltham_display *dpy =
1022 + wth_object_get_user_data((struct wth_object *)wthp_touch);
1023 + struct weston_transmitter_remote *remote = dpy->remote;
1024 + struct wl_list *seat_list = &remote->seat_list;
1025 + struct weston_transmitter_seat *seat;
1027 + seat = container_of(seat_list->next,
1028 + struct weston_transmitter_seat, link);
1030 + transmitter_seat_touch_frame(seat);
1034 +touch_handle_cancel (struct wthp_touch * wthp_touch)
1036 + struct waltham_display *dpy =
1037 + wth_object_get_user_data((struct wth_object *)wthp_touch);
1038 + struct weston_transmitter_remote *remote = dpy->remote;
1039 + struct wl_list *seat_list = &remote->seat_list;
1040 + struct weston_transmitter_seat *seat;
1042 + seat = container_of(seat_list->next,
1043 + struct weston_transmitter_seat, link);
1045 + transmitter_seat_touch_cancel(seat);
1049 +static const struct wthp_touch_listener touch_listener = {
1050 + touch_handle_down,
1052 + touch_handle_motion,
1053 + touch_handle_frame,
1054 + touch_handle_cancel
1058 +seat_capabilities(struct wthp_seat *wthp_seat,
1059 + enum wthp_seat_capability caps)
1061 + struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)wthp_seat);
1063 + weston_log("seat_capabilities\n");
1065 + if ((caps & WTHP_SEAT_CAPABILITY_POINTER) && !dpy->pointer)
1067 + weston_log("WTHP_SEAT_CAPABILITY_POINTER\n");
1068 + dpy->pointer = wthp_seat_get_pointer(dpy->seat);
1069 + wthp_pointer_set_listener(dpy->pointer, &pointer_listener, dpy);
1071 + if ((caps & WTHP_SEAT_CAPABILITY_KEYBOARD) && !dpy->keyboard)
1073 + weston_log("WTHP_SEAT_CAPABILITY_KEYBOARD\n");
1074 + dpy->keyboard = wthp_seat_get_keyboard(dpy->seat);
1075 + wthp_keyboard_set_listener(dpy->keyboard, &keyboard_listener, dpy);
1077 + if ((caps & WTHP_SEAT_CAPABILITY_TOUCH) && !dpy->touch)
1079 + weston_log("WTHP_SEAT_CAPABILITY_TOUCH\n");
1080 + dpy->touch = wthp_seat_get_touch(dpy->seat);
1081 + wthp_touch_set_listener(dpy->touch, &touch_listener, dpy);
1086 transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1088 struct weston_transmitter_seat *seat = NULL;
1090 + struct weston_seat *weston_seat = NULL;
1092 seat = zalloc(sizeof *seat);
1094 @@ -493,6 +1209,24 @@ transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1099 + if (wl_list_empty(&remote->transmitter->compositor->seat_list)) {
1100 + weston_seat = zalloc(sizeof *weston_seat);
1104 + weston_seat_init(weston_seat, remote->transmitter->compositor, name);
1105 + seat->base = weston_seat;
1106 + weston_log("Transmitter created seat=%p \n", &seat->base);
1108 + wl_list_for_each(weston_seat, &remote->transmitter->compositor->seat_list, link) {
1109 + weston_log("Transmitter weston_seat %p\n", weston_seat);
1110 + seat->base = weston_seat;
1116 weston_seat_init(&seat->base, remote->transmitter->compositor, name);
1119 @@ -515,9 +1249,12 @@ transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1121 weston_log("Transmitter created seat=%p '%s'\n",
1122 &seat->base, seat->base.seat_name);
1125 /* XXX: mirror remote capabilities */
1126 transmitter_seat_create_pointer(seat);
1127 + transmitter_seat_create_keyboard(seat);
1128 + transmitter_seat_create_touch(seat);
1130 wl_list_insert(&remote->seat_list, &seat->link);
1132 @@ -582,7 +1319,7 @@ transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
1134 if (!seat->pointer_timer) {
1135 /* schedule timer for motion */
1136 - loop = wl_display_get_event_loop(seat->base.compositor->wl_display);
1137 + loop = wl_display_get_event_loop(seat->base->compositor->wl_display);
1138 seat->pointer_timer = wl_event_loop_add_timer(loop,
1139 fake_pointer_timer_handler, seat);
1140 wl_event_source_timer_update(seat->pointer_timer, 100);
1141 diff --git a/transmitter/output.c b/transmitter/output.c
1142 index 6a78721..a3f8ed1 100644
1143 --- a/transmitter/output.c
1144 +++ b/transmitter/output.c
1147 * Copyright (C) 2016 DENSO CORPORATION
1148 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
1150 * Permission is hereby granted, free of charge, to any person obtaining
1151 * a copy of this software and associated documentation files (the
1152 @@ -73,7 +74,7 @@ make_model(struct weston_transmitter_remote *remote, int name)
1156 - if (asprintf(&str, "transmitter-%s-%d", remote->addr, name) < 0)
1157 + if (asprintf(&str, "transmitter-%s:%s-%d", remote->addr, remote->port, name) < 0)
1161 @@ -124,8 +125,6 @@ free_mode_list(struct wl_list *mode_list)
1163 transmitter_output_destroy(struct weston_transmitter_output *output)
1165 - weston_log("Transmitter destroying output '%s'\n", output->base.name);
1167 wl_list_remove(&output->link);
1169 free_mode_list(&output->base.mode_list);
1170 @@ -145,46 +144,150 @@ transmitter_output_destroy_(struct weston_output *base)
1171 transmitter_output_destroy(output);
1176 transmitter_start_repaint_loop(struct weston_output *base)
1178 - weston_log("%s(%s)\n", __func__, base->name);
1179 + struct timespec ts;
1180 + struct weston_transmitter_output *output = to_transmitter_output(base);
1182 + weston_compositor_read_presentation_clock(output->base.compositor, &ts);
1183 + weston_output_finish_frame(&output->base, &ts, 0);
1187 +transmitter_check_output(struct weston_transmitter_surface *txs,
1188 + struct weston_compositor *compositor)
1190 + struct weston_output *def_output = container_of(compositor->output_list.next,
1191 + struct weston_output, link);
1192 + struct weston_view *view;
1194 + wl_list_for_each_reverse(view, &compositor->view_list, link) {
1195 + if (view->output == def_output) {
1196 + if (view->surface == txs->surface)
1205 transmitter_output_repaint(struct weston_output *base,
1206 pixman_region32_t *damage)
1208 - weston_log("%s(%s)\n", __func__, base->name);
1209 + struct weston_transmitter_output* output = to_transmitter_output(base);
1210 + struct weston_transmitter_remote* remote = output->remote;
1211 + struct weston_transmitter* txr = remote->transmitter;
1212 + struct weston_transmitter_api* transmitter_api =
1213 + weston_get_transmitter_api(txr->compositor);
1214 + struct weston_transmitter_surface* txs;
1215 + struct weston_compositor *compositor = base->compositor;
1216 + struct weston_view *view;
1217 + bool found_output = false;
1219 + if (!output->from_frame_signal)
1222 + output->from_frame_signal = false;
1225 + * Pick up weston_view in transmitter_output and check weston_view's surface
1226 + * If the surface hasn't been conbined to weston_transmitter_surface,
1227 + * then call push_to_remote.
1228 + * If the surface has already been combined, call gather_state.
1230 + if (wl_list_empty(&compositor->view_list))
1233 + wl_list_for_each_reverse(view, &compositor->view_list, link) {
1234 + bool found_surface = false;
1235 + if (view->output == &output->base) {
1236 + found_output = true;
1237 + wl_list_for_each(txs, &remote->surface_list, link) {
1238 + if (txs->surface == view->surface) {
1239 + found_surface = true;
1240 + if (!transmitter_check_output(txs, compositor))
1243 + if (!txs->wthp_surf)
1244 + transmitter_api->surface_push_to_remote
1245 + (view->surface, remote, NULL);
1246 + transmitter_api->surface_gather_state(txs);
1250 + if (!found_surface)
1251 + transmitter_api->surface_push_to_remote(view->surface,
1255 + if (!found_output)
1262 + transmitter_start_repaint_loop(base);
1268 +transmitter_output_enable(struct weston_output *base)
1270 + struct weston_transmitter_output *output = to_transmitter_output(base);
1273 + output->base.assign_planes = NULL;
1274 + output->base.set_backlight = NULL;
1275 + output->base.set_dpms = NULL;
1276 + output->base.switch_mode = NULL;
1280 +transmitter_output_frame_handler(struct wl_listener *listener, void *data)
1282 + struct weston_transmitter_output *output;
1285 + output = container_of(listener, struct weston_transmitter_output,
1287 + output->from_frame_signal = true;
1289 + ret = transmitter_output_repaint(&output->base, NULL);
1293 -transmitter_remote_create_output(
1294 - struct weston_transmitter_remote *remote,
1295 - const struct weston_transmitter_output_info *info)
1296 +transmitter_remote_create_output(struct weston_transmitter_remote *remote,
1297 + const struct weston_transmitter_output_info *info)
1299 struct weston_transmitter_output *output;
1300 + struct weston_transmitter *txr = remote->transmitter;
1301 + struct weston_output *def_output;
1303 output = zalloc(sizeof *output);
1307 + output->parent.draw_initial_frame = true;
1309 output->base.subpixel = info->subpixel;
1311 output->base.name = make_model(remote, 1);
1312 output->base.make = strdup(WESTON_TRANSMITTER_OUTPUT_MAKE);
1313 output->base.model = make_model(remote, 1);
1314 output->base.serial_number = strdup("0");
1316 + /* x and y is fake value */
1317 wl_list_init(&output->base.mode_list);
1318 if (make_mode_list(&output->base.mode_list, info) < 0)
1321 output->base.current_mode = get_current_mode(&output->base.mode_list);
1322 + output->base.height = output->base.current_mode->height;
1323 + output->base.width = output->base.current_mode->width;
1324 /* WL_OUTPUT_MODE_CURRENT already set */
1326 weston_output_init(&output->base, remote->transmitter->compositor);
1329 @@ -200,7 +303,7 @@ transmitter_remote_create_output(
1330 * for this output, since we must not involve input device management
1331 * or color management or any kind of local management.
1334 + output->base.enable = transmitter_output_enable;
1335 output->base.start_repaint_loop = transmitter_start_repaint_loop;
1336 output->base.repaint = transmitter_output_repaint;
1337 output->base.destroy = transmitter_output_destroy_;
1338 @@ -212,13 +315,19 @@ transmitter_remote_create_output(
1340 output->base.native_mode = output->base.current_mode;
1341 output->base.native_scale = output->base.current_scale;
1342 + output->base.scale = 1;
1343 + output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1345 output->remote = remote;
1346 wl_list_insert(&remote->output_list, &output->link);
1348 - weston_log("Transmitter created output '%s': %s, %s, %s\n",
1349 - output->base.name, output->base.make, output->base.model,
1350 - output->base.serial_number);
1351 + weston_output_enable(&output->base);
1353 + output->frame_listener.notify = transmitter_output_frame_handler;
1354 + def_output = container_of(txr->compositor->output_list.next,
1355 + struct weston_output, link);
1356 + wl_signal_add(&def_output->frame_signal, &output->frame_listener);
1357 + output->from_frame_signal = false;
1361 diff --git a/transmitter/plugin.c b/transmitter/plugin.c
1362 index c5e56d3..1ebd1ef 100644
1363 --- a/transmitter/plugin.c
1364 +++ b/transmitter/plugin.c
1367 * Copyright (C) 2016 DENSO CORPORATION
1368 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
1370 * Permission is hereby granted, free of charge, to any person obtaining
1371 * a copy of this software and associated documentation files (the
1373 #include "helpers.h"
1374 #include "timespec-util.h"
1376 +#include "compositor/weston.h"
1378 #include "transmitter_api.h"
1379 +#include "plugin-registry.h"
1380 +#include "ivi-shell/ivi-layout-export.h"
1384 +#include <sys/epoll.h>
1385 +#include <sys/timerfd.h>
1386 +#include <waltham-object.h>
1387 +#include <waltham-client.h>
1388 +#include <waltham-connection.h>
1390 +#define MAX_EPOLL_WATCHES 2
1391 +#define ESTABLISH_CONNECTION_PERIOD 2000
1392 +#define RETRY_CONNECTION_PERIOD 5000
1394 /* XXX: all functions and variables with a name, and things marked with a
1395 * comment, containing the word "fake" are mockups that need to be
1396 @@ -69,63 +85,6 @@ transmitter_surface_ivi_resize(struct weston_transmitter_surface *txs,
1397 txs->resize_handler(txs->resize_handler_data, width, height);
1401 -frame_callback_handler(void *data) /* fake */
1403 - struct weston_transmitter_surface *txs = data;
1404 - struct weston_frame_callback *cb, *cnext;
1405 - struct weston_output *output;
1406 - struct weston_compositor *compositor;
1407 - uint32_t frame_time;
1408 - uint32_t presented_flags;
1409 - int32_t refresh_nsec;
1410 - struct timespec stamp;
1412 - compositor = txs->remote->transmitter->compositor;
1413 - output = txs->sync_output;
1415 - /* wl_surface.enter should arrive before any frame callbacks,
1416 - * but remote might send frame callbacks for non-visible too.
1422 - frame_time = weston_compositor_get_time();
1424 - wl_list_for_each_safe(cb, cnext, &txs->frame_callback_list, link) {
1425 - wl_callback_send_done(cb->resource, frame_time);
1426 - wl_resource_destroy(cb->resource);
1429 - presented_flags = 0;
1430 - refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
1431 - /* XXX: waaahhhahaa */
1432 - weston_compositor_read_presentation_clock(compositor, &stamp);
1433 - weston_presentation_feedback_present_list(&txs->feedback_list,
1434 - output, refresh_nsec, &stamp,
1442 -fake_frame_callback(struct weston_transmitter_surface *txs)
1444 - struct weston_transmitter *txr = txs->remote->transmitter;
1445 - struct wl_event_loop *loop;
1447 - if (!txs->frame_timer) {
1448 - loop = wl_display_get_event_loop(txr->compositor->wl_display);
1449 - txs->frame_timer =
1450 - wl_event_loop_add_timer(loop,
1451 - frame_callback_handler, txs);
1454 - wl_event_source_timer_update(txs->frame_timer, 85);
1458 transmitter_surface_configure(struct weston_transmitter_surface *txs,
1459 int32_t dx, int32_t dy)
1460 @@ -139,37 +98,75 @@ transmitter_surface_configure(struct weston_transmitter_surface *txs,
1464 -transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
1465 +buffer_send_complete(struct wthp_buffer *b, uint32_t serial)
1467 - weston_log("Transmitter: update surface %p (%d, %d), %d cb\n",
1468 - txs->surface, txs->attach_dx, txs->attach_dy,
1469 - wl_list_length(&txs->surface->frame_callback_list));
1471 - wl_list_insert_list(&txs->frame_callback_list,
1472 - &txs->surface->frame_callback_list);
1473 - wl_list_init(&txs->surface->frame_callback_list);
1475 - wl_list_insert_list(&txs->feedback_list, &txs->surface->feedback_list);
1476 - wl_list_init(&txs->surface->feedback_list);
1478 - /* TODO: transmit surface state to remote */
1480 - txs->attach_dx = 0;
1481 - txs->attach_dy = 0;
1483 + wthp_buffer_destroy(b);
1486 -/** weston_surface apply state signal handler */
1487 +static const struct wthp_buffer_listener buffer_listener = {
1488 + buffer_send_complete
1492 -transmitter_surface_apply_state(struct wl_listener *listener, void *data)
1493 +transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
1495 - struct weston_transmitter_surface *txs =
1496 - container_of(listener, struct weston_transmitter_surface,
1497 - apply_state_listener);
1499 - assert(data == NULL);
1500 + struct weston_transmitter_remote *remote = txs->remote;
1501 + struct waltham_display *dpy = remote->display;
1503 - transmitter_surface_gather_state(txs);
1504 - fake_frame_callback(txs);
1505 + if(!dpy->running) {
1506 + if(remote->status != WESTON_TRANSMITTER_CONNECTION_DISCONNECTED) {
1507 + remote->status = WESTON_TRANSMITTER_CONNECTION_DISCONNECTED;
1508 + wl_event_source_timer_update(remote->retry_timer, 1);
1512 + /* TODO: transmit surface state to remote */
1513 + /* The buffer must be transmitted to remote side */
1516 + struct weston_surface *surf = txs->surface;
1517 + struct weston_compositor *comp = surf->compositor;
1518 + int32_t width = 100;
1519 + int32_t height = 100;
1524 +// stride = surf->width * (PIXMAN_FORMAT_BPP(comp->read_format) / 8);
1525 + stride = width * (PIXMAN_FORMAT_BPP(comp->read_format) / 8);
1526 +// weston_log("width %d\n", surf->width);
1527 +// weston_log("height %d\n", surf->height);
1528 +// weston_log("stride %d\n", stride);
1529 + pixels = malloc(stride * height);
1531 + ret = weston_surface_copy_content(surf, pixels,
1532 + (stride * height), 0, 0,
1535 + fprintf(stderr, "failed to get surface content\n");
1537 + /* fake sending buffer */
1538 + txs->wthp_buf = wthp_blob_factory_create_buffer(remote->display->blob_factory,
1539 + (stride * height),
1544 + PIXMAN_FORMAT_BPP(comp->read_format));
1546 + wthp_buffer_set_listener(txs->wthp_buf, &buffer_listener, txs);
1548 + wthp_surface_attach(txs->wthp_surf, txs->wthp_buf, txs->attach_dx, txs->attach_dy);
1549 + //wthp_surface_damage(txs->wthp_surf, txs->attach_dx, txs->attach_dy, surf->width, surf->height);
1550 + wthp_surface_damage(txs->wthp_surf, txs->attach_dx, txs->attach_dy, width, height);
1551 + wthp_surface_commit(txs->wthp_surf);
1553 + wth_connection_flush(remote->display->connection);
1555 + txs->attach_dx = 0;
1556 + txs->attach_dy = 0;
1560 /** Mark the weston_transmitter_surface dead.
1561 @@ -181,8 +178,7 @@ transmitter_surface_apply_state(struct wl_listener *listener, void *data)
1563 transmitter_surface_zombify(struct weston_transmitter_surface *txs)
1565 - struct weston_frame_callback *framecb, *cnext;
1567 + struct weston_transmitter_remote *remote;
1568 /* may be called multiple times */
1571 @@ -190,20 +186,17 @@ transmitter_surface_zombify(struct weston_transmitter_surface *txs)
1572 wl_signal_emit(&txs->destroy_signal, txs);
1574 wl_list_remove(&txs->surface_destroy_listener.link);
1575 - weston_log("Transmitter unbound surface %p.\n", txs->surface);
1576 txs->surface = NULL;
1578 wl_list_remove(&txs->sync_output_destroy_listener.link);
1579 - wl_list_remove(&txs->apply_state_listener.link);
1581 - if (txs->map_timer)
1582 - wl_event_source_remove(txs->map_timer);
1583 - if (txs->frame_timer)
1584 - wl_event_source_remove(txs->frame_timer);
1586 - weston_presentation_feedback_discard_list(&txs->feedback_list);
1587 - wl_list_for_each_safe(framecb, cnext, &txs->frame_callback_list, link)
1588 - wl_resource_destroy(framecb->resource);
1589 + remote = txs->remote;
1590 + if (!remote->display->compositor)
1591 + weston_log("remote->compositor is NULL\n");
1592 + if (txs->wthp_surf)
1593 + wthp_surface_destroy(txs->wthp_surf);
1594 + if (txs->wthp_ivi_surface)
1595 + wthp_ivi_surface_destroy(txs->wthp_ivi_surface);
1597 /* In case called from destroy_transmitter() */
1599 @@ -231,25 +224,6 @@ transmitter_surface_destroyed(struct wl_listener *listener, void *data)
1600 transmitter_surface_zombify(txs);
1603 -static struct weston_transmitter_surface *
1604 -transmitter_surface_get(struct weston_surface *ws)
1606 - struct wl_listener *listener;
1607 - struct weston_transmitter_surface *txs;
1609 - listener = wl_signal_get(&ws->destroy_signal,
1610 - transmitter_surface_destroyed);
1615 - txs = container_of(listener, struct weston_transmitter_surface,
1616 - surface_destroy_listener);
1617 - assert(ws == txs->surface);
1623 sync_output_destroy_handler(struct wl_listener *listener, void *data)
1625 @@ -265,84 +239,48 @@ sync_output_destroy_handler(struct wl_listener *listener, void *data)
1629 -fake_input(struct weston_transmitter_surface *txs)
1631 - struct wl_list *seat_list = &txs->remote->seat_list;
1632 - struct weston_transmitter_seat *seat;
1634 - assert(wl_list_length(seat_list) == 1);
1635 - seat = container_of(seat_list->next,
1636 - struct weston_transmitter_seat, link);
1638 - transmitter_seat_fake_pointer_input(seat, txs);
1641 -/* fake receiving wl_surface.enter(output) */
1643 -map_timer_handler(void *data)
1645 - struct weston_transmitter_surface *txs = data;
1646 - struct weston_transmitter_output *output;
1648 - assert(!wl_list_empty(&txs->remote->output_list));
1650 - output = container_of(txs->remote->output_list.next,
1651 - struct weston_transmitter_output, link);
1653 - txs->sync_output = &output->base;
1654 - txs->sync_output_destroy_listener.notify = sync_output_destroy_handler;
1655 - wl_list_remove(&txs->sync_output_destroy_listener.link);
1656 - wl_signal_add(&txs->sync_output->destroy_signal,
1657 - &txs->sync_output_destroy_listener);
1659 - weston_surface_force_output(txs->surface, txs->sync_output);
1661 - weston_log("Transmitter: surface %p entered output %s\n",
1662 - txs->surface, txs->sync_output->name);
1664 - fake_frame_callback(txs);
1670 -/* Fake a delay for the remote end to map the surface to an output */
1672 -fake_output_mapping(struct weston_transmitter_surface *txs)
1674 - struct weston_transmitter *txr = txs->remote->transmitter;
1675 - struct wl_event_loop *loop;
1677 - loop = wl_display_get_event_loop(txr->compositor->wl_display);
1678 - txs->map_timer = wl_event_loop_add_timer(loop, map_timer_handler, txs);
1679 - wl_event_source_timer_update(txs->map_timer, 400);
1682 -/* Fake getting "connection established" from the content streamer. */
1684 -fake_stream_opening_handler(void *data)
1686 - struct weston_transmitter_surface *txs = data;
1688 - /* ...once the connection is up: */
1689 - txs->status = WESTON_TRANSMITTER_STREAM_LIVE;
1690 - wl_signal_emit(&txs->stream_status_signal, txs);
1692 - /* need to create the surface on the remote and set all state */
1693 - transmitter_surface_gather_state(txs);
1695 - fake_output_mapping(txs);
1698 -/* Fake a callback from content streamer. */
1700 -fake_stream_opening(struct weston_transmitter_surface *txs)
1701 +transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs)
1703 - struct weston_transmitter *txr = txs->remote->transmitter;
1704 - struct wl_event_loop *loop;
1706 - loop = wl_display_get_event_loop(txr->compositor->wl_display);
1707 - wl_event_loop_add_idle(loop, fake_stream_opening_handler, txs);
1708 + struct weston_transmitter_remote *remote = txs->remote;
1709 + struct waltham_display *dpy = remote->display;
1710 + struct weston_surface *ws;
1711 + struct ivi_layout_surface **pp_surface = NULL;
1712 + struct ivi_layout_surface *ivi_surf = NULL;
1713 + int32_t surface_length = 0;
1717 + ret = txs->lyt->get_surfaces(&surface_length, &pp_surface);
1719 + weston_log("No ivi_surface\n");
1721 + ws = txs->surface;
1723 + for(i = 0; i < surface_length; i++) {
1724 + ivi_surf = pp_surface[i];
1725 + if (ivi_surf->surface == ws) {
1726 + assert(txs->surface);
1727 + if (!txs->surface)
1730 + weston_log("no content in waltham_display\n");
1731 + if(!dpy->compositor)
1732 + weston_log("no content in compositor object\n");
1734 + weston_log("no content in seat object\n");
1735 + if(!dpy->application)
1736 + weston_log("no content in ivi-application object\n");
1738 + txs->wthp_ivi_surface = wthp_ivi_application_surface_create
1739 + (dpy->application, ivi_surf->id_surface, txs->wthp_surf);
1740 + weston_log("surface ID %d\n", ivi_surf->id_surface);
1741 + if(!txs->wthp_ivi_surface){
1742 + weston_log("Failed to create txs->ivi_surf\n");
1747 + pp_surface = NULL;
1750 static struct weston_transmitter_surface *
1751 @@ -350,39 +288,58 @@ transmitter_surface_push_to_remote(struct weston_surface *ws,
1752 struct weston_transmitter_remote *remote,
1753 struct wl_listener *stream_status)
1755 + struct weston_transmitter *txr = remote->transmitter;
1756 struct weston_transmitter_surface *txs;
1757 + bool found = false;
1759 - if (transmitter_surface_get(ws)) {
1760 - weston_log("Transmitter: surface %p already bound.\n", ws);
1761 + if (remote->status != WESTON_TRANSMITTER_CONNECTION_READY)
1766 - txs = zalloc(sizeof (*txs));
1769 + wl_list_for_each(txs, &remote->surface_list, link) {
1770 + if (txs->surface == ws) {
1776 - txs->remote = remote;
1777 - wl_signal_init(&txs->destroy_signal);
1778 - wl_list_insert(&remote->surface_list, &txs->link);
1781 + txs = zalloc(sizeof (*txs));
1785 - txs->status = WESTON_TRANSMITTER_STREAM_INITIALIZING;
1786 - wl_signal_init(&txs->stream_status_signal);
1787 - wl_signal_add(&txs->stream_status_signal, stream_status);
1788 + txs->remote = remote;
1789 + wl_signal_init(&txs->destroy_signal);
1790 + wl_list_insert(&remote->surface_list, &txs->link);
1792 - txs->surface = ws;
1793 - txs->surface_destroy_listener.notify = transmitter_surface_destroyed;
1794 - wl_signal_add(&ws->destroy_signal, &txs->surface_destroy_listener);
1795 + txs->status = WESTON_TRANSMITTER_STREAM_INITIALIZING;
1796 + wl_signal_init(&txs->stream_status_signal);
1797 + if (stream_status)
1798 + wl_signal_add(&txs->stream_status_signal, stream_status);
1800 - txs->apply_state_listener.notify = transmitter_surface_apply_state;
1801 - wl_signal_add(&ws->apply_state_signal, &txs->apply_state_listener);
1802 + txs->surface = ws;
1803 + txs->surface_destroy_listener.notify = transmitter_surface_destroyed;
1804 + wl_signal_add(&ws->destroy_signal, &txs->surface_destroy_listener);
1806 - wl_list_init(&txs->sync_output_destroy_listener.link);
1807 + wl_list_init(&txs->sync_output_destroy_listener.link);
1809 - wl_list_init(&txs->frame_callback_list);
1810 - wl_list_init(&txs->feedback_list);
1811 + wl_list_init(&txs->frame_callback_list);
1812 + wl_list_init(&txs->feedback_list);
1814 + txs->lyt = weston_plugin_api_get(txr->compositor,
1815 + IVI_LAYOUT_API_NAME, sizeof(txs->lyt));
1818 /* TODO: create the content stream connection... */
1819 - fake_stream_opening(txs);
1820 + if (!remote->display->compositor)
1821 + weston_log("remote->compositor is NULL\n");
1822 + if (!txs->wthp_surf) {
1823 + weston_log("txs->wthp_surf is NULL\n");
1824 + txs->wthp_surf = wthp_compositor_create_surface(remote->display->compositor);
1825 + transmitter_surface_set_ivi_id(txs);
1830 @@ -393,17 +350,53 @@ transmitter_surface_get_stream_status(struct weston_transmitter_surface *txs)
1835 -conn_timer_handler(void *data) /* fake */
1837 +/* The server advertises a global interface.
1838 + * We can store the ad for later and/or bind to it immediately
1840 + * We also need to keep track of the globals we bind to, so that
1841 + * global_remove can be handled properly (not implemented).
1844 +registry_handle_global(struct wthp_registry *registry,
1846 + const char *interface,
1849 - struct weston_transmitter_remote *remote = data;
1850 + struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)registry);
1852 + if (strcmp(interface, "wthp_compositor") == 0) {
1853 + assert(!dpy->compositor);
1854 + dpy->compositor = (struct wthp_compositor *)wthp_registry_bind(registry, name, interface, 1);
1855 + /* has no events to handle */
1856 + } else if (strcmp(interface, "wthp_blob_factory") == 0) {
1857 + assert(!dpy->blob_factory);
1858 + dpy->blob_factory = (struct wthp_blob_factory *)wthp_registry_bind(registry, name, interface, 1);
1859 + /* has no events to handle */
1860 + } else if (strcmp(interface, "wthp_seat") == 0) {
1861 + assert(!dpy->seat);
1862 + dpy->seat = (struct wthp_seat *)wthp_registry_bind(registry, name, interface, 1);
1863 + wthp_seat_set_listener(dpy->seat, &seat_listener, dpy);
1864 + } else if (strcmp(interface, "wthp_ivi_application") == 0) {
1865 + assert(!dpy->application);
1866 + dpy->application = (struct wthp_ivi_application *)wthp_registry_bind(registry, name, interface, 1);
1870 +/* notify connection ready */
1872 +conn_ready_notify(struct wl_listener *l, void *data)
1874 + struct weston_transmitter_remote *remote =
1875 + container_of(l, struct weston_transmitter_remote,
1876 + establish_listener);
1877 struct weston_transmitter_output_info info = {
1878 WL_OUTPUT_SUBPIXEL_NONE,
1879 WL_OUTPUT_TRANSFORM_NORMAL,
1884 + strdup(remote->model),
1886 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
1888 @@ -411,52 +404,303 @@ conn_timer_handler(void *data) /* fake */
1893 - weston_log("Transmitter connected to %s.\n", remote->addr);
1894 - remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
1895 - wl_signal_emit(&remote->connection_status_signal, remote);
1897 - wl_event_source_remove(remote->conn_timer);
1898 - remote->conn_timer = NULL;
1900 + if(remote->width != 0) {
1901 + if(remote->height != 0) {
1902 + info.mode.width = remote->width;
1903 + info.mode.height = remote->height;
1906 /* Outputs and seats are dynamic, do not guarantee they are all
1907 * present when signalling connection status.
1909 transmitter_remote_create_output(remote, &info);
1910 transmitter_remote_create_seat(remote);
1914 +/* The server removed a global.
1915 + * We should destroy everything we created through that global,
1916 + * and destroy the objects we created by binding to it.
1917 + * The identification happens by global's name, so we need to keep
1918 + * track what names we bound.
1919 + * (not implemented)
1922 +registry_handle_global_remove(struct wthp_registry *wthp_registry,
1925 + if (wthp_registry)
1926 + wthp_registry_free(wthp_registry);
1929 +static const struct wthp_registry_listener registry_listener = {
1930 + registry_handle_global,
1931 + registry_handle_global_remove
1935 +connection_handle_data(struct watch *w, uint32_t events)
1937 + struct waltham_display *dpy = container_of(w, struct waltham_display, conn_watch);
1938 + struct weston_transmitter_remote *remote = dpy->remote;
1942 + if (!dpy->running) {
1943 + weston_log("This server is not running yet. %s:%s\n", remote->addr, remote->port);
1947 + if (events & EPOLLERR) {
1948 + weston_log("Connection errored out.\n");
1949 + dpy->running = false;
1954 + if (events & EPOLLOUT) {
1955 + /* Flush out again. If the flush completes, stop
1956 + * polling for writable as everything has been written.
1958 + ret = wth_connection_flush(dpy->connection);
1961 + if (events & EPOLLIN) {
1962 + /* Do not ignore EPROTO */
1963 + ret = wth_connection_read(dpy->connection);
1965 + weston_log("Connection read error %s:%s\n", remote->addr, remote->port);
1966 + perror("Connection read error\n");
1967 + dpy->running = false;
1968 + perror("EPOLL_CTL_DEL\n");
1974 + if (events & EPOLLHUP) {
1975 + fprintf(stderr, "Connection hung up.\n");
1976 + dpy->running = false;
1983 +waltham_mainloop(int fd, uint32_t mask, void *data)
1985 + struct weston_transmitter_remote *remote = data;
1990 + int running_display;
1991 + running_display = 0;
1993 + struct waltham_display *dpy = remote->display;
1994 + w = &dpy->conn_watch;
1998 + if (!dpy->connection)
2001 + if (!dpy->running)
2004 + running_display++;
2005 + /* Dispatch queued events. */
2007 + ret = wth_connection_dispatch(dpy->connection);
2009 + dpy->running = false;
2010 + if (!dpy->running)
2013 + /* Run any application idle tasks at this point. */
2014 + /* (nothing to run so far) */
2016 + /* Flush out buffered requests. If the Waltham socket is
2017 + * full, poll it for writable too, and continue flushing then.
2019 + ret = wth_connection_flush(dpy->connection);
2021 + if (0 < running_display) {
2022 + /* Waltham events only read in the callback, not dispatched,
2023 + * if the Waltham socket signalled readable. If it signalled
2024 + * writable, flush more. See connection_handle_data().
2028 + wl_event_source_remove(remote->source);
2029 + remote->source = wl_event_loop_add_fd(remote->transmitter->loop,
2030 + remote->display->conn_watch.fd,
2031 + WL_EVENT_READABLE,
2032 + waltham_mainloop, remote);
2038 +/* A one-off asynchronous open-coded roundtrip handler. */
2040 +bling_done(struct wthp_callback *cb, uint32_t arg)
2042 + fprintf(stderr, "...sync done.\n");
2044 + wthp_callback_free(cb);
2047 +static const struct wthp_callback_listener bling_listener = {
2052 +waltham_client_init(struct waltham_display *dpy)
2057 + * get server_address from controller (adrress is set to weston.ini)
2059 + dpy->connection = wth_connect_to_server(dpy->remote->addr, dpy->remote->port);
2060 + if(!dpy->connection) {
2064 + dpy->remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
2065 + wl_signal_emit(&dpy->remote->connection_status_signal, dpy->remote);
2068 + dpy->conn_watch.display = dpy;
2069 + dpy->conn_watch.cb = connection_handle_data;
2070 + dpy->conn_watch.fd = wth_connection_get_fd(dpy->connection);
2072 + dpy->display = wth_connection_get_display(dpy->connection);
2073 + /* wth_display_set_listener() is already done by waltham, as
2074 + * all the events are just control messaging.
2077 + /* Create a registry so that we will get advertisements of the
2078 + * interfaces implemented by the server.
2080 + dpy->registry = wth_display_get_registry(dpy->display);
2081 + wthp_registry_set_listener(dpy->registry, ®istry_listener, dpy);
2083 + /* Roundtrip ensures all globals' ads have been received. */
2084 + if (wth_connection_roundtrip(dpy->connection) < 0) {
2085 + fprintf(stderr, "Roundtrip failed.\n");
2089 + if (!dpy->compositor) {
2090 + fprintf(stderr, "Did not find wthp_compositor, quitting.\n");
2094 + /* A one-off asynchronous roundtrip, just for fun. */
2095 + fprintf(stderr, "sending wth_display.sync...\n");
2096 + dpy->bling = wth_display_sync(dpy->display);
2097 + wthp_callback_set_listener(dpy->bling, &bling_listener, dpy);
2099 + dpy->running = true;
2104 -static struct weston_transmitter_remote *
2105 -transmitter_connect_to_remote(struct weston_transmitter *txr,
2107 - struct wl_listener *status)
2109 +establish_timer_handler(void *data)
2111 - struct weston_transmitter_remote *remote;
2112 - struct wl_event_loop *loop;
2113 + struct weston_transmitter_remote *remote = data;
2116 - remote = zalloc(sizeof (*remote));
2119 + ret = waltham_client_init(remote->display);
2121 + wl_event_source_timer_update(remote->establish_timer,
2122 + ESTABLISH_CONNECTION_PERIOD);
2125 + remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
2126 + wl_signal_emit(&remote->connection_status_signal, remote);
2130 - remote->transmitter = txr;
2131 - wl_list_insert(&txr->remote_list, &remote->link);
2132 - remote->addr = strdup(addr);
2133 - remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2134 - wl_signal_init(&remote->connection_status_signal);
2135 - wl_signal_add(&remote->connection_status_signal, status);
2136 - wl_list_init(&remote->output_list);
2137 - wl_list_init(&remote->surface_list);
2138 - wl_list_init(&remote->seat_list);
2140 +init_globals(struct waltham_display *dpy)
2142 + dpy->compositor = NULL;
2143 + dpy->blob_factory = NULL;
2145 + dpy->application = NULL;
2146 + dpy->pointer = NULL;
2147 + dpy->keyboard = NULL;
2148 + dpy->touch = NULL;
2152 +disconnect_surface(struct weston_transmitter_remote *remote)
2154 + struct weston_transmitter_surface *txs;
2155 + wl_list_for_each(txs, &remote->surface_list, link)
2157 + free(txs->wthp_ivi_surface);
2158 + free(txs->wthp_surf);
2159 + txs->wthp_ivi_surface = NULL;
2160 + txs->wthp_surf = NULL;
2164 - /* XXX: actually start connecting */
2165 - weston_log("Transmitter connecting to %s...\n", addr);
2166 - /* fake it with a one second timer */
2167 - loop = wl_display_get_event_loop(txr->compositor->wl_display);
2168 - remote->conn_timer = wl_event_loop_add_timer(loop, conn_timer_handler,
2170 - wl_event_source_timer_update(remote->conn_timer, 1000);
2172 +retry_timer_handler(void *data)
2174 + struct weston_transmitter_remote *remote = data;
2175 + struct waltham_display *dpy = remote->display;
2179 + registry_handle_global_remove(dpy->registry, 1);
2180 + init_globals(dpy);
2181 + disconnect_surface(remote);
2182 + wl_event_source_timer_update(remote->establish_timer,
2183 + ESTABLISH_CONNECTION_PERIOD);
2188 + wl_event_source_timer_update(remote->retry_timer,
2189 + RETRY_CONNECTION_PERIOD);
2193 +static struct weston_transmitter_remote *
2194 +transmitter_connect_to_remote(struct weston_transmitter *txr)
2196 + struct weston_transmitter_remote *remote;
2197 + struct wl_event_loop *loop_est, *loop_retry;
2200 + wl_list_for_each_reverse(remote, &txr->remote_list, link) {
2201 + /* XXX: actually start connecting */
2203 + remote->display = zalloc(sizeof *remote->display);
2204 + if (!remote->display)
2206 + remote->display->remote = remote;
2207 + /* set connection establish timer */
2208 + loop_est = wl_display_get_event_loop(txr->compositor->wl_display);
2209 + remote->establish_timer =
2210 + wl_event_loop_add_timer(loop_est, establish_timer_handler, remote);
2211 + wl_event_source_timer_update(remote->establish_timer, 1);
2212 + /* set connection retry timer */
2213 + loop_retry = wl_display_get_event_loop(txr->compositor->wl_display);
2214 + remote->retry_timer =
2215 + wl_event_loop_add_timer(loop_retry, retry_timer_handler, remote);
2217 + weston_log("Fatal: Transmitter waltham connecting failed.\n");
2220 + wl_signal_emit(&remote->conn_establish_signal, NULL);
2225 @@ -481,10 +725,6 @@ transmitter_remote_destroy(struct weston_transmitter_remote *remote)
2226 * the desctruction order between the shell and Transmitter is
2229 - weston_log("Transmitter disconnecting from %s.\n", remote->addr);
2231 - if (remote->conn_timer)
2232 - wl_event_source_remove(remote->conn_timer);
2234 if (!wl_list_empty(&remote->surface_list))
2235 weston_log("Transmitter warning: surfaces remain in %s.\n",
2236 @@ -502,6 +742,8 @@ transmitter_remote_destroy(struct weston_transmitter_remote *remote)
2238 wl_list_remove(&remote->link);
2240 + wl_event_source_remove(remote->source);
2245 @@ -531,7 +773,6 @@ transmitter_compositor_destroyed(struct wl_listener *listener, void *data)
2247 wl_list_remove(&txr->remote_list);
2249 - weston_log("Transmitter terminating.\n");
2253 @@ -553,6 +794,19 @@ transmitter_get(struct weston_compositor *compositor)
2258 +transmitter_register_connection_status(struct weston_transmitter *txr,
2259 + struct wl_listener *connected_listener)
2261 + wl_signal_add(&txr->connected_signal, connected_listener);
2264 +static struct weston_surface *
2265 +transmitter_get_weston_surface(struct weston_transmitter_surface *txs)
2267 + return txs->surface;
2270 static const struct weston_transmitter_api transmitter_api_impl = {
2272 transmitter_connect_to_remote,
2273 @@ -562,20 +816,12 @@ static const struct weston_transmitter_api transmitter_api_impl = {
2274 transmitter_surface_get_stream_status,
2275 transmitter_surface_destroy,
2276 transmitter_surface_configure,
2277 + transmitter_surface_gather_state,
2278 + transmitter_register_connection_status,
2279 + transmitter_get_weston_surface,
2283 -transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs,
2286 - assert(txs->surface);
2287 - if (!txs->surface)
2290 - weston_log("%s(%p, %#x)\n", __func__, txs->surface, ivi_id);
2294 transmitter_surface_set_resize_callback(
2295 struct weston_transmitter_surface *txs,
2296 weston_transmitter_ivi_resize_handler_t cb,
2297 @@ -586,10 +832,108 @@ transmitter_surface_set_resize_callback(
2300 static const struct weston_transmitter_ivi_api transmitter_ivi_api_impl = {
2301 - transmitter_surface_set_ivi_id,
2302 transmitter_surface_set_resize_callback,
2306 +transmitter_create_remote(struct weston_transmitter *txr,
2307 + const char *model,
2310 + const char *width,
2311 + const char *height)
2313 + struct weston_transmitter_remote *remote;
2315 + remote = zalloc(sizeof (*remote));
2319 + remote->transmitter = txr;
2320 + wl_list_insert(&txr->remote_list, &remote->link);
2321 + remote->model = strdup(model);
2322 + remote->addr = strdup(addr);
2323 + remote->port = strdup(port);
2324 + remote->width = atoi(width);
2325 + remote->height = atoi(height);
2326 + remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2327 + wl_signal_init(&remote->connection_status_signal);
2328 + wl_list_init(&remote->output_list);
2329 + wl_list_init(&remote->surface_list);
2330 + wl_list_init(&remote->seat_list);
2331 + wl_signal_init(&remote->conn_establish_signal);
2332 + remote->establish_listener.notify = conn_ready_notify;
2333 + wl_signal_add(&remote->conn_establish_signal, &remote->establish_listener);
2339 +transmitter_get_server_config(struct weston_transmitter *txr)
2341 + struct weston_config *config = wet_get_config(txr->compositor);
2342 + struct weston_config_section *section;
2343 + const char *name = NULL;
2344 + char *model = NULL;
2345 + char *addr = NULL;
2346 + char *port = NULL;
2347 + char *width = '0';
2348 + char *height = '0';
2351 + section = weston_config_get_section(config, "remote", NULL, NULL);
2353 + while (weston_config_next_section(config, §ion, &name)) {
2354 + if (0 == strcmp(name, "remote-output")) {
2355 + if (0 != weston_config_section_get_string(section, "output-name",
2359 + if (0 != weston_config_section_get_string(section, "server-address",
2363 + if (0 != weston_config_section_get_string(section, "port",
2367 + if (0 != weston_config_section_get_string(section, "width",
2371 + if (0 != weston_config_section_get_string(section, "height",
2374 + ret = transmitter_create_remote(txr, model, addr,
2375 + port, width, height);
2377 + weston_log("Fatal: Transmitter create_remote failed.\n");
2384 +transmitter_post_init(void *data)
2386 + struct weston_transmitter *txr = data;
2387 + struct weston_transmitter_remote *remote;
2390 + weston_log("Transmitter disabled\n");
2392 + transmitter_get_server_config(txr);
2393 + transmitter_connect_to_remote(txr);
2395 + wl_list_for_each(remote, &txr->remote_list, link) {
2396 + remote->source = wl_event_loop_add_fd(txr->loop,
2397 + remote->display->conn_watch.fd,
2398 + WL_EVENT_READABLE,
2399 + waltham_mainloop, remote);
2405 wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[])
2407 @@ -628,6 +972,9 @@ wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[])
2409 weston_log("Transmitter initialized.\n");
2411 + txr->loop = wl_display_get_event_loop(compositor->wl_display);
2412 + wl_event_loop_add_idle(txr->loop, transmitter_post_init, txr);
2417 diff --git a/transmitter/plugin.h b/transmitter/plugin.h
2418 index 710b543..48f49b8 100644
2419 --- a/transmitter/plugin.h
2420 +++ b/transmitter/plugin.h
2423 * Copyright (C) 2016 DENSO CORPORATION
2424 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
2426 * Permission is hereby granted, free of charge, to any person obtaining
2427 * a copy of this software and associated documentation files (the
2428 @@ -32,33 +33,109 @@
2432 +#include <wayland-client.h>
2434 #include "compositor.h"
2435 #include "transmitter_api.h"
2436 +#include "ivi-shell/ivi-layout-export.h"
2438 +#include <waltham-client.h>
2441 +struct waltham_display;
2443 +enum wthp_seat_capability {
2445 + * the seat has pointer devices
2447 + WTHP_SEAT_CAPABILITY_POINTER = 1,
2449 + * the seat has one or more keyboards
2451 + WTHP_SEAT_CAPABILITY_KEYBOARD = 2,
2453 + * the seat has touch devices
2455 + WTHP_SEAT_CAPABILITY_TOUCH = 4,
2458 +/* epoll structure */
2460 + struct waltham_display *display;
2462 + void (*cb)(struct watch *w, uint32_t events);
2465 +struct waltham_display {
2466 + struct wth_connection *connection;
2467 + struct watch conn_watch;
2468 + struct wth_display *display;
2472 + struct wthp_registry *registry;
2474 + struct wthp_callback *bling;
2476 + struct wthp_compositor *compositor;
2477 + struct wthp_blob_factory *blob_factory;
2478 + struct wthp_seat *seat;
2479 + struct wthp_pointer *pointer;
2480 + struct wthp_keyboard *keyboard;
2481 + struct wthp_touch *touch;
2482 + struct wthp_ivi_application *application;
2483 + struct wtimer *fiddle_timer;
2485 + struct weston_transmitter_remote *remote;
2490 +/* a timerfd based timer */
2492 + struct watch watch;
2493 + void (*func)(struct wtimer *, void *);
2497 struct weston_transmitter {
2498 struct weston_compositor *compositor;
2499 struct wl_listener compositor_destroy_listener;
2501 struct wl_list remote_list; /* transmitter_remote::link */
2503 + struct wl_listener stream_listener;
2504 + struct wl_signal connected_signal;
2505 + struct wl_event_loop *loop;
2508 struct weston_transmitter_remote {
2509 struct weston_transmitter *transmitter;
2510 struct wl_list link;
2518 enum weston_transmitter_connection_status status;
2519 struct wl_signal connection_status_signal;
2520 + struct wl_signal conn_establish_signal;
2522 struct wl_list output_list; /* weston_transmitter_output::link */
2523 struct wl_list surface_list; /* weston_transmitter_surface::link */
2524 struct wl_list seat_list; /* weston_transmitter_seat::link */
2526 - struct wl_event_source *conn_timer; /* fake */
2527 + struct wl_listener establish_listener;
2529 + struct wl_event_source *establish_timer; /* for establish connection */
2530 + struct wl_event_source *retry_timer; /* for retry connection */
2532 + struct waltham_display *display; /* waltham */
2533 + struct wl_event_source *source;
2537 struct weston_transmitter_surface {
2538 struct weston_transmitter_remote *remote;
2539 struct wl_list link; /* weston_transmitter_remote::surface_list */
2540 @@ -69,7 +146,7 @@ struct weston_transmitter_surface {
2542 struct weston_surface *surface;
2543 struct wl_listener surface_destroy_listener;
2544 - struct wl_listener apply_state_listener;
2545 + const struct ivi_layout_interface *lyt;
2547 weston_transmitter_ivi_resize_handler_t resize_handler;
2548 void *resize_handler_data;
2549 @@ -77,13 +154,17 @@ struct weston_transmitter_surface {
2550 struct weston_output *sync_output;
2551 struct wl_listener sync_output_destroy_listener;
2553 - struct wl_event_source *map_timer; /* fake */
2554 - struct wl_event_source *frame_timer; /* fake */
2556 int32_t attach_dx; /**< wl_surface.attach(buffer, dx, dy) */
2557 int32_t attach_dy; /**< wl_surface.attach(buffer, dx, dy) */
2558 struct wl_list frame_callback_list; /* weston_frame_callback::link */
2559 struct wl_list feedback_list; /* weston_presentation_feedback::link */
2562 + struct wthp_surface *wthp_surf;
2563 + struct wthp_blob_factory *wthp_blob;
2564 + struct wthp_buffer *wthp_buf;
2565 + struct wthp_ivi_surface *wthp_ivi_surface;
2566 + struct wthp_ivi_application *wthp_ivi_application;
2569 struct weston_transmitter_output_info {
2570 @@ -103,12 +184,28 @@ struct weston_transmitter_output_info {
2571 struct weston_transmitter_output {
2572 struct weston_output base;
2575 + bool draw_initial_frame;
2576 + struct wl_surface *surface;
2577 + struct wl_output *output;
2578 + struct wl_display *display;
2579 + int configure_width, configure_height;
2580 + bool wait_for_configure;
2583 struct weston_transmitter_remote *remote;
2584 struct wl_list link; /* weston_transmitter_remote::output_list */
2586 + struct frame *frame;
2588 + struct wl_callback *frame_cb;
2589 + struct wl_listener frame_listener;
2591 + bool from_frame_signal;
2594 struct weston_transmitter_seat {
2595 - struct weston_seat base;
2596 + struct weston_seat *base;
2597 struct wl_list link;
2600 @@ -124,8 +221,28 @@ struct weston_transmitter_seat {
2601 double pointer_phase; /* fake */
2604 + struct weston_transmitter_surface *keyboard_focus;
2607 + struct weston_transmitter_surface *touch_focus;
2610 +struct ivi_layout_surface {
2611 + struct wl_list link; /* ivi_layout::surface_list */
2612 + struct wl_signal property_changed;
2613 + int32_t update_count;
2614 + uint32_t id_surface;
2616 + struct ivi_layout *layout;
2617 + struct weston_surface *surface;
2619 + struct ivi_layout_surface_properties prop;
2622 + struct ivi_layout_surface_properties prop;
2625 + struct wl_list view_list; /* ivi_layout_view::surf_link */
2629 @@ -203,5 +320,14 @@ int
2630 transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
2631 struct weston_transmitter_surface *txs);
2634 +seat_capabilities(struct wthp_seat *wthp_seat,
2635 + enum wthp_seat_capability caps);
2637 +static const struct wthp_seat_listener seat_listener = {
2638 + seat_capabilities,
2643 #endif /* WESTON_TRANSMITTER_PLUGIN_H */
2644 diff --git a/transmitter/transmitter_api.h b/transmitter/transmitter_api.h
2645 index 95d82ec..b28f946 100644
2646 --- a/transmitter/transmitter_api.h
2647 +++ b/transmitter/transmitter_api.h
2650 * Copyright (C) 2016 DENSO CORPORATION
2651 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
2653 * Permission is hereby granted, free of charge, to any person obtaining
2654 * a copy of this software and associated documentation files (the
2655 @@ -90,7 +91,6 @@ struct weston_transmitter_api {
2656 * Connect to a remote server via Transmitter.
2658 * \param txr The Transmitter context.
2659 - * \param addr Address of the remote server.
2660 * \param status Listener to inform of connection status changes.
2661 * \return A handle to the remote connection, or NULL on failure.
2663 @@ -102,12 +102,9 @@ struct weston_transmitter_api {
2664 * returned by this function. Use remote_get_status() to fetch the
2667 - * The address argument is a string in the form "host:port".
2669 struct weston_transmitter_remote *
2670 - (*connect_to_remote)(struct weston_transmitter *txr,
2672 - struct wl_listener *status);
2673 + (*connect_to_remote)(struct weston_transmitter *txr);
2676 * Retrieve the connection status.
2677 @@ -191,6 +188,25 @@ struct weston_transmitter_api {
2679 (*surface_configure)(struct weston_transmitter_surface *txs,
2680 int32_t dx, int32_t dy);
2683 + (*surface_gather_state)(struct weston_transmitter_surface *txs);
2685 + /** Notify that surface is connected to receiver
2687 + * \param txr The Transmitter context.
2688 + * \param connected_listener Listener for connected_signal.
2691 + (*register_connection_status)(struct weston_transmitter *txr,
2692 + struct wl_listener *connected_listener);
2694 + /** get weston_surface from weston_transmitter_surface
2696 + * \param txs The Transmitter surface.
2698 + struct weston_surface *
2699 + (*get_weston_surface)(struct weston_transmitter_surface *txs);
2702 static inline const struct weston_transmitter_api *
2703 diff --git a/transmitter/weston.ini.transmitter b/transmitter/weston.ini.transmitter
2704 new file mode 100644
2705 index 0000000..1aff0b2
2707 +++ b/transmitter/weston.ini.transmitter
2711 +modules=transmitter.so
2714 +ivi-module=ivi-controller.so
2715 +ivi-input-module=ivi-input-controller.so
2718 +output-name=transmitter_1
2719 +server-address=192.168.2.11
2725 +output-name=transmitter_2
2726 +server-address=192.168.2.12