a27788d71e5f36d71698b1e3be607dd6a1c57ce3
[AGL/meta-agl.git] /
1 From 2bcc81912b92d6ba7a6d24e972e0bcce2e746cab Mon Sep 17 00:00:00 2001
2 From: Wataru Mizuno <wmizuno@jp.adit-jv.com>
3 Date: Wed, 4 Jul 2018 09:09:33 +0900
4 Subject: [PATCH] transmitter: initial commit for waltham-transmitter
5
6 The waltham-transmitter is the plugin of weston to enable client
7 applications to share its surface between multiple domains.
8
9 Signed-off-by: Wataru Mizuno <wmizuno@jp.adit-jv.com>
10 ---
11  CMakeLists.txt                                     |    3 +
12  waltham-transmitter/CMakeLists.txt                 |    4 +
13  waltham-transmitter/COPYING                        |   30 +
14  .../transmitter-plugin/CMakeLists.txt              |   62 +
15  waltham-transmitter/transmitter-plugin/README      |   97 ++
16  waltham-transmitter/transmitter-plugin/input.c     | 1317 ++++++++++++++++++++
17  waltham-transmitter/transmitter-plugin/output.c    |  352 ++++++
18  waltham-transmitter/transmitter-plugin/plugin.c    |  940 ++++++++++++++
19  waltham-transmitter/transmitter-plugin/plugin.h    |  330 +++++
20  .../transmitter-plugin/transmitter_api.h           |  278 +++++
21  .../transmitter-plugin/weston.ini.transmitter      |   21 +
22  .../waltham-renderer/CMakeLists.txt                |   59 +
23  .../waltham-renderer/waltham-renderer.c            |  270 ++++
24  .../waltham-renderer/waltham-renderer.h            |   41 +
25  14 files changed, 3804 insertions(+)
26  create mode 100644 CMakeLists.txt
27  create mode 100644 waltham-transmitter/CMakeLists.txt
28  create mode 100644 waltham-transmitter/COPYING
29  create mode 100644 waltham-transmitter/transmitter-plugin/CMakeLists.txt
30  create mode 100644 waltham-transmitter/transmitter-plugin/README
31  create mode 100644 waltham-transmitter/transmitter-plugin/input.c
32  create mode 100644 waltham-transmitter/transmitter-plugin/output.c
33  create mode 100644 waltham-transmitter/transmitter-plugin/plugin.c
34  create mode 100644 waltham-transmitter/transmitter-plugin/plugin.h
35  create mode 100644 waltham-transmitter/transmitter-plugin/transmitter_api.h
36  create mode 100644 waltham-transmitter/transmitter-plugin/weston.ini.transmitter
37  create mode 100644 waltham-transmitter/waltham-renderer/CMakeLists.txt
38  create mode 100644 waltham-transmitter/waltham-renderer/waltham-renderer.c
39  create mode 100644 waltham-transmitter/waltham-renderer/waltham-renderer.h
40
41 diff --git a/CMakeLists.txt b/CMakeLists.txt
42 new file mode 100644
43 index 0000000..00fd14e
44 --- /dev/null
45 +++ b/CMakeLists.txt
46 @@ -0,0 +1,3 @@
47 +project (weston-ivi-plugins)
48 +
49 +add_subdirectory(waltham-transmitter)
50 diff --git a/waltham-transmitter/CMakeLists.txt b/waltham-transmitter/CMakeLists.txt
51 new file mode 100644
52 index 0000000..b4d1243
53 --- /dev/null
54 +++ b/waltham-transmitter/CMakeLists.txt
55 @@ -0,0 +1,4 @@
56 +project (transmitter)
57 +
58 +add_subdirectory(transmitter-plugin)
59 +add_subdirectory(waltham-renderer)
60 diff --git a/waltham-transmitter/COPYING b/waltham-transmitter/COPYING
61 new file mode 100644
62 index 0000000..faefd8f
63 --- /dev/null
64 +++ b/waltham-transmitter/COPYING
65 @@ -0,0 +1,30 @@
66 +Copyright © 2008-2012 Kristian Høgsberg
67 +Copyright © 2010-2012 Intel Corporation
68 +Copyright © 2010-2011 Benjamin Franzke
69 +Copyright © 2011-2012 Collabora, Ltd.
70 +Copyright © 2010 Red Hat <mjg@redhat.com>
71
72 +Permission is hereby granted, free of charge, to any person obtaining a
73 +copy of this software and associated documentation files (the "Software"),
74 +to deal in the Software without restriction, including without limitation
75 +the rights to use, copy, modify, merge, publish, distribute, sublicense,
76 +and/or sell copies of the Software, and to permit persons to whom the
77 +Software is furnished to do so, subject to the following conditions:
78 +
79 +The above copyright notice and this permission notice (including the next
80 +paragraph) shall be included in all copies or substantial portions of the
81 +Software.
82 +
83 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
84 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
85 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
86 +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
87 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
88 +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
89 +DEALINGS IN THE SOFTWARE.
90 +
91 +---
92 +
93 +The above is the version of the MIT "Expat" License used by X.org:
94 +
95 +    http://cgit.freedesktop.org/xorg/xserver/tree/COPYING
96 diff --git a/waltham-transmitter/transmitter-plugin/CMakeLists.txt b/waltham-transmitter/transmitter-plugin/CMakeLists.txt
97 new file mode 100644
98 index 0000000..a900d3b
99 --- /dev/null
100 +++ b/waltham-transmitter/transmitter-plugin/CMakeLists.txt
101 @@ -0,0 +1,62 @@
102 +project (transmitter)
103 +
104 +find_package(PkgConfig REQUIRED)
105 +pkg_check_modules(WAYLAND_SERVER wayland-server>=1.13.0 REQUIRED)
106 +pkg_check_modules(WESTON weston>=2.0.0 REQUIRED)
107 +pkg_check_modules(PIXMAN pixman-1 REQUIRED)
108 +pkg_check_modules(WALTHAM waltham REQUIRED)
109 +
110 +include_directories(
111 +    include
112 +    ${CMAKE_SOURCE_DIR}/waltham-transmitter/waltham-renderer
113 +    ${CMAKE_CURRENT_BINARY_DIR}
114 +    ${WAYLAND_CLIENT_INCLUDE_DIRS}
115 +    ${WAYLAND_SERVER_INCLUDE_DIRS}
116 +    ${WESTON_INCLUDE_DIRS}
117 +    ${PIXMAN_INCLUDE_DIRS}
118 +    ${WALTHAM_INCLUDE_DIRS}
119 +)
120 +
121 +link_directories(
122 +    ${WAYLAND_SERVER_LIBRARY_DIRS}
123 +    ${WESTON_LIBRARY_DIRS}
124 +    ${PIXMAN_LIBRARY_DIRS}
125 +    ${WALTHAM_LIBRARY_DIRS}
126 +)
127 +
128 +add_library(${PROJECT_NAME} MODULE
129 +    plugin.c
130 +    output.c
131 +    input.c
132 +    plugin.h
133 +    transmitter_api.h
134 +)
135 +
136 +set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
137 +
138 +set(LIBS
139 +    m
140 +    ${WAYLAND_SERVER_LIBRARIES}
141 +    ${WESTON_LIBRARIES}
142 +    ${PIXMAN_LIBRARIES}
143 +    ${WALTHAM_LIBRARIES}
144 +)
145 +
146 +SET(SRC_FILES
147 +    plugin.c
148 +    output.c
149 +    input.c
150 +    plugin.h
151 +    transmitter_api.h
152 +)
153 +
154 +
155 +
156 +add_dependencies(${PROJECT_NAME} ${LIBS})
157 +
158 +target_link_libraries(${PROJECT_NAME} ${LIBS})
159 +
160 +install (
161 +    TARGETS             ${PROJECT_NAME}
162 +    LIBRARY DESTINATION lib64/weston
163 +)
164 diff --git a/waltham-transmitter/transmitter-plugin/README b/waltham-transmitter/transmitter-plugin/README
165 new file mode 100644
166 index 0000000..345142d
167 --- /dev/null
168 +++ b/waltham-transmitter/transmitter-plugin/README
169 @@ -0,0 +1,97 @@
170 +Transmitter plugin
171 +
172 +The current implementation of Transmitter is a stub which interfaces to
173 +other Weston parts appropriately, but all networking is just a mockup.
174 +
175 +Sections in this file describe:
176 +- How to build
177 +- How to write weston.ini
178 +- How to test
179 +
180 +How to build
181 +============
182 +Configure Weston with --enable-surface-remoting to build the Transmitter
183 +plugin.
184 +
185 +How to write weston.ini
186 +=======================
187 +To load transmitter plugin to weston, add 'transmitter.so' to the 'modules'
188 +key under '[core]', and make sure the 'shell' is 'ivi-shell.so'.
189 +
190 +The destination of remoting is configured in weston.ini.
191 +Add output name, server address, port number, output's width and height key
192 +under '[remote-output]'.
193 +You can speficy multiple [remote-output].
194 +
195 +In details, see 'weston.ini.transmitter'.
196 +
197 +How to test
198 +===========
199 +You can use server side test application in waltham-server directory.
200 +
201 +If you set 'WALTHAM_DEBUG=1' to your environment valuable, you can
202 +see the log like this:
203 +
204 + [13:24:08.345] Loading module '/usr/lib64/weston/transmitter.so'
205 + [13:24:08.345] Registered plugin API 'transmitter_v1' of size 88
206 + [13:24:08.345] Registered plugin API 'transmitter_ivi_v1' of size 16
207 + [13:24:08.345] Transmitter initialized.
208 + [13:24:08.345] Loading module '/usr/lib64/libweston-2/waltham-renderer.so'
209 + [13:24:08.352] gst-setting are :-->
210 + [13:24:08.352] ip = 192.168.2.52
211 + [13:24:08.352] port = 34400
212 + [13:24:08.352] bitrate = 3000000
213 + [13:24:08.352] crop = 384 x 368
214 + [13:24:08.352] width = 1920
215 + [13:24:08.352] width = 1080
216 + [13:24:08.531] open media device: platform:fe960000.vsp (fe960000.vsp)
217 + [13:24:08.532] input pad setup ('fe960000.vsp rpf.0 input':'/dev/video0')
218 + [13:24:08.533] output pad setup (fe960000.vsp wpf.0 output:/dev/video5)
219 + [13:24:08.533] vsp-device '/dev/media0' created
220 + [13:24:08.533] gst_recorder_create (1920x1080) crop 384x368 at 0,0
221 + [13:24:08.533] gst_pipeline: starting: appsrc name=src ! omxh264enc target-bitrate=3000000 control-rate=2 no-copy=k
222 + [13:24:08.582] goot 1 pools
223 + [13:24:08.583]  pool settings size 211968, min 5, max 5
224 + [13:24:08.583] gst_recorder_create done
225 + [13:24:08.583] [gst recorder] transmitter-192.168.2.52:34400-1: recorder initialized
226 + [13:24:08.583] Transmitter weston_seat 0x15424630
227 + [13:24:08.583] Transmitter created pointer=0x15625df0 for seat 0x15424630
228 + [13:24:08.583] Transmitter created keyboard=0x154247c0 for seat 0x15424630
229 + [13:24:08.583] Transmitter created touch=0x15625f10 for seat 0x15424630
230 +
231 +The connection is established, you can see following debug messages:
232 +
233 + debug: wth_connection_insert_new_object: new object id: 1
234 + debug: wth_connection_insert_new_object: new object id: 2
235 + 2018-01-09T13:24:22Z 00001000030000000100000002000000 wth_display_get_registry
236 + debug: wth_connection_insert_new_object: new object id: 3
237 + 2018-01-09T13:24:22Z 00001000020000000100000003000000 wth_display_sync
238 + debug: Message received on conn 0x15572730: (9) 40 bytes
239 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
240 + debug: wth_connection_insert_new_object: new object id: 4
241 + 2018-01-09T13:24:22Z 00002c000800000002000000010000000400000010000000777468705f636f6d706f7369746f720001000000 wthpd
242 + debug: Message received on conn 0x15572730: (9) 48 bytes
243 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 1) (opcode 9) called.
244 + debug: wth_connection_insert_new_object: new object id: 5
245 + 2018-01-09T13:24:22Z 000034000800000002000000010000000500000015000000777468705f6976695f6170706c69636174696f6e00010d
246 + debug: Message received on conn 0x15572730: (9) 44 bytes
247 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
248 + debug: wth_connection_insert_new_object: new object id: 6
249 + 2018-01-09T13:24:22Z 000030000800000002000000010000000600000012000000777468705f626c6f625f666163746f72790001000000 d
250 + debug: Message received on conn 0x15572730: (9) 36 bytes
251 + debug: wthp_registry_send_global(2, 1, [variable type const char *], 4) (opcode 9) called.
252 + debug: wth_connection_insert_new_object: new object id: 7
253 + 2018-01-09T13:24:22Z 00002800080000000200000001000000070000000a000000777468705f736561740001000000 wthp_registry_bid
254 + debug: Message received on conn 0x15572730: (11) 16 bytes
255 + debug: wthp_callback_send_done(3, 0) (opcode 11) called.
256 +
257 +Start remoting :
258 +- Start an IVI application.
259 +- Put surface on transmitter output
260 +
261 +Weston log will indicate remoting has started:
262 +
263 +[13:18:24.572] HMI transmitting surface 0x1c3dad0, ivi-id 0x9ff6
264 +[13:18:24.572] Transmitter: update surface 0x1c3dad0 (0, 0), 0 cb
265 +[13:18:24.572] transmitter_surface_set_ivi_id(0x1c3dad0, 0x9ff6)
266 +[13:18:24.972] Transmitter: surface 0x1c3dad0 entered output transmitter-0.0.0.0:66-1
267 \ No newline at end of file
268 diff --git a/waltham-transmitter/transmitter-plugin/input.c b/waltham-transmitter/transmitter-plugin/input.c
269 new file mode 100644
270 index 0000000..e00546b
271 --- /dev/null
272 +++ b/waltham-transmitter/transmitter-plugin/input.c
273 @@ -0,0 +1,1317 @@
274 +/*
275 + * Copyright (C) 2017 Advanced Driver Information Technology Joint Venture GmbH
276 + *
277 + * Permission is hereby granted, free of charge, to any person obtaining
278 + * a copy of this software and associated documentation files (the
279 + * "Software"), to deal in the Software without restriction, including
280 + * without limitation the rights to use, copy, modify, merge, publish,
281 + * distribute, sublicense, and/or sell copies of the Software, and to
282 + * permit persons to whom the Software is furnished to do so, subject to
283 + * the following conditions:
284 + *
285 + * The above copyright notice and this permission notice (including the
286 + * next paragraph) shall be included in all copies or substantial
287 + * portions of the Software.
288 + *
289 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
290 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
291 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
292 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
293 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
294 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
295 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
296 + * SOFTWARE.
297 + */
298 +
299 +#include <stdlib.h>
300 +#include <assert.h>
301 +#include <string.h>
302 +
303 +/* for fake stuff */
304 +#include <math.h>
305 +
306 +#include "compositor.h"
307 +
308 +#include "plugin.h"
309 +#include "transmitter_api.h"
310 +
311 +/** @file
312 + *
313 + * This is an implementation of a remote input.
314 + *
315 + * Request wl_data_device_manager.get_data_device would need to be blocked,
316 + * except maybe it's not necessary, we just "forget" to forward data to/from
317 + * the remote wl_seat. It might still work inside the local compositor.
318 + *
319 + * weston_compositor_set_default_pointer_grab() will break our pointer
320 + * implementation, but no in-tree code is calling it.
321 + */
322 +
323 +/* XXX: all functions and variables with a name, and things marked with a
324 + * comment, containing the word "fake" are mockups that need to be
325 + * removed from the final implementation.
326 + */
327 +
328 +static void
329 +pointer_focus_grab_handler(struct weston_pointer_grab *grab)
330 +{
331 +       /* No-op:
332 +        *
333 +        * Weston internal events do not change the focus.
334 +        */
335 +}
336 +
337 +static void
338 +pointer_motion_grab_handler(struct weston_pointer_grab *grab,
339 +                           uint32_t time,
340 +                           struct weston_pointer_motion_event *event)
341 +{
342 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
343 +                  __func__, grab->pointer);
344 +}
345 +
346 +static void
347 +pointer_button_grab_handler(struct weston_pointer_grab *grab,
348 +                           uint32_t time,
349 +                           uint32_t button,
350 +                           uint32_t state)
351 +{
352 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
353 +                  __func__, grab->pointer);
354 +}
355 +
356 +static void
357 +pointer_axis_grab_handler(struct weston_pointer_grab *grab,
358 +                         uint32_t time,
359 +                         struct weston_pointer_axis_event *event)
360 +{
361 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
362 +                  __func__, grab->pointer);
363 +}
364 +
365 +static void
366 +pointer_axis_source_grab_handler(struct weston_pointer_grab *grab,
367 +                                uint32_t source)
368 +{
369 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
370 +                  __func__, grab->pointer);
371 +}
372 +
373 +static void
374 +pointer_frame_grab_handler(struct weston_pointer_grab *grab)
375 +{
376 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
377 +                  __func__, grab->pointer);
378 +}
379 +
380 +static void
381 +pointer_cancel_grab_handler(struct weston_pointer_grab *grab)
382 +{
383 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
384 +                  __func__, grab->pointer);
385 +}
386 +
387 +/* These handlers would be called from the notify_*() functions in src/input.c.
388 + * However, as we do not use the low level input notify_*() functions that
389 + * backends drive, these are mostly uncalled, except the focus handler which
390 + * weston core generates internally.
391 + */
392 +static const struct weston_pointer_grab_interface pointer_grab_impl = {
393 +       pointer_focus_grab_handler,
394 +       pointer_motion_grab_handler,
395 +       pointer_button_grab_handler,
396 +       pointer_axis_grab_handler,
397 +       pointer_axis_source_grab_handler,
398 +       pointer_frame_grab_handler,
399 +       pointer_cancel_grab_handler,
400 +};
401 +
402 +static void
403 +keyboard_grab_key(struct weston_keyboard_grab *grab,
404 +                 uint32_t time,
405 +                 uint32_t key,
406 +                 uint32_t state)
407 +{
408 +}
409 +
410 +static void
411 +keyboard_grab_modifiers(struct weston_keyboard_grab *grab,
412 +                       uint32_t serial,
413 +                       uint32_t mods_depressed,
414 +                       uint32_t mods_latched,
415 +                       uint32_t mods_locked,
416 +                       uint32_t group)
417 +{
418 +}
419 +
420 +static void
421 +keyboard_grab_cancel(struct weston_keyboard_grab *grab)
422 +{
423 +}
424 +
425 +static const struct weston_keyboard_grab_interface keyborad_grab_impl = {
426 +       keyboard_grab_key,
427 +       keyboard_grab_modifiers,
428 +       keyboard_grab_cancel
429 +};
430 +
431 +static void
432 +touch_grab_down_handler(struct weston_touch_grab *grab,
433 +                       uint32_t time,
434 +                       int touch_id,
435 +                       wl_fixed_t x,
436 +                       wl_fixed_t y)
437 +{
438 +}
439 +
440 +static void
441 +touch_grab_up_handler(struct weston_touch_grab *grab,
442 +                     uint32_t time,
443 +                     int touch_id)
444 +{
445 +}
446 +
447 +static void
448 +touch_grab_motion_handler(struct weston_touch_grab *grab,
449 +                         uint32_t time,
450 +                         int touch_id,
451 +                         wl_fixed_t x,
452 +                         wl_fixed_t y)
453 +{
454 +}
455 +
456 +static void
457 +touch_grab_frame_handler(struct weston_touch_grab *grab)
458 +{
459 +}
460 +
461 +static void
462 +touch_grab_cancel_handler(struct weston_touch_grab *grab)
463 +{
464 +}
465 +
466 +static const struct weston_touch_grab_interface touch_grab_impl = {
467 +       touch_grab_down_handler,
468 +       touch_grab_up_handler,
469 +       touch_grab_motion_handler,
470 +       touch_grab_frame_handler,
471 +       touch_grab_cancel_handler,
472 +};
473 +
474 +
475 +/* The different ways to get pointer focus on a remoted surface:
476 + *
477 + * 1. Transmitter seat has pointer. The client has wl_pointer. Transmitter
478 + *    receives pointer.enter. (transmitter_seat_pointer_enter())
479 + *
480 + * 2. Transmitter seat has pointer. Transmitter has received pointer.enter.
481 + *    The client calls wl_seat.get_pointer. => send enter only on the new
482 + *    wl_pointer. (seat_get_pointer_handler())
483 + *
484 + * 3. Client has wl_pointer. Transmitter seat adds pointer capability.
485 + *    Transmitter receives pointer.enter. wl_pointer MUST NOT enter,
486 + *    specified by wl_seat.capabilities.
487 + *
488 + * By definition, Transmitter cannot receive pointer.enter without having
489 + * pointer capability in the seat, so no other combinations are possible.
490 + *
491 + * The same applies to wl_keyboard and wl_touch.
492 + */
493 +
494 +/* Implementor notes:
495 + *
496 + * The handling of all of wl_pointer, wl_keyboard and wl_touch should be
497 + * similar. To make it work, we need to add a signal to each of the
498 + * wl_seat.get_pointer, wl_seat.get_keyboard, and wl_seat.get_touch request
499 + * handlers in Weston core. Otherwise we cannot implement the case 2 of gaining
500 + * input device focus.
501 + *
502 + * However, weston_keyboard::focus is a weston_surface, not a weston_view, so
503 + * we may be able to leverage more of the core implementation and maybe do
504 + * without the wl_seat.get_keyboard signal. Weston_touch uses a weston_view, so
505 + * that is similar to weston_pointer.
506 + *
507 + * It might be useful to convert weston_keyboard and weston_touch to use a
508 + * similar thing as weston_pointer_client, in case it makes things more
509 + * consistent. It might also fix issues when a client has multiple copies of a
510 + * wl_keyboard or a wl_touch, but that is getting off-topic.
511 + *
512 + * This file shows which part of the Weston input path we skip and where we
513 + * hook in. We skip everything starting from the notify_*() API used by
514 + * backends, and stub out the grab handlers. Instead of actual grab handlers,
515 + * we have our own network protocol events handlers. They do much of the same
516 + * as normal grab handlers would do, except focus is pre-given, and we do not
517 + * have weston_view for the focus surfaces, so we need to bypass core code
518 + * dealing with those.
519 + *
520 + * Our remote seat implementation will leave many struct members unused and
521 + * replicate some from weston_pointer, weston_keyboard, and weston_touch.
522 + * Weston core must be kept out from the focus handling business, because we
523 + * will send enter/leave events ourselves, and focus assignments are given
524 + * to us from the remote, they cannot be changed at will by the local Weston.
525 + */
526 +
527 +/** Callback from the protocol request handler for wl_seat.get_pointer
528 + *
529 + * The Weston core handler never sees focus set on the weston_pointer,
530 + * so it won't send wl_pointer.enter nor set focus_client. It does call
531 + * weston_pointer_ensure_pointer_client() though.
532 + */
533 +static void
534 +seat_get_pointer_handler(struct wl_listener *listener, void *data)
535 +{
536 +       struct wl_resource *new_pointer = data;
537 +       struct weston_transmitter_seat *seat;
538 +       struct wl_resource *surface;
539 +       struct weston_pointer_client *pointer_client;
540 +       struct wl_client *client;
541 +       struct weston_pointer *pointer;
542 +
543 +       seat = wl_container_of(listener, seat, get_pointer_listener);
544 +       if (!seat->pointer_focus)
545 +               return;
546 +
547 +       client = wl_resource_get_client(new_pointer);
548 +       surface = seat->pointer_focus->surface->resource;
549 +
550 +       if (wl_resource_get_client(surface) != client)
551 +               return;
552 +
553 +       pointer = weston_seat_get_pointer(seat->base);
554 +       assert(pointer); /* guaranteed by having pointer_focus */
555 +       pointer_client = weston_pointer_get_pointer_client(pointer, client);
556 +
557 +       if (!pointer->focus_client)
558 +               pointer->focus_client = pointer_client;
559 +       else
560 +               assert(pointer->focus_client == pointer_client);
561 +
562 +       wl_pointer_send_enter(new_pointer, pointer->focus_serial, surface,
563 +                             seat->pointer_surface_x, seat->pointer_surface_y);
564 +
565 +       if (wl_resource_get_version(new_pointer) >=
566 +           WL_POINTER_FRAME_SINCE_VERSION)
567 +               wl_pointer_send_frame(new_pointer);
568 +}
569 +
570 +static void
571 +transmitter_seat_create_pointer(struct weston_transmitter_seat *seat)
572 +{
573 +       struct weston_pointer *pointer;
574 +
575 +       seat->pointer_phase = 0.0;
576 +       seat->pointer_surface_x = wl_fixed_from_int(-1000000);
577 +       seat->pointer_surface_y = wl_fixed_from_int(-1000000);
578 +       seat->pointer_focus = NULL;
579 +       wl_list_init(&seat->pointer_focus_destroy_listener.link);
580 +
581 +       weston_seat_init_pointer(seat->base);
582 +
583 +       pointer = weston_seat_get_pointer(seat->base);
584 +
585 +       /* not exported:
586 +        * weston_pointer_set_default_grab(pointer, &pointer_grab_impl); */
587 +       pointer->default_grab.interface = &pointer_grab_impl;
588 +
589 +       /* Changes to local outputs are irrelevant. */
590 +       wl_list_remove(&pointer->output_destroy_listener.link);
591 +       wl_list_init(&pointer->output_destroy_listener.link);
592 +
593 +       weston_log("Transmitter created pointer=%p for seat %p\n",
594 +                  pointer, seat->base);
595 +}
596 +
597 +static void
598 +seat_pointer_focus_destroy_handler(struct wl_listener *listener, void *data)
599 +{
600 +       struct weston_transmitter_surface *txs = data;
601 +       struct weston_transmitter_seat *seat;
602 +
603 +       seat = wl_container_of(listener, seat, pointer_focus_destroy_listener);
604 +       assert(seat->pointer_focus == txs);
605 +
606 +       seat->pointer_focus = NULL;
607 +}
608 +
609 +void
610 +transmitter_seat_pointer_enter(struct weston_transmitter_seat *seat,
611 +                              uint32_t serial,
612 +                              struct weston_transmitter_surface *txs,
613 +                              wl_fixed_t surface_x,
614 +                              wl_fixed_t surface_y)
615 +{
616 +       struct wl_client *client;
617 +       struct weston_pointer *pointer;
618 +       struct wl_list *focus_resource_list;
619 +       struct wl_resource *resource;
620 +
621 +       pointer = weston_seat_get_pointer(seat->base);
622 +       assert(pointer);
623 +
624 +       assert(txs->surface);
625 +       client = wl_resource_get_client(txs->surface->resource);
626 +
627 +       seat->pointer_focus = txs;
628 +       seat->pointer_focus_destroy_listener.notify =
629 +               seat_pointer_focus_destroy_handler;
630 +       wl_signal_add(&txs->destroy_signal,
631 +                     &seat->pointer_focus_destroy_listener);
632 +
633 +       /* If pointer-focus gets destroyed, txs will get destroyed, the
634 +        * remote surface object is destroyed, and the remote will send a
635 +        * leave and a frame.
636 +        */
637 +
638 +       seat->pointer_surface_x = surface_x;
639 +       seat->pointer_surface_y = surface_y;
640 +
641 +       pointer->focus_serial = serial;
642 +
643 +       /* pointer->focus is not used, because it is a weston_view, while
644 +        * remoted surfaces have no views.
645 +        *
646 +        * pointer->x,y are not used because they are in global coordinates.
647 +        * Remoted surfaces are not in the global space at all, so there are
648 +        * no such coordinates.
649 +        */
650 +
651 +       if (!pointer->focus_client)
652 +               return;
653 +
654 +       focus_resource_list = &pointer->focus_client->pointer_resources;
655 +       wl_resource_for_each(resource, focus_resource_list) {
656 +               wl_pointer_send_enter(resource,
657 +                                     serial,
658 +                                     txs->surface->resource,
659 +                                     surface_x, surface_y);
660 +       }
661 +}
662 +
663 +void
664 +transmitter_seat_pointer_leave(struct weston_transmitter_seat *seat,
665 +                              uint32_t serial,
666 +                              struct weston_transmitter_surface *txs)
667 +{
668 +       struct weston_pointer *pointer;
669 +       struct wl_list *focus_resource_list;
670 +       struct wl_resource *surface_resource;
671 +       struct wl_resource *resource;
672 +
673 +       if (txs != seat->pointer_focus) {
674 +               weston_log("Transmitter Warning: pointer leave for %p, expected %p\n",
675 +                          txs, seat->pointer_focus);
676 +       }
677 +
678 +       seat->pointer_focus = NULL;
679 +       wl_list_remove(&seat->pointer_focus_destroy_listener.link);
680 +       wl_list_init(&seat->pointer_focus_destroy_listener.link);
681 +
682 +       if (!txs)
683 +               return;
684 +       assert(txs->surface);
685 +       surface_resource = txs->surface->resource;
686 +
687 +       pointer = weston_seat_get_pointer(seat->base);
688 +       assert(pointer);
689 +       if (!pointer->focus_client)
690 +               return;
691 +
692 +       focus_resource_list = &pointer->focus_client->pointer_resources;
693 +       wl_resource_for_each(resource, focus_resource_list)
694 +               wl_pointer_send_leave(resource, serial, surface_resource);
695 +
696 +       /* Do not reset pointer->focus_client, because we need to be able
697 +        * to send a following 'frame' event in
698 +        * transmitter_seat_pointer_frame().
699 +        */
700 +}
701 +
702 +void
703 +transmitter_seat_pointer_motion(struct weston_transmitter_seat *seat,
704 +                               uint32_t time,
705 +                               wl_fixed_t surface_x,
706 +                               wl_fixed_t surface_y)
707 +{
708 +       struct weston_pointer *pointer;
709 +       struct wl_list *focus_resource_list;
710 +       struct wl_resource *resource;
711 +       struct weston_transmitter_surface *txs;
712 +
713 +       pointer = weston_seat_get_pointer(seat->base);
714 +       assert(pointer);
715 +
716 +       seat->pointer_surface_x = surface_x;
717 +       seat->pointer_surface_y = surface_y;
718 +
719 +       if (!pointer->focus_client)
720 +               return;
721 +
722 +       txs = seat->pointer_focus;
723 +       if (txs)
724 +               assert(wl_resource_get_client(txs->surface->resource) ==
725 +                      pointer->focus_client->client);
726 +
727 +       focus_resource_list = &pointer->focus_client->pointer_resources;
728 +       wl_resource_for_each(resource, focus_resource_list) {
729 +               wl_pointer_send_motion(resource, time,
730 +                                      surface_x, surface_y);
731 +       }
732 +}
733 +
734 +void
735 +transmitter_seat_pointer_button(struct weston_transmitter_seat *seat,
736 +                               uint32_t serial,
737 +                               uint32_t time,
738 +                               uint32_t button,
739 +                               uint32_t state)
740 +{
741 +       struct weston_pointer *pointer;
742 +       struct wl_list *focus_resource_list;
743 +       struct wl_resource *resource;
744 +       struct weston_transmitter_surface *txs;
745 +
746 +       pointer = weston_seat_get_pointer(seat->base);
747 +       assert(pointer);
748 +
749 +       if (!pointer->focus_client)
750 +               return;
751 +
752 +       txs = seat->pointer_focus;
753 +       if (txs)
754 +               assert(wl_resource_get_client(txs->surface->resource) ==
755 +                      pointer->focus_client->client);
756 +
757 +       focus_resource_list = &pointer->focus_client->pointer_resources;
758 +       wl_resource_for_each(resource, focus_resource_list) {
759 +               wl_pointer_send_button(resource, serial, time,
760 +                                      button, state);
761 +        }
762 +}
763 +
764 +void
765 +transmitter_seat_pointer_axis(struct weston_transmitter_seat *seat,
766 +                             uint32_t time,
767 +                             uint32_t axis,
768 +                             wl_fixed_t value)
769 +{
770 +       struct weston_pointer *pointer;
771 +       struct wl_list *focus_resource_list;
772 +       struct wl_resource *resource;
773 +       struct weston_transmitter_surface *txs;
774 +
775 +       pointer = weston_seat_get_pointer(seat->base);
776 +       assert(pointer);
777 +
778 +       if (!pointer->focus_client)
779 +               return;
780 +
781 +       txs = seat->pointer_focus;
782 +       if (txs)
783 +               assert(wl_resource_get_client(txs->surface->resource) ==
784 +                      pointer->focus_client->client);
785 +
786 +       focus_resource_list = &pointer->focus_client->pointer_resources;
787 +       wl_resource_for_each(resource, focus_resource_list) {
788 +               wl_pointer_send_axis(resource, time,
789 +                                    axis, value);
790 +       }
791 +}
792 +
793 +void
794 +transmitter_seat_pointer_frame(struct weston_transmitter_seat *seat)
795 +{
796 +       struct weston_pointer *pointer;
797 +
798 +       pointer = weston_seat_get_pointer(seat->base);
799 +       if (pointer)
800 +               weston_pointer_send_frame(pointer);
801 +}
802 +
803 +void
804 +transmitter_seat_pointer_axis_source(struct weston_transmitter_seat *seat,
805 +                                    uint32_t axis_source)
806 +{
807 +       /* ToDo : implement axis event handling */
808 +}
809 +
810 +void
811 +transmitter_seat_pointer_axis_stop(struct weston_transmitter_seat *seat,
812 +                                  uint32_t time,
813 +                                  uint32_t axis)
814 +{
815 +       /* ToDo : implement axis event handling */
816 +}
817 +
818 +void
819 +transmitter_seat_pointer_axis_discrete(struct weston_transmitter_seat *seat,
820 +                                      uint32_t axis,
821 +                                      int32_t discrete)
822 +{
823 +       /* ToDo : implement axis event handling */
824 +}
825 +
826 +static void
827 +transmitter_seat_create_keyboard(struct weston_transmitter_seat *seat)
828 +{
829 +       struct weston_keyboard *keyboard;
830 +
831 +       seat->keyboard_focus = NULL;
832 +       weston_seat_init_keyboard(seat->base, NULL);
833 +
834 +       keyboard = weston_seat_get_keyboard(seat->base);
835 +
836 +       keyboard->default_grab.interface = &keyborad_grab_impl;
837 +
838 +       weston_log("Transmitter created keyboard=%p for seat %p\n",
839 +                  keyboard, seat->base);
840 +}
841 +
842 +static void
843 +transmitter_seat_keyboard_enter(struct weston_transmitter_seat *seat,
844 +                               uint32_t serial,
845 +                               struct weston_transmitter_surface *txs,
846 +                               struct wl_array *keys)
847 +{
848 +       struct weston_keyboard *keyboard;
849 +       struct wl_resource *resource = NULL;
850 +       struct wl_resource *surface_resource;
851 +
852 +       keyboard = weston_seat_get_keyboard(seat->base);
853 +       assert(keyboard);
854 +
855 +       assert(txs->surface);
856 +       surface_resource = txs->surface->resource;
857 +
858 +       seat->keyboard_focus = txs;
859 +       wl_array_copy(&keyboard->keys, keys);
860 +
861 +       wl_resource_for_each(resource, &keyboard->resource_list) {
862 +               if (wl_resource_get_client(resource) == wl_resource_get_client(surface_resource)) {
863 +                       wl_keyboard_send_enter(resource,
864 +                                              serial,
865 +                                              surface_resource,
866 +                                              &keyboard->keys);
867 +               }
868 +       }
869 +}
870 +
871 +static void
872 +transmitter_seat_keyboard_leave(struct weston_transmitter_seat *seat,
873 +                               uint32_t serial,
874 +                               struct weston_transmitter_surface *txs)
875 +{
876 +       struct weston_keyboard *keyboard;
877 +       struct wl_resource *resource = NULL;
878 +       struct wl_resource *surface_resource;
879 +
880 +       keyboard = weston_seat_get_keyboard(seat->base);
881 +       assert(keyboard);
882 +
883 +       assert(txs->surface);
884 +       surface_resource = txs->surface->resource;
885 +
886 +       wl_resource_for_each(resource, &keyboard->resource_list) {
887 +               if (wl_resource_get_client(resource) == wl_resource_get_client(surface_resource)) {
888 +                       wl_keyboard_send_leave(resource,
889 +                                              serial,
890 +                                              surface_resource);
891 +               }
892 +       }
893 +}
894 +
895 +static void
896 +transmitter_seat_keyboard_key(struct weston_transmitter_seat *seat,
897 +       uint32_t serial,
898 +       uint32_t time,
899 +       uint32_t key,
900 +       uint32_t state)
901 +{
902 +       struct weston_keyboard *keyboard;
903 +       struct wl_resource *resource = NULL;
904 +
905 +       keyboard = weston_seat_get_keyboard(seat->base);
906 +       assert(keyboard);
907 +
908 +       wl_resource_for_each(resource, &keyboard->resource_list) {
909 +               if (wl_resource_get_client(resource) ==
910 +                   wl_resource_get_client(seat->keyboard_focus->surface->resource)) {
911 +                       wl_keyboard_send_key(resource,
912 +                                            serial,
913 +                                            time,
914 +                                            key,
915 +                                            state);
916 +               }
917 +       }
918 +}
919 +
920 +static void
921 +transmitter_seat_create_touch(struct weston_transmitter_seat *seat)
922 +{
923 +       struct weston_touch *touch;
924 +
925 +       seat->touch_focus = NULL;
926 +       weston_seat_init_touch(seat->base);
927 +
928 +       touch = weston_seat_get_touch(seat->base);
929 +
930 +       touch->default_grab.interface = &touch_grab_impl;
931 +
932 +       weston_log("Transmitter created touch=%p for seat %p\n",
933 +                  touch, seat->base);
934 +}
935 +
936 +static void
937 +transmitter_seat_touch_down (struct weston_transmitter_seat *seat,
938 +                            uint32_t serial,
939 +                            uint32_t time,
940 +                            struct weston_transmitter_surface *txs,
941 +                            int32_t touch_id,
942 +                            wl_fixed_t x,
943 +                            wl_fixed_t y)
944 +{
945 +       struct weston_touch *touch;
946 +       struct wl_resource *resource = NULL;
947 +       struct wl_resource *surface_resource;
948 +
949 +       touch = weston_seat_get_touch(seat->base);
950 +       assert(touch);
951 +
952 +       assert(txs->surface);
953 +       surface_resource = txs->surface->resource;
954 +
955 +       seat->touch_focus = txs;
956 +
957 +       wl_resource_for_each(resource, &touch->resource_list) {
958 +               if (wl_resource_get_client(resource) == wl_resource_get_client(surface_resource)) {
959 +                       wl_touch_send_down(resource, serial, time,
960 +                                          surface_resource,
961 +                                          touch_id, x, y);
962 +               }
963 +       }
964 +}
965 +
966 +static void
967 +transmitter_seat_touch_up (struct weston_transmitter_seat *seat,
968 +                          uint32_t serial,
969 +                          uint32_t time,
970 +                          int32_t touch_id)
971 +{
972 +       struct weston_touch *touch;
973 +       struct wl_resource *resource = NULL;
974 +
975 +       touch = weston_seat_get_touch(seat->base);
976 +       assert(touch);
977 +
978 +       wl_resource_for_each(resource, &touch->resource_list) {
979 +               if (wl_resource_get_client(resource) ==
980 +                   wl_resource_get_client(seat->touch_focus->surface->resource)) {
981 +                       wl_touch_send_up(resource, serial, time, touch_id);
982 +               }
983 +       }
984 +}
985 +
986 +static void
987 +transmitter_seat_touch_motion (struct weston_transmitter_seat *seat,
988 +                              uint32_t time,
989 +                              int32_t touch_id,
990 +                              wl_fixed_t x,
991 +                              wl_fixed_t y)
992 +{
993 +       struct weston_touch *touch;
994 +       struct wl_resource *resource = NULL;
995 +
996 +       touch = weston_seat_get_touch(seat->base);
997 +       assert(touch);
998 +
999 +       wl_resource_for_each(resource, &touch->resource_list) {
1000 +               if (wl_resource_get_client(resource) ==
1001 +                   wl_resource_get_client(seat->touch_focus->surface->resource)) {
1002 +                       wl_touch_send_motion(resource, time, touch_id, x, y);
1003 +               }
1004 +       }
1005 +}
1006 +
1007 +static void
1008 +transmitter_seat_touch_frame (struct weston_transmitter_seat *seat)
1009 +{
1010 +       struct weston_touch *touch;
1011 +       struct wl_resource *resource = NULL;
1012 +
1013 +       touch = weston_seat_get_touch(seat->base);
1014 +       assert(touch);
1015 +
1016 +       wl_resource_for_each(resource, &touch->resource_list) {
1017 +               if (wl_resource_get_client(resource) ==
1018 +                   wl_resource_get_client(seat->touch_focus->surface->resource)) {
1019 +                       wl_touch_send_frame(resource);
1020 +               }
1021 +       }
1022 +}
1023 +
1024 +static void
1025 +transmitter_seat_touch_cancel (struct weston_transmitter_seat *seat)
1026 +{
1027 +       struct weston_touch *touch;
1028 +       struct wl_resource *resource = NULL;
1029 +
1030 +       touch = weston_seat_get_touch(seat->base);
1031 +       assert(touch);
1032 +
1033 +       wl_resource_for_each(resource, &touch->resource_list) {
1034 +               if (wl_resource_get_client(resource) ==
1035 +                   wl_resource_get_client(seat->touch_focus->surface->resource)) {
1036 +                       wl_touch_send_cancel(resource);
1037 +               }
1038 +       }
1039 +}
1040 +
1041 +static char *
1042 +make_seat_name(struct weston_transmitter_remote *remote, const char *name)
1043 +{
1044 +       char *str;
1045 +
1046 +       if (asprintf(&str, "transmitter-%s-%s", remote->addr, name) < 0)
1047 +               return NULL;
1048 +
1049 +       return str;
1050 +}
1051 +
1052 +void
1053 +transmitter_seat_destroy(struct weston_transmitter_seat *seat)
1054 +{
1055 +       wl_list_remove(&seat->link);
1056 +
1057 +       weston_log("Transmitter destroy seat=%p\n", seat->base);
1058 +
1059 +       wl_list_remove(&seat->get_pointer_listener.link);
1060 +       wl_list_remove(&seat->pointer_focus_destroy_listener.link);
1061 +
1062 +       if (seat->pointer_timer)
1063 +               wl_event_source_remove(seat->pointer_timer);
1064 +
1065 +       free(seat);
1066 +}
1067 +
1068 +static void
1069 +pointer_handle_enter(struct wthp_pointer *wthp_pointer,
1070 +                    uint32_t serial,
1071 +                    struct wthp_surface *surface,
1072 +                    wth_fixed_t surface_x,
1073 +                    wth_fixed_t surface_y)
1074 +{
1075 +       struct waltham_display *dpy =
1076 +               wth_object_get_user_data((struct wth_object *)wthp_pointer);
1077 +       struct weston_transmitter_remote *remote = dpy->remote;
1078 +       struct wl_list *seat_list = &remote->seat_list;
1079 +       struct weston_transmitter_seat *seat;
1080 +       struct weston_transmitter_surface *txs;
1081 +
1082 +       seat = wl_container_of(seat_list->next, seat, link);
1083 +
1084 +       wl_list_for_each(txs, &remote->surface_list, link)
1085 +       {
1086 +               if (txs->wthp_surf == surface) {
1087 +                       if (txs != seat->pointer_focus)
1088 +                               transmitter_seat_pointer_leave(seat, serial, seat->pointer_focus);
1089 +                       transmitter_seat_pointer_enter(seat, serial, txs,
1090 +                                                      surface_x, surface_y);
1091 +               }
1092 +       }
1093 +}
1094 +
1095 +static void
1096 +pointer_handle_leave(struct wthp_pointer *wthp_pointer,
1097 +                    uint32_t serial,
1098 +                    struct wthp_surface *surface)
1099 +{
1100 +       struct waltham_display *dpy =
1101 +               wth_object_get_user_data((struct wth_object *)wthp_pointer);
1102 +       struct weston_transmitter_remote *remote = dpy->remote;
1103 +       struct wl_list *seat_list = &remote->seat_list;
1104 +       struct weston_transmitter_seat *seat;
1105 +       struct weston_transmitter_surface *txs;
1106 +
1107 +       seat = wl_container_of(seat_list->next, seat, link);
1108 +
1109 +       wl_list_for_each(txs, &remote->surface_list, link)
1110 +       {
1111 +               if (txs->wthp_surf == surface) {
1112 +                       transmitter_seat_pointer_leave(seat, serial, txs);
1113 +               }
1114 +       }
1115 +}
1116 +
1117 +static void
1118 +pointer_handle_motion(struct wthp_pointer *wthp_pointer,
1119 +                     uint32_t time,
1120 +                     wth_fixed_t surface_x,
1121 +                     wth_fixed_t surface_y)
1122 +{
1123 +       struct waltham_display *dpy =
1124 +               wth_object_get_user_data((struct wth_object *)wthp_pointer);
1125 +       struct weston_transmitter_remote *remote = dpy->remote;
1126 +       struct wl_list *seat_list = &remote->seat_list;
1127 +       struct weston_transmitter_seat *seat;
1128 +
1129 +       seat = wl_container_of(seat_list->next, seat, link);
1130 +
1131 +       transmitter_seat_pointer_motion(seat, time,
1132 +                                       surface_x,
1133 +                                       surface_y);
1134 +}
1135 +
1136 +static void
1137 +pointer_handle_button(struct wthp_pointer *wthp_pointer,
1138 +                     uint32_t serial,
1139 +                     uint32_t time,
1140 +                     uint32_t button,
1141 +                     uint32_t state)
1142 +{
1143 +       struct waltham_display *dpy =
1144 +               wth_object_get_user_data((struct wth_object *)wthp_pointer);
1145 +       struct weston_transmitter_remote *remote = dpy->remote;
1146 +       struct wl_list *seat_list = &remote->seat_list;
1147 +       struct weston_transmitter_seat *seat;
1148 +
1149 +       seat = wl_container_of(seat_list->next, seat, link);
1150 +
1151 +       transmitter_seat_pointer_button(seat, serial,
1152 +                                       time, button,
1153 +                                       state);
1154 +}
1155 +
1156 +static void
1157 +pointer_handle_axis(struct wthp_pointer *wthp_pointer,
1158 +                   uint32_t time,
1159 +                   uint32_t axis, wth_fixed_t value)
1160 +{
1161 +       struct waltham_display *dpy =
1162 +               wth_object_get_user_data((struct wth_object *)wthp_pointer);
1163 +       struct weston_transmitter_remote *remote = dpy->remote;
1164 +       struct wl_list *seat_list = &remote->seat_list;
1165 +       struct weston_transmitter_seat *seat;
1166 +
1167 +       seat = wl_container_of(seat_list->next, seat, link);
1168 +
1169 +       transmitter_seat_pointer_axis(seat, time,
1170 +                                     axis, value);
1171 +}
1172 +
1173 +static void
1174 +pointer_handle_frame(struct wthp_pointer *wthp_pointer)
1175 +{
1176 +       /* ToDo : implement pointer handle frame */
1177 +}
1178 +
1179 +static void
1180 +pointer_handle_axis_source(struct wthp_pointer *wthp_pointer,
1181 +                          uint32_t axis_source)
1182 +{
1183 +       /* ToDo : implement pointer handle axis source */
1184 +}
1185 +
1186 +static void
1187 +pointer_handle_axis_stop(struct wthp_pointer *wthp_pointer,
1188 +                        uint32_t time,
1189 +                        uint32_t axis)
1190 +{
1191 +       /* ToDo : implement pointer handle axis stop */
1192 +}
1193 +
1194 +static void
1195 +pointer_handle_axis_discrete(struct wthp_pointer *wthp_pointer,
1196 +                            uint32_t axis,
1197 +                            int32_t discrete)
1198 +{
1199 +       /* ToDo : implement pointer handle axis discrete */
1200 +}
1201 +
1202 +static const struct wthp_pointer_listener pointer_listener = {
1203 +       pointer_handle_enter,
1204 +       pointer_handle_leave,
1205 +       pointer_handle_motion,
1206 +       pointer_handle_button,
1207 +       pointer_handle_axis,
1208 +       pointer_handle_frame,
1209 +       pointer_handle_axis_source,
1210 +       pointer_handle_axis_stop,
1211 +       pointer_handle_axis_discrete
1212 +};
1213 +
1214 +static void
1215 +keyboard_handle_keymap(struct wthp_keyboard * wthp_keyboard,
1216 +       uint32_t format,
1217 +       uint32_t keymap_sz,
1218 +       void * keymap)
1219 +{
1220 +       /* ToDo : implement keyboard handle keymap */
1221 +}
1222 +
1223 +static void
1224 +keyboard_handle_enter(struct wthp_keyboard *wthp_keyboard,
1225 +       uint32_t serial,
1226 +       struct wthp_surface *surface,
1227 +       struct wth_array *keys)
1228 +{
1229 +       struct waltham_display *dpy =
1230 +               wth_object_get_user_data((struct wth_object *)wthp_keyboard);
1231 +       struct weston_transmitter_remote *remote = dpy->remote;
1232 +       struct wl_list *seat_list = &remote->seat_list;
1233 +       struct weston_transmitter_seat *seat;
1234 +       struct weston_transmitter_surface *txs;
1235 +       struct wl_array *wl_key = (struct wl_array *)malloc(sizeof(struct wl_array));
1236 +
1237 +       wl_key->size = keys->size;
1238 +       wl_key->alloc = keys->alloc;
1239 +       wl_key->data = keys->data;
1240 +
1241 +       seat = wl_container_of(seat_list->next, seat, link);
1242 +
1243 +       wl_list_for_each(txs, &remote->surface_list, link)
1244 +       {
1245 +               if (txs->wthp_surf == surface) {
1246 +                       //transmitter_seat_keyboard_enter(seat, serial, txs, keys);
1247 +                       transmitter_seat_keyboard_enter(seat, serial, txs, wl_key);
1248 +               }
1249 +       }
1250 +       free(wl_key);
1251 +}
1252 +
1253 +static void
1254 +keyboard_handle_leave(struct wthp_keyboard *wthp_keyboard,
1255 +       uint32_t serial,
1256 +       struct wthp_surface *surface)
1257 +{
1258 +       struct waltham_display *dpy =
1259 +               wth_object_get_user_data((struct wth_object *)wthp_keyboard);
1260 +       struct weston_transmitter_remote *remote = dpy->remote;
1261 +       struct wl_list *seat_list = &remote->seat_list;
1262 +       struct weston_transmitter_seat *seat;
1263 +       struct weston_transmitter_surface *txs;
1264 +
1265 +       seat = wl_container_of(seat_list->next, seat, link);
1266 +
1267 +       wl_list_for_each(txs, &remote->surface_list, link)
1268 +       {
1269 +               if (txs->wthp_surf == surface) {
1270 +                       transmitter_seat_keyboard_leave(seat, serial, txs);
1271 +               }
1272 +       }
1273 +}
1274 +
1275 +static void
1276 +keyboard_handle_key(struct wthp_keyboard *wthp_keyboard,
1277 +       uint32_t serial,
1278 +       uint32_t time,
1279 +       uint32_t key,
1280 +       uint32_t state)
1281 +{
1282 +       struct waltham_display *dpy =
1283 +               wth_object_get_user_data((struct wth_object *)wthp_keyboard);
1284 +       struct weston_transmitter_remote *remote = dpy->remote;
1285 +       struct wl_list *seat_list = &remote->seat_list;
1286 +       struct weston_transmitter_seat *seat;
1287 +
1288 +       seat = wl_container_of(seat_list->next, seat, link);
1289 +
1290 +       transmitter_seat_keyboard_key(seat, serial, time, key, state);
1291 +}
1292 +
1293 +static void
1294 +keyboard_handle_modifiers(struct wthp_keyboard *wthp_keyboard,
1295 +       uint32_t serial,
1296 +       uint32_t mods_depressed,
1297 +       uint32_t mods_latched,
1298 +       uint32_t mods_locked,
1299 +       uint32_t group)
1300 +{
1301 +       weston_log("keyboard_handle_modifiers\n");
1302 +}
1303 +
1304 +static void
1305 +keyboard_handle_repeat_info(struct wthp_keyboard *wthp_keyboard,
1306 +       int32_t rate,
1307 +       int32_t delay)
1308 +{
1309 +       weston_log("keyboard_handle_repeat_info\n");
1310 +}
1311 +
1312 +static const struct wthp_keyboard_listener keyboard_listener = {
1313 +       keyboard_handle_keymap,
1314 +       keyboard_handle_enter,
1315 +       keyboard_handle_leave,
1316 +       keyboard_handle_key,
1317 +       keyboard_handle_modifiers,
1318 +       keyboard_handle_repeat_info
1319 +};
1320 +
1321 +static void
1322 +touch_handle_down (struct wthp_touch * wthp_touch,
1323 +                  uint32_t serial,
1324 +                  uint32_t time,
1325 +                  struct wthp_surface * surface,
1326 +                  int32_t id,
1327 +                  wth_fixed_t x,
1328 +                  wth_fixed_t y)
1329 +{
1330 +       struct waltham_display *dpy =
1331 +               wth_object_get_user_data((struct wth_object *)wthp_touch);
1332 +       struct weston_transmitter_remote *remote = dpy->remote;
1333 +       struct wl_list *seat_list = &remote->seat_list;
1334 +       struct weston_transmitter_seat *seat;
1335 +       struct weston_transmitter_surface *txs;
1336 +
1337 +       seat = wl_container_of(seat_list->next, seat, link);
1338 +
1339 +       wl_list_for_each(txs, &remote->surface_list, link)
1340 +       {
1341 +               if (txs->wthp_surf == surface) {
1342 +                       transmitter_seat_touch_down(seat, serial, time,
1343 +                                                   txs, id, x, y);
1344 +               }
1345 +       }
1346 +}
1347 +
1348 +static void
1349 +touch_handle_up (struct wthp_touch * wthp_touch,
1350 +                uint32_t serial,
1351 +                uint32_t time,
1352 +                int32_t id)
1353 +{
1354 +       struct waltham_display *dpy =
1355 +               wth_object_get_user_data((struct wth_object *)wthp_touch);
1356 +       struct weston_transmitter_remote *remote = dpy->remote;
1357 +       struct wl_list *seat_list = &remote->seat_list;
1358 +       struct weston_transmitter_seat *seat;
1359 +
1360 +       seat = wl_container_of(seat_list->next, seat, link);
1361 +
1362 +       transmitter_seat_touch_up(seat, serial, time, id);
1363 +}
1364 +
1365 +static void
1366 +touch_handle_motion (struct wthp_touch * wthp_touch,
1367 +                    uint32_t time,
1368 +                    int32_t id,
1369 +                    wth_fixed_t x,
1370 +                    wth_fixed_t y)
1371 +{
1372 +       struct waltham_display *dpy =
1373 +               wth_object_get_user_data((struct wth_object *)wthp_touch);
1374 +       struct weston_transmitter_remote *remote = dpy->remote;
1375 +       struct wl_list *seat_list = &remote->seat_list;
1376 +       struct weston_transmitter_seat *seat;
1377 +
1378 +       seat = wl_container_of(seat_list->next, seat, link);
1379 +
1380 +       transmitter_seat_touch_motion(seat, time, id, x, y);
1381 +}
1382 +
1383 +
1384 +static void
1385 +touch_handle_frame (struct wthp_touch * wthp_touch)
1386 +{
1387 +       struct waltham_display *dpy =
1388 +               wth_object_get_user_data((struct wth_object *)wthp_touch);
1389 +       struct weston_transmitter_remote *remote = dpy->remote;
1390 +       struct wl_list *seat_list = &remote->seat_list;
1391 +       struct weston_transmitter_seat *seat;
1392 +
1393 +       seat = wl_container_of(seat_list->next, seat, link);
1394 +
1395 +       transmitter_seat_touch_frame(seat);
1396 +}
1397 +
1398 +static void
1399 +touch_handle_cancel (struct wthp_touch * wthp_touch)
1400 +{
1401 +       struct waltham_display *dpy =
1402 +               wth_object_get_user_data((struct wth_object *)wthp_touch);
1403 +       struct weston_transmitter_remote *remote = dpy->remote;
1404 +       struct wl_list *seat_list = &remote->seat_list;
1405 +       struct weston_transmitter_seat *seat;
1406 +
1407 +       seat = wl_container_of(seat_list->next, seat, link);
1408 +
1409 +       transmitter_seat_touch_cancel(seat);
1410 +}
1411 +
1412 +
1413 +static const struct wthp_touch_listener touch_listener = {
1414 +       touch_handle_down,
1415 +       touch_handle_up,
1416 +       touch_handle_motion,
1417 +       touch_handle_frame,
1418 +       touch_handle_cancel
1419 +};
1420 +
1421 +void
1422 +seat_capabilities(struct wthp_seat *wthp_seat,
1423 +                 enum wthp_seat_capability caps)
1424 +{
1425 +       struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)wthp_seat);
1426 +
1427 +       weston_log("seat_capabilities\n");
1428 +
1429 +       if ((caps & WTHP_SEAT_CAPABILITY_POINTER) && !dpy->pointer)
1430 +       {
1431 +               weston_log("WTHP_SEAT_CAPABILITY_POINTER\n");
1432 +               dpy->pointer = wthp_seat_get_pointer(dpy->seat);
1433 +               wthp_pointer_set_listener(dpy->pointer, &pointer_listener, dpy);
1434 +       }
1435 +       if ((caps & WTHP_SEAT_CAPABILITY_KEYBOARD) && !dpy->keyboard)
1436 +       {
1437 +               weston_log("WTHP_SEAT_CAPABILITY_KEYBOARD\n");
1438 +               dpy->keyboard = wthp_seat_get_keyboard(dpy->seat);
1439 +               wthp_keyboard_set_listener(dpy->keyboard, &keyboard_listener, dpy);
1440 +       }
1441 +       if ((caps & WTHP_SEAT_CAPABILITY_TOUCH) && !dpy->touch)
1442 +       {
1443 +               weston_log("WTHP_SEAT_CAPABILITY_TOUCH\n");
1444 +               dpy->touch = wthp_seat_get_touch(dpy->seat);
1445 +               wthp_touch_set_listener(dpy->touch, &touch_listener, dpy);
1446 +       }
1447 +}
1448 +
1449 +int
1450 +transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
1451 +{
1452 +       struct weston_transmitter_seat *seat = NULL;
1453 +       char *name = NULL;
1454 +       struct weston_seat *weston_seat = NULL;
1455 +
1456 +       seat = zalloc(sizeof *seat);
1457 +       if (!seat)
1458 +               goto fail;
1459 +
1460 +       wl_list_init(&seat->get_pointer_listener.link);
1461 +       wl_list_init(&seat->pointer_focus_destroy_listener.link);
1462 +
1463 +       /* XXX: get the name from remote */
1464 +       name = make_seat_name(remote, "default");
1465 +       if (!name)
1466 +               goto fail;
1467 +
1468 +
1469 +       if (wl_list_empty(&remote->transmitter->compositor->seat_list)) {
1470 +               weston_seat = zalloc(sizeof *weston_seat);
1471 +               if (!weston_seat)
1472 +                       goto fail;
1473 +
1474 +               weston_seat_init(weston_seat, remote->transmitter->compositor, name);
1475 +               seat->base = weston_seat;
1476 +               weston_log("Transmitter created seat=%p \n", &seat->base);
1477 +       } else {
1478 +               wl_list_for_each(weston_seat, &remote->transmitter->compositor->seat_list, link) {
1479 +                       weston_log("Transmitter weston_seat %p\n", weston_seat);
1480 +                       seat->base = weston_seat;
1481 +               }
1482 +       }
1483 +
1484 +       free(name);
1485 +#if DEBUG
1486 +       weston_seat_init(&seat->base, remote->transmitter->compositor, name);
1487 +       free(name);
1488 +
1489 +       /* Hide the weston_seat from the rest of Weston, there are too many
1490 +        * things making assumptions:
1491 +        * - backends assume they control all seats
1492 +        * - shells assume they control all input foci
1493 +        * We do not want either to mess with our seat.
1494 +        */
1495 +       wl_list_remove(&seat->base.link);
1496 +       wl_list_init(&seat->base.link);
1497 +
1498 +       /* The weston_compositor::seat_created_signal has already been
1499 +        * emitted. Shells use it to subscribe to focus changes, but we should
1500 +        * never handle focus with weston core... except maybe with keyboard.
1501 +        * text-backend.c will also act on the new seat.
1502 +        * It is possible weston_seat_init() needs to be split to fix this
1503 +        * properly.
1504 +        */
1505 +
1506 +       weston_log("Transmitter created seat=%p '%s'\n",
1507 +                  &seat->base, seat->base.seat_name);
1508 +#endif
1509 +
1510 +       /* XXX: mirror remote capabilities */
1511 +       transmitter_seat_create_pointer(seat);
1512 +       transmitter_seat_create_keyboard(seat);
1513 +       transmitter_seat_create_touch(seat);
1514 +
1515 +       wl_list_insert(&remote->seat_list, &seat->link);
1516 +
1517 +       return 0;
1518 +
1519 +fail:
1520 +       free(seat);
1521 +       free(name);
1522 +
1523 +       return -1;
1524 +}
1525 +
1526 +static void
1527 +fake_pointer_get_position(struct weston_transmitter_seat *seat, double step,
1528 +                         wl_fixed_t *x, wl_fixed_t *y)
1529 +{
1530 +       double s, c;
1531 +
1532 +       seat->pointer_phase += step;
1533 +       while (seat->pointer_phase > 2.0 * M_PI)
1534 +               seat->pointer_phase -= 2.0 * M_PI;
1535 +
1536 +       sincos(seat->pointer_phase, &s, &c);
1537 +       *x = wl_fixed_from_double(100.0 + 50.0 * c);
1538 +       *y = wl_fixed_from_double(100.0 + 50.0 * s);
1539 +}
1540 +
1541 +static int
1542 +fake_pointer_timer_handler(void *data)
1543 +{
1544 +       struct weston_transmitter_seat *seat = data;
1545 +       wl_fixed_t x, y;
1546 +       uint32_t time;
1547 +
1548 +       time = weston_compositor_get_time();
1549 +
1550 +       fake_pointer_get_position(seat, 18.0 / 180.0 * M_PI, &x, &y);
1551 +       transmitter_seat_pointer_motion(seat, time, x, y);
1552 +       transmitter_seat_pointer_frame(seat);
1553 +
1554 +       wl_event_source_timer_update(seat->pointer_timer, 100);
1555 +
1556 +       return 0;
1557 +}
1558 +
1559 +int
1560 +transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
1561 +                                   struct weston_transmitter_surface *txs)
1562 +{
1563 +       struct wl_event_loop *loop;
1564 +       wl_fixed_t x, y;
1565 +       uint32_t serial = 5;
1566 +
1567 +       /* remove focus from earlier surface */
1568 +       transmitter_seat_pointer_leave(seat, serial++, seat->pointer_focus);
1569 +       transmitter_seat_pointer_frame(seat);
1570 +
1571 +       /* set pointer focus to surface */
1572 +       fake_pointer_get_position(seat, 0.0, &x, &y);
1573 +       transmitter_seat_pointer_enter(seat, serial++, txs, x, y);
1574 +       transmitter_seat_pointer_frame(seat);
1575 +
1576 +       if (!seat->pointer_timer) {
1577 +               /* schedule timer for motion */
1578 +               loop = wl_display_get_event_loop(seat->base->compositor->wl_display);
1579 +               seat->pointer_timer = wl_event_loop_add_timer(loop,
1580 +                                               fake_pointer_timer_handler, seat);
1581 +               wl_event_source_timer_update(seat->pointer_timer, 100);
1582 +       }
1583 +
1584 +       /* XXX: if the now focused surface disappears, we should call
1585 +        * transmitter_seat_pointer_leave() as part of the mockup. Otherwise
1586 +        * you get a "Transmitter Warning: no pointer->focus_client?".
1587 +        */
1588 +
1589 +       return 0;
1590 +}
1591 diff --git a/waltham-transmitter/transmitter-plugin/output.c b/waltham-transmitter/transmitter-plugin/output.c
1592 new file mode 100644
1593 index 0000000..c379ce5
1594 --- /dev/null
1595 +++ b/waltham-transmitter/transmitter-plugin/output.c
1596 @@ -0,0 +1,352 @@
1597 +/*
1598 + * Copyright (C) 2017 Advanced Driver Information Technology Joint Venture GmbH
1599 + *
1600 + * Permission is hereby granted, free of charge, to any person obtaining
1601 + * a copy of this software and associated documentation files (the
1602 + * "Software"), to deal in the Software without restriction, including
1603 + * without limitation the rights to use, copy, modify, merge, publish,
1604 + * distribute, sublicense, and/or sell copies of the Software, and to
1605 + * permit persons to whom the Software is furnished to do so, subject to
1606 + * the following conditions:
1607 + *
1608 + * The above copyright notice and this permission notice (including the
1609 + * next paragraph) shall be included in all copies or substantial
1610 + * portions of the Software.
1611 + *
1612 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1613 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1614 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1615 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1616 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1617 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1618 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1619 + * SOFTWARE.
1620 + */
1621 +
1622 +#include <stdlib.h>
1623 +#include <assert.h>
1624 +#include <string.h>
1625 +
1626 +#include "compositor.h"
1627 +#include "compositor-drm.h"
1628 +#include "plugin-registry.h"
1629 +
1630 +#include "plugin.h"
1631 +#include "transmitter_api.h"
1632 +#include "waltham-renderer.h"
1633 +
1634 +/** @file
1635 + *
1636 + * This is an implementation of a remote output.
1637 + *
1638 + * A remote output must not be accepted as an argument to:
1639 + * - wl_shell_surface.set_fullscreen
1640 + * - wl_shell_surface.set_maximized
1641 + * - zwp_fullscreen_shell_v1.present_surface
1642 + * - zwp_fullscreen_shell_v1.present_surface_for_mode
1643 + * - zwp_input_panel_surface_v1.set_toplevel
1644 + * - xdg_surface.set_fullscreen
1645 + *
1646 + * If a remote output is an argument to the above or similar requests,
1647 + * it should have the same effect as NULL if possible.
1648 + *
1649 + * @todo Should we instead accept the argument and have it start remoting
1650 + * automatically? That would be shell-specific.
1651 + *
1652 + * In ivi-shell's case, only zwp_input_panel_surface_v1.set_toplevel is
1653 + * reachable from keyboard.c. That just blindly uses whatever the first
1654 + * output happens to be, so there is no need to check for now.
1655 + *
1656 + * @todo Add weston_output_set_remote() which sets weston_output::is_remote
1657 + * to true and inits weston_output::link. This should be made mutually
1658 + * exclusive with weston_compositor_add_output().
1659 + */
1660 +
1661 +static struct waltham_renderer_interface *waltham_renderer;
1662 +
1663 +static char *
1664 +make_model(struct weston_transmitter_remote *remote, int name)
1665 +{
1666 +       char *str;
1667 +
1668 +       if (asprintf(&str, "transmitter-%s:%s-%d", remote->addr, remote->port, name) < 0)
1669 +               return NULL;
1670 +
1671 +       return str;
1672 +}
1673 +
1674 +static int
1675 +make_mode_list(struct wl_list *list,
1676 +              const struct weston_transmitter_output_info *info)
1677 +{
1678 +       struct weston_mode *mode;
1679 +
1680 +       mode = zalloc(sizeof *mode);
1681 +       if (!mode)
1682 +               return -1;
1683 +
1684 +       *mode = info->mode;
1685 +       wl_list_insert(list->prev, &mode->link);
1686 +
1687 +       return 0;
1688 +}
1689 +
1690 +static struct weston_mode *
1691 +get_current_mode(struct wl_list *mode_list)
1692 +{
1693 +       struct weston_mode *mode;
1694 +
1695 +       wl_list_for_each(mode, mode_list, link)
1696 +               if (mode->flags & WL_OUTPUT_MODE_CURRENT)
1697 +                       return mode;
1698 +
1699 +       assert(0);
1700 +       return NULL;
1701 +}
1702 +
1703 +static void
1704 +free_mode_list(struct wl_list *mode_list)
1705 +{
1706 +       struct weston_mode *mode;
1707 +
1708 +       while (!wl_list_empty(mode_list)) {
1709 +               mode = wl_container_of(mode_list->next, mode, link);
1710 +
1711 +               wl_list_remove(&mode->link);
1712 +               free(mode);
1713 +       }
1714 +}
1715 +
1716 +void
1717 +transmitter_output_destroy(struct weston_transmitter_output *output)
1718 +{
1719 +       wl_list_remove(&output->link);
1720 +
1721 +       free_mode_list(&output->base.mode_list);
1722 +       free(output->base.serial_number);
1723 +       free(output->base.model);
1724 +       free(output->base.make);
1725 +
1726 +       weston_output_destroy(&output->base);
1727 +       free(output);
1728 +}
1729 +
1730 +static void
1731 +transmitter_output_destroy_(struct weston_output *base)
1732 +{
1733 +       struct weston_transmitter_output *output = wl_container_of(base, output, base);
1734 +
1735 +       transmitter_output_destroy(output);
1736 +}
1737 +
1738 +
1739 +static void
1740 +transmitter_start_repaint_loop(struct weston_output *base)
1741 +{
1742 +       struct timespec ts;
1743 +       struct weston_transmitter_output *output = wl_container_of(base, output, base);
1744 +
1745 +       weston_compositor_read_presentation_clock(output->base.compositor, &ts);
1746 +       weston_output_finish_frame(&output->base, &ts, 0);
1747 +}
1748 +
1749 +static int
1750 +transmitter_output_repaint(struct weston_output *base,
1751 +                          pixman_region32_t *damage)
1752 +{
1753 +       struct weston_transmitter_output* output = wl_container_of(base, output, base);
1754 +       struct weston_transmitter_remote* remote = output->remote;
1755 +       struct weston_transmitter* txr = remote->transmitter;
1756 +       struct weston_transmitter_api* transmitter_api =
1757 +               weston_get_transmitter_api(txr->compositor);
1758 +       struct weston_transmitter_surface* txs;
1759 +       struct weston_compositor *compositor = base->compositor;
1760 +       struct weston_view *view;
1761 +       bool found_output = false;
1762 +       struct timespec ts;
1763 +
1764 +       struct weston_drm_output_api *api =
1765 +               weston_plugin_api_get(txr->compositor,  WESTON_DRM_OUTPUT_API_NAME, sizeof(api));
1766 +
1767 +       /*
1768 +        * Pick up weston_view in transmitter_output and check weston_view's surface
1769 +        * If the surface hasn't been conbined to weston_transmitter_surface,
1770 +        * then call push_to_remote.
1771 +        * If the surface has already been combined, call gather_state.
1772 +        */
1773 +       if (wl_list_empty(&compositor->view_list))
1774 +               goto out;
1775 +
1776 +       if (remote->status == WESTON_TRANSMITTER_CONNECTION_DISCONNECTED)
1777 +               goto out;
1778 +
1779 +       wl_list_for_each_reverse(view, &compositor->view_list, link) {
1780 +               bool found_surface = false;
1781 +               if (view->output == &output->base) {
1782 +                       found_output = true;
1783 +                       wl_list_for_each(txs, &remote->surface_list, link) {
1784 +                               if (txs->surface == view->surface) {
1785 +                                       found_surface = true;
1786 +                                       if (!txs->wthp_surf)
1787 +                                               transmitter_api->surface_push_to_remote
1788 +                                                       (view->surface, remote, NULL);
1789 +
1790 +                                       output->renderer->dmafd =
1791 +                                               api->get_dma_fd_from_view(&output->base, view);
1792 +                                       if(!output->renderer->dmafd) {
1793 +                                               weston_log("Failed to get dmafd\n");
1794 +                                               goto out;
1795 +                                       }
1796 +
1797 +                                       /*
1798 +                                        * Updating the width x height
1799 +                                        * from surface to gst-recorder
1800 +                                        */
1801 +                                       output->renderer->surface_width
1802 +                                               = view->surface->width;
1803 +                                       output->renderer->surface_height
1804 +                                               = view->surface->height;
1805 +
1806 +                                       output->renderer->repaint_output(output);
1807 +                                       output->renderer->dmafd = NULL;
1808 +                                       transmitter_api->surface_gather_state(txs);
1809 +                                       weston_buffer_reference(&view->surface->buffer_ref, NULL);
1810 +                                       break;
1811 +                               }
1812 +                       }
1813 +                       if (!found_surface)
1814 +                               transmitter_api->surface_push_to_remote(view->surface,
1815 +                                                                       remote, NULL);
1816 +               }
1817 +       }
1818 +       if (!found_output)
1819 +               goto out;
1820 +
1821 +       weston_compositor_read_presentation_clock(output->base.compositor, &ts);
1822 +       weston_output_finish_frame(&output->base, &ts, 0);
1823 +
1824 +       return 0;
1825 +
1826 +out:
1827 +       transmitter_start_repaint_loop(base);
1828 +
1829 +       return 0;
1830 +}
1831 +
1832 +static void
1833 +transmitter_assign_planes(struct weston_output *base) {
1834 +       /*
1835 +        * This function prevents compositor releasing buffer early.
1836 +        */
1837 +       struct weston_transmitter_output* output = wl_container_of(base, output, base);
1838 +       struct weston_transmitter_remote* remote = output->remote;
1839 +       struct weston_transmitter_surface* txs;
1840 +       struct weston_compositor *compositor = base->compositor;
1841 +       struct weston_view *view;
1842 +
1843 +       wl_list_for_each_reverse(view, &compositor->view_list, link) {
1844 +               if (view->output == &output->base) {
1845 +                       wl_list_for_each(txs, &remote->surface_list, link) {
1846 +                               if (txs->surface == view->surface)
1847 +                                       view->surface->keep_buffer = true;
1848 +
1849 +                       }
1850 +               }
1851 +       }
1852 +}
1853 +
1854 +static void
1855 +transmitter_output_enable(struct weston_output *base)
1856 +{
1857 +       struct weston_transmitter_output *output = wl_container_of(base, output, base);
1858 +
1859 +       output->base.assign_planes = transmitter_assign_planes;
1860 +       output->base.set_backlight = NULL;
1861 +       output->base.set_dpms = NULL;
1862 +       output->base.switch_mode = NULL;
1863 +}
1864 +
1865 +int
1866 +transmitter_remote_create_output(struct weston_transmitter_remote *remote,
1867 +                                const struct weston_transmitter_output_info *info)
1868 +{
1869 +       struct weston_transmitter_output *output;
1870 +       struct weston_transmitter *txr = remote->transmitter;
1871 +       struct weston_output *def_output;
1872 +
1873 +       output = zalloc(sizeof *output);
1874 +       if (!output)
1875 +               return -1;
1876 +
1877 +       output->parent.draw_initial_frame = true;
1878 +
1879 +       output->base.subpixel = info->subpixel;
1880 +
1881 +       output->base.name = make_model(remote, 1);
1882 +       output->base.make = strdup(WESTON_TRANSMITTER_OUTPUT_MAKE);
1883 +       output->base.model = make_model(remote, 1);
1884 +       output->base.serial_number = strdup("0");
1885 +       /* x and y is fake value */
1886 +       wl_list_init(&output->base.mode_list);
1887 +       if (make_mode_list(&output->base.mode_list, info) < 0)
1888 +               goto fail;
1889 +
1890 +       output->base.current_mode = get_current_mode(&output->base.mode_list);
1891 +       output->base.height = output->base.current_mode->height;
1892 +       output->base.width = output->base.current_mode->width;
1893 +       /* WL_OUTPUT_MODE_CURRENT already set */
1894 +       weston_output_init(&output->base, remote->transmitter->compositor);
1895 +
1896 +       /*
1897 +        * renderer_output_create skipped:
1898 +        * no renderer awareness is needed for this output
1899 +        */
1900 +
1901 +       /*
1902 +        * weston_compositor_add_output() skipped:
1903 +        * Most other code uses weston_compositor::output_list when traversing
1904 +        * all outputs, we do not want any of that.
1905 +        * Also weston_compositor::output_created_signal must not trigger
1906 +        * for this output, since we must not involve input device management
1907 +        * or color management or any kind of local management.
1908 +        */
1909 +       output->base.enable = transmitter_output_enable;
1910 +       output->base.start_repaint_loop = transmitter_start_repaint_loop;
1911 +       output->base.repaint = transmitter_output_repaint;
1912 +       output->base.destroy = transmitter_output_destroy_;
1913 +       output->base.assign_planes = NULL;
1914 +       output->base.set_dpms = NULL;
1915 +       output->base.switch_mode = NULL;
1916 +       output->base.gamma_size = 0;
1917 +       output->base.set_gamma = NULL;
1918 +
1919 +       output->base.native_mode = output->base.current_mode;
1920 +       output->base.native_scale = output->base.current_scale;
1921 +       output->base.scale = 1;
1922 +       output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1923 +
1924 +       output->remote = remote;
1925 +       wl_list_insert(&remote->output_list, &output->link);
1926 +
1927 +       /* Loading a waltham renderer library */
1928 +       waltham_renderer = weston_load_module("waltham-renderer.so","waltham_renderer_interface");
1929 +
1930 +       if (waltham_renderer->display_create(output) < 0) {
1931 +               weston_log("Failed to create waltham renderer display \n");
1932 +               return -1;
1933 +       }
1934 +
1935 +       weston_output_enable(&output->base);
1936 +
1937 +       return 0;
1938 +
1939 +fail:
1940 +       free_mode_list(&output->base.mode_list);
1941 +       free(output->base.serial_number);
1942 +       free(output->base.model);
1943 +       free(output->base.make);
1944 +       free(output->base.name);
1945 +       free(output);
1946 +
1947 +       return -1;
1948 +}
1949 diff --git a/waltham-transmitter/transmitter-plugin/plugin.c b/waltham-transmitter/transmitter-plugin/plugin.c
1950 new file mode 100644
1951 index 0000000..f643bd8
1952 --- /dev/null
1953 +++ b/waltham-transmitter/transmitter-plugin/plugin.c
1954 @@ -0,0 +1,940 @@
1955 +/*
1956 + * Copyright (C) 2017 Advanced Driver Information Technology Joint Venture GmbH
1957 + *
1958 + * Permission is hereby granted, free of charge, to any person obtaining
1959 + * a copy of this software and associated documentation files (the
1960 + * "Software"), to deal in the Software without restriction, including
1961 + * without limitation the rights to use, copy, modify, merge, publish,
1962 + * distribute, sublicense, and/or sell copies of the Software, and to
1963 + * permit persons to whom the Software is furnished to do so, subject to
1964 + * the following conditions:
1965 + *
1966 + * The above copyright notice and this permission notice (including the
1967 + * next paragraph) shall be included in all copies or substantial
1968 + * portions of the Software.
1969 + *
1970 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1971 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1972 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1973 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1974 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1975 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1976 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1977 + * SOFTWARE.
1978 + */
1979 +
1980 +#include <stdlib.h>
1981 +#include <assert.h>
1982 +#include <string.h>
1983 +#include <linux/input.h>
1984 +
1985 +#include "compositor.h"
1986 +
1987 +#include "weston.h"
1988 +#include "plugin.h"
1989 +#include "transmitter_api.h"
1990 +#include "plugin-registry.h"
1991 +#include "ivi-layout-export.h"
1992 +
1993 +/* waltham */
1994 +#include <errno.h>
1995 +#include <sys/epoll.h>
1996 +#include <sys/timerfd.h>
1997 +#include <waltham-object.h>
1998 +#include <waltham-client.h>
1999 +#include <waltham-connection.h>
2000 +
2001 +#define MAX_EPOLL_WATCHES 2
2002 +#define ESTABLISH_CONNECTION_PERIOD 2000
2003 +#define RETRY_CONNECTION_PERIOD 5000
2004 +
2005 +/* XXX: all functions and variables with a name, and things marked with a
2006 + * comment, containing the word "fake" are mockups that need to be
2007 + * removed from the final implementation.
2008 + */
2009 +
2010 +/** Send configure event through ivi-shell.
2011 + *
2012 + * \param txs The Transmitter surface.
2013 + * \param width Suggestion for surface width.
2014 + * \param height Suggestion for surface height.
2015 + *
2016 + * When the networking code receives a ivi_surface.configure event, it calls
2017 + * this function to relay it to the application.
2018 + *
2019 + * \c txs cannot be a zombie, because transmitter_surface_zombify() must
2020 + * tear down the network link, so a zombie cannot receive events.
2021 + */
2022 +void
2023 +transmitter_surface_ivi_resize(struct weston_transmitter_surface *txs,
2024 +                              int32_t width, int32_t height)
2025 +{
2026 +       assert(txs->resize_handler);
2027 +       if (!txs->resize_handler)
2028 +               return;
2029 +
2030 +       assert(txs->surface);
2031 +       if (!txs->surface)
2032 +               return;
2033 +
2034 +       txs->resize_handler(txs->resize_handler_data, width, height);
2035 +}
2036 +
2037 +static void
2038 +transmitter_surface_configure(struct weston_transmitter_surface *txs,
2039 +                             int32_t dx, int32_t dy)
2040 +{
2041 +       assert(txs->surface);
2042 +       if (!txs->surface)
2043 +               return;
2044 +
2045 +       txs->attach_dx += dx;
2046 +       txs->attach_dy += dy;
2047 +}
2048 +
2049 +static void
2050 +buffer_send_complete(struct wthp_buffer *b, uint32_t serial)
2051 +{
2052 +       if (b)
2053 +               wthp_buffer_destroy(b);
2054 +}
2055 +
2056 +static const struct wthp_buffer_listener buffer_listener = {
2057 +       buffer_send_complete
2058 +};
2059 +
2060 +static void
2061 +transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
2062 +{
2063 +       struct weston_transmitter_remote *remote = txs->remote;
2064 +       struct waltham_display *dpy = remote->display;
2065 +       int ret;
2066 +
2067 +       if(!dpy->running) {
2068 +               if(remote->status != WESTON_TRANSMITTER_CONNECTION_DISCONNECTED) {
2069 +                       remote->status = WESTON_TRANSMITTER_CONNECTION_DISCONNECTED;
2070 +                       wth_connection_destroy(remote->display->connection);
2071 +                       wl_event_source_remove(remote->source);
2072 +                       wl_event_source_timer_update(remote->retry_timer, 1);
2073 +               }
2074 +       }
2075 +       else {
2076 +               /* TODO: transmit surface state to remote */
2077 +               /* The buffer must be transmitted to remote side */
2078 +
2079 +               /* waltham */
2080 +               struct weston_surface *surf = txs->surface;
2081 +               struct weston_compositor *comp = surf->compositor;
2082 +               int32_t stride, data_sz, width, height;
2083 +               void *data;
2084 +
2085 +               width = 1;
2086 +               height = 1;
2087 +               stride = width * (PIXMAN_FORMAT_BPP(comp->read_format) / 8);
2088 +
2089 +               data = malloc(stride * height);
2090 +               data_sz = stride * height;
2091 +
2092 +               /* fake sending buffer */
2093 +               txs->wthp_buf = wthp_blob_factory_create_buffer(remote->display->blob_factory,
2094 +                                                               data_sz,
2095 +                                                               data,
2096 +                                                               surf->width,
2097 +                                                               surf->height,
2098 +                                                               stride,
2099 +                                                               PIXMAN_FORMAT_BPP(comp->read_format));
2100 +
2101 +               wthp_buffer_set_listener(txs->wthp_buf, &buffer_listener, txs);
2102 +
2103 +               wthp_surface_attach(txs->wthp_surf, txs->wthp_buf, txs->attach_dx, txs->attach_dy);
2104 +               wthp_surface_damage(txs->wthp_surf, txs->attach_dx, txs->attach_dy, surf->width, surf->height);
2105 +               wthp_surface_commit(txs->wthp_surf);
2106 +
2107 +               wth_connection_flush(remote->display->connection);
2108 +               txs->attach_dx = 0;
2109 +               txs->attach_dy = 0;
2110 +       }
2111 +}
2112 +
2113 +/** Mark the weston_transmitter_surface dead.
2114 + *
2115 + * Stop all remoting actions on this surface.
2116 + *
2117 + * Still keeps the pointer stored by a shell valid, so it can be freed later.
2118 + */
2119 +static void
2120 +transmitter_surface_zombify(struct weston_transmitter_surface *txs)
2121 +{
2122 +       struct weston_transmitter_remote *remote;
2123 +       /* may be called multiple times */
2124 +       if (!txs->surface)
2125 +               return;
2126 +
2127 +       wl_signal_emit(&txs->destroy_signal, txs);
2128 +
2129 +       wl_list_remove(&txs->surface_destroy_listener.link);
2130 +       txs->surface = NULL;
2131 +
2132 +       wl_list_remove(&txs->sync_output_destroy_listener.link);
2133 +
2134 +       remote = txs->remote;
2135 +       if (!remote->display->compositor)
2136 +               weston_log("remote->compositor is NULL\n");
2137 +       if (txs->wthp_surf)
2138 +               wthp_surface_destroy(txs->wthp_surf);
2139 +       if (txs->wthp_ivi_surface)
2140 +               wthp_ivi_surface_destroy(txs->wthp_ivi_surface);
2141 +
2142 +       /* In case called from destroy_transmitter() */
2143 +       txs->remote = NULL;
2144 +}
2145 +
2146 +static void
2147 +transmitter_surface_destroy(struct weston_transmitter_surface *txs)
2148 +{
2149 +       transmitter_surface_zombify(txs);
2150 +
2151 +       wl_list_remove(&txs->link);
2152 +       free(txs);
2153 +}
2154 +
2155 +/** weston_surface destroy signal handler */
2156 +static void
2157 +transmitter_surface_destroyed(struct wl_listener *listener, void *data)
2158 +{
2159 +       struct weston_transmitter_surface *txs =
2160 +               wl_container_of(listener, txs, surface_destroy_listener);
2161 +
2162 +       assert(data == txs->surface);
2163 +
2164 +       transmitter_surface_zombify(txs);
2165 +}
2166 +
2167 +static void
2168 +sync_output_destroy_handler(struct wl_listener *listener, void *data)
2169 +{
2170 +       struct weston_transmitter_surface *txs;
2171 +
2172 +       txs = wl_container_of(listener, txs, sync_output_destroy_listener);
2173 +
2174 +       wl_list_remove(&txs->sync_output_destroy_listener.link);
2175 +       wl_list_init(&txs->sync_output_destroy_listener.link);
2176 +
2177 +       weston_surface_force_output(txs->surface, NULL);
2178 +}
2179 +
2180 +static void
2181 +transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs)
2182 +{
2183 +        struct weston_transmitter_remote *remote = txs->remote;
2184 +       struct waltham_display *dpy = remote->display;
2185 +       struct weston_surface *ws;
2186 +       struct ivi_layout_surface **pp_surface = NULL;
2187 +       struct ivi_layout_surface *ivi_surf = NULL;
2188 +       int32_t surface_length = 0;
2189 +       int32_t ret = 0;
2190 +       int32_t i = 0;
2191 +
2192 +       ret = txs->lyt->get_surfaces(&surface_length, &pp_surface);
2193 +       if(!ret)
2194 +               weston_log("No ivi_surface\n");
2195 +
2196 +       ws = txs->surface;
2197 +
2198 +       for(i = 0; i < surface_length; i++) {
2199 +               ivi_surf = pp_surface[i];
2200 +               if (ivi_surf->surface == ws) {
2201 +                       assert(txs->surface);
2202 +                       if (!txs->surface)
2203 +                               return;
2204 +                       if(!dpy)
2205 +                               weston_log("no content in waltham_display\n");
2206 +                       if(!dpy->compositor)
2207 +                               weston_log("no content in compositor object\n");
2208 +                       if(!dpy->seat)
2209 +                               weston_log("no content in seat object\n");
2210 +                       if(!dpy->application)
2211 +                               weston_log("no content in ivi-application object\n");
2212 +
2213 +                       txs->wthp_ivi_surface = wthp_ivi_application_surface_create
2214 +                               (dpy->application, ivi_surf->id_surface,  txs->wthp_surf);
2215 +                       weston_log("surface ID %d\n", ivi_surf->id_surface);
2216 +                       if(!txs->wthp_ivi_surface){
2217 +                               weston_log("Failed to create txs->ivi_surf\n");
2218 +                       }
2219 +               }
2220 +       }
2221 +       free(pp_surface);
2222 +       pp_surface = NULL;
2223 +}
2224 +
2225 +static struct weston_transmitter_surface *
2226 +transmitter_surface_push_to_remote(struct weston_surface *ws,
2227 +                                  struct weston_transmitter_remote *remote,
2228 +                                  struct wl_listener *stream_status)
2229 +{
2230 +       struct weston_transmitter *txr = remote->transmitter;
2231 +       struct weston_transmitter_surface *txs;
2232 +       bool found = false;
2233 +
2234 +       if (remote->status != WESTON_TRANSMITTER_CONNECTION_READY)
2235 +       {
2236 +               return NULL;
2237 +       }
2238 +
2239 +       wl_list_for_each(txs, &remote->surface_list, link) {
2240 +               if (txs->surface == ws) {
2241 +                       found = true;
2242 +                       break;
2243 +               }
2244 +       }
2245 +
2246 +       if (!found) {
2247 +               txs = NULL;
2248 +               txs = zalloc(sizeof (*txs));
2249 +               if (!txs)
2250 +                       return NULL;
2251 +
2252 +               txs->remote = remote;
2253 +               wl_signal_init(&txs->destroy_signal);
2254 +               wl_list_insert(&remote->surface_list, &txs->link);
2255 +
2256 +               txs->status = WESTON_TRANSMITTER_STREAM_INITIALIZING;
2257 +               wl_signal_init(&txs->stream_status_signal);
2258 +               if (stream_status)
2259 +                       wl_signal_add(&txs->stream_status_signal, stream_status);
2260 +
2261 +               txs->surface = ws;
2262 +               txs->surface_destroy_listener.notify = transmitter_surface_destroyed;
2263 +               wl_signal_add(&ws->destroy_signal, &txs->surface_destroy_listener);
2264 +
2265 +               wl_list_init(&txs->sync_output_destroy_listener.link);
2266 +
2267 +               wl_list_init(&txs->frame_callback_list);
2268 +               wl_list_init(&txs->feedback_list);
2269 +
2270 +               txs->lyt = weston_plugin_api_get(txr->compositor,
2271 +                                                IVI_LAYOUT_API_NAME, sizeof(txs->lyt));
2272 +       }
2273 +
2274 +       /* TODO: create the content stream connection... */
2275 +       if (!remote->display->compositor)
2276 +               weston_log("remote->compositor is NULL\n");
2277 +       if (!txs->wthp_surf) {
2278 +               weston_log("txs->wthp_surf is NULL\n");
2279 +               txs->wthp_surf = wthp_compositor_create_surface(remote->display->compositor);
2280 +               transmitter_surface_set_ivi_id(txs);
2281 +       }
2282 +
2283 +       return txs;
2284 +}
2285 +
2286 +static enum weston_transmitter_stream_status
2287 +transmitter_surface_get_stream_status(struct weston_transmitter_surface *txs)
2288 +{
2289 +       return txs->status;
2290 +}
2291 +
2292 +/* waltham */
2293 +/* The server advertises a global interface.
2294 + * We can store the ad for later and/or bind to it immediately
2295 + * if we want to.
2296 + * We also need to keep track of the globals we bind to, so that
2297 + * global_remove can be handled properly (not implemented).
2298 + */
2299 +static void
2300 +registry_handle_global(struct wthp_registry *registry,
2301 +                      uint32_t name,
2302 +                      const char *interface,
2303 +                      uint32_t version)
2304 +{
2305 +       struct waltham_display *dpy = wth_object_get_user_data((struct wth_object *)registry);
2306 +
2307 +       if (strcmp(interface, "wthp_compositor") == 0) {
2308 +               assert(!dpy->compositor);
2309 +               dpy->compositor = (struct wthp_compositor *)wthp_registry_bind(registry, name, interface, 1);
2310 +               /* has no events to handle */
2311 +       } else if (strcmp(interface, "wthp_blob_factory") == 0) {
2312 +               assert(!dpy->blob_factory);
2313 +               dpy->blob_factory = (struct wthp_blob_factory *)wthp_registry_bind(registry, name, interface, 1);
2314 +               /* has no events to handle */
2315 +       } else if (strcmp(interface, "wthp_seat") == 0) {
2316 +               assert(!dpy->seat);
2317 +               dpy->seat = (struct wthp_seat *)wthp_registry_bind(registry, name, interface, 1);
2318 +               wthp_seat_set_listener(dpy->seat, &seat_listener, dpy);
2319 +       } else if (strcmp(interface, "wthp_ivi_application") == 0) {
2320 +               assert(!dpy->application);
2321 +               dpy->application = (struct wthp_ivi_application *)wthp_registry_bind(registry, name, interface, 1);
2322 +       }
2323 +}
2324 +
2325 +/* notify connection ready */
2326 +static void
2327 +conn_ready_notify(struct wl_listener *l, void *data)
2328 +{
2329 +       struct weston_transmitter_remote *remote =
2330 +         wl_container_of(l, remote, establish_listener);
2331 +       struct weston_transmitter_output_info info = {
2332 +               WL_OUTPUT_SUBPIXEL_NONE,
2333 +               WL_OUTPUT_TRANSFORM_NORMAL,
2334 +               1,
2335 +               0, 0,
2336 +               300, 200,
2337 +               strdup(remote->model),
2338 +               {
2339 +                       WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
2340 +                       800, 600,
2341 +                       51519,
2342 +                       { NULL, NULL }
2343 +               }
2344 +       };
2345 +       if(remote->width != 0) {
2346 +               if(remote->height != 0) {
2347 +                       info.mode.width = remote->width;
2348 +                       info.mode.height = remote->height;
2349 +               }
2350 +       }
2351 +       /* Outputs and seats are dynamic, do not guarantee they are all
2352 +        * present when signalling connection status.
2353 +        */
2354 +       transmitter_remote_create_output(remote, &info);
2355 +       transmitter_remote_create_seat(remote);
2356 +}
2357 +
2358 +/* waltham */
2359 +/* The server removed a global.
2360 + * We should destroy everything we created through that global,
2361 + * and destroy the objects we created by binding to it.
2362 + * The identification happens by global's name, so we need to keep
2363 + * track what names we bound.
2364 + * (not implemented)
2365 + */
2366 +static void
2367 +registry_handle_global_remove(struct wthp_registry *wthp_registry,
2368 +                             uint32_t name)
2369 +{
2370 +       if (wthp_registry)
2371 +               wthp_registry_free(wthp_registry);
2372 +}
2373 +
2374 +static const struct wthp_registry_listener registry_listener = {
2375 +       registry_handle_global,
2376 +       registry_handle_global_remove
2377 +};
2378 +
2379 +static void
2380 +connection_handle_data(struct watch *w, uint32_t events)
2381 +{
2382 +       struct waltham_display *dpy = wl_container_of(w, dpy, conn_watch);
2383 +       struct weston_transmitter_remote *remote = dpy->remote;
2384 +       int ret;
2385 +
2386 +
2387 +       if (!dpy->running) {
2388 +               weston_log("This server is not running yet. %s:%s\n", remote->addr, remote->port);
2389 +               return;
2390 +       }
2391 +
2392 +       if (events & EPOLLERR) {
2393 +               weston_log("Connection errored out.\n");
2394 +               dpy->running = false;
2395 +               remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2396 +               return;
2397 +       }
2398 +
2399 +       if (events & EPOLLOUT) {
2400 +               /* Flush out again. If the flush completes, stop
2401 +                * polling for writable as everything has been written.
2402 +                */
2403 +               ret = wth_connection_flush(dpy->connection);
2404 +       }
2405 +
2406 +       if (events & EPOLLIN) {
2407 +               /* Do not ignore EPROTO */
2408 +               ret = wth_connection_read(dpy->connection);
2409 +
2410 +               if (ret < 0) {
2411 +                       weston_log("Connection read error %s:%s\n", remote->addr, remote->port);
2412 +                       perror("Connection read error\n");
2413 +                       dpy->running = false;
2414 +                       remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2415 +                       perror("EPOLL_CTL_DEL\n");
2416 +
2417 +                       return;
2418 +               }
2419 +       }
2420 +
2421 +       if (events & EPOLLHUP) {
2422 +               weston_log("Connection hung up.\n");
2423 +               dpy->running = false;
2424 +               remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2425 +
2426 +               return;
2427 +       }
2428 +}
2429 +
2430 +static void
2431 +waltham_mainloop(int fd, uint32_t mask, void *data)
2432 +{
2433 +       struct weston_transmitter_remote *remote = data;
2434 +       struct watch *w;
2435 +       int ret;
2436 +       int running_display;
2437 +       running_display = 0;
2438 +
2439 +       struct waltham_display *dpy = remote->display;
2440 +       w = &dpy->conn_watch;
2441 +       if (!dpy)
2442 +               goto not_running;
2443 +
2444 +       if (!dpy->connection)
2445 +               dpy->running = false;
2446 +
2447 +       if (!dpy->running)
2448 +               goto not_running;
2449 +
2450 +       running_display++;
2451 +       /* Dispatch queued events. */
2452 +       ret = wth_connection_dispatch(dpy->connection);
2453 +       if (ret < 0) {
2454 +               dpy->running = false;
2455 +               remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2456 +       }
2457 +       if (!dpy->running)
2458 +               goto not_running;
2459 +
2460 +       /* Run any application idle tasks at this point. */
2461 +       /* (nothing to run so far) */
2462 +
2463 +       /* Flush out buffered requests. If the Waltham socket is
2464 +        * full, poll it for writable too, and continue flushing then.
2465 +        */
2466 +       ret = wth_connection_flush(dpy->connection);
2467 +
2468 +       if (0 < running_display) {
2469 +               /* Waltham events only read in the callback, not dispatched,
2470 +                * if the Waltham socket signalled readable. If it signalled
2471 +                * writable, flush more. See connection_handle_data().
2472 +                */
2473 +               w->cb(w, mask);
2474 +       }
2475 +
2476 +not_running:
2477 +       ;
2478 +}
2479 +
2480 +static int
2481 +waltham_client_init(struct waltham_display *dpy)
2482 +{
2483 +       if (!dpy)
2484 +               return -1;
2485 +       /*
2486 +        * get server_address from controller (adrress is set to weston.ini)
2487 +        */
2488 +       dpy->connection = wth_connect_to_server(dpy->remote->addr, dpy->remote->port);
2489 +       if(!dpy->connection) {
2490 +               return -2;
2491 +       }
2492 +       else {
2493 +               dpy->remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
2494 +               wl_signal_emit(&dpy->remote->connection_status_signal, dpy->remote);
2495 +       }
2496 +
2497 +       dpy->conn_watch.display = dpy;
2498 +       dpy->conn_watch.cb = connection_handle_data;
2499 +       dpy->conn_watch.fd = wth_connection_get_fd(dpy->connection);
2500 +       dpy->remote->source = wl_event_loop_add_fd(dpy->remote->transmitter->loop,
2501 +                                                  dpy->conn_watch.fd,
2502 +                                                  WL_EVENT_READABLE,
2503 +                                                  waltham_mainloop, dpy->remote);
2504 +
2505 +       dpy->display = wth_connection_get_display(dpy->connection);
2506 +       /* wth_display_set_listener() is already done by waltham, as
2507 +        * all the events are just control messaging.
2508 +        */
2509 +
2510 +       /* Create a registry so that we will get advertisements of the
2511 +        * interfaces implemented by the server.
2512 +        */
2513 +       dpy->registry = wth_display_get_registry(dpy->display);
2514 +       wthp_registry_set_listener(dpy->registry, &registry_listener, dpy);
2515 +
2516 +       /* Roundtrip ensures all globals' ads have been received. */
2517 +       if (wth_connection_roundtrip(dpy->connection) < 0) {
2518 +               weston_log("Roundtrip failed.\n");
2519 +               return -1;
2520 +       }
2521 +
2522 +       if (!dpy->compositor) {
2523 +               weston_log("Did not find wthp_compositor, quitting.\n");
2524 +               return -1;
2525 +       }
2526 +
2527 +       dpy->running = true;
2528 +
2529 +       return 0;
2530 +}
2531 +
2532 +static int
2533 +establish_timer_handler(void *data)
2534 +{
2535 +       struct weston_transmitter_remote *remote = data;
2536 +       int ret;
2537 +
2538 +       ret = waltham_client_init(remote->display);
2539 +       if(ret == -2) {
2540 +               wl_event_source_timer_update(remote->establish_timer,
2541 +                                            ESTABLISH_CONNECTION_PERIOD);
2542 +               return 0;
2543 +       }
2544 +       remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
2545 +       wl_signal_emit(&remote->connection_status_signal, remote);
2546 +       return 0;
2547 +}
2548 +
2549 +static void
2550 +init_globals(struct waltham_display *dpy)
2551 +{
2552 +       dpy->compositor = NULL;
2553 +       dpy->blob_factory = NULL;
2554 +       dpy->seat = NULL;
2555 +       dpy->application = NULL;
2556 +       dpy->pointer = NULL;
2557 +       dpy->keyboard = NULL;
2558 +       dpy->touch = NULL;
2559 +}
2560 +
2561 +static void
2562 +disconnect_surface(struct weston_transmitter_remote *remote)
2563 +{
2564 +       struct weston_transmitter_surface *txs;
2565 +       wl_list_for_each(txs, &remote->surface_list, link)
2566 +       {
2567 +               free(txs->wthp_ivi_surface);
2568 +               txs->wthp_ivi_surface = NULL;
2569 +               free(txs->wthp_surf);
2570 +               txs->wthp_surf = NULL;
2571 +       }
2572 +}
2573 +
2574 +static int
2575 +retry_timer_handler(void *data)
2576 +{
2577 +       struct weston_transmitter_remote *remote = data;
2578 +       struct waltham_display *dpy = remote->display;
2579 +
2580 +       if(!dpy->running)
2581 +       {
2582 +               registry_handle_global_remove(dpy->registry, 1);
2583 +               init_globals(dpy);
2584 +               disconnect_surface(remote);
2585 +               wl_event_source_timer_update(remote->establish_timer,
2586 +                                            ESTABLISH_CONNECTION_PERIOD);
2587 +
2588 +               return 0;
2589 +       }
2590 +       else
2591 +               wl_event_source_timer_update(remote->retry_timer,
2592 +                                            RETRY_CONNECTION_PERIOD);
2593 +       return 0;
2594 +}
2595 +
2596 +static struct weston_transmitter_remote *
2597 +transmitter_connect_to_remote(struct weston_transmitter *txr)
2598 +{
2599 +       struct weston_transmitter_remote *remote;
2600 +       struct wl_event_loop *loop_est, *loop_retry;
2601 +       int ret;
2602 +
2603 +       wl_list_for_each_reverse(remote, &txr->remote_list, link) {
2604 +               /* XXX: actually start connecting */
2605 +               /* waltham */
2606 +               remote->display = zalloc(sizeof *remote->display);
2607 +               if (!remote->display)
2608 +                       return NULL;
2609 +               remote->display->remote = remote;
2610 +               /* set connection establish timer */
2611 +               loop_est = wl_display_get_event_loop(txr->compositor->wl_display);
2612 +               remote->establish_timer =
2613 +                       wl_event_loop_add_timer(loop_est, establish_timer_handler, remote);
2614 +               wl_event_source_timer_update(remote->establish_timer, 1);
2615 +               /* set connection retry timer */
2616 +               loop_retry = wl_display_get_event_loop(txr->compositor->wl_display);
2617 +               remote->retry_timer =
2618 +                       wl_event_loop_add_timer(loop_retry, retry_timer_handler, remote);
2619 +               if (ret < 0) {
2620 +                       weston_log("Fatal: Transmitter waltham connecting failed.\n");
2621 +                       return NULL;
2622 +               }
2623 +               wl_signal_emit(&remote->conn_establish_signal, NULL);
2624 +       }
2625 +
2626 +       return remote;
2627 +}
2628 +
2629 +static enum weston_transmitter_connection_status
2630 +transmitter_remote_get_status(struct weston_transmitter_remote *remote)
2631 +{
2632 +       return remote->status;
2633 +}
2634 +
2635 +static void
2636 +transmitter_remote_destroy(struct weston_transmitter_remote *remote)
2637 +{
2638 +       struct weston_transmitter_surface *txs;
2639 +       struct weston_transmitter_output *output, *otmp;
2640 +       struct weston_transmitter_seat *seat, *stmp;
2641 +
2642 +       /* Do not emit connection_status_signal. */
2643 +
2644 +       /*
2645 +        *  Must not touch remote->transmitter as it may be stale:
2646 +        * the desctruction order between the shell and Transmitter is
2647 +        * undefined.
2648 +        */
2649 +
2650 +       if (!wl_list_empty(&remote->surface_list))
2651 +               weston_log("Transmitter warning: surfaces remain in %s.\n",
2652 +                          __func__);
2653 +       wl_list_for_each(txs, &remote->surface_list, link)
2654 +               txs->remote = NULL;
2655 +       wl_list_remove(&remote->surface_list);
2656 +
2657 +       wl_list_for_each_safe(seat, stmp, &remote->seat_list, link)
2658 +               transmitter_seat_destroy(seat);
2659 +
2660 +       wl_list_for_each_safe(output, otmp, &remote->output_list, link)
2661 +               transmitter_output_destroy(output);
2662 +
2663 +       free(remote->addr);
2664 +       wl_list_remove(&remote->link);
2665 +
2666 +       wl_event_source_remove(remote->source);
2667 +
2668 +       free(remote);
2669 +}
2670 +
2671 +/** Transmitter is destroyed on compositor shutdown. */
2672 +static void
2673 +transmitter_compositor_destroyed(struct wl_listener *listener, void *data)
2674 +{
2675 +       struct weston_transmitter_remote *remote;
2676 +       struct weston_transmitter_surface *txs;
2677 +       struct weston_transmitter *txr =
2678 +               wl_container_of(listener, txr, compositor_destroy_listener);
2679 +
2680 +       assert(data == txr->compositor);
2681 +
2682 +       /* may be called before or after shell cleans up */
2683 +       wl_list_for_each(remote, &txr->remote_list, link) {
2684 +               wl_list_for_each(txs, &remote->surface_list, link) {
2685 +                       transmitter_surface_zombify(txs);
2686 +               }
2687 +       }
2688 +
2689 +       /*
2690 +        * Remove the head in case the list is not empty, to avoid
2691 +        * transmitter_remote_destroy() accessing freed memory if the shell
2692 +        * cleans up after Transmitter.
2693 +        */
2694 +       wl_list_remove(&txr->remote_list);
2695 +
2696 +       free(txr);
2697 +}
2698 +
2699 +static struct weston_transmitter *
2700 +transmitter_get(struct weston_compositor *compositor)
2701 +{
2702 +       struct wl_listener *listener;
2703 +       struct weston_transmitter *txr;
2704 +
2705 +       listener = wl_signal_get(&compositor->destroy_signal,
2706 +                                transmitter_compositor_destroyed);
2707 +       if (!listener)
2708 +               return NULL;
2709 +
2710 +       txr = wl_container_of(listener, txr, compositor_destroy_listener);
2711 +       assert(compositor == txr->compositor);
2712 +
2713 +       return txr;
2714 +}
2715 +
2716 +static void
2717 +transmitter_register_connection_status(struct weston_transmitter *txr,
2718 +                                      struct wl_listener *connected_listener)
2719 +{
2720 +       wl_signal_add(&txr->connected_signal, connected_listener);
2721 +}
2722 +
2723 +static struct weston_surface *
2724 +transmitter_get_weston_surface(struct weston_transmitter_surface *txs)
2725 +{
2726 +       return txs->surface;
2727 +}
2728 +
2729 +static const struct weston_transmitter_api transmitter_api_impl = {
2730 +       transmitter_get,
2731 +       transmitter_connect_to_remote,
2732 +       transmitter_remote_get_status,
2733 +       transmitter_remote_destroy,
2734 +       transmitter_surface_push_to_remote,
2735 +       transmitter_surface_get_stream_status,
2736 +       transmitter_surface_destroy,
2737 +       transmitter_surface_configure,
2738 +       transmitter_surface_gather_state,
2739 +       transmitter_register_connection_status,
2740 +       transmitter_get_weston_surface,
2741 +};
2742 +
2743 +static void
2744 +transmitter_surface_set_resize_callback(
2745 +       struct weston_transmitter_surface *txs,
2746 +       weston_transmitter_ivi_resize_handler_t cb,
2747 +       void *data)
2748 +{
2749 +       txs->resize_handler = cb;
2750 +       txs->resize_handler_data = data;
2751 +}
2752 +
2753 +static const struct weston_transmitter_ivi_api transmitter_ivi_api_impl = {
2754 +       transmitter_surface_set_resize_callback,
2755 +};
2756 +
2757 +static int
2758 +transmitter_create_remote(struct weston_transmitter *txr,
2759 +                         const char *model,
2760 +                         const char *addr,
2761 +                         const char *port,
2762 +                         const char *width,
2763 +                         const char *height)
2764 +{
2765 +       struct weston_transmitter_remote *remote;
2766 +
2767 +       remote = zalloc(sizeof (*remote));
2768 +       if (!remote)
2769 +               return -1;
2770 +
2771 +       remote->transmitter = txr;
2772 +       wl_list_insert(&txr->remote_list, &remote->link);
2773 +       remote->model = strdup(model);
2774 +       remote->addr = strdup(addr);
2775 +       remote->port = strdup(port);
2776 +       remote->width = atoi(width);
2777 +       remote->height = atoi(height);
2778 +       remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
2779 +       wl_signal_init(&remote->connection_status_signal);
2780 +       wl_list_init(&remote->output_list);
2781 +       wl_list_init(&remote->surface_list);
2782 +       wl_list_init(&remote->seat_list);
2783 +       wl_signal_init(&remote->conn_establish_signal);
2784 +       remote->establish_listener.notify = conn_ready_notify;
2785 +       wl_signal_add(&remote->conn_establish_signal, &remote->establish_listener);
2786 +
2787 +       return 0;
2788 +}
2789 +
2790 +struct wet_compositor {
2791 +       struct weston_config *config;
2792 +       struct wet_output_config *parsed_options;
2793 +       struct wl_listener pending_output_listener;
2794 +       bool drm_use_current_mode;
2795 +};
2796 +
2797 +static void
2798 +transmitter_get_server_config(struct weston_transmitter *txr)
2799 +{
2800 +       struct wet_compositor *compositor =
2801 +               (struct wet_compositor *)weston_compositor_get_user_data(txr->compositor);
2802 +       struct weston_config *config = wet_get_config(txr->compositor);
2803 +       struct weston_config_section *section;
2804 +       const char *name = NULL;
2805 +       char *model = NULL;
2806 +       char *addr = NULL;
2807 +       char *port = NULL;
2808 +       char *width = '0';
2809 +       char *height = '0';
2810 +       int ret;
2811 +
2812 +       section = weston_config_get_section(config, "remote", NULL, NULL);
2813 +
2814 +       while (weston_config_next_section(config, &section, &name)) {
2815 +               if (0 == strcmp(name, "remote-output")) {
2816 +                       if (0 != weston_config_section_get_string(section, "output-name",
2817 +                                                                 &model, 0))
2818 +                               continue;
2819 +
2820 +                       if (0 != weston_config_section_get_string(section, "server-address",
2821 +                                                                 &addr, 0))
2822 +                               continue;
2823 +
2824 +                       if (0 != weston_config_section_get_string(section, "port",
2825 +                                                                 &port, 0))
2826 +                               continue;
2827 +
2828 +                       if (0 != weston_config_section_get_string(section, "width",
2829 +                                                                 &width, 0))
2830 +                               continue;
2831 +
2832 +                       if (0 != weston_config_section_get_string(section, "height",
2833 +                                                                 &height, 0))
2834 +                               continue;
2835 +                       ret = transmitter_create_remote(txr, model, addr,
2836 +                                                       port, width, height);
2837 +                       if (ret < 0) {
2838 +                               weston_log("Fatal: Transmitter create_remote failed.\n");
2839 +                       }
2840 +               }
2841 +       }
2842 +}
2843 +
2844 +WL_EXPORT int
2845 +wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[])
2846 +{
2847 +       struct weston_transmitter *txr;
2848 +       int ret;
2849 +
2850 +       txr = zalloc(sizeof *txr);
2851 +       if (!txr){
2852 +               weston_log("Transmitter disabled\n");
2853 +               return -1;
2854 +       }
2855 +       wl_list_init(&txr->remote_list);
2856 +
2857 +       txr->compositor = compositor;
2858 +       txr->compositor_destroy_listener.notify =
2859 +               transmitter_compositor_destroyed;
2860 +       wl_signal_add(&compositor->destroy_signal,
2861 +                     &txr->compositor_destroy_listener);
2862 +
2863 +       ret = weston_plugin_api_register(compositor,
2864 +                                        WESTON_TRANSMITTER_API_NAME,
2865 +                                        &transmitter_api_impl,
2866 +                                        sizeof(transmitter_api_impl));
2867 +       if (ret < 0) {
2868 +               weston_log("Fatal: Transmitter API registration failed.\n");
2869 +               goto fail;
2870 +       }
2871 +
2872 +       ret = weston_plugin_api_register(compositor,
2873 +                                        WESTON_TRANSMITTER_IVI_API_NAME,
2874 +                                        &transmitter_ivi_api_impl,
2875 +                                        sizeof(transmitter_ivi_api_impl));
2876 +       if (ret < 0) {
2877 +               weston_log("Fatal: Transmitter IVI API registration failed.\n");
2878 +               goto fail;
2879 +       }
2880 +
2881 +       weston_log("Transmitter initialized.\n");
2882 +
2883 +       txr->loop = wl_display_get_event_loop(compositor->wl_display);
2884 +       transmitter_get_server_config(txr);
2885 +       transmitter_connect_to_remote(txr);
2886 +
2887 +       return 0;
2888 +
2889 +fail:
2890 +       wl_list_remove(&txr->compositor_destroy_listener.link);
2891 +       free(txr);
2892 +
2893 +       return -1;
2894 +}
2895 diff --git a/waltham-transmitter/transmitter-plugin/plugin.h b/waltham-transmitter/transmitter-plugin/plugin.h
2896 new file mode 100644
2897 index 0000000..a473dab
2898 --- /dev/null
2899 +++ b/waltham-transmitter/transmitter-plugin/plugin.h
2900 @@ -0,0 +1,330 @@
2901 +/*
2902 + * Copyright (C) 2017 Advanced Driver Information Technology Joint Venture GmbH
2903 + *
2904 + * Permission is hereby granted, free of charge, to any person obtaining
2905 + * a copy of this software and associated documentation files (the
2906 + * "Software"), to deal in the Software without restriction, including
2907 + * without limitation the rights to use, copy, modify, merge, publish,
2908 + * distribute, sublicense, and/or sell copies of the Software, and to
2909 + * permit persons to whom the Software is furnished to do so, subject to
2910 + * the following conditions:
2911 + *
2912 + * The above copyright notice and this permission notice (including the
2913 + * next paragraph) shall be included in all copies or substantial
2914 + * portions of the Software.
2915 + *
2916 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2917 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2918 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2919 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2920 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2921 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2922 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2923 + * SOFTWARE.
2924 + */
2925 +
2926 +#ifndef WESTON_TRANSMITTER_PLUGIN_H
2927 +#define WESTON_TRANSMITTER_PLUGIN_H
2928 +
2929 +/* XXX: all functions and variables with a name, and things marked with a
2930 + * comment, containing the word "fake" are mockups that need to be
2931 + * removed from the final implementation.
2932 + */
2933 +
2934 +#include <stdint.h>
2935 +#include <wayland-client.h>
2936 +
2937 +#include "compositor.h"
2938 +#include "transmitter_api.h"
2939 +#include "ivi-layout-export.h"
2940 +
2941 +#include <waltham-client.h>
2942 +
2943 +
2944 +struct waltham_display;
2945 +
2946 +enum wthp_seat_capability {
2947 +       /**
2948 +        * the seat has pointer devices
2949 +        */
2950 +       WTHP_SEAT_CAPABILITY_POINTER = 1,
2951 +       /**
2952 +        * the seat has one or more keyboards
2953 +        */
2954 +       WTHP_SEAT_CAPABILITY_KEYBOARD = 2,
2955 +       /**
2956 +        * the seat has touch devices
2957 +        */
2958 +       WTHP_SEAT_CAPABILITY_TOUCH = 4,
2959 +};
2960 +
2961 +/* epoll structure */
2962 +struct watch {
2963 +       struct waltham_display *display;
2964 +       int fd;
2965 +       void (*cb)(struct watch *w, uint32_t events);
2966 +};
2967 +
2968 +struct waltham_display {
2969 +       struct wth_connection *connection;
2970 +       struct watch conn_watch;
2971 +       struct wth_display *display;
2972 +
2973 +       bool running;
2974 +
2975 +       struct wthp_registry *registry;
2976 +
2977 +       struct wthp_callback *bling;
2978 +
2979 +       struct wthp_compositor *compositor;
2980 +       struct wthp_blob_factory *blob_factory;
2981 +       struct wthp_seat *seat;
2982 +       struct wthp_pointer *pointer;
2983 +       struct wthp_keyboard *keyboard;
2984 +       struct wthp_touch *touch;
2985 +        struct wthp_ivi_application *application;
2986 +       struct wtimer *fiddle_timer;
2987 +
2988 +       struct weston_transmitter_remote *remote;
2989 +       char *addr;
2990 +       char *port;
2991 +};
2992 +
2993 +/* a timerfd based timer */
2994 +struct wtimer {
2995 +       struct watch watch;
2996 +       void (*func)(struct wtimer *, void *);
2997 +       void *data;
2998 +};
2999 +
3000 +struct weston_transmitter {
3001 +       struct weston_compositor *compositor;
3002 +       struct wl_listener compositor_destroy_listener;
3003 +
3004 +       struct wl_list remote_list; /* transmitter_remote::link */
3005 +
3006 +       struct wl_listener stream_listener;
3007 +       struct wl_signal connected_signal;
3008 +       struct wl_event_loop *loop;
3009 +};
3010 +
3011 +struct weston_transmitter_remote {
3012 +       struct weston_transmitter *transmitter;
3013 +       struct wl_list link;
3014 +       char *model;
3015 +       char *addr;
3016 +       char *port;
3017 +       int32_t width;
3018 +       int32_t height;
3019 +
3020 +       enum weston_transmitter_connection_status status;
3021 +       struct wl_signal connection_status_signal;
3022 +        struct wl_signal conn_establish_signal;
3023 +
3024 +       struct wl_list output_list; /* weston_transmitter_output::link */
3025 +       struct wl_list surface_list; /* weston_transmitter_surface::link */
3026 +       struct wl_list seat_list; /* weston_transmitter_seat::link */
3027 +
3028 +        struct wl_listener establish_listener;
3029 +
3030 +        struct wl_event_source *establish_timer; /* for establish connection */
3031 +       struct wl_event_source *retry_timer; /* for retry connection */
3032 +
3033 +       struct waltham_display *display; /* waltham */
3034 +       struct wl_event_source *source;
3035 +};
3036 +
3037 +
3038 +struct weston_transmitter_surface {
3039 +       struct weston_transmitter_remote *remote;
3040 +       struct wl_list link; /* weston_transmitter_remote::surface_list */
3041 +       struct wl_signal destroy_signal; /* data: weston_transmitter_surface */
3042 +
3043 +       enum weston_transmitter_stream_status status;
3044 +       struct wl_signal stream_status_signal;
3045 +
3046 +       struct weston_surface *surface;
3047 +       struct wl_listener surface_destroy_listener;
3048 +       const struct ivi_layout_interface *lyt;
3049 +
3050 +       weston_transmitter_ivi_resize_handler_t resize_handler;
3051 +       void *resize_handler_data;
3052 +
3053 +       struct weston_output *sync_output;
3054 +       struct wl_listener sync_output_destroy_listener;
3055 +
3056 +       int32_t attach_dx; /**< wl_surface.attach(buffer, dx, dy) */
3057 +       int32_t attach_dy; /**< wl_surface.attach(buffer, dx, dy) */
3058 +       struct wl_list frame_callback_list; /* weston_frame_callback::link */
3059 +       struct wl_list feedback_list; /* weston_presentation_feedback::link */
3060 +
3061 +       /* waltham */
3062 +       struct wthp_surface *wthp_surf;
3063 +       struct wthp_blob_factory *wthp_blob;
3064 +       struct wthp_buffer *wthp_buf;
3065 +        struct wthp_ivi_surface *wthp_ivi_surface;
3066 +        struct wthp_ivi_application *wthp_ivi_application;
3067 +};
3068 +
3069 +struct weston_transmitter_output_info {
3070 +       uint32_t subpixel; /* enum wl_output_subpixel */
3071 +       uint32_t transform; /* enum wl_output_transform */
3072 +       int32_t scale;
3073 +       int32_t x;
3074 +       int32_t y;
3075 +       int32_t width_mm;
3076 +       int32_t height_mm;
3077 +       /* char *make; is WESTON_TRANSMITTER_OUTPUT_MAKE */
3078 +       char *model;
3079 +
3080 +       struct weston_mode mode;
3081 +};
3082 +
3083 +struct weston_transmitter_output {
3084 +       struct weston_output base;
3085 +
3086 +       struct {
3087 +               bool draw_initial_frame;
3088 +               struct wl_surface *surface;
3089 +               struct wl_output *output;
3090 +               struct wl_display *display;
3091 +               int configure_width, configure_height;
3092 +               bool wait_for_configure;
3093 +       } parent;
3094 +
3095 +       struct weston_transmitter_remote *remote;
3096 +       struct wl_list link; /* weston_transmitter_remote::output_list */
3097 +
3098 +       struct frame *frame;
3099 +
3100 +       struct wl_callback *frame_cb;
3101 +       struct renderer *renderer;
3102 +};
3103 +
3104 +struct weston_transmitter_seat {
3105 +       struct weston_seat *base;
3106 +       struct wl_list link;
3107 +
3108 +       /* pointer */
3109 +       wl_fixed_t pointer_surface_x;
3110 +       wl_fixed_t pointer_surface_y;
3111 +
3112 +       struct wl_listener get_pointer_listener;
3113 +       struct weston_transmitter_surface *pointer_focus;
3114 +       struct wl_listener pointer_focus_destroy_listener;
3115 +
3116 +       struct wl_event_source *pointer_timer; /* fake */
3117 +
3118 +       double pointer_phase; /* fake */
3119 +
3120 +       /* keyboard */
3121 +       struct weston_transmitter_surface *keyboard_focus;
3122 +
3123 +       /* touch */
3124 +       struct weston_transmitter_surface *touch_focus;
3125 +};
3126 +
3127 +struct ivi_layout_surface {
3128 +       struct wl_list link;    /* ivi_layout::surface_list */
3129 +       struct wl_signal property_changed;
3130 +       int32_t update_count;
3131 +       uint32_t id_surface;
3132 +
3133 +       struct ivi_layout *layout;
3134 +       struct weston_surface *surface;
3135 +
3136 +       struct ivi_layout_surface_properties prop;
3137 +
3138 +       struct {
3139 +               struct ivi_layout_surface_properties prop;
3140 +       } pending;
3141 +
3142 +       struct wl_list view_list;       /* ivi_layout_view::surf_link */
3143 +};
3144 +
3145 +void
3146 +transmitter_surface_ivi_resize(struct weston_transmitter_surface *txs,
3147 +                              int32_t width, int32_t height);
3148 +
3149 +int
3150 +transmitter_remote_create_output(struct weston_transmitter_remote *remote,
3151 +                       const struct weston_transmitter_output_info *info);
3152 +
3153 +void
3154 +transmitter_output_destroy(struct weston_transmitter_output *output);
3155 +
3156 +int
3157 +transmitter_remote_create_seat(struct weston_transmitter_remote *remote);
3158 +
3159 +void
3160 +transmitter_seat_destroy(struct weston_transmitter_seat *seat);
3161 +
3162 +/* The below are the functions to be called from the network protocol
3163 + * input event handlers.
3164 + */
3165 +
3166 +void
3167 +transmitter_seat_pointer_enter(struct weston_transmitter_seat *seat,
3168 +                              uint32_t serial,
3169 +                              struct weston_transmitter_surface *txs,
3170 +                              wl_fixed_t surface_x,
3171 +                              wl_fixed_t surface_y);
3172 +
3173 +void
3174 +transmitter_seat_pointer_leave(struct weston_transmitter_seat *seat,
3175 +                              uint32_t serial,
3176 +                              struct weston_transmitter_surface *txs);
3177 +
3178 +void
3179 +transmitter_seat_pointer_motion(struct weston_transmitter_seat *seat,
3180 +                               uint32_t time,
3181 +                               wl_fixed_t surface_x,
3182 +                               wl_fixed_t surface_y);
3183 +
3184 +void
3185 +transmitter_seat_pointer_button(struct weston_transmitter_seat *seat,
3186 +                               uint32_t serial,
3187 +                               uint32_t time,
3188 +                               uint32_t button,
3189 +                               uint32_t state);
3190 +
3191 +void
3192 +transmitter_seat_pointer_axis(struct weston_transmitter_seat *seat,
3193 +                             uint32_t time,
3194 +                             uint32_t axis,
3195 +                             wl_fixed_t value);
3196 +
3197 +void
3198 +transmitter_seat_pointer_frame(struct weston_transmitter_seat *seat);
3199 +
3200 +void
3201 +transmitter_seat_pointer_axis_source(struct weston_transmitter_seat *seat,
3202 +                                    uint32_t axis_source);
3203 +
3204 +void
3205 +transmitter_seat_pointer_axis_stop(struct weston_transmitter_seat *seat,
3206 +                                  uint32_t time,
3207 +                                  uint32_t axis);
3208 +
3209 +void
3210 +transmitter_seat_pointer_axis_discrete(struct weston_transmitter_seat *seat,
3211 +                                      uint32_t axis,
3212 +                                      int32_t discrete);
3213 +
3214 +/* Fake functions for mockup testing: */
3215 +
3216 +int
3217 +transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
3218 +                                   struct weston_transmitter_surface *txs);
3219 +
3220 +void
3221 +seat_capabilities(struct wthp_seat *wthp_seat,
3222 +                  enum wthp_seat_capability caps);
3223 +
3224 +static const struct wthp_seat_listener seat_listener = {
3225 +       seat_capabilities,
3226 +       NULL
3227 +};
3228 +
3229 +
3230 +#endif /* WESTON_TRANSMITTER_PLUGIN_H */
3231 diff --git a/waltham-transmitter/transmitter-plugin/transmitter_api.h b/waltham-transmitter/transmitter-plugin/transmitter_api.h
3232 new file mode 100644
3233 index 0000000..9b3e5fe
3234 --- /dev/null
3235 +++ b/waltham-transmitter/transmitter-plugin/transmitter_api.h
3236 @@ -0,0 +1,278 @@
3237 +/*
3238 + * Copyright (C) 2017 Advanced Driver Information Technology Joint Venture GmbH
3239 + *
3240 + * Permission is hereby granted, free of charge, to any person obtaining
3241 + * a copy of this software and associated documentation files (the
3242 + * "Software"), to deal in the Software without restriction, including
3243 + * without limitation the rights to use, copy, modify, merge, publish,
3244 + * distribute, sublicense, and/or sell copies of the Software, and to
3245 + * permit persons to whom the Software is furnished to do so, subject to
3246 + * the following conditions:
3247 + *
3248 + * The above copyright notice and this permission notice (including the
3249 + * next paragraph) shall be included in all copies or substantial
3250 + * portions of the Software.
3251 + *
3252 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3253 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3254 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3255 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3256 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3257 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3258 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3259 + * SOFTWARE.
3260 + */
3261 +
3262 +#ifndef WESTON_TRANSMITTER_API_H
3263 +#define WESTON_TRANSMITTER_API_H
3264 +
3265 +#include "plugin-registry.h"
3266 +
3267 +#include <stdint.h>
3268 +
3269 +/** \file
3270 + *
3271 + * This is the Transmitter API published via weston_plugin_api_register().
3272 + */
3273 +
3274 +struct weston_transmitter;
3275 +struct weston_transmitter_remote;
3276 +struct weston_transmitter_surface;
3277 +
3278 +#define WESTON_TRANSMITTER_API_NAME "transmitter_v1"
3279 +
3280 +/** See weston_transmitter_api::remote_get_status */
3281 +enum weston_transmitter_connection_status {
3282 +       /** The connection hand-shake is not yet complete */
3283 +       WESTON_TRANSMITTER_CONNECTION_INITIALIZING,
3284 +
3285 +       /** The connection is live and ready to be used. */
3286 +       WESTON_TRANSMITTER_CONNECTION_READY,
3287 +
3288 +       /** The connection is dead. */
3289 +       WESTON_TRANSMITTER_CONNECTION_DISCONNECTED,
3290 +};
3291 +
3292 +/** See weston_transmitter_api::surface_get_stream_status */
3293 +enum weston_transmitter_stream_status {
3294 +       /** The stream hand-shake is not yet complete. */
3295 +       WESTON_TRANSMITTER_STREAM_INITIALIZING,
3296 +
3297 +       /** The stream is carrying surface content updates as needed. */
3298 +       WESTON_TRANSMITTER_STREAM_LIVE,
3299 +
3300 +       /** The stream has failed and disconnected permanently. */
3301 +       WESTON_TRANSMITTER_STREAM_FAILED,
3302 +};
3303 +
3304 +/** The Transmitter Base API
3305 + *
3306 + * Transmitter is a Weston plugin that provides remoting of weston_surfaces
3307 + * over the network. Shells use this API to create remote connections and
3308 + * push surfaces over the network. Shells are also responsible for relaying
3309 + * basic window state changes to Transmitter.
3310 + *
3311 + * In addition to the Transmitter Base API, shells also need to use a
3312 + * shell protocol specific Transmitter API to relay specific window state
3313 + * changes.
3314 + */
3315 +struct weston_transmitter_api {
3316 +       /** Fetch the Transmitter plugin context
3317 +        *
3318 +        * \param compositor The compositor instance.
3319 +        * \return The weston_transmitter context, which is always the same
3320 +        * for the given compositor instance.
3321 +        */
3322 +       struct weston_transmitter *
3323 +       (*transmitter_get)(struct weston_compositor *compositor);
3324 +
3325 +       /**
3326 +        * Connect to a remote server via Transmitter.
3327 +        *
3328 +        * \param txr The Transmitter context.
3329 +        * \param status Listener to inform of connection status changes.
3330 +        * \return A handle to the remote connection, or NULL on failure.
3331 +        *
3332 +        * This call attempts to open a connection asynchronously. The
3333 +        * connection is not usable until the listener signals it is ready.
3334 +        * The listener may also signal that the connection failed instead.
3335 +        *
3336 +        * The listener callback argument is the weston_transmitter_remote
3337 +        * returned by this function. Use remote_get_status() to fetch the
3338 +        * current status.
3339 +        *
3340 +        */
3341 +       struct weston_transmitter_remote *
3342 +       (*connect_to_remote)(struct weston_transmitter *txr);
3343 +
3344 +       /**
3345 +        * Retrieve the connection status.
3346 +        *
3347 +        * If the status is WESTON_TRANSMITTER_CONNECTION_DISCONNECTED,
3348 +        * you have to shut the remote down completely. There is no automatic
3349 +        * reconnect.
3350 +        */
3351 +       enum weston_transmitter_connection_status
3352 +       (*remote_get_status)(struct weston_transmitter_remote *remote);
3353 +
3354 +       /**
3355 +        * Destroy/disconnect a remote connection.
3356 +        *
3357 +        * Disconnects if connected, and destroys the connection.
3358 +        * The connection status handler is not called.
3359 +        *
3360 +        * The caller is responsible for destroying all
3361 +        * weston_transmitter_surfaces before calling this.
3362 +        */
3363 +       void
3364 +       (*remote_destroy)(struct weston_transmitter_remote *remote);
3365 +
3366 +       /** Push a weston_surface to be transmitted to a remote.
3367 +        *
3368 +        * \param ws The surface to push.
3369 +        * \param remote The remote connection to use.
3370 +        * \param stream_status Listener for stream status changes.
3371 +        * \return The Transmitter surface handle.
3372 +        *
3373 +        * The surface cannot be visible on the remote until the stream
3374 +        * status listener signals WESTON_TRANSMITTER_STREAM_LIVE. After that,
3375 +        * surface updates made by the application will be automatically
3376 +        * streamed to the remote, and input events from the remote will be
3377 +        * delivered to the application.
3378 +        *
3379 +        * The listener callback argument is the weston_transmitter_surface
3380 +        * returned by this function. Use surface_get_stream_status() to
3381 +        * fetch the current status.
3382 +        */
3383 +       struct weston_transmitter_surface *
3384 +       (*surface_push_to_remote)(struct weston_surface *ws,
3385 +                                 struct weston_transmitter_remote *remote,
3386 +                                 struct wl_listener *stream_status);
3387 +
3388 +       /**
3389 +        * Retrieve the surface content stream status.
3390 +        *
3391 +        * If the status is WESTON_TRANSMITTER_STREAM_FAILED, remoting the
3392 +        * surface has stopped. There is no automatic retry.
3393 +        */
3394 +       enum weston_transmitter_stream_status
3395 +       (*surface_get_stream_status)(struct weston_transmitter_surface *txs);
3396 +
3397 +       /** Stop remoting a weston_surface
3398 +        *
3399 +        * \param txs Transmitter surface handle to be stopped and freed.
3400 +        *
3401 +        * The surface stream status handler is not called.
3402 +        */
3403 +       void
3404 +       (*surface_destroy)(struct weston_transmitter_surface *txs);
3405 +
3406 +       /** Notify of weston_surface being configured
3407 +        *
3408 +        * \param txs The Transmitter surface handle.
3409 +        * \param dx The x delta given in wl_surface.attach request.
3410 +        * \param dy The y delta given in wl_surface.attach request.
3411 +        *
3412 +        * Notifies Transmitter of new surface confguration. Transmitter will
3413 +        * forward the arguments, window state, and reference the buffer for
3414 +        * image transmission.
3415 +        *
3416 +        * Shells are meant to call this function for remoted surfaces in
3417 +        * the weston_surface::configure handler.
3418 +        *
3419 +        * XXX: Is this necessary if we have weston_surface::apply_state_signal?
3420 +        *
3421 +        * Essentially this is just an elaborate way to forward dx,dy.
3422 +        */
3423 +       void
3424 +       (*surface_configure)(struct weston_transmitter_surface *txs,
3425 +                            int32_t dx, int32_t dy);
3426 +
3427 +       void
3428 +       (*surface_gather_state)(struct weston_transmitter_surface *txs);
3429 +
3430 +       /** Notify that surface is connected to receiver
3431 +        *
3432 +        * \param txr The Transmitter context.
3433 +        * \param connected_listener Listener for connected_signal.
3434 +        */
3435 +       void
3436 +       (*register_connection_status)(struct weston_transmitter *txr,
3437 +                                     struct wl_listener *connected_listener);
3438 +
3439 +       /** get weston_surface from weston_transmitter_surface
3440 +        *
3441 +        * \param txs The Transmitter surface.
3442 +        */
3443 +       struct weston_surface *
3444 +       (*get_weston_surface)(struct weston_transmitter_surface *txs);
3445 +};
3446 +
3447 +static inline const struct weston_transmitter_api *
3448 +weston_get_transmitter_api(struct weston_compositor *compositor)
3449 +{
3450 +       return weston_plugin_api_get(compositor, WESTON_TRANSMITTER_API_NAME,
3451 +                                    sizeof(struct weston_transmitter_api));
3452 +}
3453 +
3454 +#define WESTON_TRANSMITTER_IVI_API_NAME "transmitter_ivi_v1"
3455 +
3456 +/** For relaying configure events from Transmitter to shell. */
3457 +typedef void (*weston_transmitter_ivi_resize_handler_t)(void *data,
3458 +                                                       int32_t width,
3459 +                                                       int32_t height);
3460 +
3461 +/** The Transmitter IVI-shell API
3462 + *
3463 + * Contains the IVI-shell specifics required to remote an ivi-surface.
3464 + */
3465 +struct weston_transmitter_ivi_api {
3466 +       /** Set IVI-id for a transmitter surface
3467 +        *
3468 +        * \param txs The transmitted surface.
3469 +        * \param ivi_id The IVI-surface id as specified by the
3470 +        * ivi_application.surface_create request.
3471 +        */
3472 +       void
3473 +       (*set_ivi_id)(struct weston_transmitter_surface *txs, uint32_t ivi_id);
3474 +
3475 +       /** Set callback to relay configure events.
3476 +        *
3477 +        * \param txs The transmitted surface.
3478 +        * \param cb The callback function pointer.
3479 +        * \param data User data to be passed to the callback.
3480 +        *
3481 +        * The arguments to the callback function are user data, and width and
3482 +        * height from the configure event from the remote compositor. The
3483 +        * shell must relay this event to the application.
3484 +        */
3485 +       void
3486 +       (*set_resize_callback)(struct weston_transmitter_surface *txs,
3487 +                              weston_transmitter_ivi_resize_handler_t cb,
3488 +                              void *data);
3489 +};
3490 +
3491 +static inline const struct weston_transmitter_ivi_api *
3492 +weston_get_transmitter_ivi_api(struct weston_compositor *compositor)
3493 +{
3494 +       return weston_plugin_api_get(compositor,
3495 +                                    WESTON_TRANSMITTER_IVI_API_NAME,
3496 +                                    sizeof(struct weston_transmitter_ivi_api));
3497 +}
3498 +
3499 +/** Identifies outputs created by the Transmitter by make */
3500 +#define WESTON_TRANSMITTER_OUTPUT_MAKE "Weston-Transmitter"
3501 +
3502 +/* Remote compositor/output are identified by model */
3503 +
3504 +
3505 +struct renderer {
3506 +       void (*repaint_output)(struct weston_output *base);
3507 +       struct GstAppContext *ctx;
3508 +       int32_t dmafd;    /* dmafd received from compositor-drm */
3509 +       int surface_width;
3510 +       int surface_height;
3511 +       bool recorder_enabled;
3512 +};
3513 +
3514 +#endif /* WESTON_TRANSMITTER_API_H */
3515 diff --git a/waltham-transmitter/transmitter-plugin/weston.ini.transmitter b/waltham-transmitter/transmitter-plugin/weston.ini.transmitter
3516 new file mode 100644
3517 index 0000000..1aff0b2
3518 --- /dev/null
3519 +++ b/waltham-transmitter/transmitter-plugin/weston.ini.transmitter
3520 @@ -0,0 +1,21 @@
3521 +[core]
3522 +shell=ivi-shell.so
3523 +modules=transmitter.so
3524 +
3525 +[ivi-shell]
3526 +ivi-module=ivi-controller.so
3527 +ivi-input-module=ivi-input-controller.so
3528 +
3529 +[remote-output]
3530 +output-name=transmitter_1
3531 +server-address=192.168.2.11
3532 +port=34400
3533 +width=1920
3534 +height=1080
3535 +
3536 +[remote-output]
3537 +output-name=transmitter_2
3538 +server-address=192.168.2.12
3539 +port=34400
3540 +width=1920
3541 +height=1080
3542 diff --git a/waltham-transmitter/waltham-renderer/CMakeLists.txt b/waltham-transmitter/waltham-renderer/CMakeLists.txt
3543 new file mode 100644
3544 index 0000000..abf1a4c
3545 --- /dev/null
3546 +++ b/waltham-transmitter/waltham-renderer/CMakeLists.txt
3547 @@ -0,0 +1,59 @@
3548 +project (waltham-renderer)
3549 +
3550 +find_package(PkgConfig REQUIRED)
3551 +pkg_check_modules(WAYLAND_SERVER wayland-server>=1.13.0 REQUIRED)
3552 +pkg_check_modules(WESTON weston>=2.0.0 REQUIRED)
3553 +pkg_check_modules(PIXMAN pixman-1 REQUIRED)
3554 +pkg_check_modules(WALTHAM waltham REQUIRED)
3555 +pkg_search_module(GSTREAMER gstreamer-1.0 required)
3556 +pkg_search_module(GSTREAMERAPP gstreamer-app-1.0 required)
3557 +
3558 +include_directories(
3559 +    ${CMAKE_SOURCE_DIR}/waltham-transmitter/transmitter-plugin
3560 +    ${CMAKE_CURRENT_BINARY_DIR}
3561 +    ${WAYLAND_CLIENT_INCLUDE_DIRS}
3562 +    ${WAYLAND_SERVER_INCLUDE_DIRS}
3563 +    ${WESTON_INCLUDE_DIRS}
3564 +    ${PIXMAN_INCLUDE_DIRS}
3565 +    ${WALTHAM_INCLUDE_DIRS}
3566 +    ${GSTREAMER_INCLUDE_DIRS}
3567 +    ${GSTREAMERAPP_INCLUDE_DIRS}
3568 +)
3569 +
3570 +link_directories(
3571 +    ${WAYLAND_SERVER_LIBRARY_DIRS}
3572 +    ${WESTON_LIBRARY_DIRS}
3573 +    ${PIXMAN_LIBRARY_DIRS}
3574 +    ${WALTHAM_LIBRARY_DIRS}
3575 +    ${GSTREAMER_LIBRARY_DIRS}
3576 +    ${GSTREAMERAPP_LIBRARY_DIRS}
3577 +)
3578 +
3579 +add_library(${PROJECT_NAME} MODULE
3580 +        waltham-renderer.c
3581 +        waltham-renderer.h
3582 +)
3583 +
3584 +set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
3585 +
3586 +set(LIBS
3587 +    m
3588 +    weston-2
3589 +    gstallocators-1.0
3590 +    gstvideo-1.0
3591 +    ${WAYLAND_SERVER_LIBRARIES}
3592 +    ${WESTON_LIBRARIES}
3593 +    ${PIXMAN_LIBRARIES}
3594 +    ${WALTHAM_LIBRARIES}
3595 +    ${GSTREAMER_LIBRARIES}
3596 +    ${GSTREAMERAPP_LIBRARIES}
3597 +)
3598 +
3599 +add_dependencies(${PROJECT_NAME} ${LIBS})
3600 +
3601 +target_link_libraries(${PROJECT_NAME} ${LIBS})
3602 +
3603 +install (
3604 +    TARGETS             ${PROJECT_NAME}
3605 +    LIBRARY DESTINATION lib64/libweston-2
3606 +)
3607 diff --git a/waltham-transmitter/waltham-renderer/waltham-renderer.c b/waltham-transmitter/waltham-renderer/waltham-renderer.c
3608 new file mode 100644
3609 index 0000000..16ad3f8
3610 --- /dev/null
3611 +++ b/waltham-transmitter/waltham-renderer/waltham-renderer.c
3612 @@ -0,0 +1,270 @@
3613 +/*
3614 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
3615 + *
3616 + * Permission is hereby granted, free of charge, to any person obtaining
3617 + * a copy of this software and associated documentation files (the
3618 + * "Software"), to deal in the Software without restriction, including
3619 + * without limitation the rights to use, copy, modify, merge, publish,
3620 + * distribute, sublicense, and/or sell copies of the Software, and to
3621 + * permit persons to whom the Software is furnished to do so, subject to
3622 + * the following conditions:
3623 + *
3624 + * The above copyright notice and this permission notice (including the
3625 + * next paragraph) shall be included in all copies or substantial
3626 + * portions of the Software.
3627 + *
3628 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3629 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3630 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3631 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3632 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3633 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3634 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3635 + * SOFTWARE.
3636 + */
3637 +
3638 +#include <stdlib.h>
3639 +#include <assert.h>
3640 +#include <string.h>
3641 +
3642 +#include <gst/gst.h>
3643 +#include <gst/video/gstvideometa.h>
3644 +#include <gst/allocators/gstdmabuf.h>
3645 +#include <gst/app/gstappsrc.h>
3646 +
3647 +#include "compositor.h"
3648 +
3649 +#include "transmitter_api.h"
3650 +#include "waltham-renderer.h"
3651 +#include "plugin.h"
3652 +
3653 +struct waltham_renderer {
3654 +       struct renderer base;
3655 +};
3656 +
3657 +struct GstAppContext
3658 +{
3659 +       GMainLoop *loop;
3660 +       GstBus *bus;
3661 +       GstElement *pipeline;
3662 +       GstElement *appsrc;
3663 +       GstBuffer *gstbuffer;
3664 +};
3665 +
3666 +gboolean bus_message(GstBus *bus, GstMessage *message, gpointer p)
3667 +{
3668 +       struct GstAppContext *gstctx = p;
3669 +
3670 +       switch( GST_MESSAGE_TYPE(message)) {
3671 +        case GST_MESSAGE_ERROR:
3672 +       {
3673 +               GError *err;
3674 +               gchar *debug;
3675 +
3676 +               gst_message_parse_error(message, &err, &debug);
3677 +               g_print("ERROR: %s\n", err->message);
3678 +
3679 +               g_error_free(err);
3680 +               g_free(debug);
3681 +               g_main_loop_quit(gstctx->loop);
3682 +               break;
3683 +       }
3684 +
3685 +       case GST_MESSAGE_STATE_CHANGED:
3686 +       {
3687 +               GstState oldstate, newstate;
3688 +
3689 +               gst_message_parse_state_changed(message, &oldstate, &newstate, NULL);
3690 +               switch (newstate){
3691 +               case GST_STATE_NULL:
3692 +                       fprintf(stderr, "%s: state is NULL\n", GST_MESSAGE_SRC_NAME(message));
3693 +               }
3694 +               break;
3695 +       }
3696 +        default:
3697 +               fprintf(stderr, "Unhandled message\n");
3698 +               break;
3699 +       }
3700 +}
3701 +
3702 +static int
3703 +gst_pipe_init(struct weston_transmitter_output *output, struct gst_settings *settings)
3704 +{
3705 +       struct GstAppContext *gstctx;
3706 +       gstctx=zalloc(sizeof (*gstctx));
3707 +       if(!gstctx){
3708 +               weston_log("Enable to allocate memory\n");
3709 +               return -1;
3710 +       }
3711 +       GstCaps *caps;
3712 +       int ret = 0;
3713 +       GError *gerror = NULL;
3714 +       FILE * pFile;
3715 +       long lSize;
3716 +       char * pipe = NULL;
3717 +       size_t res;
3718 +
3719 +       /* create gstreamer pipeline */
3720 +       gst_init(NULL, NULL);
3721 +       gstctx->loop = g_main_loop_new(NULL, FALSE);
3722 +
3723 +       /* read pipeline from file */
3724 +       pFile = fopen ( "/etc/xdg/weston/pipeline.cfg" , "rb" );
3725 +       if (pFile==NULL)
3726 +       {
3727 +               weston_log("File open error\n");
3728 +               return -1;
3729 +       }
3730 +
3731 +       /* obtain file size */
3732 +       fseek (pFile , 0 , SEEK_END);
3733 +       lSize = ftell (pFile);
3734 +       rewind (pFile);
3735 +
3736 +       /* allocate memory to contain the whole file: */
3737 +       pipe = (char*) zalloc (sizeof(char)*lSize);
3738 +       if (pipe == NULL)
3739 +       {
3740 +               weston_log("Cannot allocate memory\n");
3741 +               return -1;
3742 +       }
3743 +
3744 +       /* copy the file into the buffer: */
3745 +       res = fread (pipe,1,lSize,pFile);
3746 +       if (res != lSize)
3747 +       {
3748 +               weston_log("File read error\n");
3749 +               return -1;
3750 +       }
3751 +
3752 +       /* close file */
3753 +       fclose (pFile);
3754 +       weston_log("Parsing GST pipeline:%s",pipe);
3755 +       gstctx->pipeline = gst_parse_launch(pipe, &gerror);
3756 +       free(pipe);
3757 +       if(!gstctx->pipeline)
3758 +               weston_log("Could not create gstreamer pipeline.\n");
3759 +
3760 +       gstctx->bus = gst_pipeline_get_bus((GstPipeline*)((void*)gstctx->pipeline));
3761 +       gst_bus_add_watch(gstctx->bus, bus_message, &gstctx);
3762 +
3763 +       gstctx->appsrc = (GstAppSrc*)
3764 +               gst_bin_get_by_name(GST_BIN(gstctx->pipeline), "src");
3765 +       if (!gstctx->appsrc)
3766 +               return -1;
3767 +
3768 +       caps = gst_caps_new_simple("video/x-raw",
3769 +                                  "format", G_TYPE_STRING, "BGRx",
3770 +                                  "width", G_TYPE_INT, settings->width,
3771 +                                  "height", G_TYPE_INT, settings->height,
3772 +                                  NULL);
3773 +       if (!caps)
3774 +               return -1;
3775 +
3776 +       g_object_set(G_OBJECT(gstctx->appsrc),
3777 +                    "caps", caps,
3778 +                    "stream-type", 0,
3779 +                    "format", GST_FORMAT_TIME,
3780 +                    "is-live", TRUE,
3781 +                    NULL);
3782 +       gst_caps_unref(caps);
3783 +
3784 +       gst_element_set_state((GstElement*)((void*)gstctx->pipeline), GST_STATE_PLAYING);
3785 +       output->renderer->ctx = gstctx;
3786 +
3787 +       return 0;
3788 +}
3789 +
3790 +static int
3791 +recorder_enable(struct weston_transmitter_output *output)
3792 +{
3793 +       struct gst_settings *settings;
3794 +
3795 +       struct weston_output* base = &output->base;
3796 +       struct weston_compositor *compositor = base->compositor;
3797 +       struct weston_transmitter_remote* remote = output->remote;
3798 +
3799 +       /*
3800 +        * Limitation:
3801 +        * Hard coding bitrate and crop params.
3802 +        * In case of gst-recorder case these were taken from weston.ini
3803 +        */
3804 +       int32_t bitrate = 3000000;
3805 +
3806 +       settings = malloc(sizeof(* settings));
3807 +       settings->ip = remote->addr;
3808 +
3809 +       settings->port = atoi(remote->port);
3810 +
3811 +       settings->bitrate = bitrate;
3812 +       settings->width = output->renderer->surface_width;
3813 +       settings->height = output->renderer->surface_height;
3814 +
3815 +       weston_log("gst-setting are :-->\n");
3816 +       weston_log("ip = %s \n",settings->ip);
3817 +       weston_log("port = %d \n",settings->port);
3818 +       weston_log("bitrate = %d \n",settings->bitrate);
3819 +       weston_log("width = %d \n",settings->width);
3820 +       weston_log("width = %d \n",settings->height);
3821 +
3822 +       gst_pipe_init(output, settings);
3823 +
3824 +       return 0;
3825 +err:
3826 +       weston_log("[gst recorder] %s:"
3827 +               " invalid settings\n",
3828 +               output->base.name);
3829 +       free(settings);
3830 +       return -1;
3831 +}
3832 +
3833 +static void waltham_renderer_repaint_output(struct weston_transmitter_output *output)
3834 +{
3835 +       GstBuffer *gstbuffer;
3836 +       GstMemory *mem;
3837 +       GstAllocator *allocator;
3838 +       int stride = output->renderer->surface_width * 4;
3839 +       gsize offset = 0;
3840 +
3841 +       if(!output->renderer->recorder_enabled)
3842 +       {
3843 +               recorder_enable(&output->base);
3844 +               output->renderer->recorder_enabled = 1;
3845 +       }
3846 +
3847 +       gstbuffer = gst_buffer_new();
3848 +       allocator = gst_dmabuf_allocator_new();
3849 +       mem = gst_dmabuf_allocator_alloc(allocator, output->renderer->dmafd,
3850 +                                        stride * output->renderer->surface_height);
3851 +       gst_buffer_append_memory(gstbuffer, mem);
3852 +       gst_buffer_add_video_meta_full(gstbuffer,
3853 +                                      GST_VIDEO_FRAME_FLAG_NONE,
3854 +                                      GST_VIDEO_FORMAT_BGRx,
3855 +                                      output->renderer->surface_width,
3856 +                                      output->renderer->surface_height,
3857 +                                      1,
3858 +                                      &offset,
3859 +                                      &stride);
3860 +
3861 +       gst_app_src_push_buffer(output->renderer->ctx->appsrc, gstbuffer);
3862 +       gst_object_unref(allocator);
3863 +}
3864 +
3865 +static int
3866 +waltham_renderer_display_create(struct weston_transmitter_output *output)
3867 +{
3868 +       struct waltham_renderer *wth_renderer;
3869 +
3870 +       wth_renderer = zalloc(sizeof *wth_renderer);
3871 +       if (wth_renderer == NULL)
3872 +               return -1;
3873 +       wth_renderer->base.repaint_output = waltham_renderer_repaint_output;
3874 +
3875 +       output->renderer = &wth_renderer->base;
3876 +
3877 +       return 0;
3878 +}
3879 +
3880 +WL_EXPORT struct waltham_renderer_interface waltham_renderer_interface = {
3881 +               .display_create = waltham_renderer_display_create
3882 +};
3883 diff --git a/waltham-transmitter/waltham-renderer/waltham-renderer.h b/waltham-transmitter/waltham-renderer/waltham-renderer.h
3884 new file mode 100644
3885 index 0000000..a9ac513
3886 --- /dev/null
3887 +++ b/waltham-transmitter/waltham-renderer/waltham-renderer.h
3888 @@ -0,0 +1,41 @@
3889 +/*
3890 + * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
3891 + *
3892 + * Permission is hereby granted, free of charge, to any person obtaining
3893 + * a copy of this software and associated documentation files (the
3894 + * "Software"), to deal in the Software without restriction, including
3895 + * without limitation the rights to use, copy, modify, merge, publish,
3896 + * distribute, sublicense, and/or sell copies of the Software, and to
3897 + * permit persons to whom the Software is furnished to do so, subject to
3898 + * the following conditions:
3899 + *
3900 + * The above copyright notice and this permission notice (including the
3901 + * next paragraph) shall be included in all copies or substantial
3902 + * portions of the Software.
3903 + *
3904 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3905 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3906 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3907 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3908 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3909 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3910 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3911 + * SOFTWARE.
3912 + */
3913 +
3914 +#ifndef TRANSMITTER_WALTHAM_RENDERER_H_
3915 +#define TRANSMITTER_WALTHAM_RENDERER_H_
3916 +
3917 +struct waltham_renderer_interface {
3918 +       int (*display_create)(struct weston_transmitter_output *output);
3919 +};
3920 +
3921 +struct gst_settings {
3922 +       int width;
3923 +       int height;
3924 +       int bitrate;
3925 +       char *ip;
3926 +       int port;
3927 +};
3928 +
3929 +#endif /* TRANSMITTER_WALTHAM_RENDERER_H_ */
3930 -- 
3931 2.7.4
3932