// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.wayland;

using zx;

/// Protocol that provides a mechanism to connect to a Wayland server
/// and communicate with that server using Wayland protocol messages.
///
/// The server has to implement the minimal set of interfaces in the
/// core protocol require by the Wayland standard. Anything beyond that
/// is optional. Clients can discover available Wayland interfaces using
/// Wayland messsages that are part of the core protocol. The wire format
/// and the core protocol is described in detail here:
///
/// https://wayland.freedesktop.org/docs/html/ch04.html
///
/// The Wayland protocol makes use of file descriptors for data transfer.
/// Each file descriptor should be replaced with a zx::handle when
/// communicating with a server. The exact handle type depends on the
/// interface definition. File descriptors that can be memory-mapped
/// typically need to be replaced with zx:vmos.
///
/// The client can be a Fuchsia component, or a Linux program (running
/// in a VM, or using some other type of compatibility layer).
@discoverable
closed protocol Server {
    /// Establishes a new connection to the server.
    ///
    /// For a client to open a new connection, a zx::channel must be created for
    /// that connection. The client should retain one endpoint of that channel
    /// and the other endpoint will be provided to this method. The messages on
    /// the channel will be Wayland protocol messages. Each channel datagram will
    /// contain 1 or more complete Wayland messages.
    strict Connect(resource struct {
        channel zx.Handle:CHANNEL;
    });
};
