bf2f05ef189f32beb47d5b902daa05fcb8832038
[AGL/meta-agl.git] /
1 From aa3ea1af1dfa0e0ef5b452d8a5c53cd3eb508f52 Mon Sep 17 00:00:00 2001
2 From: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
3 Date: Wed, 2 Mar 2016 16:57:45 +0200
4 Subject: [PATCH 1/3] transmitter: add an incomplete plugin (output and
5  pointer)
6
7 Enabled with ./configure --enable-surface-remoting
8
9 Draft the public API for binding and unbinding a surface for remoting,
10 and another for ivi-shell specifics.
11
12 Add the plumbing needed to relay a configure event from the network to
13 the shell, to be forwarded to the application.
14
15 Implement support for (fake) connection object tracking.
16
17 Create a weston_output for a (fake) remote output. Force the
18 sync-to-output on remoted surfaces. Use timers to fake wl_surface.enter
19 and frame callback events. Also Presentation feedback is poorly faked.
20
21 Hooking to weston_surface happens in two ways: surface_configure in
22 Transmitter plugin API is used to relay the dx,dy from
23 wl_surface.attach, and weston_surface::apply_state_signal relays state
24 updates.
25
26 Create a fake seat with pointer:
27
28 - Add an internal pointer API that will be called by the networking code
29   for incoming input events. The API should match 1:1 to the events.
30   These functions will reimplement the parts of src/input.c to send out
31   the events to Wayland clients.
32
33 - Implement pointer enter/leave of the internal pointer API. Code is
34   mimicked from weston_pointer_set_focus(), but without all the logic
35   needed to determine the right actions.
36
37 - Implement pointer frame of the internal pointer API.
38
39 - Add a fake pointer input generator. It only make the pointer enter the
40   surface remoted the most recently, and moves the pointer in a circle.
41
42 All ways of getting pointer focus should be covered. Serial tracking is
43 the same as in Weston core. Seat maintains the pointer focus surface.
44 Focus_client is managed while Weston core never sees any focus.
45 Transmitter surface gained a destroy signal.
46
47 Surface destruction relies on forwarding the destroy to the remote,
48 which will then reply with appropriate pointer.leave events. This is not
49 implemented by the input faking code.
50
51 Transmitter is expected to open all inputs available on the remote and
52 multiplex those to local clients as clients subscribe.
53
54 Notes about the design and guidelines for finishing the implementation
55 are included, and all the mockup code is annotated as "fake" so it is
56 easy to spot and replace with a proper network implementation.
57
58 There are listener-based APIs for getting both remote connection status
59 changes, and per-surface stream status changes.
60
61 Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
62 ---
63  Makefile.am                   |  19 ++
64  configure.ac                  |   9 +
65  transmitter/README            |  53 ++++
66  transmitter/input.c           | 597 +++++++++++++++++++++++++++++++++++++++
67  transmitter/output.c          | 234 ++++++++++++++++
68  transmitter/plugin.c          | 638 ++++++++++++++++++++++++++++++++++++++++++
69  transmitter/plugin.h          | 207 ++++++++++++++
70  transmitter/transmitter_api.h | 253 +++++++++++++++++
71  8 files changed, 2010 insertions(+)
72  create mode 100644 transmitter/README
73  create mode 100644 transmitter/input.c
74  create mode 100644 transmitter/output.c
75  create mode 100644 transmitter/plugin.c
76  create mode 100644 transmitter/plugin.h
77  create mode 100644 transmitter/transmitter_api.h
78
79 diff --git a/Makefile.am b/Makefile.am
80 index cdf82ab..6cca875 100644
81 --- a/Makefile.am
82 +++ b/Makefile.am
83 @@ -502,6 +502,25 @@ cms_colord_la_SOURCES =                            \
84  endif
85  endif
86  
87 +if ENABLE_SURFACE_REMOTING
88 +module_LTLIBRARIES += transmitter.la
89 +transmitter_la_LDFLAGS = -module -avoid-version
90 +transmitter_la_CFLAGS =                                \
91 +       $(COMPOSITOR_CFLAGS)                    \
92 +       $(AM_CFLAGS)
93 +transmitter_la_LIBADD = $(COMPOSITOR_LIBS)
94 +transmitter_la_SOURCES =                       \
95 +       transmitter/plugin.c                    \
96 +       transmitter/plugin.h                    \
97 +       transmitter/output.c                    \
98 +       transmitter/input.c                     \
99 +       transmitter/transmitter_api.h           \
100 +       shared/helpers.h                        \
101 +       shared/timespec-util.h                  \
102 +       shared/zalloc.h                         \
103 +       src/compositor.h
104 +endif
105 +
106  noinst_PROGRAMS += spring-tool
107  spring_tool_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
108  spring_tool_LDADD = $(COMPOSITOR_LIBS) -lm
109 diff --git a/configure.ac b/configure.ac
110 index d0dee1b..06cda73 100644
111 --- a/configure.ac
112 +++ b/configure.ac
113 @@ -562,6 +562,14 @@ AS_IF([test "x$have_systemd_login_209" = "xyes"],
114        [AC_DEFINE([HAVE_SYSTEMD_LOGIN_209], [1], [Have systemd-login >= 209])])
115  
116  
117 +# surface remoting
118 +AC_ARG_ENABLE(surface-remoting,
119 +              AS_HELP_STRING([--enable-surface-remoting],
120 +                             [support for surface remoting over network]),,
121 +             enable_surface_remoting=no)
122 +AM_CONDITIONAL(ENABLE_SURFACE_REMOTING, test "x$enable_surface_remoting" = "xyes")
123 +
124 +
125  # Note that other features might want libxml2, or this feature might use
126  # alternative xml libraries at some point. Therefore the feature and
127  # pre-requisite concepts are split.
128 @@ -750,4 +758,5 @@ AC_MSG_RESULT([
129         libunwind Support               ${have_libunwind}
130         VA H.264 encoding Support       ${have_libva}
131         GStreamer H.264 enc. Support    ${enable_gst_recorder}
132 +       Surface remoting support        ${enable_surface_remoting}
133  ])
134 diff --git a/transmitter/README b/transmitter/README
135 new file mode 100644
136 index 0000000..a7977ba
137 --- /dev/null
138 +++ b/transmitter/README
139 @@ -0,0 +1,53 @@
140 +Testing Transmitter with ivi-shell
141 +
142 +The current implementation of Transmitter is a stub which interfaces to
143 +other Weston parts appropriately, but all networking is just a mockup.
144 +
145 +
146 +Configure Weston with --enable-surface-remoting to build the Transmitter
147 +plugin.
148 +
149 +In weston.ini, add 'transmitter.so' to the 'modules' key under '[core]', and
150 +make sure the 'shell' is 'ivi-shell.so'. Follow the ivi-shell example
151 +weston.ini for everything else.
152 +
153 +When you start weston, the log should contain something like this:
154 +
155 +[13:13:54.799] Loading module '/home/pq/local/lib/weston/ivi-shell.so'
156 +[13:13:54.799] launching '/home/pq/local/libexec/weston-keyboard'
157 +[13:13:54.799] Loading module '/home/pq/local/lib/weston/hmi-controller.so'
158 +[13:13:54.799] Loading module '/home/pq/local/lib/weston/transmitter.so'
159 +[13:13:54.799] Registered plugin API 'transmitter_v1' of size 48
160 +[13:13:54.799] Registered plugin API 'transmitter_ivi_v1' of size 16
161 +[13:13:54.799] Transmitter initialized.
162 +[13:13:54.799] ivi-layout: Transmitter enabled.
163 +[13:13:54.799] launching '/home/pq/build/weston/weston-ivi-shell-user-interface'
164 +[13:13:54.799] hmi-controller: Transmitter enabled.
165 +[13:13:54.799] Transmitter connecting to 0.0.0.0:66...
166 +[13:13:55.800] Transmitter connected to 0.0.0.0:66.
167 +[13:13:55.800] hmi-controller: connection status 0
168 +[13:13:55.800] Transmitter created output 'transmitter-0.0.0.0:66-1': Weston-Transmitter, transmitter-0.0.0.0:66-1, 0
169 +[13:13:55.800] Transmitter created seat=0x1c37bd0 'transmitter-0.0.0.0:66-default'
170 +[13:13:55.800] Transmitter created pointer=0x1c38430 for seat 0x1c37bd0
171 +[13:13:55.800] transmitter_start_repaint_loop(transmitter-0.0.0.0:66-1)
172 +
173 +
174 +If you have edited a client to have ivi-id >= 0xfaa01000, when you start that
175 +client it should be "remoted" automatically and not appear on screen.
176 +
177 +You can also manually start remoting:
178 +- Start an IVI application.
179 +- Move pointer onto the application window.
180 +- Press Mod+Shift+space, and then 'k'.
181 +- The window should disappear.
182 +
183 +Weston log will indicate remoting has started:
184 +
185 +[13:18:24.572] HMI transmitting surface 0x1c3dad0, ivi-id 0x9ff6
186 +[13:18:24.572] Transmitter: update surface 0x1c3dad0 (0, 0), 0 cb
187 +[13:18:24.572] transmitter_surface_set_ivi_id(0x1c3dad0, 0x9ff6)
188 +[13:18:24.972] Transmitter: surface 0x1c3dad0 entered output transmitter-0.0.0.0:66-1
189 +
190 +Once remoting has started, the mockup code will generate fake pointer input for
191 +the window. This can be seen with e.g. weston-eventdemo, or running an
192 +application with WAYLAND_DEBUG=client.
193 diff --git a/transmitter/input.c b/transmitter/input.c
194 new file mode 100644
195 index 0000000..0ba04d4
196 --- /dev/null
197 +++ b/transmitter/input.c
198 @@ -0,0 +1,597 @@
199 +/*
200 + * Copyright (C) 2016 DENSO CORPORATION
201 + *
202 + * Permission is hereby granted, free of charge, to any person obtaining
203 + * a copy of this software and associated documentation files (the
204 + * "Software"), to deal in the Software without restriction, including
205 + * without limitation the rights to use, copy, modify, merge, publish,
206 + * distribute, sublicense, and/or sell copies of the Software, and to
207 + * permit persons to whom the Software is furnished to do so, subject to
208 + * the following conditions:
209 + *
210 + * The above copyright notice and this permission notice (including the
211 + * next paragraph) shall be included in all copies or substantial
212 + * portions of the Software.
213 + *
214 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
215 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
216 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
217 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
218 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
219 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
220 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
221 + * SOFTWARE.
222 + */
223 +
224 +#include "config.h"
225 +
226 +#include <stdlib.h>
227 +#include <assert.h>
228 +#include <string.h>
229 +
230 +/* for fake stuff */
231 +#include <math.h>
232 +
233 +#include "compositor.h"
234 +#include "helpers.h"
235 +
236 +#include "plugin.h"
237 +#include "transmitter_api.h"
238 +
239 +/** @file
240 + *
241 + * This is an implementation of a remote input.
242 + *
243 + * Request wl_data_device_manager.get_data_device would need to be blocked,
244 + * except maybe it's not necessary, we just "forget" to forward data to/from
245 + * the remote wl_seat. It might still work inside the local compositor.
246 + *
247 + * weston_compositor_set_default_pointer_grab() will break our pointer
248 + * implementation, but no in-tree code is calling it.
249 + */
250 +
251 +/* XXX: all functions and variables with a name, and things marked with a
252 + * comment, containing the word "fake" are mockups that need to be
253 + * removed from the final implementation.
254 + */
255 +
256 +static void
257 +pointer_focus_grab_handler(struct weston_pointer_grab *grab)
258 +{
259 +       /* No-op:
260 +        *
261 +        * Weston internal events do not change the focus.
262 +        */
263 +}
264 +
265 +static void
266 +pointer_motion_grab_handler(struct weston_pointer_grab *grab,
267 +                           uint32_t time,
268 +                           struct weston_pointer_motion_event *event)
269 +{
270 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
271 +                  __func__, grab->pointer);
272 +}
273 +
274 +static void
275 +pointer_button_grab_handler(struct weston_pointer_grab *grab,
276 +                           uint32_t time,
277 +                           uint32_t button,
278 +                           uint32_t state)
279 +{
280 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
281 +                  __func__, grab->pointer);
282 +}
283 +
284 +static void
285 +pointer_axis_grab_handler(struct weston_pointer_grab *grab,
286 +                         uint32_t time,
287 +                         struct weston_pointer_axis_event *event)
288 +{
289 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
290 +                  __func__, grab->pointer);
291 +}
292 +
293 +static void
294 +pointer_axis_source_grab_handler(struct weston_pointer_grab *grab,
295 +                                uint32_t source)
296 +{
297 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
298 +                  __func__, grab->pointer);
299 +}
300 +
301 +static void
302 +pointer_frame_grab_handler(struct weston_pointer_grab *grab)
303 +{
304 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
305 +                  __func__, grab->pointer);
306 +}
307 +
308 +static void
309 +pointer_cancel_grab_handler(struct weston_pointer_grab *grab)
310 +{
311 +       weston_log("Unexpected! %s(pointer=%p, ...)\n",
312 +                  __func__, grab->pointer);
313 +}
314 +
315 +/* These handlers would be called from the notify_*() functions in src/input.c.
316 + * However, as we do not use the low level input notify_*() functions that
317 + * backends drive, these are mostly uncalled, except the focus handler which
318 + * weston core generates internally.
319 + */
320 +static const struct weston_pointer_grab_interface pointer_grab_impl = {
321 +       pointer_focus_grab_handler,
322 +       pointer_motion_grab_handler,
323 +       pointer_button_grab_handler,
324 +       pointer_axis_grab_handler,
325 +       pointer_axis_source_grab_handler,
326 +       pointer_frame_grab_handler,
327 +       pointer_cancel_grab_handler,
328 +};
329 +
330 +/* The different ways to get pointer focus on a remoted surface:
331 + *
332 + * 1. Transmitter seat has pointer. The client has wl_pointer. Transmitter
333 + *    receives pointer.enter. (transmitter_seat_pointer_enter())
334 + *
335 + * 2. Transmitter seat has pointer. Transmitter has received pointer.enter.
336 + *    The client calls wl_seat.get_pointer. => send enter only on the new
337 + *    wl_pointer. (seat_get_pointer_handler())
338 + *
339 + * 3. Client has wl_pointer. Transmitter seat adds pointer capability.
340 + *    Transmitter receives pointer.enter. wl_pointer MUST NOT enter,
341 + *    specified by wl_seat.capabilities.
342 + *
343 + * By definition, Transmitter cannot receive pointer.enter without having
344 + * pointer capability in the seat, so no other combinations are possible.
345 + *
346 + * The same applies to wl_keyboard and wl_touch.
347 + */
348 +
349 +/* Implementor notes:
350 + *
351 + * The handling of all of wl_pointer, wl_keyboard and wl_touch should be
352 + * similar. To make it work, we need to add a signal to each of the
353 + * wl_seat.get_pointer, wl_seat.get_keyboard, and wl_seat.get_touch request
354 + * handlers in Weston core. Otherwise we cannot implement the case 2 of gaining
355 + * input device focus.
356 + *
357 + * However, weston_keyboard::focus is a weston_surface, not a weston_view, so
358 + * we may be able to leverage more of the core implementation and maybe do
359 + * without the wl_seat.get_keyboard signal. Weston_touch uses a weston_view, so
360 + * that is similar to weston_pointer.
361 + *
362 + * It might be useful to convert weston_keyboard and weston_touch to use a
363 + * similar thing as weston_pointer_client, in case it makes things more
364 + * consistent. It might also fix issues when a client has multiple copies of a
365 + * wl_keyboard or a wl_touch, but that is getting off-topic.
366 + *
367 + * This file shows which part of the Weston input path we skip and where we
368 + * hook in. We skip everything starting from the notify_*() API used by
369 + * backends, and stub out the grab handlers. Instead of actual grab handlers,
370 + * we have our own network protocol events handlers. They do much of the same
371 + * as normal grab handlers would do, except focus is pre-given, and we do not
372 + * have weston_view for the focus surfaces, so we need to bypass core code
373 + * dealing with those.
374 + *
375 + * Our remote seat implementation will leave many struct members unused and
376 + * replicate some from weston_pointer, weston_keyboard, and weston_touch.
377 + * Weston core must be kept out from the focus handling business, because we
378 + * will send enter/leave events ourselves, and focus assignments are given
379 + * to us from the remote, they cannot be changed at will by the local Weston.
380 + */
381 +
382 +/** Callback from the protocol request handler for wl_seat.get_pointer
383 + *
384 + * The Weston core handler never sees focus set on the weston_pointer,
385 + * so it won't send wl_pointer.enter nor set focus_client. It does call
386 + * weston_pointer_ensure_pointer_client() though.
387 + */
388 +static void
389 +seat_get_pointer_handler(struct wl_listener *listener, void *data)
390 +{
391 +       struct wl_resource *new_pointer = data;
392 +       struct weston_transmitter_seat *seat;
393 +       struct wl_resource *surface;
394 +       struct weston_pointer_client *pointer_client;
395 +       struct wl_client *client;
396 +       struct weston_pointer *pointer;
397 +
398 +       seat = wl_container_of(listener, seat, get_pointer_listener);
399 +       if (!seat->pointer_focus)
400 +               return;
401 +
402 +       client = wl_resource_get_client(new_pointer);
403 +       surface = seat->pointer_focus->surface->resource;
404 +
405 +       if (wl_resource_get_client(surface) != client)
406 +               return;
407 +
408 +       pointer = weston_seat_get_pointer(&seat->base);
409 +       assert(pointer); /* guaranteed by having pointer_focus */
410 +       pointer_client = weston_pointer_get_pointer_client(pointer, client);
411 +
412 +       if (!pointer->focus_client)
413 +               pointer->focus_client = pointer_client;
414 +       else
415 +               assert(pointer->focus_client == pointer_client);
416 +
417 +       wl_pointer_send_enter(new_pointer, pointer->focus_serial, surface,
418 +                             seat->pointer_surface_x, seat->pointer_surface_y);
419 +
420 +       if (wl_resource_get_version(new_pointer) >=
421 +           WL_POINTER_FRAME_SINCE_VERSION)
422 +               wl_pointer_send_frame(new_pointer);
423 +}
424 +
425 +static void
426 +transmitter_seat_create_pointer(struct weston_transmitter_seat *seat)
427 +{
428 +       struct weston_pointer *pointer;
429 +
430 +       seat->pointer_phase = 0.0;
431 +       seat->pointer_surface_x = wl_fixed_from_int(-1000000);
432 +       seat->pointer_surface_y = wl_fixed_from_int(-1000000);
433 +       seat->pointer_focus = NULL;
434 +       wl_list_init(&seat->pointer_focus_destroy_listener.link);
435 +
436 +       weston_seat_init_pointer(&seat->base);
437 +
438 +       seat->get_pointer_listener.notify = seat_get_pointer_handler;
439 +       wl_signal_add(&seat->base.get_pointer_signal,
440 +                     &seat->get_pointer_listener);
441 +
442 +       pointer = weston_seat_get_pointer(&seat->base);
443 +
444 +       /* not exported:
445 +        * weston_pointer_set_default_grab(pointer, &pointer_grab_impl); */
446 +       pointer->default_grab.interface = &pointer_grab_impl;
447 +
448 +       /* Changes to local outputs are irrelevant. */
449 +       wl_list_remove(&pointer->output_destroy_listener.link);
450 +       wl_list_init(&pointer->output_destroy_listener.link);
451 +
452 +       weston_log("Transmitter created pointer=%p for seat %p\n",
453 +                  pointer, &seat->base);
454 +}
455 +
456 +static void
457 +seat_pointer_focus_destroy_handler(struct wl_listener *listener, void *data)
458 +{
459 +       struct weston_transmitter_surface *txs = data;
460 +       struct weston_transmitter_seat *seat;
461 +
462 +       seat = wl_container_of(listener, seat, pointer_focus_destroy_listener);
463 +       assert(seat->pointer_focus == txs);
464 +
465 +       seat->pointer_focus = NULL;
466 +}
467 +
468 +void
469 +transmitter_seat_pointer_enter(struct weston_transmitter_seat *seat,
470 +                              uint32_t serial,
471 +                              struct weston_transmitter_surface *txs,
472 +                              wl_fixed_t surface_x,
473 +                              wl_fixed_t surface_y)
474 +{
475 +       struct wl_client *client;
476 +       struct weston_pointer *pointer;
477 +       struct wl_list *focus_resource_list;
478 +       struct wl_resource *resource;
479 +
480 +       pointer = weston_seat_get_pointer(&seat->base);
481 +       assert(pointer);
482 +
483 +       assert(txs->surface);
484 +       client = wl_resource_get_client(txs->surface->resource);
485 +
486 +       seat->pointer_focus = txs;
487 +       seat->pointer_focus_destroy_listener.notify =
488 +               seat_pointer_focus_destroy_handler;
489 +       wl_signal_add(&txs->destroy_signal,
490 +                     &seat->pointer_focus_destroy_listener);
491 +
492 +       /* If pointer-focus gets destroyed, txs will get destroyed, the
493 +        * remote surface object is destroyed, and the remote will send a
494 +        * leave and a frame.
495 +        */
496 +
497 +       seat->pointer_surface_x = surface_x;
498 +       seat->pointer_surface_y = surface_y;
499 +
500 +       pointer->focus_client = weston_pointer_get_pointer_client(pointer,
501 +                                                                 client);
502 +       pointer->focus_serial = serial;
503 +
504 +       /* pointer->focus is not used, because it is a weston_view, while
505 +        * remoted surfaces have no views.
506 +        *
507 +        * pointer->x,y are not used because they are in global coordinates.
508 +        * Remoted surfaces are not in the global space at all, so there are
509 +        * no such coordinates.
510 +        */
511 +
512 +       if (!pointer->focus_client)
513 +               return;
514 +
515 +       focus_resource_list = &pointer->focus_client->pointer_resources;
516 +       wl_resource_for_each(resource, focus_resource_list) {
517 +               wl_pointer_send_enter(resource,
518 +                                     serial,
519 +                                     txs->surface->resource,
520 +                                     surface_x, surface_y);
521 +       }
522 +}
523 +
524 +void
525 +transmitter_seat_pointer_leave(struct weston_transmitter_seat *seat,
526 +                              uint32_t serial,
527 +                              struct weston_transmitter_surface *txs)
528 +{
529 +       struct weston_pointer *pointer;
530 +       struct wl_list *focus_resource_list;
531 +       struct wl_resource *surface_resource;
532 +       struct wl_resource *resource;
533 +
534 +       if (txs != seat->pointer_focus) {
535 +               weston_log("Transmitter Warning: pointer leave for %p, expected %p\n",
536 +                          txs, seat->pointer_focus);
537 +       }
538 +
539 +       seat->pointer_focus = NULL;
540 +       wl_list_remove(&seat->pointer_focus_destroy_listener.link);
541 +       wl_list_init(&seat->pointer_focus_destroy_listener.link);
542 +
543 +       if (!txs)
544 +               return;
545 +       assert(txs->surface);
546 +       surface_resource = txs->surface->resource;
547 +
548 +       pointer = weston_seat_get_pointer(&seat->base);
549 +       assert(pointer);
550 +       if (!pointer->focus_client)
551 +               return;
552 +
553 +       focus_resource_list = &pointer->focus_client->pointer_resources;
554 +       wl_resource_for_each(resource, focus_resource_list)
555 +               wl_pointer_send_leave(resource, serial, surface_resource);
556 +
557 +       /* Do not reset pointer->focus_client, because we need to be able
558 +        * to send a following 'frame' event in
559 +        * transmitter_seat_pointer_frame().
560 +        */
561 +}
562 +
563 +void
564 +transmitter_seat_pointer_motion(struct weston_transmitter_seat *seat,
565 +                               uint32_t time,
566 +                               wl_fixed_t surface_x,
567 +                               wl_fixed_t surface_y)
568 +{
569 +       struct weston_pointer *pointer;
570 +       struct wl_list *focus_resource_list;
571 +       struct wl_resource *resource;
572 +       struct weston_transmitter_surface *txs;
573 +
574 +       pointer = weston_seat_get_pointer(&seat->base);
575 +       assert(pointer);
576 +
577 +       seat->pointer_surface_x = surface_x;
578 +       seat->pointer_surface_y = surface_y;
579 +
580 +       if (!pointer->focus_client)
581 +               return;
582 +
583 +       txs = seat->pointer_focus;
584 +       if (txs)
585 +               assert(wl_resource_get_client(txs->surface->resource) ==
586 +                      pointer->focus_client->client);
587 +
588 +       focus_resource_list = &pointer->focus_client->pointer_resources;
589 +       wl_resource_for_each(resource, focus_resource_list) {
590 +               wl_pointer_send_motion(resource, time,
591 +                                      surface_x, surface_y);
592 +       }
593 +}
594 +
595 +void
596 +transmitter_seat_pointer_button(struct weston_transmitter_seat *seat,
597 +                               uint32_t serial,
598 +                               uint32_t time,
599 +                               uint32_t button,
600 +                               uint32_t state)
601 +{
602 +       assert(!"TODO");
603 +}
604 +
605 +void
606 +transmitter_seat_pointer_axis(struct weston_transmitter_seat *seat,
607 +                             uint32_t time,
608 +                             uint32_t axis,
609 +                             wl_fixed_t value)
610 +{
611 +       assert(!"TODO");
612 +}
613 +
614 +void
615 +transmitter_seat_pointer_frame(struct weston_transmitter_seat *seat)
616 +{
617 +       struct weston_pointer *pointer;
618 +
619 +       pointer = weston_seat_get_pointer(&seat->base);
620 +       if (pointer)
621 +               weston_pointer_send_frame(pointer);
622 +}
623 +
624 +void
625 +transmitter_seat_pointer_axis_source(struct weston_transmitter_seat *seat,
626 +                                    uint32_t axis_source)
627 +{
628 +       assert(!"TODO");
629 +}
630 +
631 +void
632 +transmitter_seat_pointer_axis_stop(struct weston_transmitter_seat *seat,
633 +                                  uint32_t time,
634 +                                  uint32_t axis)
635 +{
636 +       assert(!"TODO");
637 +}
638 +
639 +void
640 +transmitter_seat_pointer_axis_discrete(struct weston_transmitter_seat *seat,
641 +                                      uint32_t axis,
642 +                                      int32_t discrete)
643 +{
644 +       assert(!"TODO");
645 +}
646 +
647 +static char *
648 +make_seat_name(struct weston_transmitter_remote *remote, const char *name)
649 +{
650 +       char *str;
651 +
652 +       if (asprintf(&str, "transmitter-%s-%s", remote->addr, name) < 0)
653 +               return NULL;
654 +
655 +       return str;
656 +}
657 +
658 +void
659 +transmitter_seat_destroy(struct weston_transmitter_seat *seat)
660 +{
661 +       wl_list_remove(&seat->link);
662 +
663 +       weston_log("Transmitter destroy seat=%p\n", &seat->base);
664 +
665 +       weston_seat_release(&seat->base);
666 +
667 +       wl_list_remove(&seat->get_pointer_listener.link);
668 +       wl_list_remove(&seat->pointer_focus_destroy_listener.link);
669 +
670 +       if (seat->pointer_timer)
671 +               wl_event_source_remove(seat->pointer_timer);
672 +
673 +       free(seat);
674 +}
675 +
676 +int
677 +transmitter_remote_create_seat(struct weston_transmitter_remote *remote)
678 +{
679 +       struct weston_transmitter_seat *seat = NULL;
680 +       char *name = NULL;
681 +
682 +       seat = zalloc(sizeof *seat);
683 +       if (!seat)
684 +               goto fail;
685 +
686 +       wl_list_init(&seat->get_pointer_listener.link);
687 +       wl_list_init(&seat->pointer_focus_destroy_listener.link);
688 +
689 +       /* XXX: get the name from remote */
690 +       name = make_seat_name(remote, "default");
691 +       if (!name)
692 +               goto fail;
693 +
694 +       weston_seat_init(&seat->base, remote->transmitter->compositor, name);
695 +       free(name);
696 +
697 +       /* Hide the weston_seat from the rest of Weston, there are too many
698 +        * things making assumptions:
699 +        * - backends assume they control all seats
700 +        * - shells assume they control all input foci
701 +        * We do not want either to mess with our seat.
702 +        */
703 +       wl_list_remove(&seat->base.link);
704 +       wl_list_init(&seat->base.link);
705 +
706 +       /* The weston_compositor::seat_created_signal has already been
707 +        * emitted. Shells use it to subscribe to focus changes, but we should
708 +        * never handle focus with weston core... except maybe with keyboard.
709 +        * text-backend.c will also act on the new seat.
710 +        * It is possible weston_seat_init() needs to be split to fix this
711 +        * properly.
712 +        */
713 +
714 +       weston_log("Transmitter created seat=%p '%s'\n",
715 +                  &seat->base, seat->base.seat_name);
716 +
717 +       /* XXX: mirror remote capabilities */
718 +       transmitter_seat_create_pointer(seat);
719 +
720 +       wl_list_insert(&remote->seat_list, &seat->link);
721 +
722 +       return 0;
723 +
724 +fail:
725 +       free(seat);
726 +       free(name);
727 +
728 +       return -1;
729 +}
730 +
731 +static void
732 +fake_pointer_get_position(struct weston_transmitter_seat *seat, double step,
733 +                         wl_fixed_t *x, wl_fixed_t *y)
734 +{
735 +       double s, c;
736 +
737 +       seat->pointer_phase += step;
738 +       while (seat->pointer_phase > 2.0 * M_PI)
739 +               seat->pointer_phase -= 2.0 * M_PI;
740 +
741 +       sincos(seat->pointer_phase, &s, &c);
742 +       *x = wl_fixed_from_double(100.0 + 50.0 * c);
743 +       *y = wl_fixed_from_double(100.0 + 50.0 * s);
744 +}
745 +
746 +static int
747 +fake_pointer_timer_handler(void *data)
748 +{
749 +       struct weston_transmitter_seat *seat = data;
750 +       wl_fixed_t x, y;
751 +       uint32_t time;
752 +
753 +       time = weston_compositor_get_time();
754 +
755 +       fake_pointer_get_position(seat, 18.0 / 180.0 * M_PI, &x, &y);
756 +       transmitter_seat_pointer_motion(seat, time, x, y);
757 +       transmitter_seat_pointer_frame(seat);
758 +
759 +       wl_event_source_timer_update(seat->pointer_timer, 100);
760 +
761 +       return 0;
762 +}
763 +
764 +int
765 +transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
766 +                                   struct weston_transmitter_surface *txs)
767 +{
768 +       struct wl_event_loop *loop;
769 +       wl_fixed_t x, y;
770 +       uint32_t serial = 5;
771 +
772 +       /* remove focus from earlier surface */
773 +       transmitter_seat_pointer_leave(seat, serial++, seat->pointer_focus);
774 +       transmitter_seat_pointer_frame(seat);
775 +
776 +       /* set pointer focus to surface */
777 +       fake_pointer_get_position(seat, 0.0, &x, &y);
778 +       transmitter_seat_pointer_enter(seat, serial++, txs, x, y);
779 +       transmitter_seat_pointer_frame(seat);
780 +
781 +       if (!seat->pointer_timer) {
782 +               /* schedule timer for motion */
783 +               loop = wl_display_get_event_loop(seat->base.compositor->wl_display);
784 +               seat->pointer_timer = wl_event_loop_add_timer(loop,
785 +                                               fake_pointer_timer_handler, seat);
786 +               wl_event_source_timer_update(seat->pointer_timer, 100);
787 +       }
788 +
789 +       /* XXX: if the now focused surface disappears, we should call
790 +        * transmitter_seat_pointer_leave() as part of the mockup. Otherwise
791 +        * you get a "Transmitter Warning: no pointer->focus_client?".
792 +        */
793 +
794 +       return 0;
795 +}
796 diff --git a/transmitter/output.c b/transmitter/output.c
797 new file mode 100644
798 index 0000000..6a78721
799 --- /dev/null
800 +++ b/transmitter/output.c
801 @@ -0,0 +1,234 @@
802 +/*
803 + * Copyright (C) 2016 DENSO CORPORATION
804 + *
805 + * Permission is hereby granted, free of charge, to any person obtaining
806 + * a copy of this software and associated documentation files (the
807 + * "Software"), to deal in the Software without restriction, including
808 + * without limitation the rights to use, copy, modify, merge, publish,
809 + * distribute, sublicense, and/or sell copies of the Software, and to
810 + * permit persons to whom the Software is furnished to do so, subject to
811 + * the following conditions:
812 + *
813 + * The above copyright notice and this permission notice (including the
814 + * next paragraph) shall be included in all copies or substantial
815 + * portions of the Software.
816 + *
817 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
818 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
819 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
820 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
821 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
822 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
823 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
824 + * SOFTWARE.
825 + */
826 +
827 +#include "config.h"
828 +
829 +#include <stdlib.h>
830 +#include <assert.h>
831 +#include <string.h>
832 +
833 +#include "compositor.h"
834 +#include "helpers.h"
835 +
836 +#include "plugin.h"
837 +#include "transmitter_api.h"
838 +
839 +/** @file
840 + *
841 + * This is an implementation of a remote output.
842 + *
843 + * A remote output must not be accepted as an argument to:
844 + * - wl_shell_surface.set_fullscreen
845 + * - wl_shell_surface.set_maximized
846 + * - zwp_fullscreen_shell_v1.present_surface
847 + * - zwp_fullscreen_shell_v1.present_surface_for_mode
848 + * - zwp_input_panel_surface_v1.set_toplevel
849 + * - xdg_surface.set_fullscreen
850 + *
851 + * If a remote output is an argument to the above or similar requests,
852 + * it should have the same effect as NULL if possible.
853 + *
854 + * @todo Should we instead accept the argument and have it start remoting
855 + * automatically? That would be shell-specific.
856 + *
857 + * In ivi-shell's case, only zwp_input_panel_surface_v1.set_toplevel is
858 + * reachable from keyboard.c. That just blindly uses whatever the first
859 + * output happens to be, so there is no need to check for now.
860 + *
861 + * @todo Add weston_output_set_remote() which sets weston_output::is_remote
862 + * to true and inits weston_output::link. This should be made mutually
863 + * exclusive with weston_compositor_add_output().
864 + */
865 +
866 +static inline struct weston_transmitter_output *
867 +to_transmitter_output(struct weston_output *base)
868 +{
869 +       return container_of(base, struct weston_transmitter_output, base);
870 +}
871 +
872 +static char *
873 +make_model(struct weston_transmitter_remote *remote, int name)
874 +{
875 +       char *str;
876 +
877 +       if (asprintf(&str, "transmitter-%s-%d", remote->addr, name) < 0)
878 +               return NULL;
879 +
880 +       return str;
881 +}
882 +
883 +static int
884 +make_mode_list(struct wl_list *list,
885 +              const struct weston_transmitter_output_info *info)
886 +{
887 +       struct weston_mode *mode;
888 +
889 +       mode = zalloc(sizeof *mode);
890 +       if (!mode)
891 +               return -1;
892 +
893 +       *mode = info->mode;
894 +       wl_list_insert(list->prev, &mode->link);
895 +
896 +       return 0;
897 +}
898 +
899 +static struct weston_mode *
900 +get_current_mode(struct wl_list *mode_list)
901 +{
902 +       struct weston_mode *mode;
903 +
904 +       wl_list_for_each(mode, mode_list, link)
905 +               if (mode->flags & WL_OUTPUT_MODE_CURRENT)
906 +                       return mode;
907 +
908 +       assert(0);
909 +       return NULL;
910 +}
911 +
912 +static void
913 +free_mode_list(struct wl_list *mode_list)
914 +{
915 +       struct weston_mode *mode;
916 +
917 +       while (!wl_list_empty(mode_list)) {
918 +               mode = container_of(mode_list->next, struct weston_mode, link);
919 +
920 +               wl_list_remove(&mode->link);
921 +               free(mode);
922 +       }
923 +}
924 +
925 +void
926 +transmitter_output_destroy(struct weston_transmitter_output *output)
927 +{
928 +       weston_log("Transmitter destroying output '%s'\n", output->base.name);
929 +
930 +       wl_list_remove(&output->link);
931 +
932 +       free_mode_list(&output->base.mode_list);
933 +       free(output->base.serial_number);
934 +       free(output->base.model);
935 +       free(output->base.make);
936 +
937 +       weston_output_destroy(&output->base);
938 +       free(output);
939 +}
940 +
941 +static void
942 +transmitter_output_destroy_(struct weston_output *base)
943 +{
944 +       struct weston_transmitter_output *output = to_transmitter_output(base);
945 +
946 +       transmitter_output_destroy(output);
947 +}
948 +
949 +static void
950 +transmitter_start_repaint_loop(struct weston_output *base)
951 +{
952 +       weston_log("%s(%s)\n", __func__, base->name);
953 +}
954 +
955 +static int
956 +transmitter_output_repaint(struct weston_output *base,
957 +                          pixman_region32_t *damage)
958 +{
959 +       weston_log("%s(%s)\n", __func__, base->name);
960 +
961 +       return -1;
962 +}
963 +
964 +int
965 +transmitter_remote_create_output(
966 +       struct weston_transmitter_remote *remote,
967 +       const struct weston_transmitter_output_info *info)
968 +{
969 +       struct weston_transmitter_output *output;
970 +
971 +       output = zalloc(sizeof *output);
972 +       if (!output)
973 +               return -1;
974 +
975 +       output->base.subpixel = info->subpixel;
976 +
977 +       output->base.name = make_model(remote, 1);
978 +       output->base.make = strdup(WESTON_TRANSMITTER_OUTPUT_MAKE);
979 +       output->base.model = make_model(remote, 1);
980 +       output->base.serial_number = strdup("0");
981 +
982 +       wl_list_init(&output->base.mode_list);
983 +       if (make_mode_list(&output->base.mode_list, info) < 0)
984 +               goto fail;
985 +
986 +       output->base.current_mode = get_current_mode(&output->base.mode_list);
987 +       /* WL_OUTPUT_MODE_CURRENT already set */
988 +
989 +       weston_output_init(&output->base, remote->transmitter->compositor);
990 +
991 +       /*
992 +        * renderer_output_create skipped:
993 +        * no renderer awareness is needed for this output
994 +        */
995 +
996 +       /*
997 +        * weston_compositor_add_output() skipped:
998 +        * Most other code uses weston_compositor::output_list when traversing
999 +        * all outputs, we do not want any of that.
1000 +        * Also weston_compositor::output_created_signal must not trigger
1001 +        * for this output, since we must not involve input device management
1002 +        * or color management or any kind of local management.
1003 +        */
1004 +
1005 +       output->base.start_repaint_loop = transmitter_start_repaint_loop;
1006 +       output->base.repaint = transmitter_output_repaint;
1007 +       output->base.destroy = transmitter_output_destroy_;
1008 +       output->base.assign_planes = NULL;
1009 +       output->base.set_dpms = NULL;
1010 +       output->base.switch_mode = NULL;
1011 +       output->base.gamma_size = 0;
1012 +       output->base.set_gamma = NULL;
1013 +
1014 +       output->base.native_mode = output->base.current_mode;
1015 +       output->base.native_scale = output->base.current_scale;
1016 +
1017 +       output->remote = remote;
1018 +       wl_list_insert(&remote->output_list, &output->link);
1019 +
1020 +       weston_log("Transmitter created output '%s': %s, %s, %s\n",
1021 +                  output->base.name, output->base.make, output->base.model,
1022 +                  output->base.serial_number);
1023 +
1024 +       return 0;
1025 +
1026 +fail:
1027 +       free_mode_list(&output->base.mode_list);
1028 +       free(output->base.serial_number);
1029 +       free(output->base.model);
1030 +       free(output->base.make);
1031 +       free(output->base.name);
1032 +       free(output);
1033 +
1034 +       return -1;
1035 +}
1036 diff --git a/transmitter/plugin.c b/transmitter/plugin.c
1037 new file mode 100644
1038 index 0000000..c5e56d3
1039 --- /dev/null
1040 +++ b/transmitter/plugin.c
1041 @@ -0,0 +1,638 @@
1042 +/*
1043 + * Copyright (C) 2016 DENSO CORPORATION
1044 + *
1045 + * Permission is hereby granted, free of charge, to any person obtaining
1046 + * a copy of this software and associated documentation files (the
1047 + * "Software"), to deal in the Software without restriction, including
1048 + * without limitation the rights to use, copy, modify, merge, publish,
1049 + * distribute, sublicense, and/or sell copies of the Software, and to
1050 + * permit persons to whom the Software is furnished to do so, subject to
1051 + * the following conditions:
1052 + *
1053 + * The above copyright notice and this permission notice (including the
1054 + * next paragraph) shall be included in all copies or substantial
1055 + * portions of the Software.
1056 + *
1057 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1058 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1059 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1060 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1061 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1062 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1063 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1064 + * SOFTWARE.
1065 + */
1066 +
1067 +#include "config.h"
1068 +
1069 +#include <stdlib.h>
1070 +#include <assert.h>
1071 +#include <string.h>
1072 +#include <linux/input.h>
1073 +
1074 +#include "compositor.h"
1075 +#include "helpers.h"
1076 +#include "timespec-util.h"
1077 +
1078 +#include "plugin.h"
1079 +#include "transmitter_api.h"
1080 +
1081 +/* XXX: all functions and variables with a name, and things marked with a
1082 + * comment, containing the word "fake" are mockups that need to be
1083 + * removed from the final implementation.
1084 + */
1085 +
1086 +/** Send configure event through ivi-shell.
1087 + *
1088 + * \param txs The Transmitter surface.
1089 + * \param width Suggestion for surface width.
1090 + * \param height Suggestion for surface height.
1091 + *
1092 + * When the networking code receives a ivi_surface.configure event, it calls
1093 + * this function to relay it to the application.
1094 + *
1095 + * \c txs cannot be a zombie, because transmitter_surface_zombify() must
1096 + * tear down the network link, so a zombie cannot receive events.
1097 + */
1098 +void
1099 +transmitter_surface_ivi_resize(struct weston_transmitter_surface *txs,
1100 +                              int32_t width, int32_t height)
1101 +{
1102 +       assert(txs->resize_handler);
1103 +       if (!txs->resize_handler)
1104 +               return;
1105 +
1106 +       assert(txs->surface);
1107 +       if (!txs->surface)
1108 +               return;
1109 +
1110 +       txs->resize_handler(txs->resize_handler_data, width, height);
1111 +}
1112 +
1113 +static int
1114 +frame_callback_handler(void *data) /* fake */
1115 +{
1116 +       struct weston_transmitter_surface *txs = data;
1117 +       struct weston_frame_callback *cb, *cnext;
1118 +       struct weston_output *output;
1119 +       struct weston_compositor *compositor;
1120 +       uint32_t frame_time;
1121 +       uint32_t presented_flags;
1122 +       int32_t refresh_nsec;
1123 +       struct timespec stamp;
1124 +
1125 +       compositor = txs->remote->transmitter->compositor;
1126 +       output = txs->sync_output;
1127 +
1128 +       /* wl_surface.enter should arrive before any frame callbacks,
1129 +        * but remote might send frame callbacks for non-visible too.
1130 +        */
1131 +       if (!output)
1132 +               return 0;
1133 +
1134 +       /* XXX: eeeew */
1135 +       frame_time = weston_compositor_get_time();
1136 +
1137 +       wl_list_for_each_safe(cb, cnext, &txs->frame_callback_list, link) {
1138 +               wl_callback_send_done(cb->resource, frame_time);
1139 +               wl_resource_destroy(cb->resource);
1140 +       }
1141 +
1142 +       presented_flags = 0;
1143 +       refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
1144 +       /* XXX: waaahhhahaa */
1145 +       weston_compositor_read_presentation_clock(compositor, &stamp);
1146 +       weston_presentation_feedback_present_list(&txs->feedback_list,
1147 +                                                 output, refresh_nsec, &stamp,
1148 +                                                 output->msc,
1149 +                                                 presented_flags);
1150 +
1151 +       return 0;
1152 +}
1153 +
1154 +static void
1155 +fake_frame_callback(struct weston_transmitter_surface *txs)
1156 +{
1157 +       struct weston_transmitter *txr = txs->remote->transmitter;
1158 +       struct wl_event_loop *loop;
1159 +
1160 +       if (!txs->frame_timer) {
1161 +               loop = wl_display_get_event_loop(txr->compositor->wl_display);
1162 +               txs->frame_timer =
1163 +                       wl_event_loop_add_timer(loop,
1164 +                                               frame_callback_handler, txs);
1165 +       }
1166 +
1167 +       wl_event_source_timer_update(txs->frame_timer, 85);
1168 +}
1169 +
1170 +static void
1171 +transmitter_surface_configure(struct weston_transmitter_surface *txs,
1172 +                             int32_t dx, int32_t dy)
1173 +{
1174 +       assert(txs->surface);
1175 +       if (!txs->surface)
1176 +               return;
1177 +
1178 +       txs->attach_dx += dx;
1179 +       txs->attach_dy += dy;
1180 +}
1181 +
1182 +static void
1183 +transmitter_surface_gather_state(struct weston_transmitter_surface *txs)
1184 +{
1185 +       weston_log("Transmitter: update surface %p (%d, %d), %d cb\n",
1186 +                  txs->surface, txs->attach_dx, txs->attach_dy,
1187 +                  wl_list_length(&txs->surface->frame_callback_list));
1188 +
1189 +       wl_list_insert_list(&txs->frame_callback_list,
1190 +                           &txs->surface->frame_callback_list);
1191 +       wl_list_init(&txs->surface->frame_callback_list);
1192 +
1193 +       wl_list_insert_list(&txs->feedback_list, &txs->surface->feedback_list);
1194 +       wl_list_init(&txs->surface->feedback_list);
1195 +
1196 +       /* TODO: transmit surface state to remote */
1197 +
1198 +       txs->attach_dx = 0;
1199 +       txs->attach_dy = 0;
1200 +}
1201 +
1202 +/** weston_surface apply state signal handler */
1203 +static void
1204 +transmitter_surface_apply_state(struct wl_listener *listener, void *data)
1205 +{
1206 +       struct weston_transmitter_surface *txs =
1207 +               container_of(listener, struct weston_transmitter_surface,
1208 +                            apply_state_listener);
1209 +
1210 +       assert(data == NULL);
1211 +
1212 +       transmitter_surface_gather_state(txs);
1213 +       fake_frame_callback(txs);
1214 +}
1215 +
1216 +/** Mark the weston_transmitter_surface dead.
1217 + *
1218 + * Stop all remoting actions on this surface.
1219 + *
1220 + * Still keeps the pointer stored by a shell valid, so it can be freed later.
1221 + */
1222 +static void
1223 +transmitter_surface_zombify(struct weston_transmitter_surface *txs)
1224 +{
1225 +       struct weston_frame_callback *framecb, *cnext;
1226 +
1227 +       /* may be called multiple times */
1228 +       if (!txs->surface)
1229 +               return;
1230 +
1231 +       wl_signal_emit(&txs->destroy_signal, txs);
1232 +
1233 +       wl_list_remove(&txs->surface_destroy_listener.link);
1234 +       weston_log("Transmitter unbound surface %p.\n", txs->surface);
1235 +       txs->surface = NULL;
1236 +
1237 +       wl_list_remove(&txs->sync_output_destroy_listener.link);
1238 +       wl_list_remove(&txs->apply_state_listener.link);
1239 +
1240 +       if (txs->map_timer)
1241 +               wl_event_source_remove(txs->map_timer);
1242 +       if (txs->frame_timer)
1243 +               wl_event_source_remove(txs->frame_timer);
1244 +
1245 +       weston_presentation_feedback_discard_list(&txs->feedback_list);
1246 +       wl_list_for_each_safe(framecb, cnext, &txs->frame_callback_list, link)
1247 +               wl_resource_destroy(framecb->resource);
1248 +
1249 +       /* In case called from destroy_transmitter() */
1250 +       txs->remote = NULL;
1251 +}
1252 +
1253 +static void
1254 +transmitter_surface_destroy(struct weston_transmitter_surface *txs)
1255 +{
1256 +       transmitter_surface_zombify(txs);
1257 +
1258 +       wl_list_remove(&txs->link);
1259 +       free(txs);
1260 +}
1261 +
1262 +/** weston_surface destroy signal handler */
1263 +static void
1264 +transmitter_surface_destroyed(struct wl_listener *listener, void *data)
1265 +{
1266 +       struct weston_transmitter_surface *txs =
1267 +               container_of(listener, struct weston_transmitter_surface,
1268 +                            surface_destroy_listener);
1269 +
1270 +       assert(data == txs->surface);
1271 +
1272 +       transmitter_surface_zombify(txs);
1273 +}
1274 +
1275 +static struct weston_transmitter_surface *
1276 +transmitter_surface_get(struct weston_surface *ws)
1277 +{
1278 +       struct wl_listener *listener;
1279 +       struct weston_transmitter_surface *txs;
1280 +
1281 +       listener = wl_signal_get(&ws->destroy_signal,
1282 +                                transmitter_surface_destroyed);
1283 +
1284 +       if (!listener)
1285 +               return NULL;
1286 +
1287 +       txs = container_of(listener, struct weston_transmitter_surface,
1288 +                          surface_destroy_listener);
1289 +       assert(ws == txs->surface);
1290 +
1291 +       return txs;
1292 +}
1293 +
1294 +static void
1295 +sync_output_destroy_handler(struct wl_listener *listener, void *data)
1296 +{
1297 +       struct weston_transmitter_surface *txs;
1298 +
1299 +       txs = container_of(listener, struct weston_transmitter_surface,
1300 +                          sync_output_destroy_listener);
1301 +
1302 +       wl_list_remove(&txs->sync_output_destroy_listener.link);
1303 +       wl_list_init(&txs->sync_output_destroy_listener.link);
1304 +
1305 +       weston_surface_force_output(txs->surface, NULL);
1306 +}
1307 +
1308 +static void
1309 +fake_input(struct weston_transmitter_surface *txs)
1310 +{
1311 +       struct wl_list *seat_list = &txs->remote->seat_list;
1312 +       struct weston_transmitter_seat *seat;
1313 +
1314 +       assert(wl_list_length(seat_list) == 1);
1315 +       seat = container_of(seat_list->next,
1316 +                           struct weston_transmitter_seat, link);
1317 +
1318 +       transmitter_seat_fake_pointer_input(seat, txs);
1319 +}
1320 +
1321 +/* fake receiving wl_surface.enter(output) */
1322 +static int
1323 +map_timer_handler(void *data)
1324 +{
1325 +       struct weston_transmitter_surface *txs = data;
1326 +       struct weston_transmitter_output *output;
1327 +
1328 +       assert(!wl_list_empty(&txs->remote->output_list));
1329 +
1330 +       output = container_of(txs->remote->output_list.next,
1331 +                             struct weston_transmitter_output, link);
1332 +
1333 +       txs->sync_output = &output->base;
1334 +       txs->sync_output_destroy_listener.notify = sync_output_destroy_handler;
1335 +       wl_list_remove(&txs->sync_output_destroy_listener.link);
1336 +       wl_signal_add(&txs->sync_output->destroy_signal,
1337 +                     &txs->sync_output_destroy_listener);
1338 +
1339 +       weston_surface_force_output(txs->surface, txs->sync_output);
1340 +
1341 +       weston_log("Transmitter: surface %p entered output %s\n",
1342 +                  txs->surface, txs->sync_output->name);
1343 +
1344 +       fake_frame_callback(txs);
1345 +       fake_input(txs);
1346 +
1347 +       return 0;
1348 +}
1349 +
1350 +/* Fake a delay for the remote end to map the surface to an output */
1351 +static void
1352 +fake_output_mapping(struct weston_transmitter_surface *txs)
1353 +{
1354 +       struct weston_transmitter *txr = txs->remote->transmitter;
1355 +       struct wl_event_loop *loop;
1356 +
1357 +       loop = wl_display_get_event_loop(txr->compositor->wl_display);
1358 +       txs->map_timer = wl_event_loop_add_timer(loop, map_timer_handler, txs);
1359 +       wl_event_source_timer_update(txs->map_timer, 400);
1360 +}
1361 +
1362 +/* Fake getting "connection established" from the content streamer. */
1363 +static void
1364 +fake_stream_opening_handler(void *data)
1365 +{
1366 +       struct weston_transmitter_surface *txs = data;
1367 +
1368 +       /* ...once the connection is up: */
1369 +       txs->status = WESTON_TRANSMITTER_STREAM_LIVE;
1370 +       wl_signal_emit(&txs->stream_status_signal, txs);
1371 +
1372 +       /* need to create the surface on the remote and set all state */
1373 +       transmitter_surface_gather_state(txs);
1374 +
1375 +       fake_output_mapping(txs);
1376 +}
1377 +
1378 +/* Fake a callback from content streamer. */
1379 +static void
1380 +fake_stream_opening(struct weston_transmitter_surface *txs)
1381 +{
1382 +       struct weston_transmitter *txr = txs->remote->transmitter;
1383 +       struct wl_event_loop *loop;
1384 +
1385 +       loop = wl_display_get_event_loop(txr->compositor->wl_display);
1386 +       wl_event_loop_add_idle(loop, fake_stream_opening_handler, txs);
1387 +}
1388 +
1389 +static struct weston_transmitter_surface *
1390 +transmitter_surface_push_to_remote(struct weston_surface *ws,
1391 +                                  struct weston_transmitter_remote *remote,
1392 +                                  struct wl_listener *stream_status)
1393 +{
1394 +       struct weston_transmitter_surface *txs;
1395 +
1396 +       if (transmitter_surface_get(ws)) {
1397 +               weston_log("Transmitter: surface %p already bound.\n", ws);
1398 +               return NULL;
1399 +       }
1400 +
1401 +       txs = zalloc(sizeof (*txs));
1402 +       if (!txs)
1403 +               return NULL;
1404 +
1405 +       txs->remote = remote;
1406 +       wl_signal_init(&txs->destroy_signal);
1407 +       wl_list_insert(&remote->surface_list, &txs->link);
1408 +
1409 +       txs->status = WESTON_TRANSMITTER_STREAM_INITIALIZING;
1410 +       wl_signal_init(&txs->stream_status_signal);
1411 +       wl_signal_add(&txs->stream_status_signal, stream_status);
1412 +
1413 +       txs->surface = ws;
1414 +       txs->surface_destroy_listener.notify = transmitter_surface_destroyed;
1415 +       wl_signal_add(&ws->destroy_signal, &txs->surface_destroy_listener);
1416 +
1417 +       txs->apply_state_listener.notify = transmitter_surface_apply_state;
1418 +       wl_signal_add(&ws->apply_state_signal, &txs->apply_state_listener);
1419 +
1420 +       wl_list_init(&txs->sync_output_destroy_listener.link);
1421 +
1422 +       wl_list_init(&txs->frame_callback_list);
1423 +       wl_list_init(&txs->feedback_list);
1424 +
1425 +       /* TODO: create the content stream connection... */
1426 +       fake_stream_opening(txs);
1427 +
1428 +       return txs;
1429 +}
1430 +
1431 +static enum weston_transmitter_stream_status
1432 +transmitter_surface_get_stream_status(struct weston_transmitter_surface *txs)
1433 +{
1434 +       return txs->status;
1435 +}
1436 +
1437 +static int
1438 +conn_timer_handler(void *data) /* fake */
1439 +{
1440 +       struct weston_transmitter_remote *remote = data;
1441 +       struct weston_transmitter_output_info info = {
1442 +               WL_OUTPUT_SUBPIXEL_NONE,
1443 +               WL_OUTPUT_TRANSFORM_NORMAL,
1444 +               1,
1445 +               0, 0,
1446 +               300, 200,
1447 +               "fake",
1448 +               {
1449 +                       WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
1450 +                       800, 600,
1451 +                       51519,
1452 +                       { NULL, NULL }
1453 +               }
1454 +       };
1455 +
1456 +       weston_log("Transmitter connected to %s.\n", remote->addr);
1457 +       remote->status = WESTON_TRANSMITTER_CONNECTION_READY;
1458 +       wl_signal_emit(&remote->connection_status_signal, remote);
1459 +
1460 +       wl_event_source_remove(remote->conn_timer);
1461 +       remote->conn_timer = NULL;
1462 +
1463 +       /* Outputs and seats are dynamic, do not guarantee they are all
1464 +        * present when signalling connection status.
1465 +        */
1466 +       transmitter_remote_create_output(remote, &info);
1467 +       transmitter_remote_create_seat(remote);
1468 +
1469 +       return 0;
1470 +}
1471 +
1472 +static struct weston_transmitter_remote *
1473 +transmitter_connect_to_remote(struct weston_transmitter *txr,
1474 +                             const char *addr,
1475 +                             struct wl_listener *status)
1476 +{
1477 +       struct weston_transmitter_remote *remote;
1478 +       struct wl_event_loop *loop;
1479 +
1480 +       remote = zalloc(sizeof (*remote));
1481 +       if (!remote)
1482 +               return NULL;
1483 +
1484 +       remote->transmitter = txr;
1485 +       wl_list_insert(&txr->remote_list, &remote->link);
1486 +       remote->addr = strdup(addr);
1487 +       remote->status = WESTON_TRANSMITTER_CONNECTION_INITIALIZING;
1488 +       wl_signal_init(&remote->connection_status_signal);
1489 +       wl_signal_add(&remote->connection_status_signal, status);
1490 +       wl_list_init(&remote->output_list);
1491 +       wl_list_init(&remote->surface_list);
1492 +       wl_list_init(&remote->seat_list);
1493 +
1494 +       /* XXX: actually start connecting */
1495 +       weston_log("Transmitter connecting to %s...\n", addr);
1496 +       /* fake it with a one second timer */
1497 +       loop = wl_display_get_event_loop(txr->compositor->wl_display);
1498 +       remote->conn_timer = wl_event_loop_add_timer(loop, conn_timer_handler,
1499 +                                                    remote);
1500 +       wl_event_source_timer_update(remote->conn_timer, 1000);
1501 +
1502 +       return remote;
1503 +}
1504 +
1505 +static enum weston_transmitter_connection_status
1506 +transmitter_remote_get_status(struct weston_transmitter_remote *remote)
1507 +{
1508 +       return remote->status;
1509 +}
1510 +
1511 +static void
1512 +transmitter_remote_destroy(struct weston_transmitter_remote *remote)
1513 +{
1514 +       struct weston_transmitter_surface *txs;
1515 +       struct weston_transmitter_output *output, *otmp;
1516 +       struct weston_transmitter_seat *seat, *stmp;
1517 +
1518 +       /* Do not emit connection_status_signal. */
1519 +
1520 +       /*
1521 +        *  Must not touch remote->transmitter as it may be stale:
1522 +        * the desctruction order between the shell and Transmitter is
1523 +        * undefined.
1524 +        */
1525 +       weston_log("Transmitter disconnecting from %s.\n", remote->addr);
1526 +
1527 +       if (remote->conn_timer)
1528 +               wl_event_source_remove(remote->conn_timer);
1529 +
1530 +       if (!wl_list_empty(&remote->surface_list))
1531 +               weston_log("Transmitter warning: surfaces remain in %s.\n",
1532 +                          __func__);
1533 +       wl_list_for_each(txs, &remote->surface_list, link)
1534 +               txs->remote = NULL;
1535 +       wl_list_remove(&remote->surface_list);
1536 +
1537 +       wl_list_for_each_safe(seat, stmp, &remote->seat_list, link)
1538 +               transmitter_seat_destroy(seat);
1539 +
1540 +       wl_list_for_each_safe(output, otmp, &remote->output_list, link)
1541 +               transmitter_output_destroy(output);
1542 +
1543 +       free(remote->addr);
1544 +       wl_list_remove(&remote->link);
1545 +
1546 +       free(remote);
1547 +}
1548 +
1549 +/** Transmitter is destroyed on compositor shutdown. */
1550 +static void
1551 +transmitter_compositor_destroyed(struct wl_listener *listener, void *data)
1552 +{
1553 +       struct weston_transmitter_remote *remote;
1554 +       struct weston_transmitter_surface *txs;
1555 +       struct weston_transmitter *txr =
1556 +               container_of(listener, struct weston_transmitter,
1557 +                            compositor_destroy_listener);
1558 +
1559 +       assert(data == txr->compositor);
1560 +
1561 +       /* may be called before or after shell cleans up */
1562 +       wl_list_for_each(remote, &txr->remote_list, link) {
1563 +               wl_list_for_each(txs, &remote->surface_list, link) {
1564 +                       transmitter_surface_zombify(txs);
1565 +               }
1566 +       }
1567 +
1568 +       /*
1569 +        * Remove the head in case the list is not empty, to avoid
1570 +        * transmitter_remote_destroy() accessing freed memory if the shell
1571 +        * cleans up after Transmitter.
1572 +        */
1573 +       wl_list_remove(&txr->remote_list);
1574 +
1575 +       weston_log("Transmitter terminating.\n");
1576 +       free(txr);
1577 +}
1578 +
1579 +static struct weston_transmitter *
1580 +transmitter_get(struct weston_compositor *compositor)
1581 +{
1582 +       struct wl_listener *listener;
1583 +       struct weston_transmitter *txr;
1584 +
1585 +       listener = wl_signal_get(&compositor->destroy_signal,
1586 +                                transmitter_compositor_destroyed);
1587 +       if (!listener)
1588 +               return NULL;
1589 +
1590 +       txr = container_of(listener, struct weston_transmitter,
1591 +                          compositor_destroy_listener);
1592 +       assert(compositor == txr->compositor);
1593 +
1594 +       return txr;
1595 +}
1596 +
1597 +static const struct weston_transmitter_api transmitter_api_impl = {
1598 +       transmitter_get,
1599 +       transmitter_connect_to_remote,
1600 +       transmitter_remote_get_status,
1601 +       transmitter_remote_destroy,
1602 +       transmitter_surface_push_to_remote,
1603 +       transmitter_surface_get_stream_status,
1604 +       transmitter_surface_destroy,
1605 +       transmitter_surface_configure,
1606 +};
1607 +
1608 +static void
1609 +transmitter_surface_set_ivi_id(struct weston_transmitter_surface *txs,
1610 +                              uint32_t ivi_id)
1611 +{
1612 +       assert(txs->surface);
1613 +       if (!txs->surface)
1614 +               return;
1615 +
1616 +       weston_log("%s(%p, %#x)\n", __func__, txs->surface, ivi_id);
1617 +}
1618 +
1619 +static void
1620 +transmitter_surface_set_resize_callback(
1621 +       struct weston_transmitter_surface *txs,
1622 +       weston_transmitter_ivi_resize_handler_t cb,
1623 +       void *data)
1624 +{
1625 +       txs->resize_handler = cb;
1626 +       txs->resize_handler_data = data;
1627 +}
1628 +
1629 +static const struct weston_transmitter_ivi_api transmitter_ivi_api_impl = {
1630 +       transmitter_surface_set_ivi_id,
1631 +       transmitter_surface_set_resize_callback,
1632 +};
1633 +
1634 +WL_EXPORT int
1635 +wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[])
1636 +{
1637 +       struct weston_transmitter *txr;
1638 +       int ret;
1639 +
1640 +       txr = zalloc(sizeof *txr);
1641 +       if (!txr)
1642 +               return -1;
1643 +
1644 +       wl_list_init(&txr->remote_list);
1645 +
1646 +       txr->compositor = compositor;
1647 +       txr->compositor_destroy_listener.notify =
1648 +               transmitter_compositor_destroyed;
1649 +       wl_signal_add(&compositor->destroy_signal,
1650 +                     &txr->compositor_destroy_listener);
1651 +
1652 +       ret = weston_plugin_api_register(compositor,
1653 +                                        WESTON_TRANSMITTER_API_NAME,
1654 +                                        &transmitter_api_impl,
1655 +                                        sizeof(transmitter_api_impl));
1656 +       if (ret < 0) {
1657 +               weston_log("Fatal: Transmitter API registration failed.\n");
1658 +               goto fail;
1659 +       }
1660 +
1661 +       ret = weston_plugin_api_register(compositor,
1662 +                                        WESTON_TRANSMITTER_IVI_API_NAME,
1663 +                                        &transmitter_ivi_api_impl,
1664 +                                        sizeof(transmitter_ivi_api_impl));
1665 +       if (ret < 0) {
1666 +               weston_log("Fatal: Transmitter IVI API registration failed.\n");
1667 +               goto fail;
1668 +       }
1669 +
1670 +       weston_log("Transmitter initialized.\n");
1671 +
1672 +       return 0;
1673 +
1674 +fail:
1675 +       wl_list_remove(&txr->compositor_destroy_listener.link);
1676 +       free(txr);
1677 +
1678 +       return -1;
1679 +}
1680 diff --git a/transmitter/plugin.h b/transmitter/plugin.h
1681 new file mode 100644
1682 index 0000000..710b543
1683 --- /dev/null
1684 +++ b/transmitter/plugin.h
1685 @@ -0,0 +1,207 @@
1686 +/*
1687 + * Copyright (C) 2016 DENSO CORPORATION
1688 + *
1689 + * Permission is hereby granted, free of charge, to any person obtaining
1690 + * a copy of this software and associated documentation files (the
1691 + * "Software"), to deal in the Software without restriction, including
1692 + * without limitation the rights to use, copy, modify, merge, publish,
1693 + * distribute, sublicense, and/or sell copies of the Software, and to
1694 + * permit persons to whom the Software is furnished to do so, subject to
1695 + * the following conditions:
1696 + *
1697 + * The above copyright notice and this permission notice (including the
1698 + * next paragraph) shall be included in all copies or substantial
1699 + * portions of the Software.
1700 + *
1701 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1702 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1703 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1704 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1705 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1706 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1707 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1708 + * SOFTWARE.
1709 + */
1710 +
1711 +#ifndef WESTON_TRANSMITTER_PLUGIN_H
1712 +#define WESTON_TRANSMITTER_PLUGIN_H
1713 +
1714 +/* XXX: all functions and variables with a name, and things marked with a
1715 + * comment, containing the word "fake" are mockups that need to be
1716 + * removed from the final implementation.
1717 + */
1718 +
1719 +#include <stdint.h>
1720 +
1721 +#include "compositor.h"
1722 +#include "transmitter_api.h"
1723 +
1724 +struct weston_transmitter {
1725 +       struct weston_compositor *compositor;
1726 +       struct wl_listener compositor_destroy_listener;
1727 +
1728 +       struct wl_list remote_list; /* transmitter_remote::link */
1729 +};
1730 +
1731 +struct weston_transmitter_remote {
1732 +       struct weston_transmitter *transmitter;
1733 +       struct wl_list link;
1734 +
1735 +       char *addr;
1736 +
1737 +       enum weston_transmitter_connection_status status;
1738 +       struct wl_signal connection_status_signal;
1739 +
1740 +       struct wl_list output_list; /* weston_transmitter_output::link */
1741 +       struct wl_list surface_list; /* weston_transmitter_surface::link */
1742 +       struct wl_list seat_list; /* weston_transmitter_seat::link */
1743 +
1744 +       struct wl_event_source *conn_timer; /* fake */
1745 +};
1746 +
1747 +struct weston_transmitter_surface {
1748 +       struct weston_transmitter_remote *remote;
1749 +       struct wl_list link; /* weston_transmitter_remote::surface_list */
1750 +       struct wl_signal destroy_signal; /* data: weston_transmitter_surface */
1751 +
1752 +       enum weston_transmitter_stream_status status;
1753 +       struct wl_signal stream_status_signal;
1754 +
1755 +       struct weston_surface *surface;
1756 +       struct wl_listener surface_destroy_listener;
1757 +       struct wl_listener apply_state_listener;
1758 +
1759 +       weston_transmitter_ivi_resize_handler_t resize_handler;
1760 +       void *resize_handler_data;
1761 +
1762 +       struct weston_output *sync_output;
1763 +       struct wl_listener sync_output_destroy_listener;
1764 +
1765 +       struct wl_event_source *map_timer; /* fake */
1766 +       struct wl_event_source *frame_timer; /* fake */
1767 +
1768 +       int32_t attach_dx; /**< wl_surface.attach(buffer, dx, dy) */
1769 +       int32_t attach_dy; /**< wl_surface.attach(buffer, dx, dy) */
1770 +       struct wl_list frame_callback_list; /* weston_frame_callback::link */
1771 +       struct wl_list feedback_list; /* weston_presentation_feedback::link */
1772 +};
1773 +
1774 +struct weston_transmitter_output_info {
1775 +       uint32_t subpixel; /* enum wl_output_subpixel */
1776 +       uint32_t transform; /* enum wl_output_transform */
1777 +       int32_t scale;
1778 +       int32_t x;
1779 +       int32_t y;
1780 +       int32_t width_mm;
1781 +       int32_t height_mm;
1782 +       /* char *make; is WESTON_TRANSMITTER_OUTPUT_MAKE */
1783 +       char *model;
1784 +
1785 +       struct weston_mode mode;
1786 +};
1787 +
1788 +struct weston_transmitter_output {
1789 +       struct weston_output base;
1790 +
1791 +       struct weston_transmitter_remote *remote;
1792 +       struct wl_list link; /* weston_transmitter_remote::output_list */
1793 +};
1794 +
1795 +struct weston_transmitter_seat {
1796 +       struct weston_seat base;
1797 +       struct wl_list link;
1798 +
1799 +       /* pointer */
1800 +       wl_fixed_t pointer_surface_x;
1801 +       wl_fixed_t pointer_surface_y;
1802 +
1803 +       struct wl_listener get_pointer_listener;
1804 +       struct weston_transmitter_surface *pointer_focus;
1805 +       struct wl_listener pointer_focus_destroy_listener;
1806 +
1807 +       struct wl_event_source *pointer_timer; /* fake */
1808 +
1809 +       double pointer_phase; /* fake */
1810 +
1811 +       /* keyboard */
1812 +
1813 +       /* touch */
1814 +};
1815 +
1816 +void
1817 +transmitter_surface_ivi_resize(struct weston_transmitter_surface *txs,
1818 +                              int32_t width, int32_t height);
1819 +
1820 +int
1821 +transmitter_remote_create_output(struct weston_transmitter_remote *remote,
1822 +                       const struct weston_transmitter_output_info *info);
1823 +
1824 +void
1825 +transmitter_output_destroy(struct weston_transmitter_output *output);
1826 +
1827 +int
1828 +transmitter_remote_create_seat(struct weston_transmitter_remote *remote);
1829 +
1830 +void
1831 +transmitter_seat_destroy(struct weston_transmitter_seat *seat);
1832 +
1833 +/* The below are the functions to be called from the network protocol
1834 + * input event handlers.
1835 + */
1836 +
1837 +void
1838 +transmitter_seat_pointer_enter(struct weston_transmitter_seat *seat,
1839 +                              uint32_t serial,
1840 +                              struct weston_transmitter_surface *txs,
1841 +                              wl_fixed_t surface_x,
1842 +                              wl_fixed_t surface_y);
1843 +
1844 +void
1845 +transmitter_seat_pointer_leave(struct weston_transmitter_seat *seat,
1846 +                              uint32_t serial,
1847 +                              struct weston_transmitter_surface *txs);
1848 +
1849 +void
1850 +transmitter_seat_pointer_motion(struct weston_transmitter_seat *seat,
1851 +                               uint32_t time,
1852 +                               wl_fixed_t surface_x,
1853 +                               wl_fixed_t surface_y);
1854 +
1855 +void
1856 +transmitter_seat_pointer_button(struct weston_transmitter_seat *seat,
1857 +                               uint32_t serial,
1858 +                               uint32_t time,
1859 +                               uint32_t button,
1860 +                               uint32_t state);
1861 +
1862 +void
1863 +transmitter_seat_pointer_axis(struct weston_transmitter_seat *seat,
1864 +                             uint32_t time,
1865 +                             uint32_t axis,
1866 +                             wl_fixed_t value);
1867 +
1868 +void
1869 +transmitter_seat_pointer_frame(struct weston_transmitter_seat *seat);
1870 +
1871 +void
1872 +transmitter_seat_pointer_axis_source(struct weston_transmitter_seat *seat,
1873 +                                    uint32_t axis_source);
1874 +
1875 +void
1876 +transmitter_seat_pointer_axis_stop(struct weston_transmitter_seat *seat,
1877 +                                  uint32_t time,
1878 +                                  uint32_t axis);
1879 +
1880 +void
1881 +transmitter_seat_pointer_axis_discrete(struct weston_transmitter_seat *seat,
1882 +                                      uint32_t axis,
1883 +                                      int32_t discrete);
1884 +
1885 +/* Fake functions for mockup testing: */
1886 +
1887 +int
1888 +transmitter_seat_fake_pointer_input(struct weston_transmitter_seat *seat,
1889 +                                   struct weston_transmitter_surface *txs);
1890 +
1891 +
1892 +#endif /* WESTON_TRANSMITTER_PLUGIN_H */
1893 diff --git a/transmitter/transmitter_api.h b/transmitter/transmitter_api.h
1894 new file mode 100644
1895 index 0000000..95d82ec
1896 --- /dev/null
1897 +++ b/transmitter/transmitter_api.h
1898 @@ -0,0 +1,253 @@
1899 +/*
1900 + * Copyright (C) 2016 DENSO CORPORATION
1901 + *
1902 + * Permission is hereby granted, free of charge, to any person obtaining
1903 + * a copy of this software and associated documentation files (the
1904 + * "Software"), to deal in the Software without restriction, including
1905 + * without limitation the rights to use, copy, modify, merge, publish,
1906 + * distribute, sublicense, and/or sell copies of the Software, and to
1907 + * permit persons to whom the Software is furnished to do so, subject to
1908 + * the following conditions:
1909 + *
1910 + * The above copyright notice and this permission notice (including the
1911 + * next paragraph) shall be included in all copies or substantial
1912 + * portions of the Software.
1913 + *
1914 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1915 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1916 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1917 + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1918 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1919 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1920 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1921 + * SOFTWARE.
1922 + */
1923 +
1924 +#ifndef WESTON_TRANSMITTER_API_H
1925 +#define WESTON_TRANSMITTER_API_H
1926 +
1927 +#include "plugin-registry.h"
1928 +
1929 +#include <stdint.h>
1930 +
1931 +/** \file
1932 + *
1933 + * This is the Transmitter API published via weston_plugin_api_register().
1934 + */
1935 +
1936 +struct weston_transmitter;
1937 +struct weston_transmitter_remote;
1938 +struct weston_transmitter_surface;
1939 +
1940 +#define WESTON_TRANSMITTER_API_NAME "transmitter_v1"
1941 +
1942 +/** See weston_transmitter_api::remote_get_status */
1943 +enum weston_transmitter_connection_status {
1944 +       /** The connection hand-shake is not yet complete */
1945 +       WESTON_TRANSMITTER_CONNECTION_INITIALIZING,
1946 +
1947 +       /** The connection is live and ready to be used. */
1948 +       WESTON_TRANSMITTER_CONNECTION_READY,
1949 +
1950 +       /** The connection is dead. */
1951 +       WESTON_TRANSMITTER_CONNECTION_DISCONNECTED,
1952 +};
1953 +
1954 +/** See weston_transmitter_api::surface_get_stream_status */
1955 +enum weston_transmitter_stream_status {
1956 +       /** The stream hand-shake is not yet complete. */
1957 +       WESTON_TRANSMITTER_STREAM_INITIALIZING,
1958 +
1959 +       /** The stream is carrying surface content updates as needed. */
1960 +       WESTON_TRANSMITTER_STREAM_LIVE,
1961 +
1962 +       /** The stream has failed and disconnected permanently. */
1963 +       WESTON_TRANSMITTER_STREAM_FAILED,
1964 +};
1965 +
1966 +/** The Transmitter Base API
1967 + *
1968 + * Transmitter is a Weston plugin that provides remoting of weston_surfaces
1969 + * over the network. Shells use this API to create remote connections and
1970 + * push surfaces over the network. Shells are also responsible for relaying
1971 + * basic window state changes to Transmitter.
1972 + *
1973 + * In addition to the Transmitter Base API, shells also need to use a
1974 + * shell protocol specific Transmitter API to relay specific window state
1975 + * changes.
1976 + */
1977 +struct weston_transmitter_api {
1978 +       /** Fetch the Transmitter plugin context
1979 +        *
1980 +        * \param compositor The compositor instance.
1981 +        * \return The weston_transmitter context, which is always the same
1982 +        * for the given compositor instance.
1983 +        */
1984 +       struct weston_transmitter *
1985 +       (*transmitter_get)(struct weston_compositor *compositor);
1986 +
1987 +       /**
1988 +        * Connect to a remote server via Transmitter.
1989 +        *
1990 +        * \param txr The Transmitter context.
1991 +        * \param addr Address of the remote server.
1992 +        * \param status Listener to inform of connection status changes.
1993 +        * \return A handle to the remote connection, or NULL on failure.
1994 +        *
1995 +        * This call attempts to open a connection asynchronously. The
1996 +        * connection is not usable until the listener signals it is ready.
1997 +        * The listener may also signal that the connection failed instead.
1998 +        *
1999 +        * The listener callback argument is the weston_transmitter_remote
2000 +        * returned by this function. Use remote_get_status() to fetch the
2001 +        * current status.
2002 +        *
2003 +        * The address argument is a string in the form "host:port".
2004 +        */
2005 +       struct weston_transmitter_remote *
2006 +       (*connect_to_remote)(struct weston_transmitter *txr,
2007 +                            const char *addr,
2008 +                            struct wl_listener *status);
2009 +
2010 +       /**
2011 +        * Retrieve the connection status.
2012 +        *
2013 +        * If the status is WESTON_TRANSMITTER_CONNECTION_DISCONNECTED,
2014 +        * you have to shut the remote down completely. There is no automatic
2015 +        * reconnect.
2016 +        */
2017 +       enum weston_transmitter_connection_status
2018 +       (*remote_get_status)(struct weston_transmitter_remote *remote);
2019 +
2020 +       /**
2021 +        * Destroy/disconnect a remote connection.
2022 +        *
2023 +        * Disconnects if connected, and destroys the connection.
2024 +        * The connection status handler is not called.
2025 +        *
2026 +        * The caller is responsible for destroying all
2027 +        * weston_transmitter_surfaces before calling this.
2028 +        */
2029 +       void
2030 +       (*remote_destroy)(struct weston_transmitter_remote *remote);
2031 +
2032 +       /** Push a weston_surface to be transmitted to a remote.
2033 +        *
2034 +        * \param ws The surface to push.
2035 +        * \param remote The remote connection to use.
2036 +        * \param stream_status Listener for stream status changes.
2037 +        * \return The Transmitter surface handle.
2038 +        *
2039 +        * The surface cannot be visible on the remote until the stream
2040 +        * status listener signals WESTON_TRANSMITTER_STREAM_LIVE. After that,
2041 +        * surface updates made by the application will be automatically
2042 +        * streamed to the remote, and input events from the remote will be
2043 +        * delivered to the application.
2044 +        *
2045 +        * The listener callback argument is the weston_transmitter_surface
2046 +        * returned by this function. Use surface_get_stream_status() to
2047 +        * fetch the current status.
2048 +        */
2049 +       struct weston_transmitter_surface *
2050 +       (*surface_push_to_remote)(struct weston_surface *ws,
2051 +                                 struct weston_transmitter_remote *remote,
2052 +                                 struct wl_listener *stream_status);
2053 +
2054 +       /**
2055 +        * Retrieve the surface content stream status.
2056 +        *
2057 +        * If the status is WESTON_TRANSMITTER_STREAM_FAILED, remoting the
2058 +        * surface has stopped. There is no automatic retry.
2059 +        */
2060 +       enum weston_transmitter_stream_status
2061 +       (*surface_get_stream_status)(struct weston_transmitter_surface *txs);
2062 +
2063 +       /** Stop remoting a weston_surface
2064 +        *
2065 +        * \param txs Transmitter surface handle to be stopped and freed.
2066 +        *
2067 +        * The surface stream status handler is not called.
2068 +        */
2069 +       void
2070 +       (*surface_destroy)(struct weston_transmitter_surface *txs);
2071 +
2072 +       /** Notify of weston_surface being configured
2073 +        *
2074 +        * \param txs The Transmitter surface handle.
2075 +        * \param dx The x delta given in wl_surface.attach request.
2076 +        * \param dy The y delta given in wl_surface.attach request.
2077 +        *
2078 +        * Notifies Transmitter of new surface confguration. Transmitter will
2079 +        * forward the arguments, window state, and reference the buffer for
2080 +        * image transmission.
2081 +        *
2082 +        * Shells are meant to call this function for remoted surfaces in
2083 +        * the weston_surface::configure handler.
2084 +        *
2085 +        * XXX: Is this necessary if we have weston_surface::apply_state_signal?
2086 +        *
2087 +        * Essentially this is just an elaborate way to forward dx,dy.
2088 +        */
2089 +       void
2090 +       (*surface_configure)(struct weston_transmitter_surface *txs,
2091 +                            int32_t dx, int32_t dy);
2092 +};
2093 +
2094 +static inline const struct weston_transmitter_api *
2095 +weston_get_transmitter_api(struct weston_compositor *compositor)
2096 +{
2097 +       return weston_plugin_api_get(compositor, WESTON_TRANSMITTER_API_NAME,
2098 +                                    sizeof(struct weston_transmitter_api));
2099 +}
2100 +
2101 +#define WESTON_TRANSMITTER_IVI_API_NAME "transmitter_ivi_v1"
2102 +
2103 +/** For relaying configure events from Transmitter to shell. */
2104 +typedef void (*weston_transmitter_ivi_resize_handler_t)(void *data,
2105 +                                                       int32_t width,
2106 +                                                       int32_t height);
2107 +
2108 +/** The Transmitter IVI-shell API
2109 + *
2110 + * Contains the IVI-shell specifics required to remote an ivi-surface.
2111 + */
2112 +struct weston_transmitter_ivi_api {
2113 +       /** Set IVI-id for a transmitter surface
2114 +        *
2115 +        * \param txs The transmitted surface.
2116 +        * \param ivi_id The IVI-surface id as specified by the
2117 +        * ivi_application.surface_create request.
2118 +        */
2119 +       void
2120 +       (*set_ivi_id)(struct weston_transmitter_surface *txs, uint32_t ivi_id);
2121 +
2122 +       /** Set callback to relay configure events.
2123 +        *
2124 +        * \param txs The transmitted surface.
2125 +        * \param cb The callback function pointer.
2126 +        * \param data User data to be passed to the callback.
2127 +        *
2128 +        * The arguments to the callback function are user data, and width and
2129 +        * height from the configure event from the remote compositor. The
2130 +        * shell must relay this event to the application.
2131 +        */
2132 +       void
2133 +       (*set_resize_callback)(struct weston_transmitter_surface *txs,
2134 +                              weston_transmitter_ivi_resize_handler_t cb,
2135 +                              void *data);
2136 +};
2137 +
2138 +static inline const struct weston_transmitter_ivi_api *
2139 +weston_get_transmitter_ivi_api(struct weston_compositor *compositor)
2140 +{
2141 +       return weston_plugin_api_get(compositor,
2142 +                                    WESTON_TRANSMITTER_IVI_API_NAME,
2143 +                                    sizeof(struct weston_transmitter_ivi_api));
2144 +}
2145 +
2146 +/** Identifies outputs created by the Transmitter by make */
2147 +#define WESTON_TRANSMITTER_OUTPUT_MAKE "Weston-Transmitter"
2148 +
2149 +/* Remote compositor/output are identified by model */
2150 +
2151 +#endif /* WESTON_TRANSMITTER_API_H */
2152 -- 
2153 2.7.4
2154