// 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.hardware.input;

using zx;

using ReportId = uint8;

enum BootProtocol : uint32 {
    NONE = 0;
    KBD = 1;
    MOUSE = 2;
};

const uint16 MAX_DESC_LEN = 8192;
const uint16 MAX_REPORT_LEN = 8192;
const uint16 MAX_REPORT_IDS = 256;

enum ReportType : uint8 {
    INPUT = 1;
    OUTPUT = 2;
    FEATURE = 3;
};

[Layout = "Simple"]
protocol Device {
    // Get the HID boot interface protocol this device supports
    GetBootProtocol() -> (BootProtocol protocol);

    // Get the size of the report descriptor
    GetReportDescSize() -> (uint16 size);

    // Get the report descriptor
    GetReportDesc() -> (vector<uint8>:MAX_DESC_LEN desc);

    // Get the number of reports in the report descriptor
    GetNumReports() -> (uint16 count);

    // Get the report ids that are used in the report descriptor
    GetReportIds() -> (vector<ReportId>:MAX_REPORT_IDS ids);

    // Get the size of a single report for the given (type, id) pair.
    GetReportSize(ReportType type, ReportId id) -> (zx.status s, uint16 size);

    // Get the maximum size of a single input report.
    GetMaxInputReportSize() -> (uint16 size);

    // Get a single report of the given (type, id) pair.  This interface is not intended
    // to be used for continuous polling of the reports.
    GetReport(ReportType type, ReportId id) -> (zx.status s, vector<uint8>:MAX_REPORT_LEN report);

    // Set a single report of the given (type, id) pair.
    SetReport(ReportType type, ReportId id, vector<uint8>:MAX_REPORT_LEN report) -> (zx.status s);

    // Set the trace ID that is used for HID report flow events.
    SetTraceId(uint32 id);
};
