259 lines
9.9 KiB
Dart
259 lines
9.9 KiB
Dart
// This file is automatically generated, so please do not edit it.
|
|
// @generated by `flutter_rust_bridge`@ 2.13.0.
|
|
|
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
|
|
|
import 'frb_generated.dart';
|
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
|
import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
|
|
part 'api.freezed.dart';
|
|
|
|
// These functions are ignored because they are not marked as `pub`: `cancels`, `host_cancels`, `host_frames`, `host_pending`, `map_host_event`, `pending`, `rgb_to_rgba`, `runtime`, `sessions`, `with_session`
|
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `clone`, `fmt`, `fmt`, `fmt`
|
|
|
|
/// Start a session against `ws_url` / `host_id` with `password` + `totp`, and
|
|
/// return its **handle**. The actual connect + handshake + H.264 decode run on
|
|
/// the background Tokio runtime; subscribe to the resulting [`NdEvent`]s with
|
|
/// [`session_events`] (passing this handle), and drive input / control with the
|
|
/// other functions here. A failed connect still returns a valid handle and
|
|
/// reports [`NdEvent::Ended`] / [`NdEvent::Denied`] on the stream.
|
|
Future<BigInt> connect(
|
|
{required String wsUrl,
|
|
required String hostId,
|
|
required String password,
|
|
required String totp}) =>
|
|
RustLib.instance.api.crateApiConnect(
|
|
wsUrl: wsUrl, hostId: hostId, password: password, totp: totp);
|
|
|
|
/// Subscribe to the [`NdEvent`] stream for a `handle` returned by [`connect`].
|
|
/// In Dart this is `Stream<NdEvent> sessionEvents({required BigInt handle})`.
|
|
/// Call it once per handle, right after `connect`.
|
|
Stream<NdEvent> sessionEvents({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiSessionEvents(handle: handle);
|
|
|
|
/// Send a pointer event (coordinates in the remote screen's pixel space).
|
|
/// `buttons` is the button bitmask, `wheel`/`hwheel` are scroll deltas.
|
|
void sendMouse(
|
|
{required BigInt handle,
|
|
required int x,
|
|
required int y,
|
|
required int buttons,
|
|
required double wheel,
|
|
required double hwheel}) =>
|
|
RustLib.instance.api.crateApiSendMouse(
|
|
handle: handle,
|
|
x: x,
|
|
y: y,
|
|
buttons: buttons,
|
|
wheel: wheel,
|
|
hwheel: hwheel);
|
|
|
|
/// Send a key event. `code` is a DOM-style key code (e.g. "KeyA", "Enter").
|
|
void sendKey(
|
|
{required BigInt handle, required String code, required bool down}) =>
|
|
RustLib.instance.api
|
|
.crateApiSendKey(handle: handle, code: code, down: down);
|
|
|
|
/// Reconfigure the host encoder: target `fps`, `bitrate` (kbps), resolution `scale`.
|
|
void setQuality(
|
|
{required BigInt handle,
|
|
required int fps,
|
|
required int bitrate,
|
|
required double scale}) =>
|
|
RustLib.instance.api.crateApiSetQuality(
|
|
handle: handle, fps: fps, bitrate: bitrate, scale: scale);
|
|
|
|
/// Switch the captured monitor to index `i` (as advertised by
|
|
/// [`session_monitors`]). Immediately asks the host for a fresh keyframe so the
|
|
/// new display paints without waiting for the next natural IDR — the messages
|
|
/// travel the same WebSocket in order, so the keyframe is of the *new* monitor.
|
|
void monitorSwitch({required BigInt handle, required int i}) =>
|
|
RustLib.instance.api.crateApiMonitorSwitch(handle: handle, i: i);
|
|
|
|
/// The real list of displays the host reported (its `info.monitors`). The UI
|
|
/// uses this to show exactly the monitors that exist — never a hardcoded count.
|
|
/// Returns empty until the session is accepted, or if the host sent none.
|
|
List<NdMonitor> sessionMonitors({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiSessionMonitors(handle: handle);
|
|
|
|
/// The monitor index the host is currently capturing (as reported at accept).
|
|
int sessionCurrentMonitor({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiSessionCurrentMonitor(handle: handle);
|
|
|
|
/// Send Ctrl+Alt+Del on the host.
|
|
void ctrlAltDel({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiCtrlAltDel(handle: handle);
|
|
|
|
/// Send a chat message to the host.
|
|
void sendChat({required BigInt handle, required String text}) =>
|
|
RustLib.instance.api.crateApiSendChat(handle: handle, text: text);
|
|
|
|
/// Push text to the remote clipboard (and announce our local clipboard).
|
|
void setClipboard({required BigInt handle, required String text}) =>
|
|
RustLib.instance.api.crateApiSetClipboard(handle: handle, text: text);
|
|
|
|
/// End the session: tell the host, then drop the handle. The event stream
|
|
/// receives a final [`NdEvent::Ended`] when the network task unwinds.
|
|
void disconnect({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiDisconnect(handle: handle);
|
|
|
|
/// A fresh 9-digit host id to persist on the device (shown to viewers).
|
|
String hostGenId() => RustLib.instance.api.crateApiHostGenId();
|
|
|
|
/// A fresh friendly unattended password (no look-alike chars).
|
|
String hostGenPassword() => RustLib.instance.api.crateApiHostGenPassword();
|
|
|
|
/// Start hosting: register `host_id` with the server and serve one viewer at a
|
|
/// time, authenticating against `password`. Returns a handle; drive input/
|
|
/// control via [`host_events`], feed video via [`host_push_frame`], stop with
|
|
/// [`host_stop`]. Credentials are derived fresh from `password` each run (the
|
|
/// challenge carries the salt, so the viewer only needs the password).
|
|
Future<BigInt> hostStart(
|
|
{required String wsUrl,
|
|
required String hostId,
|
|
required String name,
|
|
required String password,
|
|
required int width,
|
|
required int height}) =>
|
|
RustLib.instance.api.crateApiHostStart(
|
|
wsUrl: wsUrl,
|
|
hostId: hostId,
|
|
name: name,
|
|
password: password,
|
|
width: width,
|
|
height: height);
|
|
|
|
/// Subscribe to the [`NdHostEvent`] stream for a `handle` from [`host_start`].
|
|
Stream<NdHostEvent> hostEvents({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiHostEvents(handle: handle);
|
|
|
|
/// Feed one encoded H.264 access unit (Annex-B) from the platform encoder. Cheap
|
|
/// + non-blocking; dropped when no viewer is connected.
|
|
void hostPushFrame(
|
|
{required BigInt handle,
|
|
required List<int> data,
|
|
required bool keyframe}) =>
|
|
RustLib.instance.api
|
|
.crateApiHostPushFrame(handle: handle, data: data, keyframe: keyframe);
|
|
|
|
/// Stop hosting: end the reconnect loop and drop the handle.
|
|
void hostStop({required BigInt handle}) =>
|
|
RustLib.instance.api.crateApiHostStop(handle: handle);
|
|
|
|
@freezed
|
|
sealed class NdEvent with _$NdEvent {
|
|
const NdEvent._();
|
|
|
|
/// The WebSocket is dialing / the handshake is in flight.
|
|
const factory NdEvent.connecting() = NdEvent_Connecting;
|
|
|
|
/// Session accepted; the remote screen is about to stream.
|
|
const factory NdEvent.connected({
|
|
required int w,
|
|
required int h,
|
|
required bool e2E,
|
|
required String hostName,
|
|
}) = NdEvent_Connected;
|
|
|
|
/// A decoded, paint-ready frame: tightly-packed RGBA8 (`width*height*4`).
|
|
const factory NdEvent.frame({
|
|
required int width,
|
|
required int height,
|
|
required Uint8List rgba,
|
|
}) = NdEvent_Frame;
|
|
|
|
/// The session ended (socket closed, host ended it, connect failed, …).
|
|
const factory NdEvent.ended({
|
|
required String reason,
|
|
}) = NdEvent_Ended;
|
|
|
|
/// The host refused the session (bad password/TOTP, busy, blocked, …).
|
|
const factory NdEvent.denied({
|
|
required String reason,
|
|
}) = NdEvent_Denied;
|
|
|
|
/// A chat message from the host.
|
|
const factory NdEvent.chatMessage({
|
|
required String from,
|
|
required String text,
|
|
}) = NdEvent_ChatMessage;
|
|
|
|
/// Remote clipboard text pushed by the host (RustDesk-style sync).
|
|
const factory NdEvent.clipboard({
|
|
required String text,
|
|
}) = NdEvent_Clipboard;
|
|
}
|
|
|
|
@freezed
|
|
sealed class NdHostEvent with _$NdHostEvent {
|
|
const NdHostEvent._();
|
|
|
|
/// Registered with the server; the device is reachable at its host id.
|
|
const factory NdHostEvent.registered() = NdHostEvent_Registered;
|
|
|
|
/// A viewer authenticated; the session is live (inject input, feed frames).
|
|
const factory NdHostEvent.viewerConnected({
|
|
required bool e2E,
|
|
}) = NdHostEvent_ViewerConnected;
|
|
|
|
/// The viewer left; the host stays registered for the next one.
|
|
const factory NdHostEvent.viewerLeft() = NdHostEvent_ViewerLeft;
|
|
|
|
/// Pointer in the captured image's pixel space (buttons = bitmask).
|
|
const factory NdHostEvent.mouse({
|
|
required int x,
|
|
required int y,
|
|
required int buttons,
|
|
required double wheel,
|
|
}) = NdHostEvent_Mouse;
|
|
|
|
/// Key: DOM-style code + down/up.
|
|
const factory NdHostEvent.key({
|
|
required String code,
|
|
required bool down,
|
|
}) = NdHostEvent_Key;
|
|
|
|
/// The viewer asked for a fresh keyframe — request one from the encoder.
|
|
const factory NdHostEvent.keyframeRequested() = NdHostEvent_KeyframeRequested;
|
|
|
|
/// The viewer changed quality targets.
|
|
const factory NdHostEvent.quality({
|
|
required int fps,
|
|
required int bitrate,
|
|
required double scale,
|
|
}) = NdHostEvent_Quality;
|
|
|
|
/// The server link dropped; auto-reconnecting.
|
|
const factory NdHostEvent.reconnecting() = NdHostEvent_Reconnecting;
|
|
|
|
/// The host loop stopped for good (host_stop / fatal).
|
|
const factory NdHostEvent.ended({
|
|
required String reason,
|
|
}) = NdHostEvent_Ended;
|
|
}
|
|
|
|
/// A display the host advertised at accept time (index + pixel size).
|
|
class NdMonitor {
|
|
final int i;
|
|
final int w;
|
|
final int h;
|
|
|
|
const NdMonitor({
|
|
required this.i,
|
|
required this.w,
|
|
required this.h,
|
|
});
|
|
|
|
@override
|
|
int get hashCode => i.hashCode ^ w.hashCode ^ h.hashCode;
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is NdMonitor &&
|
|
runtimeType == other.runtimeType &&
|
|
i == other.i &&
|
|
w == other.w &&
|
|
h == other.h;
|
|
}
|