// Copyright 2019 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.

/// A PTY (pseudoterminal) emulates terminal devices, with a "server" side
/// (which represents the keyboard+monitor side of the terminal and is obtained
/// by opening /dev/misc/ptmx) and a number of "client" sides which are obtained
/// by calling `OpenClient`.
///
/// Client PTYs are identified by the `id` used in the `OpenClient` call. The
/// first Client PTY *must* be 0, and it is the only Client PTY that is allowed
/// to create additional Client PTYs, receive Events, etc. It is the
/// Controlling PTY.
library fuchsia.hardware.pty;

using fuchsia.io;
using zx;

/// When Feature Raw is enabled, OOB Events like ^c, ^z, etc are not generated.
/// Instead the character is read from the read() input path.
const uint32 FEATURE_RAW = 1;

struct WindowSize {
    uint32 width;
    uint32 height;
};

/// The terminal has no active client.
const uint32 EVENT_HANGUP = 1;
/// The terminal received a ^C control character.
const uint32 EVENT_INTERRUPT = 2;
/// The terminal received a ^Z control character.
const uint32 EVENT_SUSPEND = 4;
/// All events
const uint32 EVENT_MASK = 7;

/// When an event is pending, this signal is asserted on the Controlling PTY.
const uint32 SIGNAL_EVENT = 0x02000000; // DEVICE_SIGNAL_OOB

[Discoverable]
protocol Device {
    // Compose from fuchsia.io.File so we can support Read/Write and export
    // a "Tty" type node info
    compose fuchsia.io.File;

    /// Open a client PTY device with a unique `id`. `client` should be a handle
    /// to one endpoint of a channel that (on success) will become an open
    /// connection to the newly created device. On failure, the channel will be
    /// closed. Closing the channel will close the connection and release the
    /// device. If the provided `id` is 0, then the new client is a controlling
    /// client and has the capability to open additional clients. If the
    /// current device is not a controlling client, `ZX_ERR_ACCESS_DENIED` will be
    /// returned. If `id` is not unique, `ZX_ERR_INVALID_ARGS` will be returned.
    /// Otherwise the status code from `device_add` is passed on.
    OpenClient(uint32 id, zx.handle:CHANNEL client) -> (zx.status s);

    /// allowed on Client PTYs
    /// -----------------------------
    /// Clear and/or Set PTY Features
    ClrSetFeature(uint32 clr, uint32 set) -> (zx.status status, uint32 features);

    /// Obtain the window size (in character cells)
    GetWindowSize() -> (zx.status status, WindowSize size);

    /// allowed on the Controlling PTY
    /// -------------------------------------
    /// Select which Client PTY receives input.
    /// Reads will simply block on non-active PTYs.
    MakeActive(uint32 client_pty_id) -> (zx.status status);

    /// Returns pending OOB events, simultaneously clearing them
    ReadEvents() -> (zx.status status, uint32 events);

    /// allowed on the Server PTY
    /// --------------------------------
    /// Sets the window size
    SetWindowSize(WindowSize size) -> (zx.status status);
};
