input

package
v1.0.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package input implements JetKVM HID-RPC encoding and bounded input execution.

Index

Constants

View Source
const (
	MaxKeyHoldDuration = 12 * time.Second
	MaxActions         = 16
	MaxBatchDuration   = 15 * time.Second
	MaxWaitDuration    = 5 * time.Second
	MaxTotalWait       = 10 * time.Second
)
View Source
const (
	HIDRPCVersion byte = 0x01
)

HID-RPC v1 message types observed in the JetKVM 0.5.8/dev protocol.

View Source
const MaxTextRunes = 4096

Variables

View Source
var (
	ErrInvalidAction    = errors.New("invalid input action")
	ErrObservationStale = errors.New("bound observation is stale")
)
View Source
var (
	ErrUnknownKey      = errors.New("unknown key")
	ErrUnsupportedText = errors.New("text contains a character unsupported by the US keyboard layout")
)
View Source
var (
	ErrLeaseBusy          = errors.New("input lease is already held")
	ErrStaleGeneration    = errors.New("input generation is stale")
	ErrLeaseReleased      = errors.New("input lease is released")
	ErrInputUncertain     = errors.New("input state is uncertain")
	ErrNeutralization     = errors.New("input neutralization could not be confirmed")
	ErrObservationMissing = errors.New("screenshot observer is unavailable")
)
View Source
var ErrInvalidProtocolValue = errors.New("invalid HID protocol value")

Functions

func CompileKeyCombo

func CompileKeyCombo(names []string) (modifier byte, keys []byte, err error)

CompileKeyCombo resolves a named chord to a complete keyboard report. Names are case-insensitive and ignore '-', '_', and spaces.

func Handshake

func Handshake() []byte

Handshake marshals the HID-RPC v1 handshake.

func KeyboardReport

func KeyboardReport(modifier byte, keys ...byte) ([]byte, error)

KeyboardReport marshals one complete boot-keyboard state. Unused slots are zeroed.

func KeypressReport

func KeypressReport(key byte, pressed bool) ([]byte, error)

KeypressReport marshals a single key transition.

func ParseHandshake

func ParseHandshake(data []byte) (byte, error)

ParseHandshake validates a device handshake and returns its negotiated version.

func PointerReport

func PointerReport(x, y int, buttons ButtonMask) ([]byte, error)

PointerReport marshals absolute coordinates in JetKVM's 0..32767 HID space.

func RelativeMouseReport

func RelativeMouseReport(dx, dy int, buttons ButtonMask) ([]byte, error)

RelativeMouseReport marshals one relative pointer update.

Types

type Action

type Action struct {
	Type     ActionType    `json:"type"`
	X        int           `json:"x,omitzero"`
	Y        int           `json:"y,omitzero"`
	Button   Button        `json:"button,omitempty"`
	Path     []Point       `json:"path,omitempty"`
	DeltaX   int           `json:"delta_x,omitzero"`
	DeltaY   int           `json:"delta_y,omitzero"`
	Keys     []string      `json:"keys,omitempty"`
	Text     string        `json:"text,omitempty"`
	Duration time.Duration `json:"duration,omitzero"`
}

Action is a closed union. Validate rejects fields that do not belong to Type.

type ActionReceipt

type ActionReceipt struct {
	Index  int          `json:"index"`
	Type   ActionType   `json:"type"`
	Status ActionStatus `json:"status"`
	Error  string       `json:"error,omitzero"`
}

type ActionStatus

type ActionStatus string
const (
	ActionNotStarted  ActionStatus = "not_started"
	ActionSendStarted ActionStatus = "send_started"
	ActionAccepted    ActionStatus = "accepted"
	ActionFailed      ActionStatus = "failed"
	ActionAmbiguous   ActionStatus = "ambiguous"
)

type ActionType

type ActionType string
const (
	ActionMove        ActionType = "move"
	ActionClick       ActionType = "click"
	ActionDoubleClick ActionType = "double_click"
	ActionDrag        ActionType = "drag"
	ActionScroll      ActionType = "scroll"
	ActionKeypress    ActionType = "keypress"
	ActionKeyHold     ActionType = "key_hold"
	ActionTypeText    ActionType = "type"
	ActionWait        ActionType = "wait"
	ActionScreenshot  ActionType = "screenshot"
)

type Batch

type Batch struct {
	Observation *ObservationBinding
	Actions     []Action
}

type BatchReceipt

type BatchReceipt struct {
	Generation     uint64          `json:"generation"`
	Status         BatchStatus     `json:"status"`
	Actions        []ActionReceipt `json:"actions"`
	Observation    Observation     `json:"observation,omitzero"`
	Neutralized    bool            `json:"neutralized"`
	CleanupFailure string          `json:"cleanup_failure,omitzero"`
}

type BatchStatus

type BatchStatus string
const (
	BatchAccepted  BatchStatus = "accepted"
	BatchPartial   BatchStatus = "partial"
	BatchFailed    BatchStatus = "failed"
	BatchAmbiguous BatchStatus = "ambiguous"
)

type Button

type Button string
const (
	ButtonLeft    Button = "left"
	ButtonRight   Button = "right"
	ButtonMiddle  Button = "middle"
	ButtonBack    Button = "back"
	ButtonForward Button = "forward"
)

type ButtonMask

type ButtonMask byte

type GenerationToken

type GenerationToken struct {
	// contains filtered or unexported fields
}

GenerationToken binds every input operation to one control generation and one exclusive lease. Its opaque nonce prevents a stale caller from reusing another lease in the same generation.

func (GenerationToken) Generation

func (t GenerationToken) Generation() uint64

type HIDTransport

type HIDTransport interface {
	SendHID(context.Context, uint64, Reliability, []byte) error
	SendWheel(context.Context, uint64, int8, int8) error
	Flush(context.Context, uint64) error
}

HIDTransport is the device actor's narrow input transport. SendHID carries HID-RPC v1 frames. SendWheel is separate because JetKVM 0.5.8/dev exposes wheelReport through JSON-RPC rather than handling HID-RPC message 0x04. Implementations must fence generation at their final send boundary.

type Keystroke

type Keystroke struct {
	Modifier byte
	Key      byte
}

func CompileText

func CompileText(text string) ([]Keystroke, error)

CompileText completely validates and translates printable US-layout text. It returns no partial result when any rune is unsupported.

type Lease

type Lease struct {
	// contains filtered or unexported fields
}

func (*Lease) Release

func (l *Lease) Release() error

func (*Lease) RunActions

func (l *Lease) RunActions(ctx context.Context, batch Batch) (receipt BatchReceipt, err error)

func (*Lease) Token

func (l *Lease) Token() GenerationToken

type Limits

type Limits struct {
	KeyHold           time.Duration
	InterKey          time.Duration
	DoubleClickDelay  time.Duration
	MaxActions        int
	MaxBatchDuration  time.Duration
	MaxWaitDuration   time.Duration
	MaxTotalWait      time.Duration
	MaxObservationAge time.Duration
}

func DefaultLimits

func DefaultLimits() Limits

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

func NewManager

func NewManager(cfg ManagerConfig) (*Manager, error)

func (*Manager) Acquire

func (m *Manager) Acquire(expectedGeneration uint64) (*Lease, error)

func (*Manager) AdvanceGeneration

func (m *Manager) AdvanceGeneration(ctx context.Context, next uint64) error

AdvanceGeneration neutralizes the old session before publishing a newer generation. A failure leaves the old generation fenced as uncertain.

func (*Manager) Fence

func (m *Manager) Fence(expectedGeneration uint64) error

Fence immediately rejects further sends from the current generation. It is used when the device actor observes a disconnect or session replacement. The uncertain latch remains set even if the lease later neutralizes cleanly; callers must reconnect and Reconcile before accepting more input.

func (*Manager) Generation

func (m *Manager) Generation() uint64

func (*Manager) Reconcile

func (m *Manager) Reconcile(ctx context.Context, expectedGeneration uint64) error

Reconcile sends authoritative neutral state and clears an uncertain latch. It is the only path that may make an uncertain manager ready again.

func (*Manager) RunActions

func (m *Manager) RunActions(ctx context.Context, expectedGeneration uint64, batch Batch) (BatchReceipt, error)

RunActions acquires a single-use exclusive lease, executes the prevalidated batch, and always attempts input neutralization before returning.

func (*Manager) State

func (m *Manager) State() State

type ManagerConfig

type ManagerConfig struct {
	Transport      HIDTransport
	Observer       ScreenshotObserver
	Generation     uint64
	Limits         Limits
	CleanupTimeout time.Duration
	Random         io.Reader
	Now            func() time.Time
}

type Observation

type Observation struct {
	ID         string `json:"observation_id"`
	Generation uint64 `json:"generation"`
}

type ObservationBinding

type ObservationBinding struct {
	ID         string
	Generation uint64
	Width      int
	Height     int
	CapturedAt time.Time
}

ObservationBinding ties pixel coordinates to one fresh video frame and control generation. Coordinate actions are rejected without this binding.

type Point

type Point struct {
	X int `json:"x"`
	Y int `json:"y"`
}

type Reliability

type Reliability uint8
const (
	Reliable Reliability = iota
	Motion
)

type ScreenshotObserver

type ScreenshotObserver interface {
	Capture(context.Context, uint64) (Observation, error)
}

type State

type State string
const (
	StateReady     State = "ready"
	StateUncertain State = "uncertain"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL