// Copyright 2018 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.ui.scenic;

using fuchsia.images;
using fuchsia.mem;
using fuchsia.ui.gfx;
using fuchsia.ui.pointer;
using fuchsia.ui.views;
using zx;

/// Scenic.TakeScreenshot() returns a raw BGRA formatted image in
/// sRGB color space and with a non-linear transfer function in this
/// struct.
type ScreenshotData = resource struct {
    info fuchsia.images.ImageInfo;
    data fuchsia.mem.Buffer;
};

/// The protocol endpoints used in creating a Scenic Session.
type SessionEndpoints = resource table {
    /// Enqueue commands and present content.
    /// Required.
    1: session server_end:Session;

    /// Receive session-related events.
    /// Optional.
    2: session_listener client_end:SessionListener;

    /// Change view focus, within the session view's subtree.
    /// Optional.
    3: view_focuser server_end:fuchsia.ui.views.Focuser;

    /// Learn when this session view receives or loses view focus.
    /// Optional.
    4: view_ref_focused server_end:fuchsia.ui.views.ViewRefFocused;

    /// Ask for touch events and negotiate for gesture ownership.
    /// Optional.
    5: touch_source server_end:fuchsia.ui.pointer.TouchSource;

    /// Ask for mouse events.
    /// Optional.
    6: mouse_source server_end:fuchsia.ui.pointer.MouseSource;
};

@discoverable
closed protocol Scenic {
    /// Create a new Session, which is the primary way to interact with Scenic.
    strict CreateSession(resource struct {
        session server_end:Session;
        listener client_end:<SessionListener, optional>;
    });

    /// Create a new Session, which is the primary way to interact with Scenic.
    ///
    /// In this variant, the caller may register a request for focus management.
    /// The `view_focuser`'s client is coupled to the requested `session`, and
    /// this coupling acts as a security boundary: the ViewRef used as the basis
    /// for authority by `view_focuser` must come from `session`.
    strict CreateSession2(resource struct {
        session server_end:Session;
        listener client_end:<SessionListener, optional>;
        view_focuser server_end:<fuchsia.ui.views.Focuser, optional>;
    });

    /// Create a new Session, which is the primary way to interact with Scenic.
    ///
    /// In this variant, the caller may submit a combination of protocols
    /// that make sense for it. The Session protocol is the only required
    /// protocol. The SessionEndpoints table may be extended with more protocol
    /// fields, but these extensions should retain ABI and API compatibility
    /// with existing (pre-compiled) clients.
    ///
    /// The response acknowledges the request to create a Session, but actual
    /// creation may happen later.
    strict CreateSessionT(resource struct {
        endpoints SessionEndpoints;
    }) -> ();

    /// Get information about the Scenic's primary display.
    // TODO(https://fxbug.dev/42097799): in the future there will probably be a DisplayManager, and
    // info about which displays to use will be provided to the Scenic.
    strict GetDisplayInfo() -> (struct {
        info fuchsia.ui.gfx.DisplayInfo;
    });
    /// Gets an event signaled with displayOwnedSignal or displayNotOwnedSignal
    /// when display ownership changes.
    strict GetDisplayOwnershipEvent() -> (resource struct {
        ownership_event zx.Handle:EVENT;
    });

    /// Take a screenshot and return the data in `img_data`. `img_data` will
    /// not contain BGRA data if `success` is false.
    // TODO(https://fxbug.dev/42098038): The permissions here are too wide (anyone can take a
    // screenshot), we should narrow them.
    strict TakeScreenshot() -> (resource struct {
        img_data ScreenshotData;
        success bool;
    });

    /// Returns whether the clients should use [`fuchsia.ui.composition/Flatland`] protocol to
    /// interact with Scenic instead.
    // TODO(https://fxbug.dev/42142792): Remove after Flatland migration is completed.
    strict UsesFlatland() -> (struct {
        flatland_enabled bool;
    });
};

const displayOwnedSignal uint32 = 0x02000000;
const displayNotOwnedSignal uint32 = 0x01000000;
