// SPDX-License-Identifier: GPL-2.0-or-later

#ifndef IPTSD_IPTS_PROTOCOL_LEGACY_HPP
#define IPTSD_IPTS_PROTOCOL_LEGACY_HPP

#include <common/types.hpp>

#include <array>

namespace iptsd::ipts::protocol::legacy {

/*!
 * The first IPTS devices didn't use HID to transmit data to userspace. Instead, they transmitted
 * it to the GPU where it was processed into usable touch coordinates.
 *
 * The format that these devices use to structure their data is functionally equivalent to HID
 * frames, but unfortunately they are not the same.
 *
 * In absence of a better name, we are going to call this format a "legacy frame".
 *
 * Legacy frames consist of a header, followed by a number of report groups.
 */
struct [[gnu::packed]] Header {
	//! How many frames have been generated by the device?
	u32 counter;

	//! How many report groups does this frame contain?
	u32 elements;

	//! ...
	std::array<u8, 4> reserved;
};
static_assert(sizeof(Header) == 12);

// NOLINTNEXTLINE(performance-enum-size)
enum class GroupType : u16 {
	//! The group contains report frames with stylus data.
	Stylus = 0x6,

	//! The group contains report frames with touchscreen data.
	Touch = 0x8,
};

/*!
 * Report groups are the payload of a legacy frame.
 *
 * They consist of a header, followed by a number of report frames as the payload.
 * The payload frames all contain data related to the type of the group.
 */
struct [[gnu::packed]] ReportGroup {
	//! The position of the report group within the legacy frame.
	u16 index;

	//! The type of this group. Determines, what kind of report frames it can contain.
	GroupType type;

	//! The total size of the payload in bytes.
	u32 size;

	//! ...
	std::array<u8, 8> reserved;
};
static_assert(sizeof(ReportGroup) == 16);

}; // namespace iptsd::ipts::protocol::legacy

#endif // IPTSD_IPTS_PROTOCOL_LEGACY_HPP
