6b4f276fe64bebed5b3072a03fcaf245aa83301a
[AGL/meta-agl.git] /
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
5
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.
10
11 Signed-off-by: Wataru Mizuno <wmizuno@jp.adit-jv.com>
12 ---
13  Makefile.am                        |  11 +-
14  configure.ac                       |  12 +
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
24
25 diff --git a/Makefile.am b/Makefile.am
26 index 6cca875..2cb1920 100644
27 --- a/Makefile.am
28 +++ b/Makefile.am
29 @@ -306,6 +306,11 @@ westoninclude_HEADERS +=                           \
30         ivi-shell/ivi-layout-export.h
31  endif
32  
33 +if ENABLE_SURFACE_REMOTING
34 +westoninclude_HEADERS +=                               \
35 +       transmitter/transmitter_api.h
36 +endif
37 +
38  if ENABLE_EGL
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)                    \
45 -       $(AM_CFLAGS)
46 -transmitter_la_LIBADD = $(COMPOSITOR_LIBS)
47 +       $(AM_CFLAGS)                            \
48 +       $(WALTHAM_CFLAGS)
49 +transmitter_la_LIBADD = $(COMPOSITOR_LIBS) \
50 +                       -lwaltham
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
56 --- a/configure.ac
57 +++ b/configure.ac
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,
64 +                         waltham >= 0.1.0,
65 +                         have_waltham=yes,
66 +                         have_waltham=no)
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])
69 +       fi
70 +       if test "x$have_waltham" = "xyes"; then
71 +            enable_surface_remoting=yes
72 +       fi
73 +fi
74  AM_CONDITIONAL(ENABLE_SURFACE_REMOTING, test "x$enable_surface_remoting" = "xyes")
75  
76  
77 diff --git a/transmitter/README b/transmitter/README
78 index a7977ba..af80574 100644
79 --- a/transmitter/README
80 +++ b/transmitter/README
81 @@ -1,45 +1,84 @@
82 -Testing Transmitter with ivi-shell
83 +Transmitter plugin 
84  
85  The current implementation of Transmitter is a stub which interfaces to
86  other Weston parts appropriately, but all networking is just a mockup.
87  
88 +Sections in this file describe:
89 +- How to build
90 +- How to write weston.ini
91 +- How to test
92  
93 +How to build
94 +============
95  Configure Weston with --enable-surface-remoting to build the Transmitter
96  plugin.
97  
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.
101 -
102 -When you start weston, the log should contain something like this:
103 -
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)
121 -
122 -
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.
125 -
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'. 
131 +
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].
136 +
137 +In details, see 'weston.ini.transmitter'.
138 +
139 +How to test
140 +===========
141 +You can use server side test application in waltham repository.
142 +
143 +If you set 'WALTHAM_DEBUG=1' to your environment valuable, you can
144 +see the log like this:
145 +
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
160 +
161 +The connection is established, you can see following debug messages:
162 +
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.
187 + ...sync done.
188 +
189 +Start remoting :
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
196  
197  Weston log will indicate remoting has started:
198  
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
202  
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
210 @@ -1,5 +1,6 @@
211  /*
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
214   *
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,
219  };
220  
221 +static void
222 +keyboard_grab_key(struct weston_keyboard_grab *grab,
223 +                 uint32_t time,
224 +                 uint32_t key,
225 +                 uint32_t state)
226 +{
227 +}
228 +
229 +static void
230 +keyboard_grab_modifiers(struct weston_keyboard_grab *grab,
231 +                       uint32_t serial,
232 +                       uint32_t mods_depressed,
233 +                       uint32_t mods_latched,
234 +                       uint32_t mods_locked,
235 +                       uint32_t group)
236 +{
237 +}
238 +
239 +static void
240 +keyboard_grab_cancel(struct weston_keyboard_grab *grab)
241 +{
242 +}
243 +
244 +static const struct weston_keyboard_grab_interface keyborad_grab_impl = {
245 +       keyboard_grab_key,
246 +       keyboard_grab_modifiers,
247 +       keyboard_grab_cancel
248 +};
249 +
250 +static void
251 +touch_grab_down_handler(struct weston_touch_grab *grab,
252 +                       uint32_t time,
253 +                       int touch_id,
254 +                       wl_fixed_t x,
255 +                       wl_fixed_t y)
256 +{
257 +}
258 +
259 +static void
260 +touch_grab_up_handler(struct weston_touch_grab *grab,
261 +                     uint32_t time,
262 +                     int touch_id)
263 +{
264 +}
265 +
266 +static void
267 +touch_grab_motion_handler(struct weston_touch_grab *grab,
268 +                         uint32_t time,
269 +                         int touch_id,
270 +                         wl_fixed_t x,
271 +                         wl_fixed_t y)
272 +{
273 +}
274 +
275 +static void
276 +touch_grab_frame_handler(struct weston_touch_grab *grab)
277 +{
278 +}
279 +
280 +static void
281 +touch_grab_cancel_handler(struct weston_touch_grab *grab)
282 +{
283 +}
284 +
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,
291 +};
292 +
293 +
294  /* The different ways to get pointer focus on a remoted surface:
295   *
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)
299                 return;
300  
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);
305  
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);
309  
310 -       weston_seat_init_pointer(&seat->base);
311 -
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);
316  
317 -       pointer = weston_seat_get_pointer(&seat->base);
318 +       pointer = weston_seat_get_pointer(seat->base);
319  
320         /* not exported:
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);
324  
325         weston_log("Transmitter created pointer=%p for seat %p\n",
326 -                  pointer, &seat->base);
327 +                  pointer, seat->base);
328  }
329  
330  static void
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;
334  
335 -       pointer = weston_seat_get_pointer(&seat->base);
336 +       pointer = weston_seat_get_pointer(seat->base);
337         assert(pointer);
338  
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;
343  
344 -       pointer->focus_client = weston_pointer_get_pointer_client(pointer,
345 -                                                                 client);
346         pointer->focus_serial = serial;
347  
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;
352  
353 -       pointer = weston_seat_get_pointer(&seat->base);
354 +       pointer = weston_seat_get_pointer(seat->base);
355         assert(pointer);
356         if (!pointer->focus_client)
357                 return;
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;
361  
362 -       pointer = weston_seat_get_pointer(&seat->base);
363 +       pointer = weston_seat_get_pointer(seat->base);
364         assert(pointer);
365  
366         seat->pointer_surface_x = surface_x;
367 @@ -401,7 +469,27 @@ transmitter_seat_pointer_button(struct weston_transmitter_seat *seat,
368                                 uint32_t button,
369                                 uint32_t state)
370  {
371 -       assert(!"TODO");
372 +       struct weston_pointer *pointer;
373 +       struct wl_list *focus_resource_list;
374 +       struct wl_resource *resource;
375 +       struct weston_transmitter_surface *txs;
376 +
377 +       pointer = weston_seat_get_pointer(seat->base);
378 +       assert(pointer);
379 +
380 +       if (!pointer->focus_client)
381 +               return;
382 +
383 +       txs = seat->pointer_focus;
384 +       if (txs)
385 +               assert(wl_resource_get_client(txs->surface->resource) ==
386 +                      pointer->focus_client->client);
387 +
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,
391 +                                      button, state);
392 +        }
393  }
394  
395  void
396 @@ -410,7 +498,27 @@ transmitter_seat_pointer_axis(struct weston_transmitter_seat *seat,
397                               uint32_t axis,
398                               wl_fixed_t value)
399  {
400 -       assert(!"TODO");
401 +       struct weston_pointer *pointer;
402 +       struct wl_list *focus_resource_list;
403 +       struct wl_resource *resource;
404 +       struct weston_transmitter_surface *txs;
405 +
406 +       pointer = weston_seat_get_pointer(seat->base);
407 +       assert(pointer);
408 +
409 +       if (!pointer->focus_client)
410 +               return;
411 +
412 +       txs = seat->pointer_focus;
413 +       if (txs)
414 +               assert(wl_resource_get_client(txs->surface->resource) ==
415 +                      pointer->focus_client->client);
416 +
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,
420 +                                    axis, value);
421 +       }
422  }
423  
424  void
425 @@ -418,7 +526,7 @@ transmitter_seat_pointer_frame(struct weston_transmitter_seat *seat)
426  {
427         struct weston_pointer *pointer;
428  
429 -       pointer = weston_seat_get_pointer(&seat->base);
430 +       pointer = weston_seat_get_pointer(seat->base);
431         if (pointer)
432                 weston_pointer_send_frame(pointer);
433  }
434 @@ -427,7 +535,7 @@ void
435  transmitter_seat_pointer_axis_source(struct weston_transmitter_seat *seat,
436                                      uint32_t axis_source)
437  {
438 -       assert(!"TODO");
439 +       /* ToDo : implement axis event handling */
440  }
441  
442  void
443 @@ -435,7 +543,7 @@ transmitter_seat_pointer_axis_stop(struct weston_transmitter_seat *seat,
444                                    uint32_t time,
445                                    uint32_t axis)
446  {
447 -       assert(!"TODO");
448 +       /* ToDo : implement axis event handling */
449  }
450  
451  void
452 @@ -443,7 +551,222 @@ transmitter_seat_pointer_axis_discrete(struct weston_transmitter_seat *seat,
453                                        uint32_t axis,
454                                        int32_t discrete)
455  {
456 -       assert(!"TODO");
457 +       /* ToDo : implement axis event handling */
458 +}
459 +
460 +static void
461 +transmitter_seat_create_keyboard(struct weston_transmitter_seat *seat)
462 +{
463 +       struct weston_keyboard *keyboard;
464 +
465 +       seat->keyboard_focus = NULL;
466 +       weston_seat_init_keyboard(seat->base, NULL);
467 +
468 +       keyboard = weston_seat_get_keyboard(seat->base);
469 +
470 +       keyboard->default_grab.interface = &keyborad_grab_impl;
471 +
472 +       weston_log("Transmitter created keyboard=%p for seat %p\n",
473 +                  keyboard, seat->base);
474 +}
475 +
476 +static void
477 +transmitter_seat_keyboard_enter(struct weston_transmitter_seat *seat,
478 +                               uint32_t serial,
479 +                               struct weston_transmitter_surface *txs,
480 +                               struct wl_array *keys)
481 +{
482 +       struct weston_keyboard *keyboard;
483 +       struct wl_resource *resource = NULL;
484 +       struct wl_resource *surface_resource;
485 +
486 +       keyboard = weston_seat_get_keyboard(seat->base);
487 +       assert(keyboard);
488 +
489 +       assert(txs->surface);
490 +       surface_resource = txs->surface->resource;
491 +
492 +       seat->keyboard_focus = txs;
493 +       wl_array_copy(&keyboard->keys, keys);
494 +
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,
498 +                                              serial,
499 +                                              surface_resource,
500 +                                              &keyboard->keys);
501 +               }
502 +       }
503 +}
504 +
505 +static void
506 +transmitter_seat_keyboard_leave(struct weston_transmitter_seat *seat,
507 +                               uint32_t serial,
508 +                               struct weston_transmitter_surface *txs)
509 +{
510 +       struct weston_keyboard *keyboard;
511 +       struct wl_resource *resource = NULL;
512 +       struct wl_resource *surface_resource;
513 +
514 +       keyboard = weston_seat_get_keyboard(seat->base);
515 +       assert(keyboard);
516 +
517 +       assert(txs->surface);
518 +       surface_resource = txs->surface->resource;
519 +
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,
523 +                                              serial,
524 +                                              surface_resource);
525 +               }
526 +       }
527 +}
528 +
529 +static void
530 +transmitter_seat_keyboard_key(struct weston_transmitter_seat *seat,
531 +       uint32_t serial,
532 +       uint32_t time,
533 +       uint32_t key,
534 +       uint32_t state)
535 +{
536 +       struct weston_keyboard *keyboard;
537 +       struct wl_resource *resource = NULL;
538 +
539 +       keyboard = weston_seat_get_keyboard(seat->base);
540 +       assert(keyboard);
541 +
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,
546 +                                            serial,
547 +                                            time,
548 +                                            key,
549 +                                            state);
550 +               }
551 +       }
552 +}
553 +
554 +static void
555 +transmitter_seat_create_touch(struct weston_transmitter_seat *seat)
556 +{
557 +       struct weston_touch *touch;
558 +
559 +       seat->touch_focus = NULL;
560 +       weston_seat_init_touch(seat->base);
561 +
562 +       touch = weston_seat_get_touch(seat->base);
563 +
564 +       touch->default_grab.interface = &touch_grab_impl;
565 +
566 +       weston_log("Transmitter created touch=%p for seat %p\n",
567 +                  touch, seat->base);
568 +}
569 +
570 +static void
571 +transmitter_seat_touch_down (struct weston_transmitter_seat *seat,
572 +                            uint32_t serial,
573 +                            uint32_t time,
574 +                            struct weston_transmitter_surface *txs,
575 +                            int32_t touch_id,
576 +                            wl_fixed_t x,
577 +                            wl_fixed_t y)
578 +{
579 +       struct weston_touch *touch;
580 +       struct wl_resource *resource = NULL;
581 +       struct wl_resource *surface_resource;
582 +
583 +       touch = weston_seat_get_touch(seat->base);
584 +       assert(touch);
585 +
586 +       assert(txs->surface);
587 +       surface_resource = txs->surface->resource;
588 +
589 +       seat->touch_focus = txs;
590 +
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,
594 +                                          surface_resource,
595 +                                          touch_id, x, y);
596 +               }
597 +       }
598 +}
599 +
600 +static void
601 +transmitter_seat_touch_up (struct weston_transmitter_seat *seat,
602 +                          uint32_t serial,
603 +                          uint32_t time,
604 +                          int32_t touch_id)
605 +{
606 +       struct weston_touch *touch;
607 +       struct wl_resource *resource = NULL;
608 +
609 +       touch = weston_seat_get_touch(seat->base);
610 +       assert(touch);
611 +
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);
616 +               }
617 +       }
618 +}
619 +
620 +static void
621 +transmitter_seat_touch_motion (struct weston_transmitter_seat *seat,
622 +                              uint32_t time,
623 +                              int32_t touch_id,
624 +                              wl_fixed_t x,
625 +                              wl_fixed_t y)
626 +{
627 +       struct weston_touch *touch;
628 +       struct wl_resource *resource = NULL;
629 +
630 +       touch = weston_seat_get_touch(seat->base);
631 +       assert(touch);
632 +
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);
637 +               }
638 +       }
639 +}
640 +
641 +static void
642 +transmitter_seat_touch_frame (struct weston_transmitter_seat *seat)
643 +{
644 +       struct weston_touch *touch;
645 +       struct wl_resource *resource = NULL;
646 +
647 +       touch = weston_seat_get_touch(seat->base);
648 +       assert(touch);
649 +
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);
654 +               }
655 +       }
656 +}
657 +
658 +static void
659 +transmitter_seat_touch_cancel (struct weston_transmitter_seat *seat)
660 +{
661 +       struct weston_touch *touch;
662 +       struct wl_resource *resource = NULL;
663 +
664 +       touch = weston_seat_get_touch(seat->base);
665 +       assert(touch);
666 +
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);
671 +               }
672 +       }
673  }
674  
675  static char *
676 @@ -462,9 +785,7 @@ transmitter_seat_destroy(struct weston_transmitter_seat *seat)
677  {
678         wl_list_remove(&seat->link);
679  
680 -       weston_log("Transmitter destroy seat=%p\n", &seat->base);
681 -
682 -       weston_seat_release(&seat->base);
683 +       weston_log("Transmitter destroy seat=%p\n", seat->base);
684  
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)
688         free(seat);
689  }
690  
691 +static void
692 +pointer_handle_enter(struct wthp_pointer *wthp_pointer,
693 +                    uint32_t serial,
694 +                    struct wthp_surface *surface,
695 +                    wth_fixed_t surface_x,
696 +                    wth_fixed_t surface_y)
697 +{
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;
704 +
705 +       seat = container_of(seat_list->next,
706 +                           struct weston_transmitter_seat, link);
707 +
708 +       wl_list_for_each(txs, &remote->surface_list, link)
709 +       {
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);
715 +               }
716 +       }
717 +}
718 +
719 +static void
720 +pointer_handle_leave(struct wthp_pointer *wthp_pointer,
721 +                    uint32_t serial,
722 +                    struct wthp_surface *surface)
723 +{
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;
730 +
731 +       seat = container_of(seat_list->next,
732 +                           struct weston_transmitter_seat, link);
733 +
734 +       wl_list_for_each(txs, &remote->surface_list, link)
735 +       {
736 +               if (txs->wthp_surf == surface) {
737 +                       transmitter_seat_pointer_leave(seat, serial, txs);
738 +               }
739 +       }
740 +}
741 +
742 +static void
743 +pointer_handle_motion(struct wthp_pointer *wthp_pointer,
744 +                     uint32_t time,
745 +                     wth_fixed_t surface_x,
746 +                     wth_fixed_t surface_y)
747 +{
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;
753 +
754 +       seat = container_of(seat_list->next,
755 +                           struct weston_transmitter_seat, link);
756 +
757 +       transmitter_seat_pointer_motion(seat, time,
758 +                                       surface_x,
759 +                                       surface_y);
760 +}
761 +
762 +static void
763 +pointer_handle_button(struct wthp_pointer *wthp_pointer,
764 +                     uint32_t serial,
765 +                     uint32_t time,
766 +                     uint32_t button,
767 +                     uint32_t state)
768 +{
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;
774 +
775 +       seat = container_of(seat_list->next,
776 +                           struct weston_transmitter_seat, link);
777 +
778 +       transmitter_seat_pointer_button(seat, serial,
779 +                                       time, button,
780 +                                       state);
781 +}
782 +
783 +static void
784 +pointer_handle_axis(struct wthp_pointer *wthp_pointer,
785 +                   uint32_t time,
786 +                   uint32_t axis, wth_fixed_t value)
787 +{
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;
793 +
794 +       seat = container_of(seat_list->next,
795 +                           struct weston_transmitter_seat, link);
796 +
797 +       transmitter_seat_pointer_axis(seat, time,
798 +                                     axis, value);
799 +}
800 +
801 +static void
802 +pointer_handle_frame(struct wthp_pointer *wthp_pointer)
803 +{
804 +       /* ToDo : implement pointer handle frame */
805 +}
806 +
807 +static void
808 +pointer_handle_axis_source(struct wthp_pointer *wthp_pointer,
809 +                          uint32_t axis_source)
810 +{
811 +       /* ToDo : implement pointer handle axis source */
812 +}
813 +
814 +static void
815 +pointer_handle_axis_stop(struct wthp_pointer *wthp_pointer,
816 +                        uint32_t time,
817 +                        uint32_t axis)
818 +{
819 +       /* ToDo : implement pointer handle axis stop */
820 +}
821 +
822 +static void
823 +pointer_handle_axis_discrete(struct wthp_pointer *wthp_pointer,
824 +                            uint32_t axis,
825 +                            int32_t discrete)
826 +{
827 +       /* ToDo : implement pointer handle axis discrete */
828 +}
829 +
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
840 +};
841 +
842 +static void
843 +keyboard_handle_keymap(struct wthp_keyboard * wthp_keyboard,
844 +       uint32_t format,
845 +       uint32_t keymap_sz,
846 +       void * keymap)
847 +{
848 +       /* ToDo : implement keyboard handle keymap */
849 +}
850 +
851 +static void
852 +keyboard_handle_enter(struct wthp_keyboard *wthp_keyboard,
853 +       uint32_t serial,
854 +       struct wthp_surface *surface,
855 +       struct wth_array *keys)
856 +{
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));
864 +
865 +       wl_key->size = keys->size;
866 +       wl_key->alloc = keys->alloc;
867 +       wl_key->data = keys->data;
868 +       
869 +       seat = container_of(seat_list->next,
870 +       struct weston_transmitter_seat, link);
871 +
872 +       wl_list_for_each(txs, &remote->surface_list, link)
873 +       {
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);
877 +               }
878 +       }
879 +       free(wl_key);
880 +}
881 +
882 +static void
883 +keyboard_handle_leave(struct wthp_keyboard *wthp_keyboard,
884 +       uint32_t serial,
885 +       struct wthp_surface *surface)
886 +{
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;
893 +
894 +       seat = container_of(seat_list->next,
895 +       struct weston_transmitter_seat, link);
896 +
897 +       wl_list_for_each(txs, &remote->surface_list, link)
898 +       {
899 +               if (txs->wthp_surf == surface) {
900 +                       transmitter_seat_keyboard_leave(seat, serial, txs);
901 +               }
902 +       }
903 +}
904 +
905 +static void
906 +keyboard_handle_key(struct wthp_keyboard *wthp_keyboard,
907 +       uint32_t serial,
908 +       uint32_t time,
909 +       uint32_t key,
910 +       uint32_t state)
911 +{
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;
917 +
918 +       seat = container_of(seat_list->next,
919 +       struct weston_transmitter_seat, link);
920 +
921 +       transmitter_seat_keyboard_key(seat, serial, time, key, state);
922 +}
923 +
924 +static void
925 +keyboard_handle_modifiers(struct wthp_keyboard *wthp_keyboard,
926 +       uint32_t serial,
927 +       uint32_t mods_depressed,
928 +       uint32_t mods_latched,
929 +       uint32_t mods_locked,
930 +       uint32_t group)
931 +{
932 +       weston_log("keyboard_handle_modifiers\n");
933 +}
934 +
935 +static void
936 +keyboard_handle_repeat_info(struct wthp_keyboard *wthp_keyboard,
937 +       int32_t rate,
938 +       int32_t delay)
939 +{
940 +       weston_log("keyboard_handle_repeat_info\n");
941 +}
942 +
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
950 +};
951 +
952 +static void
953 +touch_handle_down (struct wthp_touch * wthp_touch,
954 +                  uint32_t serial,
955 +                  uint32_t time,
956 +                  struct wthp_surface * surface,
957 +                  int32_t id,
958 +                  wth_fixed_t x,
959 +                  wth_fixed_t y)
960 +{
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;
967 +
968 +       seat = container_of(seat_list->next,
969 +                           struct weston_transmitter_seat, link);
970 +
971 +       wl_list_for_each(txs, &remote->surface_list, link)
972 +       {
973 +               if (txs->wthp_surf == surface) {
974 +                       transmitter_seat_touch_down(seat, serial, time,
975 +                                                   txs, id, x, y);
976 +               }
977 +       }
978 +}
979 +
980 +static void
981 +touch_handle_up (struct wthp_touch * wthp_touch,
982 +                uint32_t serial,
983 +                uint32_t time,
984 +                int32_t id)
985 +{
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;
991 +
992 +       seat = container_of(seat_list->next,
993 +                           struct weston_transmitter_seat, link);
994 +
995 +       transmitter_seat_touch_up(seat, serial, time, id);
996 +}
997 +
998 +static void
999 +touch_handle_motion (struct wthp_touch * wthp_touch,
1000 +                    uint32_t time,
1001 +                    int32_t id,
1002 +                    wth_fixed_t x,
1003 +                    wth_fixed_t y)
1004 +{
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;
1010 +
1011 +       seat = container_of(seat_list->next,
1012 +                           struct weston_transmitter_seat, link);
1013 +
1014 +       transmitter_seat_touch_motion(seat, time, id, x, y);
1015 +}
1016 +
1017 +
1018 +static void
1019 +touch_handle_frame (struct wthp_touch * wthp_touch)
1020 +{
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;
1026 +
1027 +       seat = container_of(seat_list->next,
1028 +                           struct weston_transmitter_seat, link);
1029 +
1030 +       transmitter_seat_touch_frame(seat);
1031 +}
1032 +
1033 +static void
1034 +touch_handle_cancel (struct wthp_touch * wthp_touch)
1035 +{
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;
1041 +
1042 +       seat = container_of(seat_list->next,
1043 +                           struct weston_transmitter_seat, link);
1044 +
1045 +       transmitter_seat_touch_cancel(seat);
1046 +}
1047 +
1048 +
1049 +static const struct wthp_touch_listener touch_listener = {
1050 +       touch_handle_down,
1051 +       touch_handle_up,
1052 +       touch_handle_motion,
1053 +       touch_handle_frame,
1054 +       touch_handle_cancel
1055 +};
1056 +
1057 +void
1058 +seat_capabilities(struct wthp_seat *wthp_seat,
1059 +                 enum wthp_seat_capability caps)
1060 +{
1061 +       struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)wthp_seat);
1062 +
1063 +       weston_log("seat_capabilities\n");
1064 +
1065 +       if ((caps & WTHP_SEAT_CAPABILITY_POINTER) && !dpy->pointer)
1066 +       {
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);
1070 +       }
1071 +       if ((caps & WTHP_SEAT_CAPABILITY_KEYBOARD) && !dpy->keyboard)
1072 +       {
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);
1076 +       }
1077 +       if ((caps & WTHP_SEAT_CAPABILITY_TOUCH) && !dpy->touch)
1078 +       {
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);
1082 +       }
1083 +}
1084 +
1085  int
1086  transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1087  {
1088         struct weston_transmitter_seat *seat = NULL;
1089         char *name = NULL;
1090 +       struct weston_seat *weston_seat = NULL;
1091  
1092         seat = zalloc(sizeof *seat);
1093         if (!seat)
1094 @@ -493,6 +1209,24 @@ transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1095         if (!name)
1096                 goto fail;
1097  
1098 +
1099 +       if (wl_list_empty(&remote->transmitter->compositor->seat_list)) {
1100 +               weston_seat = zalloc(sizeof *weston_seat);
1101 +               if (!weston_seat)
1102 +                       goto fail;
1103 +
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);
1107 +       } else {
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;
1111 +               }
1112 +       }
1113 +
1114 +       free(name);
1115 +#if DEBUG
1116         weston_seat_init(&seat->base, remote->transmitter->compositor, name);
1117         free(name);
1118  
1119 @@ -515,9 +1249,12 @@ transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1120  
1121         weston_log("Transmitter created seat=%p '%s'\n",
1122                    &seat->base, seat->base.seat_name);
1123 +#endif
1124  
1125         /* XXX: mirror remote capabilities */
1126         transmitter_seat_create_pointer(seat);
1127 +       transmitter_seat_create_keyboard(seat);
1128 +       transmitter_seat_create_touch(seat);
1129  
1130         wl_list_insert(&remote->seat_list, &seat->link);
1131  
1132 @@ -582,7 +1319,7 @@ transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
1133  
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
1145 @@ -1,5 +1,6 @@
1146  /*
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
1149   *
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)
1153  {
1154         char *str;
1155  
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)
1158                 return NULL;
1159  
1160         return str;
1161 @@ -124,8 +125,6 @@ free_mode_list(struct wl_list *mode_list)
1162  void
1163  transmitter_output_destroy(struct weston_transmitter_output *output)
1164  {
1165 -       weston_log("Transmitter destroying output '%s'\n", output->base.name);
1166 -
1167         wl_list_remove(&output->link);
1168  
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);
1172  }
1173  
1174 +
1175  static void
1176  transmitter_start_repaint_loop(struct weston_output *base)
1177  {
1178 -       weston_log("%s(%s)\n", __func__, base->name);
1179 +       struct timespec ts;
1180 +       struct weston_transmitter_output *output = to_transmitter_output(base);
1181 +
1182 +       weston_compositor_read_presentation_clock(output->base.compositor, &ts);
1183 +       weston_output_finish_frame(&output->base, &ts, 0);
1184 +}
1185 +
1186 +static int
1187 +transmitter_check_output(struct weston_transmitter_surface *txs,
1188 +                        struct weston_compositor *compositor)
1189 +{
1190 +       struct weston_output *def_output = container_of(compositor->output_list.next,
1191 +                                                       struct weston_output, link);
1192 +       struct weston_view *view;
1193 +
1194 +       wl_list_for_each_reverse(view, &compositor->view_list, link) {
1195 +               if (view->output == def_output) {
1196 +                       if (view->surface == txs->surface)
1197 +                               return 1;
1198 +               }
1199 +       }
1200 +
1201 +       return 0;
1202  }
1203  
1204  static int
1205  transmitter_output_repaint(struct weston_output *base,
1206                            pixman_region32_t *damage)
1207  {
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;
1218 +
1219 +       if (!output->from_frame_signal)
1220 +               return 0;
1221 +
1222 +       output->from_frame_signal = false;
1223 +
1224 +       /* 
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.
1229 +        */
1230 +       if (wl_list_empty(&compositor->view_list))
1231 +               goto out;
1232 +
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))
1241 +                                               break;
1242 +
1243 +                                       if (!txs->wthp_surf)
1244 +                                               transmitter_api->surface_push_to_remote
1245 +                                                       (view->surface, remote, NULL);
1246 +                                       transmitter_api->surface_gather_state(txs);
1247 +                                       break;
1248 +                               }
1249 +                       }
1250 +                       if (!found_surface)
1251 +                               transmitter_api->surface_push_to_remote(view->surface, 
1252 +                                                                       remote, NULL);
1253 +               }
1254 +       }
1255 +       if (!found_output)
1256 +               goto out;
1257  
1258 -       return -1;
1259 +       return 0;
1260 +
1261 +out:
1262 +       transmitter_start_repaint_loop(base);
1263 +
1264 +       return 0;
1265 +}
1266 +
1267 +static void
1268 +transmitter_output_enable(struct weston_output *base)
1269 +{
1270 +       struct weston_transmitter_output *output = to_transmitter_output(base);
1271 +
1272 +       
1273 +       output->base.assign_planes = NULL;
1274 +       output->base.set_backlight = NULL;
1275 +       output->base.set_dpms = NULL;
1276 +       output->base.switch_mode = NULL;
1277 +}
1278 +
1279 +static void
1280 +transmitter_output_frame_handler(struct wl_listener *listener, void *data)
1281 +{
1282 +       struct weston_transmitter_output *output;
1283 +       int ret;
1284 +
1285 +       output = container_of(listener, struct weston_transmitter_output,
1286 +                             frame_listener);
1287 +       output->from_frame_signal = true;
1288 +
1289 +       ret = transmitter_output_repaint(&output->base, NULL);
1290  }
1291  
1292  int
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)
1298  {
1299         struct weston_transmitter_output *output;
1300 +       struct weston_transmitter *txr = remote->transmitter;
1301 +       struct weston_output *def_output;
1302  
1303         output = zalloc(sizeof *output);
1304         if (!output)
1305                 return -1;
1306  
1307 +       output->parent.draw_initial_frame = true;
1308 +
1309         output->base.subpixel = info->subpixel;
1310  
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");
1315 -
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)
1319                 goto fail;
1320  
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 */
1325 -
1326         weston_output_init(&output->base, remote->transmitter->compositor);
1327  
1328         /*
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.
1332          */
1333 -
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(
1339  
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;
1344  
1345         output->remote = remote;
1346         wl_list_insert(&remote->output_list, &output->link);
1347  
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);
1352 +
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;
1358  
1359         return 0;
1360  
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
1365 @@ -1,5 +1,6 @@
1366  /*
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
1369   *
1370   * Permission is hereby granted, free of charge, to any person obtaining
1371   * a copy of this software and associated documentation files (the
1372 @@ -34,8 +35,23 @@
1373  #include "helpers.h"
1374  #include "timespec-util.h"
1375  
1376 +#include "compositor/weston.h"
1377  #include "plugin.h"
1378  #include "transmitter_api.h"
1379 +#include "plugin-registry.h"
1380 +#include "ivi-shell/ivi-layout-export.h"
1381 +
1382 +/* waltham */
1383 +#include <errno.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>
1389 +
1390 +#define MAX_EPOLL_WATCHES 2
1391 +#define ESTABLISH_CONNECTION_PERIOD 2000
1392 +#define RETRY_CONNECTION_PERIOD 5000
1393  
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);
1398  }
1399  
1400 -static int
1401 -frame_callback_handler(void *data) /* fake */
1402 -{
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;
1411 -
1412 -       compositor = txs->remote->transmitter->compositor;
1413 -       output = txs->sync_output;
1414 -
1415 -       /* wl_surface.enter should arrive before any frame callbacks,
1416 -        * but remote might send frame callbacks for non-visible too.
1417 -        */
1418 -       if (!output)
1419 -               return 0;
1420 -
1421 -       /* XXX: eeeew */
1422 -       frame_time = weston_compositor_get_time();
1423 -
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);
1427 -       }
1428 -
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,
1435 -                                                 output->msc,
1436 -                                                 presented_flags);
1437 -
1438 -       return 0;
1439 -}
1440 -
1441 -static void
1442 -fake_frame_callback(struct weston_transmitter_surface *txs)
1443 -{
1444 -       struct weston_transmitter *txr = txs->remote->transmitter;
1445 -       struct wl_event_loop *loop;
1446 -
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);
1452 -       }
1453 -
1454 -       wl_event_source_timer_update(txs->frame_timer, 85);
1455 -}
1456 -
1457  static void
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,
1461  }
1462  
1463  static void
1464 -transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
1465 +buffer_send_complete(struct wthp_buffer *b, uint32_t serial)
1466  {
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));
1470 -
1471 -       wl_list_insert_list(&txs->frame_callback_list,
1472 -                           &txs->surface->frame_callback_list);
1473 -       wl_list_init(&txs->surface->frame_callback_list);
1474 -
1475 -       wl_list_insert_list(&txs->feedback_list, &txs->surface->feedback_list);
1476 -       wl_list_init(&txs->surface->feedback_list);
1477 -
1478 -       /* TODO: transmit surface state to remote */
1479 -
1480 -       txs->attach_dx = 0;
1481 -       txs->attach_dy = 0;
1482 +       if (b)
1483 +               wthp_buffer_destroy(b);
1484  }
1485  
1486 -/** weston_surface apply state signal handler */
1487 +static const struct wthp_buffer_listener buffer_listener = {
1488 +       buffer_send_complete
1489 +};
1490 +
1491  static void
1492 -transmitter_surface_apply_state(struct wl_listener *listener, void *data)
1493 +transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
1494  {
1495 -       struct weston_transmitter_surface *txs =
1496 -               container_of(listener, struct weston_transmitter_surface,
1497 -                            apply_state_listener);
1498 -
1499 -       assert(data == NULL);
1500 +       struct weston_transmitter_remote *remote = txs->remote;
1501 +       struct waltham_display *dpy = remote->display;
1502  
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);
1509 +               }
1510 +       }
1511 +       else {
1512 +               /* TODO: transmit surface state to remote */
1513 +               /* The buffer must be transmitted to remote side */
1514 +               
1515 +               /* waltham */
1516 +               struct weston_surface *surf = txs->surface;
1517 +               struct weston_compositor *comp = surf->compositor;
1518 +               int32_t width = 100;
1519 +               int32_t height = 100;
1520 +               int32_t stride;
1521 +               int ret = 0;
1522 +               void *pixels;
1523 +
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);
1530 +               
1531 +               ret = weston_surface_copy_content(surf, pixels,
1532 +                                                 (stride * height), 0, 0,
1533 +                                                 width, height);
1534 +               if(ret < 0)
1535 +                       fprintf(stderr, "failed to get surface content\n");
1536 +
1537 +               /* fake sending buffer */
1538 +               txs->wthp_buf = wthp_blob_factory_create_buffer(remote->display->blob_factory,
1539 +                                                               (stride * height),
1540 +                                                               pixels,
1541 +                                                               width,
1542 +                                                               height,
1543 +                                                               stride,
1544 +                                                               PIXMAN_FORMAT_BPP(comp->read_format));
1545 +               
1546 +               wthp_buffer_set_listener(txs->wthp_buf, &buffer_listener, txs);
1547 +               
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);
1552 +
1553 +               wth_connection_flush(remote->display->connection);
1554 +               
1555 +               txs->attach_dx = 0;
1556 +               txs->attach_dy = 0;
1557 +       }
1558  }
1559  
1560  /** Mark the weston_transmitter_surface dead.
1561 @@ -181,8 +178,7 @@ transmitter_surface_apply_state(struct wl_listener *listener, void *data)
1562  static void
1563  transmitter_surface_zombify(struct weston_transmitter_surface *txs)
1564  {
1565 -       struct weston_frame_callback *framecb, *cnext;
1566 -
1567 +       struct weston_transmitter_remote *remote;
1568         /* may be called multiple times */
1569         if (!txs->surface)
1570                 return;
1571 @@ -190,20 +186,17 @@ transmitter_surface_zombify(struct weston_transmitter_surface *txs)
1572         wl_signal_emit(&txs->destroy_signal, txs);
1573  
1574         wl_list_remove(&txs->surface_destroy_listener.link);
1575 -       weston_log("Transmitter unbound surface %p.\n", txs->surface);
1576         txs->surface = NULL;
1577  
1578         wl_list_remove(&txs->sync_output_destroy_listener.link);
1579 -       wl_list_remove(&txs->apply_state_listener.link);
1580 -
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);
1585  
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);
1596  
1597         /* In case called from destroy_transmitter() */
1598         txs->remote = NULL;
1599 @@ -231,25 +224,6 @@ transmitter_surface_destroyed(struct wl_listener *listener, void *data)
1600         transmitter_surface_zombify(txs);
1601  }
1602  
1603 -static struct weston_transmitter_surface *
1604 -transmitter_surface_get(struct weston_surface *ws)
1605 -{
1606 -       struct wl_listener *listener;
1607 -       struct weston_transmitter_surface *txs;
1608 -
1609 -       listener = wl_signal_get(&ws->destroy_signal,
1610 -                                transmitter_surface_destroyed);
1611 -
1612 -       if (!listener)
1613 -               return NULL;
1614 -
1615 -       txs = container_of(listener, struct weston_transmitter_surface,
1616 -                          surface_destroy_listener);
1617 -       assert(ws == txs->surface);
1618 -
1619 -       return txs;
1620 -}
1621 -
1622  static void
1623  sync_output_destroy_handler(struct wl_listener *listener, void *data)
1624  {
1625 @@ -265,84 +239,48 @@ sync_output_destroy_handler(struct wl_listener *listener, void *data)
1626  }
1627  
1628  static void
1629 -fake_input(struct weston_transmitter_surface *txs)
1630 -{
1631 -       struct wl_list *seat_list = &txs->remote->seat_list;
1632 -       struct weston_transmitter_seat *seat;
1633 -
1634 -       assert(wl_list_length(seat_list) == 1);
1635 -       seat = container_of(seat_list->next,
1636 -                           struct weston_transmitter_seat, link);
1637 -
1638 -       transmitter_seat_fake_pointer_input(seat, txs);
1639 -}
1640 -
1641 -/* fake receiving wl_surface.enter(output) */
1642 -static int
1643 -map_timer_handler(void *data)
1644 -{
1645 -       struct weston_transmitter_surface *txs = data;
1646 -       struct weston_transmitter_output *output;
1647 -
1648 -       assert(!wl_list_empty(&txs->remote->output_list));
1649 -
1650 -       output = container_of(txs->remote->output_list.next,
1651 -                             struct weston_transmitter_output, link);
1652 -
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);
1658 -
1659 -       weston_surface_force_output(txs->surface, txs->sync_output);
1660 -
1661 -       weston_log("Transmitter: surface %p entered output %s\n",
1662 -                  txs->surface, txs->sync_output->name);
1663 -
1664 -       fake_frame_callback(txs);
1665 -       fake_input(txs);
1666 -
1667 -       return 0;
1668 -}
1669 -
1670 -/* Fake a delay for the remote end to map the surface to an output */
1671 -static void
1672 -fake_output_mapping(struct weston_transmitter_surface *txs)
1673 -{
1674 -       struct weston_transmitter *txr = txs->remote->transmitter;
1675 -       struct wl_event_loop *loop;
1676 -
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);
1680 -}
1681 -
1682 -/* Fake getting "connection established" from the content streamer. */
1683 -static void
1684 -fake_stream_opening_handler(void *data)
1685 -{
1686 -       struct weston_transmitter_surface *txs = data;
1687 -
1688 -       /* ...once the connection is up: */
1689 -       txs->status = WESTON_TRANSMITTER_STREAM_LIVE;
1690 -       wl_signal_emit(&txs->stream_status_signal, txs);
1691 -
1692 -       /* need to create the surface on the remote and set all state */
1693 -       transmitter_surface_gather_state(txs);
1694 -
1695 -       fake_output_mapping(txs);
1696 -}
1697 -
1698 -/* Fake a callback from content streamer. */
1699 -static void
1700 -fake_stream_opening(struct weston_transmitter_surface *txs)
1701 +transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs)
1702  {
1703 -       struct weston_transmitter *txr = txs->remote->transmitter;
1704 -       struct wl_event_loop *loop;
1705 -
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;
1714 +       int32_t ret = 0;
1715 +       int32_t i = 0;
1716 +
1717 +       ret = txs->lyt->get_surfaces(&surface_length, &pp_surface);
1718 +       if(!ret)
1719 +               weston_log("No ivi_surface\n");
1720 +
1721 +       ws = txs->surface;
1722 +
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)
1728 +                               return;
1729 +                       if(!dpy)
1730 +                               weston_log("no content in waltham_display\n");
1731 +                       if(!dpy->compositor)
1732 +                               weston_log("no content in compositor object\n");
1733 +                       if(!dpy->seat)
1734 +                               weston_log("no content in seat object\n");
1735 +                       if(!dpy->application)
1736 +                               weston_log("no content in ivi-application object\n");
1737 +                       
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");
1743 +                       }
1744 +               }
1745 +       }
1746 +       free(pp_surface);
1747 +       pp_surface = NULL;
1748  }
1749  
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)
1754  {
1755 +       struct weston_transmitter *txr = remote->transmitter;
1756         struct weston_transmitter_surface *txs;
1757 +       bool found = false;
1758  
1759 -       if (transmitter_surface_get(ws)) {
1760 -               weston_log("Transmitter: surface %p already bound.\n", ws);
1761 +       if (remote->status != WESTON_TRANSMITTER_CONNECTION_READY)
1762 +       {
1763                 return NULL;
1764         }
1765  
1766 -       txs = zalloc(sizeof (*txs));
1767 -       if (!txs)
1768 -               return NULL;
1769 +       wl_list_for_each(txs, &remote->surface_list, link) {
1770 +               if (txs->surface == ws) {
1771 +                       found = true;
1772 +                       break;
1773 +               }
1774 +       }
1775  
1776 -       txs->remote = remote;
1777 -       wl_signal_init(&txs->destroy_signal);
1778 -       wl_list_insert(&remote->surface_list, &txs->link);
1779 +       if (!found) {
1780 +               txs = NULL;
1781 +               txs = zalloc(sizeof (*txs));
1782 +               if (!txs)
1783 +                       return NULL;
1784  
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);
1791  
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);
1799  
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);
1805  
1806 -       wl_list_init(&txs->sync_output_destroy_listener.link);
1807 +               wl_list_init(&txs->sync_output_destroy_listener.link);
1808  
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);
1813 +
1814 +               txs->lyt = weston_plugin_api_get(txr->compositor, 
1815 +                                                IVI_LAYOUT_API_NAME, sizeof(txs->lyt));
1816 +       }
1817  
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);
1826 +       }
1827  
1828         return txs;
1829  }
1830 @@ -393,17 +350,53 @@ transmitter_surface_get_stream_status(struct weston_transmitter_surface *txs)
1831         return txs->status;
1832  }
1833  
1834 -static int
1835 -conn_timer_handler(void *data) /* fake */
1836 +/* waltham */
1837 +/* The server advertises a global interface.
1838 + * We can store the ad for later and/or bind to it immediately
1839 + * if we want to.
1840 + * We also need to keep track of the globals we bind to, so that
1841 + * global_remove can be handled properly (not implemented).
1842 + */
1843 +static void
1844 +registry_handle_global(struct wthp_registry *registry,
1845 +                      uint32_t name,
1846 +                      const char *interface,
1847 +                      uint32_t version)
1848  {
1849 -       struct weston_transmitter_remote *remote = data;
1850 +       struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)registry);
1851 +       
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);
1867 +       }
1868 +}
1869 +
1870 +/* notify connection ready */
1871 +static void
1872 +conn_ready_notify(struct wl_listener *l, void *data)
1873 +{
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,
1880                 1,
1881                 0, 0,
1882                 300, 200,
1883 -               "fake",
1884 +               strdup(remote->model),
1885                 {
1886                         WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
1887                         800, 600,
1888 @@ -411,52 +404,303 @@ conn_timer_handler(void *data) /* fake */
1889                         { NULL, NULL }
1890                 }
1891         };
1892 -
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);
1896 -
1897 -       wl_event_source_remove(remote->conn_timer);
1898 -       remote->conn_timer = NULL;
1899 -
1900 +       if(remote->width != 0) {
1901 +               if(remote->height != 0) {
1902 +                       info.mode.width = remote->width;
1903 +                       info.mode.height = remote->height;
1904 +               }
1905 +       }
1906         /* Outputs and seats are dynamic, do not guarantee they are all
1907          * present when signalling connection status.
1908          */
1909         transmitter_remote_create_output(remote, &info);
1910         transmitter_remote_create_seat(remote);
1911 +}
1912 +
1913 +/* waltham */
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)
1920 + */
1921 +static void
1922 +registry_handle_global_remove(struct wthp_registry *wthp_registry,
1923 +                             uint32_t name)
1924 +{
1925 +       if (wthp_registry)
1926 +               wthp_registry_free(wthp_registry);
1927 +}
1928 +
1929 +static const struct wthp_registry_listener registry_listener = {
1930 +       registry_handle_global,
1931 +       registry_handle_global_remove
1932 +};
1933 +
1934 +static void
1935 +connection_handle_data(struct watch *w, uint32_t events)
1936 +{
1937 +       struct waltham_display *dpy = container_of(w, struct waltham_display, conn_watch);
1938 +       struct weston_transmitter_remote *remote = dpy->remote;
1939 +       int ret;
1940 +
1941 +
1942 +       if (!dpy->running) {
1943 +               weston_log("This server is not running yet. %s:%s\n", remote->addr, remote->port);
1944 +               return;
1945 +       }
1946 +
1947 +       if (events & EPOLLERR) {
1948 +               weston_log("Connection errored out.\n");
1949 +               dpy->running = false;
1950 +
1951 +               return;
1952 +       }
1953 +
1954 +       if (events & EPOLLOUT) {
1955 +               /* Flush out again. If the flush completes, stop
1956 +                * polling for writable as everything has been written.
1957 +                */
1958 +               ret = wth_connection_flush(dpy->connection);
1959 +       }
1960 +
1961 +       if (events & EPOLLIN) {
1962 +               /* Do not ignore EPROTO */
1963 +               ret = wth_connection_read(dpy->connection);
1964 +               if (ret < 0) {
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");
1969 +
1970 +                       return;
1971 +               }
1972 +       }
1973 +
1974 +       if (events & EPOLLHUP) {
1975 +               fprintf(stderr, "Connection hung up.\n");
1976 +               dpy->running = false;
1977 +
1978 +               return;
1979 +       }
1980 +}
1981 +
1982 +static void
1983 +waltham_mainloop(int fd, uint32_t mask, void *data)
1984 +{
1985 +       struct weston_transmitter_remote *remote = data;
1986 +       struct watch *w;
1987 +       int count;
1988 +       int i;
1989 +       int ret;
1990 +       int running_display;
1991 +       running_display = 0;
1992 +
1993 +       struct waltham_display *dpy = remote->display;
1994 +       w = &dpy->conn_watch;
1995 +       if (!dpy)
1996 +               goto not_running;
1997 +       
1998 +       if (!dpy->connection)
1999 +               goto not_running;
2000 +       
2001 +       if (!dpy->running)
2002 +               goto not_running;
2003 +       
2004 +       running_display++;
2005 +       /* Dispatch queued events. */
2006 +       
2007 +       ret = wth_connection_dispatch(dpy->connection);
2008 +       if (ret < 0)
2009 +               dpy->running = false;
2010 +       if (!dpy->running)
2011 +               goto not_running;
2012 +
2013 +       /* Run any application idle tasks at this point. */
2014 +       /* (nothing to run so far) */
2015 +       
2016 +       /* Flush out buffered requests. If the Waltham socket is
2017 +        * full, poll it for writable too, and continue flushing then.
2018 +        */
2019 +       ret = wth_connection_flush(dpy->connection);
2020 +
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().
2025 +                */
2026 +               w->cb(w, mask);
2027 +       }
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);
2033 +
2034 +not_running:
2035 +       ;
2036 +}
2037 +
2038 +/* A one-off asynchronous open-coded roundtrip handler. */
2039 +static void
2040 +bling_done(struct wthp_callback *cb, uint32_t arg)
2041 +{
2042 +       fprintf(stderr, "...sync done.\n");
2043 +
2044 +       wthp_callback_free(cb);
2045 +}
2046 +
2047 +static const struct wthp_callback_listener bling_listener = {
2048 +       bling_done
2049 +};
2050 +
2051 +static int
2052 +waltham_client_init(struct waltham_display *dpy)
2053 +{
2054 +       if (!dpy)
2055 +               return -1;
2056 +       /*
2057 +        * get server_address from controller (adrress is set to weston.ini)
2058 +        */
2059 +       dpy->connection = wth_connect_to_server(dpy->remote->addr, dpy->remote->port);
2060 +       if(!dpy->connection) {
2061 +               return -2;
2062 +       }
2063 +       else {
2064 +               dpy->remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
2065 +               wl_signal_emit(&dpy->remote->connection_status_signal, dpy->remote);
2066 +       }
2067 +
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);
2071 +
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.
2075 +        */
2076 +
2077 +       /* Create a registry so that we will get advertisements of the
2078 +        * interfaces implemented by the server.
2079 +        */
2080 +       dpy->registry = wth_display_get_registry(dpy->display);
2081 +       wthp_registry_set_listener(dpy->registry, &registry_listener, dpy);
2082 +
2083 +       /* Roundtrip ensures all globals' ads have been received. */
2084 +       if (wth_connection_roundtrip(dpy->connection) < 0) {
2085 +               fprintf(stderr, "Roundtrip failed.\n");
2086 +               return -1;
2087 +       }
2088 +
2089 +       if (!dpy->compositor) {
2090 +               fprintf(stderr, "Did not find wthp_compositor, quitting.\n");
2091 +               return -1;
2092 +       }
2093 +
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);
2098 +
2099 +       dpy->running = true;
2100  
2101         return 0;
2102  }
2103  
2104 -static struct weston_transmitter_remote *
2105 -transmitter_connect_to_remote(struct weston_transmitter *txr,
2106 -                             const char *addr,
2107 -                             struct wl_listener *status)
2108 +static int
2109 +establish_timer_handler(void *data)
2110  {
2111 -       struct weston_transmitter_remote *remote;
2112 -       struct wl_event_loop *loop;
2113 +       struct weston_transmitter_remote *remote = data;
2114 +       int ret;
2115  
2116 -       remote = zalloc(sizeof (*remote));
2117 -       if (!remote)
2118 -               return NULL;
2119 +       ret = waltham_client_init(remote->display);
2120 +       if(ret == -2) {
2121 +               wl_event_source_timer_update(remote->establish_timer, 
2122 +                                            ESTABLISH_CONNECTION_PERIOD);
2123 +               return 0;
2124 +       }
2125 +       remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
2126 +       wl_signal_emit(&remote->connection_status_signal, remote);
2127 +       return 0;
2128 +}
2129  
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);
2139 +static void
2140 +init_globals(struct waltham_display *dpy)
2141 +{
2142 +       dpy->compositor = NULL;
2143 +       dpy->blob_factory = NULL;
2144 +       dpy->seat = NULL;
2145 +       dpy->application = NULL;
2146 +       dpy->pointer = NULL;
2147 +       dpy->keyboard = NULL;
2148 +       dpy->touch = NULL;
2149 +}
2150 +
2151 +static void
2152 +disconnect_surface(struct weston_transmitter_remote *remote)
2153 +{
2154 +       struct weston_transmitter_surface *txs;
2155 +       wl_list_for_each(txs, &remote->surface_list, link)
2156 +       {
2157 +               free(txs->wthp_ivi_surface);
2158 +               free(txs->wthp_surf);
2159 +               txs->wthp_ivi_surface = NULL;
2160 +               txs->wthp_surf = NULL;
2161 +       }
2162 +}
2163  
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,
2169 -                                                    remote);
2170 -       wl_event_source_timer_update(remote->conn_timer, 1000);
2171 +static int
2172 +retry_timer_handler(void *data)
2173 +{
2174 +       struct weston_transmitter_remote *remote = data;
2175 +       struct waltham_display *dpy = remote->display;
2176 +
2177 +       if(!dpy->running)
2178 +       {
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);
2184 +
2185 +               return 0;
2186 +       }
2187 +       else
2188 +               wl_event_source_timer_update(remote->retry_timer, 
2189 +                                            RETRY_CONNECTION_PERIOD);
2190 +       return 0;
2191 +}
2192 +
2193 +static struct weston_transmitter_remote *
2194 +transmitter_connect_to_remote(struct weston_transmitter *txr)
2195 +{
2196 +       struct weston_transmitter_remote *remote;
2197 +       struct wl_event_loop *loop_est, *loop_retry;
2198 +       int ret;
2199 +       
2200 +       wl_list_for_each_reverse(remote, &txr->remote_list, link) {
2201 +               /* XXX: actually start connecting */
2202 +               /* waltham */
2203 +               remote->display = zalloc(sizeof *remote->display);
2204 +               if (!remote->display)
2205 +                       return NULL;
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);
2216 +               if (ret < 0) {
2217 +                       weston_log("Fatal: Transmitter waltham connecting failed.\n");
2218 +                       return NULL;
2219 +               }
2220 +               wl_signal_emit(&remote->conn_establish_signal, NULL);
2221 +       }
2222  
2223         return remote;
2224  }
2225 @@ -481,10 +725,6 @@ transmitter_remote_destroy(struct weston_transmitter_remote *remote)
2226          * the desctruction order between the shell and Transmitter is
2227          * undefined.
2228          */
2229 -       weston_log("Transmitter disconnecting from %s.\n", remote->addr);
2230 -
2231 -       if (remote->conn_timer)
2232 -               wl_event_source_remove(remote->conn_timer);
2233  
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)
2237         free(remote->addr);
2238         wl_list_remove(&remote->link);
2239  
2240 +       wl_event_source_remove(remote->source);
2241 +
2242         free(remote);
2243  }
2244  
2245 @@ -531,7 +773,6 @@ transmitter_compositor_destroyed(struct wl_listener *listener, void *data)
2246          */
2247         wl_list_remove(&txr->remote_list);
2248  
2249 -       weston_log("Transmitter terminating.\n");
2250         free(txr);
2251  }
2252  
2253 @@ -553,6 +794,19 @@ transmitter_get(struct weston_compositor *compositor)
2254         return txr;
2255  }
2256  
2257 +static void
2258 +transmitter_register_connection_status(struct weston_transmitter *txr,
2259 +                                      struct wl_listener *connected_listener)
2260 +{
2261 +       wl_signal_add(&txr->connected_signal, connected_listener);
2262 +}
2263 +
2264 +static struct weston_surface *
2265 +transmitter_get_weston_surface(struct weston_transmitter_surface *txs)
2266 +{
2267 +       return txs->surface;
2268 +}
2269 +
2270  static const struct weston_transmitter_api transmitter_api_impl = {
2271         transmitter_get,
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,
2280  };
2281  
2282  static void
2283 -transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs,
2284 -                              uint32_t ivi_id)
2285 -{
2286 -       assert(txs->surface);
2287 -       if (!txs->surface)
2288 -               return;
2289 -
2290 -       weston_log("%s(%p, %#x)\n", __func__, txs->surface, ivi_id);
2291 -}
2292 -
2293 -static void
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(
2298  }
2299  
2300  static const struct weston_transmitter_ivi_api transmitter_ivi_api_impl = {
2301 -       transmitter_surface_set_ivi_id,
2302         transmitter_surface_set_resize_callback,
2303  };
2304  
2305 +static int
2306 +transmitter_create_remote(struct weston_transmitter *txr,
2307 +                         const char *model,
2308 +                         const char *addr,
2309 +                         const char *port,
2310 +                         const char *width,
2311 +                         const char *height)
2312 +{
2313 +       struct weston_transmitter_remote *remote;
2314 +
2315 +       remote = zalloc(sizeof (*remote));
2316 +       if (!remote)
2317 +               return -1;
2318 +
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);
2334 +
2335 +       return 0;
2336 +}
2337 +
2338 +static void
2339 +transmitter_get_server_config(struct weston_transmitter *txr)
2340 +{
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';
2349 +       int ret;
2350 +
2351 +       section = weston_config_get_section(config, "remote", NULL, NULL);
2352 +
2353 +       while (weston_config_next_section(config, &section, &name)) {
2354 +               if (0 == strcmp(name, "remote-output")) {
2355 +                       if (0 != weston_config_section_get_string(section, "output-name",
2356 +                                                                 &model, 0))
2357 +                               continue;
2358 +
2359 +                       if (0 != weston_config_section_get_string(section, "server-address",
2360 +                                                                 &addr, 0))
2361 +                               continue;
2362 +
2363 +                       if (0 != weston_config_section_get_string(section, "port",
2364 +                                                                 &port, 0))
2365 +                               continue;
2366 +
2367 +                       if (0 != weston_config_section_get_string(section, "width",
2368 +                                                                 &width, 0))
2369 +                               continue;
2370 +
2371 +                       if (0 != weston_config_section_get_string(section, "height",
2372 +                                                                 &height, 0))
2373 +                               continue;
2374 +                       ret = transmitter_create_remote(txr, model, addr,
2375 +                                                       port, width, height);
2376 +                       if (ret < 0) {
2377 +                               weston_log("Fatal: Transmitter create_remote failed.\n");
2378 +                       }
2379 +               }
2380 +       }
2381 +}
2382 +
2383 +static void
2384 +transmitter_post_init(void *data)
2385 +{
2386 +       struct weston_transmitter *txr = data;
2387 +       struct weston_transmitter_remote *remote;
2388 +       
2389 +       if (!txr) {
2390 +               weston_log("Transmitter disabled\n");
2391 +       } else {
2392 +               transmitter_get_server_config(txr);
2393 +               transmitter_connect_to_remote(txr);
2394 +
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);
2400 +               }
2401 +       }
2402 +}
2403 +
2404  WL_EXPORT int
2405  wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[])
2406  {
2407 @@ -628,6 +972,9 @@ wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[])
2408  
2409         weston_log("Transmitter initialized.\n");
2410  
2411 +       txr->loop = wl_display_get_event_loop(compositor->wl_display);
2412 +       wl_event_loop_add_idle(txr->loop, transmitter_post_init, txr);
2413 +
2414         return 0;
2415  
2416  fail:
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
2421 @@ -1,5 +1,6 @@
2422  /*
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
2425   *
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 @@
2429   */
2430  
2431  #include <stdint.h>
2432 +#include <wayland-client.h>
2433  
2434  #include "compositor.h"
2435  #include "transmitter_api.h"
2436 +#include "ivi-shell/ivi-layout-export.h"
2437 +
2438 +#include <waltham-client.h>
2439 +
2440 +
2441 +struct waltham_display;
2442 +
2443 +enum wthp_seat_capability {
2444 +       /**
2445 +        * the seat has pointer devices
2446 +        */
2447 +       WTHP_SEAT_CAPABILITY_POINTER = 1,
2448 +       /**
2449 +        * the seat has one or more keyboards
2450 +        */
2451 +       WTHP_SEAT_CAPABILITY_KEYBOARD = 2,
2452 +       /**
2453 +        * the seat has touch devices
2454 +        */
2455 +       WTHP_SEAT_CAPABILITY_TOUCH = 4,
2456 +};
2457 +
2458 +/* epoll structure */
2459 +struct watch { 
2460 +       struct waltham_display *display;
2461 +       int fd;
2462 +       void (*cb)(struct watch *w, uint32_t events);
2463 +};
2464 +
2465 +struct waltham_display {
2466 +       struct wth_connection *connection;
2467 +       struct watch conn_watch;
2468 +       struct wth_display *display;
2469 +
2470 +       bool running;
2471 +
2472 +       struct wthp_registry *registry;
2473 +
2474 +       struct wthp_callback *bling;
2475 +
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;
2484 +
2485 +       struct weston_transmitter_remote *remote;
2486 +       char *addr;
2487 +       char *port;
2488 +};
2489 +
2490 +/* a timerfd based timer */
2491 +struct wtimer {
2492 +       struct watch watch;
2493 +       void (*func)(struct wtimer *, void *);
2494 +       void *data;
2495 +};
2496  
2497  struct weston_transmitter {
2498         struct weston_compositor *compositor;
2499         struct wl_listener compositor_destroy_listener;
2500  
2501         struct wl_list remote_list; /* transmitter_remote::link */
2502 +
2503 +       struct wl_listener stream_listener;
2504 +       struct wl_signal connected_signal;
2505 +       struct wl_event_loop *loop;
2506  };
2507  
2508  struct weston_transmitter_remote {
2509         struct weston_transmitter *transmitter;
2510         struct wl_list link;
2511 -
2512 +       char *model;
2513         char *addr;
2514 +       char *port;
2515 +       int32_t width;
2516 +       int32_t height;
2517  
2518         enum weston_transmitter_connection_status status;
2519         struct wl_signal connection_status_signal;
2520 +        struct wl_signal conn_establish_signal;
2521  
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 */
2525  
2526 -       struct wl_event_source *conn_timer; /* fake */
2527 +        struct wl_listener establish_listener;
2528 +
2529 +        struct wl_event_source *establish_timer; /* for establish connection */
2530 +       struct wl_event_source *retry_timer; /* for retry connection */
2531 +
2532 +       struct waltham_display *display; /* waltham */
2533 +       struct wl_event_source *source;
2534  };
2535  
2536 +
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 {
2541  
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;
2546  
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;
2552  
2553 -       struct wl_event_source *map_timer; /* fake */
2554 -       struct wl_event_source *frame_timer; /* fake */
2555 -
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 */
2560 +
2561 +       /* waltham */
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;
2567  };
2568  
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;
2573  
2574 +       struct {
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;
2581 +       } parent;
2582 +
2583         struct weston_transmitter_remote *remote;
2584         struct wl_list link; /* weston_transmitter_remote::output_list */
2585 +
2586 +       struct frame *frame;
2587 +
2588 +       struct wl_callback *frame_cb;
2589 +       struct wl_listener frame_listener;
2590 +
2591 +       bool from_frame_signal;
2592  };
2593  
2594  struct weston_transmitter_seat {
2595 -       struct weston_seat base;
2596 +       struct weston_seat *base;
2597         struct wl_list link;
2598  
2599         /* pointer */
2600 @@ -124,8 +221,28 @@ struct weston_transmitter_seat {
2601         double pointer_phase; /* fake */
2602  
2603         /* keyboard */
2604 +       struct weston_transmitter_surface *keyboard_focus;
2605  
2606         /* touch */
2607 +       struct weston_transmitter_surface *touch_focus;
2608 +};
2609 +
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;
2615 +
2616 +       struct ivi_layout *layout;
2617 +       struct weston_surface *surface;
2618 +
2619 +       struct ivi_layout_surface_properties prop;
2620 +
2621 +       struct {
2622 +               struct ivi_layout_surface_properties prop;
2623 +       } pending;
2624 +
2625 +       struct wl_list view_list;       /* ivi_layout_view::surf_link */
2626  };
2627  
2628  void
2629 @@ -203,5 +320,14 @@ int
2630  transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
2631                                     struct weston_transmitter_surface *txs);
2632  
2633 +void
2634 +seat_capabilities(struct wthp_seat *wthp_seat,
2635 +                  enum wthp_seat_capability caps);
2636 +
2637 +static const struct wthp_seat_listener seat_listener = {
2638 +       seat_capabilities,
2639 +       NULL
2640 +};
2641 +
2642  
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
2648 @@ -1,5 +1,6 @@
2649  /*
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
2652   *
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.
2657          *
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.
2662          *
2663 @@ -102,12 +102,9 @@ struct weston_transmitter_api {
2664          * returned by this function. Use remote_get_status() to fetch the
2665          * current status.
2666          *
2667 -        * The address argument is a string in the form "host:port".
2668          */
2669         struct weston_transmitter_remote *
2670 -       (*connect_to_remote)(struct weston_transmitter *txr,
2671 -                            const char *addr,
2672 -                            struct wl_listener *status);
2673 +       (*connect_to_remote)(struct weston_transmitter *txr);
2674  
2675         /**
2676          * Retrieve the connection status.
2677 @@ -191,6 +188,25 @@ struct weston_transmitter_api {
2678         void
2679         (*surface_configure)(struct weston_transmitter_surface *txs,
2680                              int32_t dx, int32_t dy);
2681 +
2682 +       void
2683 +       (*surface_gather_state)(struct weston_transmitter_surface *txs);
2684 +
2685 +       /** Notify that surface is connected to receiver
2686 +        *
2687 +        * \param txr The Transmitter context.
2688 +        * \param connected_listener Listener for connected_signal.
2689 +        */
2690 +       void
2691 +       (*register_connection_status)(struct weston_transmitter *txr,
2692 +                                     struct wl_listener *connected_listener);
2693 +
2694 +       /** get weston_surface from weston_transmitter_surface
2695 +        *
2696 +        * \param txs The Transmitter surface.
2697 +        */
2698 +       struct weston_surface *
2699 +       (*get_weston_surface)(struct weston_transmitter_surface *txs);
2700  };
2701  
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
2706 --- /dev/null
2707 +++ b/transmitter/weston.ini.transmitter
2708 @@ -0,0 +1,21 @@
2709 +[core]
2710 +shell=ivi-shell.so
2711 +modules=transmitter.so
2712 +
2713 +[ivi-shell]
2714 +ivi-module=ivi-controller.so
2715 +ivi-input-module=ivi-input-controller.so
2716 +
2717 +[remote-output]
2718 +output-name=transmitter_1
2719 +server-address=192.168.2.11
2720 +port=34400
2721 +width=1920
2722 +height=1080
2723 +
2724 +[remote-output]
2725 +output-name=transmitter_2
2726 +server-address=192.168.2.12
2727 +port=34400
2728 +width=1920
2729 +height=1080
2730 -- 
2731 2.7.4
2732