mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-03 09:49:24 +02:00
refactor(scrcpy) make large enums tree-shakeable (#798)
This commit is contained in:
parent
b2512856be
commit
27a6614680
89 changed files with 1056 additions and 1089 deletions
7
.changeset/clean-moons-obey.md
Normal file
7
.changeset/clean-moons-obey.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
"@yume-chan/scrcpy": major
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert `ScrcpyOptionsX_YY.prototype.controlMessageTypes` to a mapping from internal control message types to version-specific values.
|
||||||
|
|
||||||
|
Generally, `ScrcpyControlMessageSerializer`, `ScrcpyControlMessageWriter`, or `AdbScrcpyClient.prototype.controller` should be used to send control messages to devices, instead of using `controlMessageTypes` directly.
|
|
@ -143,16 +143,6 @@ export class AdbDaemonWebUsbConnection
|
||||||
new MaybeConsumable.WritableStream({
|
new MaybeConsumable.WritableStream({
|
||||||
write: async (chunk) => {
|
write: async (chunk) => {
|
||||||
try {
|
try {
|
||||||
if (
|
|
||||||
typeof SharedArrayBuffer !== "undefined" &&
|
|
||||||
chunk.buffer instanceof SharedArrayBuffer
|
|
||||||
) {
|
|
||||||
// Copy data to a non-shared ArrayBuffer
|
|
||||||
const copy = new Uint8Array(chunk.byteLength);
|
|
||||||
copy.set(chunk);
|
|
||||||
chunk = copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
await device.raw.transferOut(
|
await device.raw.transferOut(
|
||||||
outEndpoint.endpointNumber,
|
outEndpoint.endpointNumber,
|
||||||
// WebUSB doesn't support SharedArrayBuffer
|
// WebUSB doesn't support SharedArrayBuffer
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class AdbScrcpyOptions3_3_2<TVideo extends boolean>
|
||||||
) {
|
) {
|
||||||
super(init);
|
super(init);
|
||||||
|
|
||||||
this.version = clientOptions?.version ?? "3.3.1";
|
this.version = clientOptions?.version ?? "3.3.2";
|
||||||
this.spawner = clientOptions?.spawner;
|
this.spawner = clientOptions?.spawner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,5 @@ export function toLocalUint8Array(value: Uint8Array): Uint8Array<ArrayBuffer> {
|
||||||
return value as Uint8Array<ArrayBuffer>;
|
return value as Uint8Array<ArrayBuffer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const copy = new Uint8Array(value.length);
|
return new Uint8Array(value);
|
||||||
copy.set(value);
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -862,21 +862,21 @@ export function parseShortTermReferencePictureSet(
|
||||||
export const AspectRatioIndicator = {
|
export const AspectRatioIndicator = {
|
||||||
Unspecified: 0,
|
Unspecified: 0,
|
||||||
Square: 1,
|
Square: 1,
|
||||||
_12_11: 2,
|
["12:11"]: 2,
|
||||||
_10_11: 3,
|
["10:11"]: 3,
|
||||||
_16_11: 4,
|
["16:11"]: 4,
|
||||||
_40_33: 5,
|
["40:33"]: 5,
|
||||||
_24_11: 6,
|
["24:11"]: 6,
|
||||||
_20_11: 7,
|
["20:11"]: 7,
|
||||||
_32_11: 8,
|
["32:11"]: 8,
|
||||||
_80_33: 9,
|
["80:33"]: 9,
|
||||||
_18_11: 10,
|
["18:11"]: 10,
|
||||||
_15_11: 11,
|
["15:11"]: 11,
|
||||||
_64_33: 12,
|
["64:33"]: 12,
|
||||||
_160_99: 13,
|
["160:99"]: 13,
|
||||||
_4_3: 15,
|
["4:3"]: 15,
|
||||||
_3_2: 16,
|
["3:2"]: 16,
|
||||||
_2_1: 17,
|
["2:1"]: 17,
|
||||||
Extended: 255,
|
Extended: 255,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
|
import type { ScrcpyControlMessageTypeMap } from "../../base/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/index.js";
|
import { ScrcpyControlMessageType } from "../../base/index.js";
|
||||||
|
|
||||||
export const ControlMessageTypes: readonly ScrcpyControlMessageType[] =
|
export const ControlMessageTypes = {
|
||||||
/* #__PURE__ */ (() => [
|
[ScrcpyControlMessageType.InjectKeyCode]: 0,
|
||||||
/* 0 */ ScrcpyControlMessageType.InjectKeyCode,
|
[ScrcpyControlMessageType.InjectText]: 1,
|
||||||
/* 1 */ ScrcpyControlMessageType.InjectText,
|
[ScrcpyControlMessageType.InjectTouch]: 2,
|
||||||
/* 2 */ ScrcpyControlMessageType.InjectTouch,
|
[ScrcpyControlMessageType.InjectScroll]: 3,
|
||||||
/* 3 */ ScrcpyControlMessageType.InjectScroll,
|
[ScrcpyControlMessageType.BackOrScreenOn]: 4,
|
||||||
/* 4 */ ScrcpyControlMessageType.BackOrScreenOn,
|
[ScrcpyControlMessageType.ExpandNotificationPanel]: 5,
|
||||||
/* 5 */ ScrcpyControlMessageType.ExpandNotificationPanel,
|
[ScrcpyControlMessageType.CollapseNotificationPanel]: 6,
|
||||||
/* 6 */ ScrcpyControlMessageType.CollapseNotificationPanel,
|
[ScrcpyControlMessageType.GetClipboard]: 7,
|
||||||
/* 7 */ ScrcpyControlMessageType.GetClipboard,
|
[ScrcpyControlMessageType.SetClipboard]: 8,
|
||||||
/* 8 */ ScrcpyControlMessageType.SetClipboard,
|
[ScrcpyControlMessageType.SetDisplayPower]: 9,
|
||||||
/* 9 */ ScrcpyControlMessageType.SetDisplayPower,
|
[ScrcpyControlMessageType.RotateDevice]: 10,
|
||||||
/* 10 */ ScrcpyControlMessageType.RotateDevice,
|
} as const satisfies ScrcpyControlMessageTypeMap;
|
||||||
])();
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ export const PointerId = {
|
||||||
|
|
||||||
export const InjectTouchControlMessage = struct(
|
export const InjectTouchControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
action: u8<AndroidMotionEventAction>(),
|
action: u8<AndroidMotionEventAction>(),
|
||||||
pointerId: u64,
|
pointerId: u64,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import type { ScrcpyInjectScrollControlMessage } from "../../latest.js";
|
||||||
|
|
||||||
export const InjectScrollControlMessage = struct(
|
export const InjectScrollControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
|
|
|
@ -4,7 +4,11 @@ import { string, struct, u32, u8 } from "@yume-chan/struct";
|
||||||
import type { ScrcpySetClipboardControlMessage } from "../../latest.js";
|
import type { ScrcpySetClipboardControlMessage } from "../../latest.js";
|
||||||
|
|
||||||
export const SetClipboardControlMessage = struct(
|
export const SetClipboardControlMessage = struct(
|
||||||
{ type: u8, content: string(u32) },
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
|
type: u8,
|
||||||
|
content: string(u32),
|
||||||
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
ScrcpyOptions,
|
ScrcpyOptions,
|
||||||
|
@ -38,7 +37,7 @@ export class ScrcpyOptions1_15 implements ScrcpyOptions<Init> {
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
import { ScrcpyOptions1_15 } from "./1_15/index.js";
|
export { ScrcpyOptions1_15 as ScrcpyOptions1_15_1 } from "./1_15/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions1_15_1 extends ScrcpyOptions1_15 {
|
|
||||||
constructor(init: ScrcpyOptions1_15.Init) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions1_15_1 {
|
|
||||||
export type Init = ScrcpyOptions1_15.Init;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
import { ScrcpyOptions1_15 } from "./1_15/index.js";
|
export { ScrcpyOptions1_15 as ScrcpyOptions1_16 } from "./1_15/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions1_16 extends ScrcpyOptions1_15 {
|
|
||||||
constructor(init: ScrcpyOptions1_15.Init) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions1_16 {
|
|
||||||
export type Init = ScrcpyOptions1_15.Init;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
encoderName: undefined,
|
||||||
encoderName: undefined,
|
} as const satisfies Required<Init>;
|
||||||
}) as const satisfies Required<Init>)();
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -45,7 +44,7 @@ export class ScrcpyOptions1_17
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
|
import type { ScrcpyControlMessageTypeMap } from "../../base/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/index.js";
|
import { ScrcpyControlMessageType } from "../../base/index.js";
|
||||||
|
|
||||||
import { PrevImpl } from "./prev.js";
|
export const ControlMessageTypes = {
|
||||||
|
[ScrcpyControlMessageType.InjectKeyCode]: 0,
|
||||||
export const ControlMessageTypes: readonly ScrcpyControlMessageType[] =
|
[ScrcpyControlMessageType.InjectText]: 1,
|
||||||
/* #__PURE__ */ (() => {
|
[ScrcpyControlMessageType.InjectTouch]: 2,
|
||||||
const result = PrevImpl.ControlMessageTypes.slice();
|
[ScrcpyControlMessageType.InjectScroll]: 3,
|
||||||
result.splice(6, 0, ScrcpyControlMessageType.ExpandSettingPanel);
|
[ScrcpyControlMessageType.BackOrScreenOn]: 4,
|
||||||
return result;
|
[ScrcpyControlMessageType.ExpandNotificationPanel]: 5,
|
||||||
})();
|
[ScrcpyControlMessageType.ExpandSettingPanel]: 6,
|
||||||
|
[ScrcpyControlMessageType.CollapseNotificationPanel]: 7,
|
||||||
|
[ScrcpyControlMessageType.GetClipboard]: 8,
|
||||||
|
[ScrcpyControlMessageType.SetClipboard]: 9,
|
||||||
|
[ScrcpyControlMessageType.SetDisplayPower]: 10,
|
||||||
|
[ScrcpyControlMessageType.RotateDevice]: 11,
|
||||||
|
} as const satisfies ScrcpyControlMessageTypeMap;
|
||||||
|
|
|
@ -2,10 +2,9 @@ import type { Init } from "./init.js";
|
||||||
import { VideoOrientation } from "./init.js";
|
import { VideoOrientation } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
logLevel: "debug",
|
||||||
logLevel: "debug",
|
lockVideoOrientation: VideoOrientation.Unlocked,
|
||||||
lockVideoOrientation: VideoOrientation.Unlocked,
|
powerOffOnClose: false,
|
||||||
powerOffOnClose: false,
|
} as const satisfies Required<Init>;
|
||||||
}) as const satisfies Required<Init>)();
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -45,7 +44,7 @@ export class ScrcpyOptions1_18
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
import { ScrcpyOptions1_18 } from "./1_18/index.js";
|
export { ScrcpyOptions1_18 as ScrcpyOptions1_19 } from "./1_18/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions1_19 extends ScrcpyOptions1_18 {
|
|
||||||
constructor(init: ScrcpyOptions1_18.Init) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions1_19 {
|
|
||||||
export type Init = ScrcpyOptions1_18.Init;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
import { ScrcpyOptions1_18 } from "./1_18/index.js";
|
export { ScrcpyOptions1_18 as ScrcpyOptions1_20 } from "./1_18/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions1_20 extends ScrcpyOptions1_18 {
|
|
||||||
constructor(init: ScrcpyOptions1_18.Init) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions1_20 {
|
|
||||||
export type Init = ScrcpyOptions1_18.Init;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
clipboardAutosync: true,
|
||||||
clipboardAutosync: true,
|
} as const satisfies Required<Init>;
|
||||||
}) as const satisfies Required<Init>)();
|
|
||||||
|
|
|
@ -7,4 +7,5 @@ export {
|
||||||
AckClipboardDeviceMessage,
|
AckClipboardDeviceMessage,
|
||||||
AckClipboardHandler,
|
AckClipboardHandler,
|
||||||
SetClipboardControlMessage,
|
SetClipboardControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
} from "./set-clipboard.js";
|
} from "./set-clipboard.js";
|
||||||
|
|
|
@ -12,6 +12,7 @@ export const AckClipboardDeviceMessage = struct(
|
||||||
|
|
||||||
export const SetClipboardControlMessage = struct(
|
export const SetClipboardControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
sequence: u64,
|
sequence: u64,
|
||||||
paste: u8<boolean>(),
|
paste: u8<boolean>(),
|
||||||
|
@ -75,3 +76,16 @@ export class AckClipboardHandler implements ScrcpyDeviceMessageParser {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function serializeSetClipboardControlMessage(
|
||||||
|
message: ScrcpySetClipboardControlMessage,
|
||||||
|
ackHandler: AckClipboardHandler | undefined,
|
||||||
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
|
if (!ackHandler) {
|
||||||
|
throw new Error(
|
||||||
|
"`serializeSetClipboardControlMessage` requires `control: true` option",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ackHandler.serializeSetClipboardControlMessage(message);
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -44,7 +44,7 @@ export class ScrcpyOptions1_21
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +63,12 @@ export class ScrcpyOptions1_21
|
||||||
constructor(init: Init) {
|
constructor(init: Init) {
|
||||||
this.value = { ...Defaults, ...init };
|
this.value = { ...Defaults, ...init };
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -122,8 +124,9 @@ export class ScrcpyOptions1_21
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
downsizeOnError: true,
|
||||||
downsizeOnError: true,
|
sendDeviceMeta: true,
|
||||||
sendDeviceMeta: true,
|
sendDummyByte: true,
|
||||||
sendDummyByte: true,
|
} as const satisfies Required<Init>;
|
||||||
}) as const satisfies Required<Init>)();
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -44,7 +44,7 @@ export class ScrcpyOptions1_22
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +63,12 @@ export class ScrcpyOptions1_22
|
||||||
constructor(init: Init) {
|
constructor(init: Init) {
|
||||||
this.value = { ...Defaults, ...init };
|
this.value = { ...Defaults, ...init };
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -122,8 +124,9 @@ export class ScrcpyOptions1_22
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
cleanup: true,
|
||||||
cleanup: true,
|
} as const satisfies Required<Init>;
|
||||||
}) as const satisfies Required<Init>)();
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -44,7 +44,7 @@ export class ScrcpyOptions1_23
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +63,12 @@ export class ScrcpyOptions1_23
|
||||||
constructor(init: Init) {
|
constructor(init: Init) {
|
||||||
this.value = { ...Defaults, ...init };
|
this.value = { ...Defaults, ...init };
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -122,8 +124,9 @@ export class ScrcpyOptions1_23
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
powerOn: true,
|
||||||
powerOn: true,
|
} as const satisfies Required<Init>;
|
||||||
}) as const satisfies Required<Init>)();
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -44,7 +44,7 @@ export class ScrcpyOptions1_24
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +63,12 @@ export class ScrcpyOptions1_24
|
||||||
constructor(init: Init) {
|
constructor(init: Init) {
|
||||||
this.value = { ...Defaults, ...init };
|
this.value = { ...Defaults, ...init };
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -122,8 +124,9 @@ export class ScrcpyOptions1_24
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { Field, StructInit } from "@yume-chan/struct";
|
||||||
import { field, struct, u16, u32, u8 } from "@yume-chan/struct";
|
import { field, struct, u16, u32, u8 } from "@yume-chan/struct";
|
||||||
|
|
||||||
import type { ScrcpyScrollController } from "../../base/index.js";
|
import type { ScrcpyScrollController } from "../../base/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/index.js";
|
|
||||||
import type { ScrcpyInjectScrollControlMessage } from "../../latest.js";
|
import type { ScrcpyInjectScrollControlMessage } from "../../latest.js";
|
||||||
import { clamp } from "../../utils/index.js";
|
import { clamp } from "../../utils/index.js";
|
||||||
|
|
||||||
|
@ -24,20 +23,20 @@ export const SignedFloat: Field<number, never, never> = field(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const InjectScrollControlMessage = /* #__PURE__ */ (() =>
|
export const InjectScrollControlMessage = struct(
|
||||||
struct(
|
{
|
||||||
{
|
// value of `type` can change between versions
|
||||||
type: u8(ScrcpyControlMessageType.InjectScroll),
|
type: u8,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
videoWidth: u16,
|
videoWidth: u16,
|
||||||
videoHeight: u16,
|
videoHeight: u16,
|
||||||
scrollX: SignedFloat,
|
scrollX: SignedFloat,
|
||||||
scrollY: SignedFloat,
|
scrollY: SignedFloat,
|
||||||
buttons: u32,
|
buttons: u32,
|
||||||
},
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
))();
|
);
|
||||||
|
|
||||||
export type InjectScrollControlMessage = StructInit<
|
export type InjectScrollControlMessage = StructInit<
|
||||||
typeof InjectScrollControlMessage
|
typeof InjectScrollControlMessage
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async";
|
||||||
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -44,7 +44,7 @@ export class ScrcpyOptions1_25
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +63,12 @@ export class ScrcpyOptions1_25
|
||||||
constructor(init: Init) {
|
constructor(init: Init) {
|
||||||
this.value = { ...Defaults, ...init };
|
this.value = { ...Defaults, ...init };
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -122,8 +124,9 @@ export class ScrcpyOptions1_25
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,30 @@
|
||||||
import { omit } from "../../utils/index.js";
|
|
||||||
|
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...{
|
||||||
...omit(PrevImpl.Defaults, "bitRate", "codecOptions", "encoderName"),
|
...PrevImpl.Defaults,
|
||||||
scid: undefined,
|
// Remove obsolete values
|
||||||
|
// relies on the minifier to flatten the nested spread
|
||||||
|
bitRate: undefined,
|
||||||
|
codecOptions: undefined,
|
||||||
|
encoderName: undefined,
|
||||||
|
},
|
||||||
|
|
||||||
videoCodec: "h264",
|
scid: undefined,
|
||||||
videoBitRate: 8000000,
|
|
||||||
videoCodecOptions: undefined,
|
|
||||||
videoEncoder: undefined,
|
|
||||||
|
|
||||||
audio: true,
|
videoCodec: "h264",
|
||||||
audioCodec: "opus",
|
videoBitRate: 8000000,
|
||||||
audioBitRate: 128000,
|
videoCodecOptions: undefined,
|
||||||
audioCodecOptions: undefined,
|
videoEncoder: undefined,
|
||||||
audioEncoder: undefined,
|
|
||||||
|
|
||||||
listEncoders: false,
|
audio: true,
|
||||||
listDisplays: false,
|
audioCodec: "opus",
|
||||||
sendCodecMeta: true,
|
audioBitRate: 128000,
|
||||||
}) as const satisfies Required<Init>)();
|
audioCodecOptions: undefined,
|
||||||
|
audioEncoder: undefined,
|
||||||
|
|
||||||
|
listEncoders: false,
|
||||||
|
listDisplays: false,
|
||||||
|
sendCodecMeta: true,
|
||||||
|
} as const satisfies Required<Init>;
|
||||||
|
|
|
@ -2,27 +2,26 @@ import type { StructInit } from "@yume-chan/struct";
|
||||||
import { struct, u16, u32, u64, u8 } from "@yume-chan/struct";
|
import { struct, u16, u32, u64, u8 } from "@yume-chan/struct";
|
||||||
|
|
||||||
import type { AndroidMotionEventAction } from "../../android/motion-event.js";
|
import type { AndroidMotionEventAction } from "../../android/motion-event.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/control-message-type.js";
|
|
||||||
import type { ScrcpyInjectTouchControlMessage } from "../../latest.js";
|
import type { ScrcpyInjectTouchControlMessage } from "../../latest.js";
|
||||||
|
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const InjectTouchControlMessage = /* #__PURE__ */ (() =>
|
export const InjectTouchControlMessage = struct(
|
||||||
struct(
|
{
|
||||||
{
|
// value of `type` can change between versions
|
||||||
type: u8(ScrcpyControlMessageType.InjectTouch),
|
type: u8,
|
||||||
action: u8<AndroidMotionEventAction>(),
|
action: u8<AndroidMotionEventAction>(),
|
||||||
pointerId: u64,
|
pointerId: u64,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
videoWidth: u16,
|
videoWidth: u16,
|
||||||
videoHeight: u16,
|
videoHeight: u16,
|
||||||
pressure: PrevImpl.UnsignedFloat,
|
pressure: PrevImpl.UnsignedFloat,
|
||||||
actionButton: u32,
|
actionButton: u32,
|
||||||
buttons: u32,
|
buttons: u32,
|
||||||
},
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
))();
|
);
|
||||||
|
|
||||||
export type InjectTouchControlMessage = StructInit<
|
export type InjectTouchControlMessage = StructInit<
|
||||||
typeof InjectTouchControlMessage
|
typeof InjectTouchControlMessage
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -34,6 +33,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -45,7 +45,7 @@ export class ScrcpyOptions2_0
|
||||||
|
|
||||||
readonly value: Required<Init>;
|
readonly value: Required<Init>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,12 @@ export class ScrcpyOptions2_0
|
||||||
constructor(init: Init) {
|
constructor(init: Init) {
|
||||||
this.value = { ...Defaults, ...init };
|
this.value = { ...Defaults, ...init };
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -129,8 +131,9 @@ export class ScrcpyOptions2_0
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
video: true,
|
||||||
video: true,
|
audioSource: "output",
|
||||||
audioSource: "output",
|
} as const satisfies Required<Init<true>>;
|
||||||
}) as const satisfies Required<Init<true>>)();
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -34,6 +33,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -45,7 +45,7 @@ export class ScrcpyOptions2_1<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,12 @@ export class ScrcpyOptions2_1<TVideo extends boolean>
|
||||||
constructor(init: Init<TVideo>) {
|
constructor(init: Init<TVideo>) {
|
||||||
this.value = { ...Defaults, ...init } as never;
|
this.value = { ...Defaults, ...init } as never;
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -129,8 +131,9 @@ export class ScrcpyOptions2_1<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions2_1 } from "./2_1/index.js";
|
export { ScrcpyOptions2_1 as ScrcpyOptions2_1_1 } from "./2_1/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions2_1_1<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions2_1<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions2_1.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions2_1_1 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions2_1.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
videoSource: "display",
|
||||||
videoSource: "display",
|
displayId: 0,
|
||||||
displayId: 0,
|
cameraId: undefined,
|
||||||
cameraId: undefined,
|
cameraSize: undefined,
|
||||||
cameraSize: undefined,
|
cameraFacing: undefined,
|
||||||
cameraFacing: undefined,
|
cameraAr: undefined,
|
||||||
cameraAr: undefined,
|
cameraFps: undefined,
|
||||||
cameraFps: undefined,
|
cameraHighSpeed: false,
|
||||||
cameraHighSpeed: false,
|
listCameras: false,
|
||||||
listCameras: false,
|
listCameraSizes: false,
|
||||||
listCameraSizes: false,
|
} as const satisfies Required<Init<true>>;
|
||||||
}) as const satisfies Required<Init<true>>)();
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -34,6 +33,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -45,7 +45,7 @@ export class ScrcpyOptions2_2<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,10 +68,12 @@ export class ScrcpyOptions2_2<TVideo extends boolean>
|
||||||
this.value.control = false;
|
this.value.control = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -133,8 +135,9 @@ export class ScrcpyOptions2_2<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -34,6 +33,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
} from "./impl/index.js";
|
} from "./impl/index.js";
|
||||||
|
@ -45,7 +45,7 @@ export class ScrcpyOptions2_3<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,10 +68,12 @@ export class ScrcpyOptions2_3<TVideo extends boolean>
|
||||||
this.value.control = false;
|
this.value.control = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.value.control && this.value.clipboardAutosync) {
|
if (this.value.control) {
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
if (this.value.clipboardAutosync) {
|
||||||
new ClipboardStream(),
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
);
|
new ClipboardStream(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
new AckClipboardHandler(),
|
new AckClipboardHandler(),
|
||||||
|
@ -133,8 +135,9 @@ export class ScrcpyOptions2_3<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions2_3 } from "./2_3/index.js";
|
export { ScrcpyOptions2_3 as ScrcpyOptions2_3_1 } from "./2_3/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions2_3_1<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions2_3<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions2_3.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions2_3_1 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions2_3.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
|
import type { ScrcpyControlMessageTypeMap } from "../../base/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/index.js";
|
import { ScrcpyControlMessageType } from "../../base/index.js";
|
||||||
|
|
||||||
import { PrevImpl } from "./prev.js";
|
export const ControlMessageTypes = {
|
||||||
|
[ScrcpyControlMessageType.InjectKeyCode]: 0,
|
||||||
export const ControlMessageTypes: readonly ScrcpyControlMessageType[] =
|
[ScrcpyControlMessageType.InjectText]: 1,
|
||||||
/* #__PURE__ */ (() => [
|
[ScrcpyControlMessageType.InjectTouch]: 2,
|
||||||
...PrevImpl.ControlMessageTypes,
|
[ScrcpyControlMessageType.InjectScroll]: 3,
|
||||||
ScrcpyControlMessageType.UHidCreate,
|
[ScrcpyControlMessageType.BackOrScreenOn]: 4,
|
||||||
ScrcpyControlMessageType.UHidInput,
|
[ScrcpyControlMessageType.ExpandNotificationPanel]: 5,
|
||||||
ScrcpyControlMessageType.OpenHardKeyboardSettings,
|
[ScrcpyControlMessageType.ExpandSettingPanel]: 6,
|
||||||
])();
|
[ScrcpyControlMessageType.CollapseNotificationPanel]: 7,
|
||||||
|
[ScrcpyControlMessageType.GetClipboard]: 8,
|
||||||
|
[ScrcpyControlMessageType.SetClipboard]: 9,
|
||||||
|
[ScrcpyControlMessageType.SetDisplayPower]: 10,
|
||||||
|
[ScrcpyControlMessageType.RotateDevice]: 11,
|
||||||
|
[ScrcpyControlMessageType.UHidCreate]: 12,
|
||||||
|
[ScrcpyControlMessageType.UHidInput]: 13,
|
||||||
|
[ScrcpyControlMessageType.OpenHardKeyboardSettings]: 14,
|
||||||
|
} as const satisfies ScrcpyControlMessageTypeMap;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type { ScrcpyUHidCreateControlMessage } from "../../latest.js";
|
||||||
|
|
||||||
export const UHidCreateControlMessage = struct(
|
export const UHidCreateControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
id: u16,
|
id: u16,
|
||||||
data: buffer(u16),
|
data: buffer(u16),
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions2_4<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +84,12 @@ export class ScrcpyOptions2_4<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -150,8 +150,9 @@ export class ScrcpyOptions2_4<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions2_4 } from "./2_4/index.js";
|
export { ScrcpyOptions2_4 as ScrcpyOptions2_5 } from "./2_4/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions2_5<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions2_4<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions2_4.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions2_5 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions2_4.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
audioDup: false,
|
||||||
audioDup: false,
|
} as const satisfies Required<Init<true>>;
|
||||||
}) as const satisfies Required<Init<true>>)();
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions2_6<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ export class ScrcpyOptions2_6<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -154,8 +154,9 @@ export class ScrcpyOptions2_6<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions2_6 } from "./2_6/index.js";
|
export { ScrcpyOptions2_6 as ScrcpyOptions2_6_1 } from "./2_6/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions2_6_1<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions2_6<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions2_6.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions2_6_1 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions2_6.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
|
import type { ScrcpyControlMessageTypeMap } from "../../base/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/index.js";
|
import { ScrcpyControlMessageType } from "../../base/index.js";
|
||||||
|
|
||||||
import { PrevImpl } from "./prev.js";
|
export const ControlMessageTypes = {
|
||||||
|
[ScrcpyControlMessageType.InjectKeyCode]: 0,
|
||||||
export const ControlMessageTypes: readonly ScrcpyControlMessageType[] =
|
[ScrcpyControlMessageType.InjectText]: 1,
|
||||||
/* #__PURE__ */ (() => {
|
[ScrcpyControlMessageType.InjectTouch]: 2,
|
||||||
const result = PrevImpl.ControlMessageTypes.slice();
|
[ScrcpyControlMessageType.InjectScroll]: 3,
|
||||||
result.splice(14, 0, ScrcpyControlMessageType.UHidDestroy);
|
[ScrcpyControlMessageType.BackOrScreenOn]: 4,
|
||||||
return result;
|
[ScrcpyControlMessageType.ExpandNotificationPanel]: 5,
|
||||||
})();
|
[ScrcpyControlMessageType.ExpandSettingPanel]: 6,
|
||||||
|
[ScrcpyControlMessageType.CollapseNotificationPanel]: 7,
|
||||||
|
[ScrcpyControlMessageType.GetClipboard]: 8,
|
||||||
|
[ScrcpyControlMessageType.SetClipboard]: 9,
|
||||||
|
[ScrcpyControlMessageType.SetDisplayPower]: 10,
|
||||||
|
[ScrcpyControlMessageType.RotateDevice]: 11,
|
||||||
|
[ScrcpyControlMessageType.UHidCreate]: 12,
|
||||||
|
[ScrcpyControlMessageType.UHidInput]: 13,
|
||||||
|
[ScrcpyControlMessageType.UHidDestroy]: 14,
|
||||||
|
[ScrcpyControlMessageType.OpenHardKeyboardSettings]: 15,
|
||||||
|
} as const satisfies ScrcpyControlMessageTypeMap;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type { ScrcpyUHidCreateControlMessage } from "../../latest.js";
|
||||||
|
|
||||||
export const UHidCreateControlMessage = struct(
|
export const UHidCreateControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
id: u16,
|
id: u16,
|
||||||
name: string(u8),
|
name: string(u8),
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions2_7<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ export class ScrcpyOptions2_7<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -154,8 +154,9 @@ export class ScrcpyOptions2_7<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
|
import type { ScrcpyControlMessageTypeMap } from "../../base/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../base/index.js";
|
import { ScrcpyControlMessageType } from "../../base/index.js";
|
||||||
|
|
||||||
import { PrevImpl } from "./prev.js";
|
export const ControlMessageTypes = {
|
||||||
|
[ScrcpyControlMessageType.InjectKeyCode]: 0,
|
||||||
export const ControlMessageTypes: readonly ScrcpyControlMessageType[] =
|
[ScrcpyControlMessageType.InjectText]: 1,
|
||||||
/* #__PURE__ */ (() => [
|
[ScrcpyControlMessageType.InjectTouch]: 2,
|
||||||
...PrevImpl.ControlMessageTypes,
|
[ScrcpyControlMessageType.InjectScroll]: 3,
|
||||||
ScrcpyControlMessageType.StartApp,
|
[ScrcpyControlMessageType.BackOrScreenOn]: 4,
|
||||||
ScrcpyControlMessageType.ResetVideo,
|
[ScrcpyControlMessageType.ExpandNotificationPanel]: 5,
|
||||||
])();
|
[ScrcpyControlMessageType.ExpandSettingPanel]: 6,
|
||||||
|
[ScrcpyControlMessageType.CollapseNotificationPanel]: 7,
|
||||||
|
[ScrcpyControlMessageType.GetClipboard]: 8,
|
||||||
|
[ScrcpyControlMessageType.SetClipboard]: 9,
|
||||||
|
[ScrcpyControlMessageType.SetDisplayPower]: 10,
|
||||||
|
[ScrcpyControlMessageType.RotateDevice]: 11,
|
||||||
|
[ScrcpyControlMessageType.UHidCreate]: 12,
|
||||||
|
[ScrcpyControlMessageType.UHidInput]: 13,
|
||||||
|
[ScrcpyControlMessageType.UHidDestroy]: 14,
|
||||||
|
[ScrcpyControlMessageType.OpenHardKeyboardSettings]: 15,
|
||||||
|
[ScrcpyControlMessageType.StartApp]: 16,
|
||||||
|
[ScrcpyControlMessageType.ResetVideo]: 17,
|
||||||
|
} as const satisfies ScrcpyControlMessageTypeMap;
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import { omit } from "../../utils/index.js";
|
|
||||||
|
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...{
|
||||||
...omit(PrevImpl.Defaults, "lockVideoOrientation"),
|
...PrevImpl.Defaults,
|
||||||
captureOrientation: undefined,
|
// Remove obsolete values
|
||||||
angle: 0,
|
// relies on the minifier to flatten the nested spread
|
||||||
screenOffTimeout: undefined,
|
lockVideoOrientation: undefined,
|
||||||
listApps: false,
|
},
|
||||||
newDisplay: undefined,
|
|
||||||
vdSystemDecorations: true,
|
captureOrientation: undefined,
|
||||||
}) as const satisfies Required<Init<true>>)();
|
angle: 0,
|
||||||
|
screenOffTimeout: undefined,
|
||||||
|
listApps: false,
|
||||||
|
newDisplay: undefined,
|
||||||
|
vdSystemDecorations: true,
|
||||||
|
} as const satisfies Required<Init<true>>;
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions3_0<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ export class ScrcpyOptions3_0<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -154,8 +154,9 @@ export class ScrcpyOptions3_0<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions3_0 } from "./3_0/index.js";
|
export { ScrcpyOptions3_0 as ScrcpyOptions3_0_1 } from "./3_0/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions3_0_1<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions3_0<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions3_0.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions3_0_1 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions3_0.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions3_0 } from "./3_0/index.js";
|
export { ScrcpyOptions3_0 as ScrcpyOptions3_0_2 } from "./3_0/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions3_0_2<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions3_0<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions3_0.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions3_0_2 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions3_0.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
vdDestroyContent: false,
|
||||||
vdDestroyContent: false,
|
} as const satisfies Required<Init<true>>;
|
||||||
}) as const satisfies Required<Init<true>>)();
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type { ScrcpyUHidCreateControlMessage } from "../../latest.js";
|
||||||
|
|
||||||
export const UHidCreateControlMessage = struct(
|
export const UHidCreateControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
id: u16,
|
id: u16,
|
||||||
vendorId: u16,
|
vendorId: u16,
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions3_1<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ export class ScrcpyOptions3_1<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -154,8 +154,9 @@ export class ScrcpyOptions3_1<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Init } from "./init.js";
|
import type { Init } from "./init.js";
|
||||||
import { PrevImpl } from "./prev.js";
|
import { PrevImpl } from "./prev.js";
|
||||||
|
|
||||||
export const Defaults = /* #__PURE__ */ (() =>
|
export const Defaults = {
|
||||||
({
|
...PrevImpl.Defaults,
|
||||||
...PrevImpl.Defaults,
|
displayImePolicy: undefined,
|
||||||
displayImePolicy: undefined,
|
} as const satisfies Required<Init<true>>;
|
||||||
}) as const satisfies Required<Init<true>>)();
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions3_2<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ export class ScrcpyOptions3_2<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -154,8 +154,9 @@ export class ScrcpyOptions3_2<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions3_2 } from "./3_2/index.js";
|
export { ScrcpyOptions3_2 as ScrcpyOptions3_3 } from "./3_2/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions3_3<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions3_2<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions3_2.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions3_3 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions3_2.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ScrcpyAudioStreamMetadata,
|
ScrcpyAudioStreamMetadata,
|
||||||
ScrcpyControlMessageType,
|
|
||||||
ScrcpyDisplay,
|
ScrcpyDisplay,
|
||||||
ScrcpyEncoder,
|
ScrcpyEncoder,
|
||||||
ScrcpyMediaStreamPacket,
|
ScrcpyMediaStreamPacket,
|
||||||
|
@ -36,6 +35,7 @@ import {
|
||||||
serialize,
|
serialize,
|
||||||
serializeBackOrScreenOnControlMessage,
|
serializeBackOrScreenOnControlMessage,
|
||||||
serializeInjectTouchControlMessage,
|
serializeInjectTouchControlMessage,
|
||||||
|
serializeSetClipboardControlMessage,
|
||||||
serializeUHidCreateControlMessage,
|
serializeUHidCreateControlMessage,
|
||||||
setListDisplays,
|
setListDisplays,
|
||||||
setListEncoders,
|
setListEncoders,
|
||||||
|
@ -49,7 +49,7 @@ export class ScrcpyOptions3_3_1<TVideo extends boolean>
|
||||||
|
|
||||||
readonly value: Required<Init<TVideo>>;
|
readonly value: Required<Init<TVideo>>;
|
||||||
|
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[] {
|
get controlMessageTypes(): typeof ControlMessageTypes {
|
||||||
return ControlMessageTypes;
|
return ControlMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ export class ScrcpyOptions3_3_1<TVideo extends boolean>
|
||||||
this.#clipboard = this.#deviceMessageParsers.add(
|
this.#clipboard = this.#deviceMessageParsers.add(
|
||||||
new ClipboardStream(),
|
new ClipboardStream(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
|
||||||
new AckClipboardHandler(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#ackClipboardHandler = this.#deviceMessageParsers.add(
|
||||||
|
new AckClipboardHandler(),
|
||||||
|
);
|
||||||
|
|
||||||
this.#uHidOutput = this.#deviceMessageParsers.add(
|
this.#uHidOutput = this.#deviceMessageParsers.add(
|
||||||
new UHidOutputStream(),
|
new UHidOutputStream(),
|
||||||
);
|
);
|
||||||
|
@ -154,8 +154,9 @@ export class ScrcpyOptions3_3_1<TVideo extends boolean>
|
||||||
serializeSetClipboardControlMessage(
|
serializeSetClipboardControlMessage(
|
||||||
message: ScrcpySetClipboardControlMessage,
|
message: ScrcpySetClipboardControlMessage,
|
||||||
): Uint8Array | [Uint8Array, Promise<void>] {
|
): Uint8Array | [Uint8Array, Promise<void>] {
|
||||||
return this.#ackClipboardHandler!.serializeSetClipboardControlMessage(
|
return serializeSetClipboardControlMessage(
|
||||||
message,
|
message,
|
||||||
|
this.#ackClipboardHandler,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
import { ScrcpyOptions3_3_1 } from "./3_3_1/index.js";
|
export { ScrcpyOptions3_3_1 as ScrcpyOptions3_3_2 } from "./3_3_1/index.js";
|
||||||
|
|
||||||
export class ScrcpyOptions3_3_2<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions3_3_1<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions3_3_1.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptions3_3_2 {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions3_3_1.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
194
libraries/scrcpy/src/android/key-code-value.ts
Normal file
194
libraries/scrcpy/src/android/key-code-value.ts
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/KeyEvent.java;l=97;drc=95c1165bb895dd844e1793460710f7163dd330a3
|
||||||
|
// Android key code to Chrome key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/keyboard_code_conversion_android.cc
|
||||||
|
// Chrome key code to DOM key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_code_data.inc
|
||||||
|
// Some keys are not mapped to `KeyboardEvent.code`, only to `KeyboardEvent.key`: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_key_data.inc
|
||||||
|
|
||||||
|
export const AndroidHome = 3;
|
||||||
|
export const AndroidBack = 4;
|
||||||
|
export const AndroidCall = 5;
|
||||||
|
export const AndroidEndCall = 6;
|
||||||
|
|
||||||
|
export const Digit0 = 7;
|
||||||
|
export const Digit1 = 8;
|
||||||
|
export const Digit2 = 9;
|
||||||
|
export const Digit3 = 10;
|
||||||
|
export const Digit4 = 11;
|
||||||
|
export const Digit5 = 12;
|
||||||
|
export const Digit6 = 13;
|
||||||
|
export const Digit7 = 14;
|
||||||
|
export const Digit8 = 15;
|
||||||
|
export const Digit9 = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* '*' key.
|
||||||
|
*/
|
||||||
|
export const Star = 17; // Name not verified
|
||||||
|
/**
|
||||||
|
* '#' key.
|
||||||
|
*/
|
||||||
|
export const Pound = 18; // Name not verified
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directional Pad Up key.
|
||||||
|
*/
|
||||||
|
export const ArrowUp = 19;
|
||||||
|
/**
|
||||||
|
* Directional Pad Down key.
|
||||||
|
*/
|
||||||
|
export const ArrowDown = 20;
|
||||||
|
/**
|
||||||
|
* Directional Pad Left key.
|
||||||
|
*/
|
||||||
|
export const ArrowLeft = 21;
|
||||||
|
/**
|
||||||
|
* Directional Pad Right key.
|
||||||
|
*/
|
||||||
|
export const ArrowRight = 22;
|
||||||
|
/**
|
||||||
|
* Directional Pad Center key.
|
||||||
|
*/
|
||||||
|
export const AndroidDPadCenter = 23;
|
||||||
|
|
||||||
|
export const VolumeUp = 24; // Name not verified
|
||||||
|
export const VolumeDown = 25; // Name not verified
|
||||||
|
export const Power = 26; // Name not verified
|
||||||
|
export const AndroidCamera = 27;
|
||||||
|
export const Clear = 28; // Name not verified
|
||||||
|
|
||||||
|
export const KeyA = 29;
|
||||||
|
export const KeyB = 30;
|
||||||
|
export const KeyC = 31;
|
||||||
|
export const KeyD = 32;
|
||||||
|
export const KeyE = 33;
|
||||||
|
export const KeyF = 34;
|
||||||
|
export const KeyG = 35;
|
||||||
|
export const KeyH = 36;
|
||||||
|
export const KeyI = 37;
|
||||||
|
export const KeyJ = 38;
|
||||||
|
export const KeyK = 39;
|
||||||
|
export const KeyL = 40;
|
||||||
|
export const KeyM = 41;
|
||||||
|
export const KeyN = 42;
|
||||||
|
export const KeyO = 43;
|
||||||
|
export const KeyP = 44;
|
||||||
|
export const KeyQ = 45;
|
||||||
|
export const KeyR = 46;
|
||||||
|
export const KeyS = 47;
|
||||||
|
export const KeyT = 48;
|
||||||
|
export const KeyU = 49;
|
||||||
|
export const KeyV = 50;
|
||||||
|
export const KeyW = 51;
|
||||||
|
export const KeyX = 52;
|
||||||
|
export const KeyY = 53;
|
||||||
|
export const KeyZ = 54;
|
||||||
|
export const Comma = 55;
|
||||||
|
export const Period = 56;
|
||||||
|
export const AltLeft = 57;
|
||||||
|
export const AltRight = 58;
|
||||||
|
export const ShiftLeft = 59;
|
||||||
|
export const ShiftRight = 60;
|
||||||
|
export const Tab = 61;
|
||||||
|
export const Space = 62;
|
||||||
|
export const AndroidSymbol = 63;
|
||||||
|
export const AndroidExplorer = 64;
|
||||||
|
export const AndroidEnvelope = 65;
|
||||||
|
export const Enter = 66;
|
||||||
|
export const Backspace = 67;
|
||||||
|
export const Backquote = 68;
|
||||||
|
export const Minus = 69;
|
||||||
|
export const Equal = 70;
|
||||||
|
export const BracketLeft = 71;
|
||||||
|
export const BracketRight = 72;
|
||||||
|
export const Backslash = 73;
|
||||||
|
export const Semicolon = 74;
|
||||||
|
export const Quote = 75;
|
||||||
|
export const Slash = 76;
|
||||||
|
export const At = 77; // Name not verified
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number modifier key.
|
||||||
|
*
|
||||||
|
* Used to enter numeric symbols.
|
||||||
|
* This key is not Num Lock; it is more like {@link AltLeft} and is
|
||||||
|
* interpreted as an ALT key by `android.text.method.MetaKeyKeyListener`.
|
||||||
|
*/
|
||||||
|
export const AndroidNum = 78;
|
||||||
|
/**
|
||||||
|
* Headset Hook key.
|
||||||
|
*
|
||||||
|
* Used to hang up calls and stop media.
|
||||||
|
*/
|
||||||
|
export const AndroidHeadsetHook = 79;
|
||||||
|
/**
|
||||||
|
* Camera Focus key.
|
||||||
|
*
|
||||||
|
* Used to focus the camera.
|
||||||
|
*/
|
||||||
|
export const AndroidFocus = 80;
|
||||||
|
|
||||||
|
export const Plus = 81; // Name not verified
|
||||||
|
export const ContextMenu = 82;
|
||||||
|
export const AndroidNotification = 83;
|
||||||
|
export const AndroidSearch = 84;
|
||||||
|
|
||||||
|
export const PageUp = 92;
|
||||||
|
export const PageDown = 93;
|
||||||
|
|
||||||
|
export const Escape = 111;
|
||||||
|
export const Delete = 112;
|
||||||
|
export const ControlLeft = 113;
|
||||||
|
export const ControlRight = 114;
|
||||||
|
export const CapsLock = 115;
|
||||||
|
export const ScrollLock = 116;
|
||||||
|
export const MetaLeft = 117;
|
||||||
|
export const MetaRight = 118;
|
||||||
|
export const AndroidFunction = 119;
|
||||||
|
export const PrintScreen = 120;
|
||||||
|
export const Pause = 121;
|
||||||
|
|
||||||
|
export const Home = 122;
|
||||||
|
export const End = 123;
|
||||||
|
export const Insert = 124;
|
||||||
|
export const AndroidForward = 125;
|
||||||
|
|
||||||
|
export const F1 = 131;
|
||||||
|
export const F2 = 132;
|
||||||
|
export const F3 = 133;
|
||||||
|
export const F4 = 134;
|
||||||
|
export const F5 = 135;
|
||||||
|
export const F6 = 136;
|
||||||
|
export const F7 = 137;
|
||||||
|
export const F8 = 138;
|
||||||
|
export const F9 = 139;
|
||||||
|
export const F10 = 140;
|
||||||
|
export const F11 = 141;
|
||||||
|
export const F12 = 142;
|
||||||
|
|
||||||
|
export const NumLock = 143;
|
||||||
|
export const Numpad0 = 144;
|
||||||
|
export const Numpad1 = 145;
|
||||||
|
export const Numpad2 = 146;
|
||||||
|
export const Numpad3 = 147;
|
||||||
|
export const Numpad4 = 148;
|
||||||
|
export const Numpad5 = 149;
|
||||||
|
export const Numpad6 = 150;
|
||||||
|
export const Numpad7 = 151;
|
||||||
|
export const Numpad8 = 152;
|
||||||
|
export const Numpad9 = 153;
|
||||||
|
export const NumpadDivide = 154;
|
||||||
|
export const NumpadMultiply = 155;
|
||||||
|
export const NumpadSubtract = 156;
|
||||||
|
export const NumpadAdd = 157;
|
||||||
|
export const NumpadDecimal = 158;
|
||||||
|
export const NumpadComma = 159; // Name not verified
|
||||||
|
export const NumpadEnter = 160;
|
||||||
|
export const NumpadEquals = 161; // Name not verified
|
||||||
|
export const NumpadLeftParen = 162; // Name not verified
|
||||||
|
export const NumpadRightParen = 163; // Name not verified
|
||||||
|
|
||||||
|
export const VolumeMute = 164; // Name not verified
|
||||||
|
export const AndroidAppSwitch = 187; // Name not verified
|
||||||
|
|
||||||
|
export const AndroidCut = 277;
|
||||||
|
export const AndroidCopy = 278;
|
||||||
|
export const AndroidPaste = 279;
|
|
@ -1,3 +1,5 @@
|
||||||
|
import * as AndroidKeyCode from "./key-code-value.js";
|
||||||
|
|
||||||
export const AndroidKeyEventAction = {
|
export const AndroidKeyEventAction = {
|
||||||
Down: 0,
|
Down: 0,
|
||||||
Up: 1,
|
Up: 1,
|
||||||
|
@ -29,189 +31,10 @@ export const AndroidKeyEventMeta = {
|
||||||
export type AndroidKeyEventMeta =
|
export type AndroidKeyEventMeta =
|
||||||
(typeof AndroidKeyEventMeta)[keyof typeof AndroidKeyEventMeta];
|
(typeof AndroidKeyEventMeta)[keyof typeof AndroidKeyEventMeta];
|
||||||
|
|
||||||
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/KeyEvent.java;l=97;drc=95c1165bb895dd844e1793460710f7163dd330a3
|
// biome-ignore lint/suspicious/noRedeclare: TypeScript declaration merging for enum-like object
|
||||||
// Android key code to Chrome key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/keyboard_code_conversion_android.cc
|
type AndroidKeyCode = (typeof AndroidKeyCode)[keyof typeof AndroidKeyCode];
|
||||||
// Chrome key code to DOM key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_code_data.inc
|
|
||||||
// Some keys are not mapped to `KeyboardEvent.code`, only to `KeyboardEvent.key`: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_key_data.inc
|
|
||||||
export const AndroidKeyCode = {
|
|
||||||
AndroidHome: 3,
|
|
||||||
AndroidBack: 4,
|
|
||||||
AndroidCall: 5,
|
|
||||||
AndroidEndCall: 6,
|
|
||||||
|
|
||||||
Digit0: 7,
|
export { AndroidKeyCode };
|
||||||
Digit1: 8,
|
|
||||||
Digit2: 9,
|
|
||||||
Digit3: 10,
|
|
||||||
Digit4: 11,
|
|
||||||
Digit5: 12,
|
|
||||||
Digit6: 13,
|
|
||||||
Digit7: 14,
|
|
||||||
Digit8: 15,
|
|
||||||
Digit9: 16,
|
|
||||||
/**
|
|
||||||
* '*' key.
|
|
||||||
*/
|
|
||||||
Star: 17, // Name not verified
|
|
||||||
/**
|
|
||||||
* '#' key.
|
|
||||||
*/
|
|
||||||
Pound: 18, // Name not verified
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Directional Pad Up key.
|
|
||||||
*/
|
|
||||||
ArrowUp: 19,
|
|
||||||
/**
|
|
||||||
* Directional Pad Down key.
|
|
||||||
*/
|
|
||||||
ArrowDown: 20,
|
|
||||||
/**
|
|
||||||
* Directional Pad Left key.
|
|
||||||
*/
|
|
||||||
ArrowLeft: 21,
|
|
||||||
/**
|
|
||||||
* Directional Pad Right key.
|
|
||||||
*/
|
|
||||||
ArrowRight: 22,
|
|
||||||
/**
|
|
||||||
* Directional Pad Center key.
|
|
||||||
*/
|
|
||||||
AndroidDPadCenter: 23,
|
|
||||||
|
|
||||||
VolumeUp: 24, // Name not verified
|
|
||||||
VolumeDown: 25, // Name not verified
|
|
||||||
Power: 26, // Name not verified
|
|
||||||
AndroidCamera: 27,
|
|
||||||
Clear: 28, // Name not verified
|
|
||||||
|
|
||||||
KeyA: 29,
|
|
||||||
KeyB: 30,
|
|
||||||
KeyC: 31,
|
|
||||||
KeyD: 32,
|
|
||||||
KeyE: 33,
|
|
||||||
KeyF: 34,
|
|
||||||
KeyG: 35,
|
|
||||||
KeyH: 36,
|
|
||||||
KeyI: 37,
|
|
||||||
KeyJ: 38,
|
|
||||||
KeyK: 39,
|
|
||||||
KeyL: 40,
|
|
||||||
KeyM: 41,
|
|
||||||
KeyN: 42,
|
|
||||||
KeyO: 43,
|
|
||||||
KeyP: 44,
|
|
||||||
KeyQ: 45,
|
|
||||||
KeyR: 46,
|
|
||||||
KeyS: 47,
|
|
||||||
KeyT: 48,
|
|
||||||
KeyU: 49,
|
|
||||||
KeyV: 50,
|
|
||||||
KeyW: 51,
|
|
||||||
KeyX: 52,
|
|
||||||
KeyY: 53,
|
|
||||||
KeyZ: 54,
|
|
||||||
Comma: 55,
|
|
||||||
Period: 56,
|
|
||||||
AltLeft: 57,
|
|
||||||
AltRight: 58,
|
|
||||||
ShiftLeft: 59,
|
|
||||||
ShiftRight: 60,
|
|
||||||
Tab: 61,
|
|
||||||
Space: 62,
|
|
||||||
AndroidSymbol: 63,
|
|
||||||
AndroidExplorer: 64,
|
|
||||||
AndroidEnvelope: 65,
|
|
||||||
Enter: 66,
|
|
||||||
Backspace: 67,
|
|
||||||
Backquote: 68,
|
|
||||||
Minus: 69,
|
|
||||||
Equal: 70,
|
|
||||||
BracketLeft: 71,
|
|
||||||
BracketRight: 72,
|
|
||||||
Backslash: 73,
|
|
||||||
Semicolon: 74,
|
|
||||||
Quote: 75,
|
|
||||||
Slash: 76,
|
|
||||||
At: 77, // Name not verified
|
|
||||||
|
|
||||||
AndroidNum: 78,
|
|
||||||
AndroidHeadsetHook: 79,
|
|
||||||
/**
|
|
||||||
* Camera Focus key。
|
|
||||||
*/
|
|
||||||
AndroidFocus: 80,
|
|
||||||
|
|
||||||
Plus: 81, // Name not verified
|
|
||||||
ContextMenu: 82,
|
|
||||||
AndroidNotification: 83,
|
|
||||||
AndroidSearch: 84,
|
|
||||||
|
|
||||||
PageUp: 92,
|
|
||||||
PageDown: 93,
|
|
||||||
|
|
||||||
Escape: 111,
|
|
||||||
Delete: 112,
|
|
||||||
ControlLeft: 113,
|
|
||||||
ControlRight: 114,
|
|
||||||
CapsLock: 115,
|
|
||||||
ScrollLock: 116,
|
|
||||||
MetaLeft: 117,
|
|
||||||
MetaRight: 118,
|
|
||||||
AndroidFunction: 119,
|
|
||||||
PrintScreen: 120,
|
|
||||||
Pause: 121,
|
|
||||||
|
|
||||||
Home: 122,
|
|
||||||
End: 123,
|
|
||||||
Insert: 124,
|
|
||||||
AndroidForward: 125,
|
|
||||||
|
|
||||||
F1: 131,
|
|
||||||
F2: 132,
|
|
||||||
F3: 133,
|
|
||||||
F4: 134,
|
|
||||||
F5: 135,
|
|
||||||
F6: 136,
|
|
||||||
F7: 137,
|
|
||||||
F8: 138,
|
|
||||||
F9: 139,
|
|
||||||
F10: 140,
|
|
||||||
F11: 141,
|
|
||||||
F12: 142,
|
|
||||||
|
|
||||||
NumLock: 143,
|
|
||||||
Numpad0: 144,
|
|
||||||
Numpad1: 145,
|
|
||||||
Numpad2: 146,
|
|
||||||
Numpad3: 147,
|
|
||||||
Numpad4: 148,
|
|
||||||
Numpad5: 149,
|
|
||||||
Numpad6: 150,
|
|
||||||
Numpad7: 151,
|
|
||||||
Numpad8: 152,
|
|
||||||
Numpad9: 153,
|
|
||||||
NumpadDivide: 154,
|
|
||||||
NumpadMultiply: 155,
|
|
||||||
NumpadSubtract: 156,
|
|
||||||
NumpadAdd: 157,
|
|
||||||
NumpadDecimal: 158,
|
|
||||||
NumpadComma: 159, // Name not verified
|
|
||||||
NumpadEnter: 160,
|
|
||||||
NumpadEquals: 161, // Name not verified
|
|
||||||
NumpadLeftParen: 162, // Name not verified
|
|
||||||
NumpadRightParen: 163, // Name not verified
|
|
||||||
|
|
||||||
VolumeMute: 164, // Name not verified
|
|
||||||
AndroidAppSwitch: 187, // Name not verified
|
|
||||||
|
|
||||||
AndroidCut: 277,
|
|
||||||
AndroidCopy: 278,
|
|
||||||
AndroidPaste: 279,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type AndroidKeyCode =
|
|
||||||
(typeof AndroidKeyCode)[keyof typeof AndroidKeyCode];
|
|
||||||
|
|
||||||
export const AndroidKeyNames = /* #__PURE__ */ (() =>
|
export const AndroidKeyNames = /* #__PURE__ */ (() =>
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
|
|
18
libraries/scrcpy/src/base/control-message-type-value.ts
Normal file
18
libraries/scrcpy/src/base/control-message-type-value.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
export const InjectKeyCode = 0;
|
||||||
|
export const InjectText = 1;
|
||||||
|
export const InjectTouch = 2;
|
||||||
|
export const InjectScroll = 3;
|
||||||
|
export const BackOrScreenOn = 4;
|
||||||
|
export const ExpandNotificationPanel = 5;
|
||||||
|
export const ExpandSettingPanel = 6;
|
||||||
|
export const CollapseNotificationPanel = 7;
|
||||||
|
export const GetClipboard = 8;
|
||||||
|
export const SetClipboard = 9;
|
||||||
|
export const SetDisplayPower = 10;
|
||||||
|
export const RotateDevice = 11;
|
||||||
|
export const UHidCreate = 12;
|
||||||
|
export const UHidInput = 13;
|
||||||
|
export const UHidDestroy = 14;
|
||||||
|
export const OpenHardKeyboardSettings = 15;
|
||||||
|
export const StartApp = 16;
|
||||||
|
export const ResetVideo = 17;
|
|
@ -1,24 +1,8 @@
|
||||||
// Their IDs change between versions, so always use `options.getControlMessageTypes()`
|
import * as ScrcpyControlMessageType from "./control-message-type-value.js";
|
||||||
export const ScrcpyControlMessageType = {
|
|
||||||
InjectKeyCode: 0,
|
|
||||||
InjectText: 1,
|
|
||||||
InjectTouch: 2,
|
|
||||||
InjectScroll: 3,
|
|
||||||
BackOrScreenOn: 4,
|
|
||||||
ExpandNotificationPanel: 5,
|
|
||||||
ExpandSettingPanel: 6,
|
|
||||||
CollapseNotificationPanel: 7,
|
|
||||||
GetClipboard: 8,
|
|
||||||
SetClipboard: 9,
|
|
||||||
SetDisplayPower: 10,
|
|
||||||
RotateDevice: 11,
|
|
||||||
UHidCreate: 12,
|
|
||||||
UHidInput: 13,
|
|
||||||
UHidDestroy: 14,
|
|
||||||
OpenHardKeyboardSettings: 15,
|
|
||||||
StartApp: 16,
|
|
||||||
ResetVideo: 17,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type ScrcpyControlMessageType =
|
// These IDs change between versions, so always use `options.controlMessageTypes`
|
||||||
|
// biome-ignore lint/suspicious/noRedeclare: TypeScript declaration merging for enum-like object
|
||||||
|
type ScrcpyControlMessageType =
|
||||||
(typeof ScrcpyControlMessageType)[keyof typeof ScrcpyControlMessageType];
|
(typeof ScrcpyControlMessageType)[keyof typeof ScrcpyControlMessageType];
|
||||||
|
|
||||||
|
export { ScrcpyControlMessageType };
|
||||||
|
|
|
@ -18,8 +18,12 @@ import type { ScrcpyMediaStreamPacket } from "./media.js";
|
||||||
import type { ScrcpyScrollController } from "./scroll-controller.js";
|
import type { ScrcpyScrollController } from "./scroll-controller.js";
|
||||||
import type { ScrcpyVideoStream } from "./video.js";
|
import type { ScrcpyVideoStream } from "./video.js";
|
||||||
|
|
||||||
|
export type ScrcpyControlMessageTypeMap = Partial<
|
||||||
|
Record<ScrcpyControlMessageType, number>
|
||||||
|
>;
|
||||||
|
|
||||||
export interface ScrcpyOptions<T extends object> {
|
export interface ScrcpyOptions<T extends object> {
|
||||||
get controlMessageTypes(): readonly ScrcpyControlMessageType[];
|
get controlMessageTypes(): ScrcpyControlMessageTypeMap;
|
||||||
|
|
||||||
value: Required<T>;
|
value: Required<T>;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
export * from "./empty.js";
|
export * from "./empty.js";
|
||||||
export * from "./inject-key-code.js";
|
export * from "./inject-key-code.js";
|
||||||
export * from "./inject-text.js";
|
export * from "./inject-text.js";
|
||||||
export * from "./message-type-map.js";
|
|
||||||
export * from "./serializer.js";
|
export * from "./serializer.js";
|
||||||
export * from "./set-screen-power-mode.js";
|
export * from "./set-screen-power-mode.js";
|
||||||
export * from "./writer.js";
|
export * from "./writer.js";
|
||||||
|
|
|
@ -6,19 +6,18 @@ import type {
|
||||||
AndroidKeyEventAction,
|
AndroidKeyEventAction,
|
||||||
AndroidKeyEventMeta,
|
AndroidKeyEventMeta,
|
||||||
} from "../android/index.js";
|
} from "../android/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../base/index.js";
|
|
||||||
|
|
||||||
export const ScrcpyInjectKeyCodeControlMessage = /* #__PURE__ */ (() =>
|
export const ScrcpyInjectKeyCodeControlMessage = struct(
|
||||||
struct(
|
{
|
||||||
{
|
// value of `type` can change between versions
|
||||||
type: u8(ScrcpyControlMessageType.InjectKeyCode),
|
type: u8,
|
||||||
action: u8<AndroidKeyEventAction>(),
|
action: u8<AndroidKeyEventAction>(),
|
||||||
keyCode: u32<AndroidKeyCode>(),
|
keyCode: u32<AndroidKeyCode>(),
|
||||||
repeat: u32,
|
repeat: u32,
|
||||||
metaState: u32<AndroidKeyEventMeta>(),
|
metaState: u32<AndroidKeyEventMeta>(),
|
||||||
},
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
))();
|
);
|
||||||
|
|
||||||
export type ScrcpyInjectKeyCodeControlMessage = StructInit<
|
export type ScrcpyInjectKeyCodeControlMessage = StructInit<
|
||||||
typeof ScrcpyInjectKeyCodeControlMessage
|
typeof ScrcpyInjectKeyCodeControlMessage
|
||||||
|
|
|
@ -2,7 +2,11 @@ import type { StructInit } from "@yume-chan/struct";
|
||||||
import { string, struct, u32, u8 } from "@yume-chan/struct";
|
import { string, struct, u32, u8 } from "@yume-chan/struct";
|
||||||
|
|
||||||
export const ScrcpyInjectTextControlMessage = struct(
|
export const ScrcpyInjectTextControlMessage = struct(
|
||||||
{ type: u8, text: string(u32) },
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
|
type: u8,
|
||||||
|
text: string(u32),
|
||||||
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import type { ScrcpyControlMessageType, ScrcpyOptions } from "../base/index.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scrcpy control message types have different values between versions.
|
|
||||||
*
|
|
||||||
* This class provides a way to get the actual value for a given type.
|
|
||||||
*/
|
|
||||||
export class ScrcpyControlMessageTypeMap {
|
|
||||||
#types: readonly ScrcpyControlMessageType[];
|
|
||||||
|
|
||||||
constructor(options: ScrcpyOptions<object>) {
|
|
||||||
this.#types = options.controlMessageTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
get(type: ScrcpyControlMessageType): number {
|
|
||||||
const value = this.#types.indexOf(type);
|
|
||||||
if (value === -1) {
|
|
||||||
throw new TypeError("Invalid or unsupported control message type");
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
fillMessageType<T extends { type: number }>(
|
|
||||||
message: Omit<T, "type">,
|
|
||||||
type: ScrcpyControlMessageType,
|
|
||||||
): T {
|
|
||||||
(message as T).type = this.get(type);
|
|
||||||
return message as T;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ import type {
|
||||||
import { EmptyControlMessage } from "./empty.js";
|
import { EmptyControlMessage } from "./empty.js";
|
||||||
import { ScrcpyInjectKeyCodeControlMessage } from "./inject-key-code.js";
|
import { ScrcpyInjectKeyCodeControlMessage } from "./inject-key-code.js";
|
||||||
import { ScrcpyInjectTextControlMessage } from "./inject-text.js";
|
import { ScrcpyInjectTextControlMessage } from "./inject-text.js";
|
||||||
import { ScrcpyControlMessageTypeMap } from "./message-type-map.js";
|
|
||||||
import { ScrcpySetDisplayPowerControlMessage } from "./set-screen-power-mode.js";
|
import { ScrcpySetDisplayPowerControlMessage } from "./set-screen-power-mode.js";
|
||||||
import { ScrcpyStartAppControlMessage } from "./start-app.js";
|
import { ScrcpyStartAppControlMessage } from "./start-app.js";
|
||||||
import {
|
import {
|
||||||
|
@ -24,28 +23,39 @@ import {
|
||||||
|
|
||||||
export class ScrcpyControlMessageSerializer {
|
export class ScrcpyControlMessageSerializer {
|
||||||
#options: ScrcpyOptions<object>;
|
#options: ScrcpyOptions<object>;
|
||||||
#typeMap: ScrcpyControlMessageTypeMap;
|
|
||||||
#scrollController: ScrcpyScrollController;
|
#scrollController: ScrcpyScrollController;
|
||||||
|
|
||||||
constructor(options: ScrcpyOptions<object>) {
|
constructor(options: ScrcpyOptions<object>) {
|
||||||
this.#options = options;
|
this.#options = options;
|
||||||
this.#typeMap = new ScrcpyControlMessageTypeMap(options);
|
|
||||||
this.#scrollController = options.createScrollController();
|
this.#scrollController = options.createScrollController();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getType(type: ScrcpyControlMessageType): number {
|
||||||
|
const value = this.#options.controlMessageTypes[type];
|
||||||
|
if (value === undefined) {
|
||||||
|
throw new TypeError(`Invalid control message type: ${type}`);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addType<T extends { type: number }>(
|
||||||
|
message: Omit<T, "type">,
|
||||||
|
type: ScrcpyControlMessageType,
|
||||||
|
): T {
|
||||||
|
(message as T).type = this.getType(type);
|
||||||
|
return message as T;
|
||||||
|
}
|
||||||
|
|
||||||
injectKeyCode(message: Omit<ScrcpyInjectKeyCodeControlMessage, "type">) {
|
injectKeyCode(message: Omit<ScrcpyInjectKeyCodeControlMessage, "type">) {
|
||||||
return ScrcpyInjectKeyCodeControlMessage.serialize(
|
return ScrcpyInjectKeyCodeControlMessage.serialize(
|
||||||
this.#typeMap.fillMessageType(
|
this.#addType(message, ScrcpyControlMessageType.InjectKeyCode),
|
||||||
message,
|
|
||||||
ScrcpyControlMessageType.InjectKeyCode,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
injectText(text: string) {
|
injectText(text: string) {
|
||||||
return ScrcpyInjectTextControlMessage.serialize({
|
return ScrcpyInjectTextControlMessage.serialize({
|
||||||
text,
|
text,
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.InjectText),
|
type: this.getType(ScrcpyControlMessageType.InjectText),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +64,7 @@ export class ScrcpyControlMessageSerializer {
|
||||||
*/
|
*/
|
||||||
injectTouch(message: Omit<ScrcpyInjectTouchControlMessage, "type">) {
|
injectTouch(message: Omit<ScrcpyInjectTouchControlMessage, "type">) {
|
||||||
return this.#options.serializeInjectTouchControlMessage(
|
return this.#options.serializeInjectTouchControlMessage(
|
||||||
this.#typeMap.fillMessageType(
|
this.#addType(message, ScrcpyControlMessageType.InjectTouch),
|
||||||
message,
|
|
||||||
ScrcpyControlMessageType.InjectTouch,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,30 +73,27 @@ export class ScrcpyControlMessageSerializer {
|
||||||
*/
|
*/
|
||||||
injectScroll(message: Omit<ScrcpyInjectScrollControlMessage, "type">) {
|
injectScroll(message: Omit<ScrcpyInjectScrollControlMessage, "type">) {
|
||||||
return this.#scrollController.serializeScrollMessage(
|
return this.#scrollController.serializeScrollMessage(
|
||||||
this.#typeMap.fillMessageType(
|
this.#addType(message, ScrcpyControlMessageType.InjectScroll),
|
||||||
message,
|
|
||||||
ScrcpyControlMessageType.InjectScroll,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
backOrScreenOn(action: AndroidKeyEventAction) {
|
backOrScreenOn(action: AndroidKeyEventAction) {
|
||||||
return this.#options.serializeBackOrScreenOnControlMessage({
|
return this.#options.serializeBackOrScreenOnControlMessage({
|
||||||
action,
|
action,
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.BackOrScreenOn),
|
type: this.getType(ScrcpyControlMessageType.BackOrScreenOn),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setDisplayPower(mode: AndroidScreenPowerMode) {
|
setDisplayPower(mode: AndroidScreenPowerMode) {
|
||||||
return ScrcpySetDisplayPowerControlMessage.serialize({
|
return ScrcpySetDisplayPowerControlMessage.serialize({
|
||||||
mode,
|
mode,
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.SetDisplayPower),
|
type: this.getType(ScrcpyControlMessageType.SetDisplayPower),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
expandNotificationPanel() {
|
expandNotificationPanel() {
|
||||||
return EmptyControlMessage.serialize({
|
return EmptyControlMessage.serialize({
|
||||||
type: this.#typeMap.get(
|
type: this.getType(
|
||||||
ScrcpyControlMessageType.ExpandNotificationPanel,
|
ScrcpyControlMessageType.ExpandNotificationPanel,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
@ -97,15 +101,13 @@ export class ScrcpyControlMessageSerializer {
|
||||||
|
|
||||||
expandSettingPanel() {
|
expandSettingPanel() {
|
||||||
return EmptyControlMessage.serialize({
|
return EmptyControlMessage.serialize({
|
||||||
type: this.#typeMap.get(
|
type: this.getType(ScrcpyControlMessageType.ExpandSettingPanel),
|
||||||
ScrcpyControlMessageType.ExpandSettingPanel,
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
collapseNotificationPanel() {
|
collapseNotificationPanel() {
|
||||||
return EmptyControlMessage.serialize({
|
return EmptyControlMessage.serialize({
|
||||||
type: this.#typeMap.get(
|
type: this.getType(
|
||||||
ScrcpyControlMessageType.CollapseNotificationPanel,
|
ScrcpyControlMessageType.CollapseNotificationPanel,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
@ -113,14 +115,14 @@ export class ScrcpyControlMessageSerializer {
|
||||||
|
|
||||||
rotateDevice() {
|
rotateDevice() {
|
||||||
return EmptyControlMessage.serialize({
|
return EmptyControlMessage.serialize({
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.RotateDevice),
|
type: this.getType(ScrcpyControlMessageType.RotateDevice),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setClipboard(message: Omit<ScrcpySetClipboardControlMessage, "type">) {
|
setClipboard(message: Omit<ScrcpySetClipboardControlMessage, "type">) {
|
||||||
return this.#options.serializeSetClipboardControlMessage({
|
return this.#options.serializeSetClipboardControlMessage({
|
||||||
...message,
|
...message,
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.SetClipboard),
|
type: this.getType(ScrcpyControlMessageType.SetClipboard),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,25 +132,19 @@ export class ScrcpyControlMessageSerializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.#options.serializeUHidCreateControlMessage(
|
return this.#options.serializeUHidCreateControlMessage(
|
||||||
this.#typeMap.fillMessageType(
|
this.#addType(message, ScrcpyControlMessageType.UHidCreate),
|
||||||
message,
|
|
||||||
ScrcpyControlMessageType.UHidCreate,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
uHidInput(message: Omit<ScrcpyUHidInputControlMessage, "type">) {
|
uHidInput(message: Omit<ScrcpyUHidInputControlMessage, "type">) {
|
||||||
return ScrcpyUHidInputControlMessage.serialize(
|
return ScrcpyUHidInputControlMessage.serialize(
|
||||||
this.#typeMap.fillMessageType(
|
this.#addType(message, ScrcpyControlMessageType.UHidInput),
|
||||||
message,
|
|
||||||
ScrcpyControlMessageType.UHidInput,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
uHidDestroy(id: number) {
|
uHidDestroy(id: number) {
|
||||||
return ScrcpyUHidDestroyControlMessage.serialize({
|
return ScrcpyUHidDestroyControlMessage.serialize({
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.UHidDestroy),
|
type: this.getType(ScrcpyControlMessageType.UHidDestroy),
|
||||||
id,
|
id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -165,14 +161,14 @@ export class ScrcpyControlMessageSerializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ScrcpyStartAppControlMessage.serialize({
|
return ScrcpyStartAppControlMessage.serialize({
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.StartApp),
|
type: this.getType(ScrcpyControlMessageType.StartApp),
|
||||||
name,
|
name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
resetVideo() {
|
resetVideo() {
|
||||||
return EmptyControlMessage.serialize({
|
return EmptyControlMessage.serialize({
|
||||||
type: this.#typeMap.get(ScrcpyControlMessageType.ResetVideo),
|
type: this.getType(ScrcpyControlMessageType.ResetVideo),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,11 @@ import { struct, u8 } from "@yume-chan/struct";
|
||||||
import type { AndroidScreenPowerMode } from "../android/index.js";
|
import type { AndroidScreenPowerMode } from "../android/index.js";
|
||||||
|
|
||||||
export const ScrcpySetDisplayPowerControlMessage = struct(
|
export const ScrcpySetDisplayPowerControlMessage = struct(
|
||||||
{ type: u8, mode: u8<AndroidScreenPowerMode>() },
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
|
type: u8,
|
||||||
|
mode: u8<AndroidScreenPowerMode>(),
|
||||||
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { string, struct, u8 } from "@yume-chan/struct";
|
||||||
|
|
||||||
export const ScrcpyStartAppControlMessage = struct(
|
export const ScrcpyStartAppControlMessage = struct(
|
||||||
{
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
type: u8,
|
type: u8,
|
||||||
name: string(u8),
|
name: string(u8),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
import type { StructInit } from "@yume-chan/struct";
|
import type { StructInit } from "@yume-chan/struct";
|
||||||
import { buffer, struct, u16, u8 } from "@yume-chan/struct";
|
import { buffer, struct, u16, u8 } from "@yume-chan/struct";
|
||||||
|
|
||||||
import { ScrcpyControlMessageType } from "../base/index.js";
|
export const ScrcpyUHidInputControlMessage = struct(
|
||||||
|
{
|
||||||
export const ScrcpyUHidInputControlMessage = /* #__PURE__ */ (() =>
|
// value of `type` can change between versions
|
||||||
struct(
|
type: u8,
|
||||||
{
|
id: u16,
|
||||||
type: u8(ScrcpyControlMessageType.UHidInput),
|
data: buffer(u16),
|
||||||
id: u16,
|
},
|
||||||
data: buffer(u16),
|
{ littleEndian: false },
|
||||||
},
|
);
|
||||||
{ littleEndian: false },
|
|
||||||
))();
|
|
||||||
|
|
||||||
export type ScrcpyUHidInputControlMessage = StructInit<
|
export type ScrcpyUHidInputControlMessage = StructInit<
|
||||||
typeof ScrcpyUHidInputControlMessage
|
typeof ScrcpyUHidInputControlMessage
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export const ScrcpyUHidDestroyControlMessage = struct(
|
export const ScrcpyUHidDestroyControlMessage = struct(
|
||||||
{ type: u8, id: u16 },
|
{
|
||||||
|
// value of `type` can change between versions
|
||||||
|
type: u8,
|
||||||
|
id: u16,
|
||||||
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
import { ScrcpyOptions3_3_2 } from "./3_3_2.js";
|
export { ScrcpyOptions3_3_2 as ScrcpyOptionsLatest } from "./3_3_2.js";
|
||||||
|
|
||||||
export class ScrcpyOptionsLatest<
|
|
||||||
TVideo extends boolean,
|
|
||||||
> extends ScrcpyOptions3_3_2<TVideo> {
|
|
||||||
constructor(init: ScrcpyOptions3_3_2.Init<TVideo>) {
|
|
||||||
super(init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace ScrcpyOptionsLatest {
|
|
||||||
export type Init<TVideo extends boolean = boolean> =
|
|
||||||
ScrcpyOptions3_3_2.Init<TVideo>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
BackOrScreenOnControlMessage as ScrcpyBackOrScreenOnControlMessage,
|
BackOrScreenOnControlMessage as ScrcpyBackOrScreenOnControlMessage,
|
||||||
|
|
|
@ -24,7 +24,7 @@ export type BipedalGenerator<This, T, A extends unknown[]> = (
|
||||||
this: This,
|
this: This,
|
||||||
then: <U>(value: MaybePromiseLike<U>) => Iterable<unknown, U, unknown>,
|
then: <U>(value: MaybePromiseLike<U>) => Iterable<unknown, U, unknown>,
|
||||||
...args: A
|
...args: A
|
||||||
) => Generator<unknown, T, unknown>;
|
) => Generator<unknown, MaybePromiseLike<T>, unknown>;
|
||||||
|
|
||||||
/* #__NO_SIDE_EFFECTS__ */
|
/* #__NO_SIDE_EFFECTS__ */
|
||||||
export function bipedal<This, T, A extends unknown[]>(
|
export function bipedal<This, T, A extends unknown[]>(
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
import type { Field } from "./field/index.js";
|
import type {
|
||||||
|
BipedalFieldDeserializer,
|
||||||
|
ByobFieldSerializer,
|
||||||
|
Field,
|
||||||
|
} from "./field/index.js";
|
||||||
import { field } from "./field/index.js";
|
import { field } from "./field/index.js";
|
||||||
|
|
||||||
export const EmptyUint8Array = new Uint8Array(0);
|
export const EmptyUint8Array = new Uint8Array(0);
|
||||||
|
|
||||||
function copyMaybeDifferentLength(
|
function copyMaybeDifferentLength(
|
||||||
dist: Uint8Array,
|
dest: Uint8Array,
|
||||||
source: Uint8Array,
|
source: Uint8Array,
|
||||||
index: number,
|
index: number,
|
||||||
length: number,
|
length: number,
|
||||||
) {
|
) {
|
||||||
if (source.length < length) {
|
if (source.length < length) {
|
||||||
dist.set(source, index);
|
dest.set(source, index);
|
||||||
// Clear trailing bytes
|
// Clear trailing bytes
|
||||||
dist.fill(0, index + source.length, index + length);
|
dest.fill(0, index + source.length, index + length);
|
||||||
} else if (source.length === length) {
|
} else if (source.length === length) {
|
||||||
dist.set(source, index);
|
dest.set(source, index);
|
||||||
} else {
|
} else {
|
||||||
dist.set(source.subarray(0, length), index);
|
dest.set(source.subarray(0, length), index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,70 +33,97 @@ export interface BufferLengthConverter<K, KT> extends Converter<KT, number> {
|
||||||
field: K;
|
field: K;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BufferLike {
|
/**
|
||||||
(length: number): Field<Uint8Array, never, never, Uint8Array>;
|
* Create a fixed-length `Uint8Array` field.
|
||||||
<U>(
|
*
|
||||||
length: number,
|
* @param length Length of the field
|
||||||
converter: Converter<Uint8Array, U>,
|
*/
|
||||||
): Field<U, never, never, Uint8Array>;
|
export function buffer(
|
||||||
|
length: number,
|
||||||
<K extends string>(
|
): Field<Uint8Array, never, never, Uint8Array>;
|
||||||
lengthField: K,
|
/**
|
||||||
): Field<Uint8Array, K, Record<K, number>, Uint8Array>;
|
* Create a custom-typed field, backed by a fixed-length `Uint8Array`.
|
||||||
<K extends string, U>(
|
*
|
||||||
lengthField: K,
|
* @param length Length of the field
|
||||||
converter: Converter<Uint8Array, U>,
|
* @param converter A value converter to convert between `Uint8Array` and the target type
|
||||||
): Field<U, K, Record<K, number>, Uint8Array>;
|
*/
|
||||||
|
export function buffer<U>(
|
||||||
<K extends string, KT>(
|
|
||||||
length: BufferLengthConverter<K, KT>,
|
|
||||||
): Field<Uint8Array, K, Record<K, KT>, Uint8Array>;
|
|
||||||
<K extends string, KT, U>(
|
|
||||||
length: BufferLengthConverter<K, KT>,
|
|
||||||
converter: Converter<Uint8Array, U>,
|
|
||||||
): Field<U, K, Record<K, KT>, Uint8Array>;
|
|
||||||
|
|
||||||
<LengthOmitInit extends string, LengthDependencies>(
|
|
||||||
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
|
||||||
): Field<Uint8Array, LengthOmitInit, LengthDependencies, Uint8Array>;
|
|
||||||
<LengthOmitInit extends string, LengthDependencies, U>(
|
|
||||||
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
|
||||||
converter: Converter<Uint8Array, U>,
|
|
||||||
): Field<U, LengthOmitInit, LengthDependencies, Uint8Array>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _buffer(length: number): Field<Uint8Array, never, never, Uint8Array>;
|
|
||||||
function _buffer<U>(
|
|
||||||
length: number,
|
length: number,
|
||||||
converter: Converter<Uint8Array, U>,
|
converter: Converter<Uint8Array, U>,
|
||||||
): Field<U, never, never, Uint8Array>;
|
): Field<U, never, never, Uint8Array>;
|
||||||
|
|
||||||
function _buffer<K extends string>(
|
/**
|
||||||
|
* Create a variable-length `Uint8Array` field.
|
||||||
|
* The length is determined by another number-typed field.
|
||||||
|
*
|
||||||
|
* @param lengthField Name of the length field. Must be declared before this field
|
||||||
|
*/
|
||||||
|
export function buffer<K extends string>(
|
||||||
lengthField: K,
|
lengthField: K,
|
||||||
): Field<Uint8Array, K, Record<K, number>, Uint8Array>;
|
): Field<Uint8Array, K, Record<K, number>, Uint8Array>;
|
||||||
function _buffer<K extends string, U>(
|
/**
|
||||||
|
* Create a custom-typed field, backed by a variable-length `Uint8Array`.
|
||||||
|
* The length is determined by another number-typed field.
|
||||||
|
*
|
||||||
|
* @param lengthField Name of the length field. Must be declared before this field
|
||||||
|
* @param converter A value converter to convert between `Uint8Array` and the target type
|
||||||
|
*/
|
||||||
|
export function buffer<K extends string, U>(
|
||||||
lengthField: K,
|
lengthField: K,
|
||||||
converter: Converter<Uint8Array, U>,
|
converter: Converter<Uint8Array, U>,
|
||||||
): Field<U, K, Record<K, number>, Uint8Array>;
|
): Field<U, K, Record<K, number>, Uint8Array>;
|
||||||
|
|
||||||
function _buffer<K extends string, KT>(
|
/**
|
||||||
|
* Create a variable-length `Uint8Array` field.
|
||||||
|
* The length is determined by converting another field to `number`.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* Name of the length field,
|
||||||
|
* and a converter to convert between source type and `number`.
|
||||||
|
* Must be declared before this field
|
||||||
|
*/
|
||||||
|
export function buffer<K extends string, KT>(
|
||||||
length: BufferLengthConverter<K, KT>,
|
length: BufferLengthConverter<K, KT>,
|
||||||
): Field<Uint8Array, K, Record<K, KT>, Uint8Array>;
|
): Field<Uint8Array, K, Record<K, KT>, Uint8Array>;
|
||||||
function _buffer<K extends string, KT, U>(
|
/**
|
||||||
|
* Create a custom-typed field, backed by a variable-length `Uint8Array`.
|
||||||
|
* The length is determined by converting another field to `number`.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* Name of the length field,
|
||||||
|
* and a converter to convert between source type and `number`.
|
||||||
|
* Must be declared before this field
|
||||||
|
* @param converter
|
||||||
|
* A value converter to convert between `Uint8Array` and the target type
|
||||||
|
*/
|
||||||
|
export function buffer<K extends string, KT, U>(
|
||||||
length: BufferLengthConverter<K, KT>,
|
length: BufferLengthConverter<K, KT>,
|
||||||
converter: Converter<Uint8Array, U>,
|
converter: Converter<Uint8Array, U>,
|
||||||
): Field<U, K, Record<K, KT>, Uint8Array>;
|
): Field<U, K, Record<K, KT>, Uint8Array>;
|
||||||
|
|
||||||
function _buffer<LengthOmitInit extends string, LengthDependencies>(
|
/**
|
||||||
|
* Create a length field, and a variable-length `Uint8Array` field.
|
||||||
|
* This is a shortcut when the length field is directly before the data field.
|
||||||
|
*
|
||||||
|
* @param length The length field declaration
|
||||||
|
*/
|
||||||
|
export function buffer<LengthOmitInit extends string, LengthDependencies>(
|
||||||
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
||||||
): Field<Uint8Array, LengthOmitInit, LengthDependencies, Uint8Array>;
|
): Field<Uint8Array, LengthOmitInit, LengthDependencies, Uint8Array>;
|
||||||
function _buffer<LengthOmitInit extends string, LengthDependencies, U>(
|
/**
|
||||||
|
* Create a length field, and a custom-typed field, backed by a variable-length `Uint8Array`.
|
||||||
|
* This is a shortcut when the length field is directly before the data field.
|
||||||
|
*
|
||||||
|
* @param length The length field declaration
|
||||||
|
* @param converter A value converter to convert between `Uint8Array` and the target type
|
||||||
|
*/
|
||||||
|
export function buffer<LengthOmitInit extends string, LengthDependencies, U>(
|
||||||
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
||||||
converter: Converter<Uint8Array, U>,
|
converter: Converter<Uint8Array, U>,
|
||||||
): Field<U, LengthOmitInit, LengthDependencies, Uint8Array>;
|
): Field<U, LengthOmitInit, LengthDependencies, Uint8Array>;
|
||||||
|
|
||||||
/* #__NO_SIDE_EFFECTS__ */
|
/* #__NO_SIDE_EFFECTS__ */
|
||||||
function _buffer(
|
export function buffer(
|
||||||
lengthOrField:
|
lengthOrField:
|
||||||
| string
|
| string
|
||||||
| number
|
| number
|
||||||
|
@ -102,67 +133,47 @@ function _buffer(
|
||||||
): Field<unknown, string, Record<string, unknown>, Uint8Array> {
|
): Field<unknown, string, Record<string, unknown>, Uint8Array> {
|
||||||
// Fixed length
|
// Fixed length
|
||||||
if (typeof lengthOrField === "number") {
|
if (typeof lengthOrField === "number") {
|
||||||
if (converter) {
|
let serialize: ByobFieldSerializer<Uint8Array>;
|
||||||
if (lengthOrField === 0) {
|
let deserialize: BipedalFieldDeserializer<
|
||||||
return field(
|
unknown,
|
||||||
0,
|
Record<string, unknown>
|
||||||
"byob",
|
>;
|
||||||
() => {},
|
let init: ((value: unknown) => Uint8Array) | undefined;
|
||||||
// eslint-disable-next-line require-yield
|
|
||||||
function* () {
|
|
||||||
return converter.convert(EmptyUint8Array);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return field(
|
|
||||||
lengthOrField,
|
|
||||||
"byob",
|
|
||||||
(value, { buffer, index }) => {
|
|
||||||
copyMaybeDifferentLength(
|
|
||||||
buffer,
|
|
||||||
value,
|
|
||||||
index,
|
|
||||||
lengthOrField,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
function* (then, reader) {
|
|
||||||
const array = yield* then(
|
|
||||||
reader.readExactly(lengthOrField),
|
|
||||||
);
|
|
||||||
return converter.convert(array);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
init(value) {
|
|
||||||
return converter.back(value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lengthOrField === 0) {
|
if (lengthOrField === 0) {
|
||||||
return field(
|
serialize = () => {};
|
||||||
0,
|
|
||||||
"byob",
|
if (converter) {
|
||||||
() => {},
|
|
||||||
// eslint-disable-next-line require-yield
|
// eslint-disable-next-line require-yield
|
||||||
function* () {
|
deserialize = function* () {
|
||||||
|
return converter.convert(EmptyUint8Array);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line require-yield
|
||||||
|
deserialize = function* () {
|
||||||
return EmptyUint8Array;
|
return EmptyUint8Array;
|
||||||
},
|
};
|
||||||
);
|
}
|
||||||
|
} else {
|
||||||
|
serialize = (value, { buffer, index }) =>
|
||||||
|
copyMaybeDifferentLength(buffer, value, index, lengthOrField);
|
||||||
|
|
||||||
|
if (converter) {
|
||||||
|
deserialize = function* (then, reader) {
|
||||||
|
const array = reader.readExactly(lengthOrField);
|
||||||
|
return converter.convert(yield* then(array));
|
||||||
|
};
|
||||||
|
init = (value) => converter.back(value);
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line require-yield
|
||||||
|
deserialize = function* (_then, reader) {
|
||||||
|
const array = reader.readExactly(lengthOrField);
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return field(
|
return field(lengthOrField, "byob", serialize, deserialize, { init });
|
||||||
lengthOrField,
|
|
||||||
"byob",
|
|
||||||
(value, { buffer, index }) => {
|
|
||||||
copyMaybeDifferentLength(buffer, value, index, lengthOrField);
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line require-yield
|
|
||||||
function* (_then, reader) {
|
|
||||||
return reader.readExactly(lengthOrField);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare length field
|
// Declare length field
|
||||||
|
@ -172,48 +183,31 @@ function _buffer(
|
||||||
typeof lengthOrField === "function") &&
|
typeof lengthOrField === "function") &&
|
||||||
"serialize" in lengthOrField
|
"serialize" in lengthOrField
|
||||||
) {
|
) {
|
||||||
|
let deserialize: BipedalFieldDeserializer<
|
||||||
|
unknown,
|
||||||
|
Record<string, unknown>
|
||||||
|
>;
|
||||||
|
let init: ((value: unknown) => Uint8Array) | undefined;
|
||||||
|
|
||||||
if (converter) {
|
if (converter) {
|
||||||
return field(
|
deserialize = function* (then, reader, context) {
|
||||||
lengthOrField.size,
|
const length = yield* then(
|
||||||
"default",
|
lengthOrField.deserialize(reader, context),
|
||||||
(value, { littleEndian }) => {
|
);
|
||||||
if (lengthOrField.type === "default") {
|
const array =
|
||||||
const lengthBuffer = lengthOrField.serialize(
|
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
||||||
value.length,
|
return converter.convert(yield* then(array));
|
||||||
{ littleEndian },
|
};
|
||||||
);
|
init = (value) => converter.back(value);
|
||||||
const result = new Uint8Array(
|
} else {
|
||||||
lengthBuffer.length + value.length,
|
deserialize = function* (then, reader, context) {
|
||||||
);
|
const length = yield* then(
|
||||||
result.set(lengthBuffer, 0);
|
lengthOrField.deserialize(reader, context),
|
||||||
result.set(value, lengthBuffer.length);
|
);
|
||||||
return result;
|
const array =
|
||||||
} else {
|
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
||||||
const result = new Uint8Array(
|
return array;
|
||||||
lengthOrField.size + value.length,
|
};
|
||||||
);
|
|
||||||
lengthOrField.serialize(value.length, {
|
|
||||||
buffer: result,
|
|
||||||
index: 0,
|
|
||||||
littleEndian,
|
|
||||||
});
|
|
||||||
result.set(value, lengthOrField.size);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function* (then, reader, context) {
|
|
||||||
const length = yield* then(
|
|
||||||
lengthOrField.deserialize(reader, context),
|
|
||||||
);
|
|
||||||
const array = yield* then(reader.readExactly(length));
|
|
||||||
return converter.convert(array);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
init(value) {
|
|
||||||
return converter.back(value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return field(
|
return field(
|
||||||
|
@ -224,6 +218,11 @@ function _buffer(
|
||||||
const lengthBuffer = lengthOrField.serialize(value.length, {
|
const lengthBuffer = lengthOrField.serialize(value.length, {
|
||||||
littleEndian,
|
littleEndian,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (value.length === 0) {
|
||||||
|
return lengthBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
const result = new Uint8Array(
|
const result = new Uint8Array(
|
||||||
lengthBuffer.length + value.length,
|
lengthBuffer.length + value.length,
|
||||||
);
|
);
|
||||||
|
@ -243,114 +242,91 @@ function _buffer(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function* (then, reader, context) {
|
deserialize,
|
||||||
const length = yield* then(
|
{ init },
|
||||||
lengthOrField.deserialize(reader, context),
|
|
||||||
);
|
|
||||||
return yield* then(reader.readExactly(length));
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference exiting length field
|
// Reference existing length field
|
||||||
if (typeof lengthOrField === "string") {
|
if (typeof lengthOrField === "string") {
|
||||||
if (converter) {
|
let deserialize: BipedalFieldDeserializer<
|
||||||
return field(
|
unknown,
|
||||||
0,
|
Record<string, unknown>
|
||||||
"default",
|
>;
|
||||||
(source) => source,
|
let init: (
|
||||||
// eslint-disable-next-line require-yield
|
value: unknown,
|
||||||
function* (_then, reader, { dependencies }) {
|
dependencies: Record<string, unknown>,
|
||||||
const length = dependencies[lengthOrField] as number;
|
) => Uint8Array;
|
||||||
if (length === 0) {
|
|
||||||
return EmptyUint8Array;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reader.readExactly(length);
|
if (converter) {
|
||||||
},
|
deserialize = function* (then, reader, { dependencies }) {
|
||||||
{
|
const length = dependencies[lengthOrField] as number;
|
||||||
init(value, dependencies) {
|
const array =
|
||||||
const array = converter.back(value);
|
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
||||||
dependencies[lengthOrField] = array.length;
|
return converter.convert(yield* then(array));
|
||||||
return array;
|
};
|
||||||
},
|
init = (value, dependencies) => {
|
||||||
},
|
const array = converter.back(value);
|
||||||
);
|
dependencies[lengthOrField] = array.length;
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line require-yield
|
||||||
|
deserialize = function* (_then, reader, { dependencies }) {
|
||||||
|
const length = dependencies[lengthOrField] as number;
|
||||||
|
const array =
|
||||||
|
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
init = (value, dependencies) => {
|
||||||
|
const array = value as Uint8Array;
|
||||||
|
dependencies[lengthOrField] = array.length;
|
||||||
|
return array;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return field(
|
return field(0, "default", (source) => source, deserialize, { init });
|
||||||
0,
|
|
||||||
"default",
|
|
||||||
(source) => source,
|
|
||||||
// eslint-disable-next-line require-yield
|
|
||||||
function* (_then, reader, { dependencies }) {
|
|
||||||
const length = dependencies[lengthOrField] as number;
|
|
||||||
if (length === 0) {
|
|
||||||
return EmptyUint8Array;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reader.readExactly(length);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
init(value, dependencies) {
|
|
||||||
dependencies[lengthOrField] = (value as Uint8Array).length;
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference existing length field + converter
|
let deserialize: BipedalFieldDeserializer<unknown, Record<string, unknown>>;
|
||||||
|
let init: (
|
||||||
|
value: unknown,
|
||||||
|
dependencies: Record<string, unknown>,
|
||||||
|
) => Uint8Array;
|
||||||
|
|
||||||
|
// Reference existing length field + length converter
|
||||||
if (converter) {
|
if (converter) {
|
||||||
return field(
|
deserialize = function* (then, reader, { dependencies }) {
|
||||||
0,
|
|
||||||
"default",
|
|
||||||
(source) => source,
|
|
||||||
// eslint-disable-next-line require-yield
|
|
||||||
function* (_then, reader, { dependencies }) {
|
|
||||||
const rawLength = dependencies[lengthOrField.field];
|
|
||||||
const length = lengthOrField.convert(rawLength);
|
|
||||||
if (length === 0) {
|
|
||||||
return EmptyUint8Array;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reader.readExactly(length);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
init(value, dependencies) {
|
|
||||||
const array = converter.back(value);
|
|
||||||
dependencies[lengthOrField.field] = lengthOrField.back(
|
|
||||||
array.length,
|
|
||||||
);
|
|
||||||
return array;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return field(
|
|
||||||
0,
|
|
||||||
"default",
|
|
||||||
(source) => source,
|
|
||||||
// eslint-disable-next-line require-yield
|
|
||||||
function* (_then, reader, { dependencies }) {
|
|
||||||
const rawLength = dependencies[lengthOrField.field];
|
const rawLength = dependencies[lengthOrField.field];
|
||||||
const length = lengthOrField.convert(rawLength);
|
const length = lengthOrField.convert(rawLength);
|
||||||
if (length === 0) {
|
const array =
|
||||||
return EmptyUint8Array;
|
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
||||||
}
|
return converter.convert(yield* then(array));
|
||||||
|
};
|
||||||
|
init = (value, dependencies) => {
|
||||||
|
const array = converter.back(value);
|
||||||
|
dependencies[lengthOrField.field] = lengthOrField.back(
|
||||||
|
array.length,
|
||||||
|
);
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line require-yield
|
||||||
|
deserialize = function* (_then, reader, { dependencies }) {
|
||||||
|
const rawLength = dependencies[lengthOrField.field];
|
||||||
|
const length = lengthOrField.convert(rawLength);
|
||||||
|
const array =
|
||||||
|
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
init = (value, dependencies) => {
|
||||||
|
const array = value as Uint8Array;
|
||||||
|
dependencies[lengthOrField.field] = lengthOrField.back(
|
||||||
|
array.length,
|
||||||
|
);
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return reader.readExactly(length);
|
return field(0, "default", (source) => source, deserialize, { init });
|
||||||
},
|
|
||||||
{
|
|
||||||
init(value, dependencies) {
|
|
||||||
dependencies[lengthOrField.field] = lengthOrField.back(
|
|
||||||
(value as Uint8Array).length,
|
|
||||||
);
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buffer = _buffer;
|
|
||||||
|
|
|
@ -25,7 +25,10 @@ export interface Field<T, OmitInit extends string, D, Raw = T>
|
||||||
FieldDeserializer<T, D> {
|
FieldDeserializer<T, D> {
|
||||||
omitInit: OmitInit | undefined;
|
omitInit: OmitInit | undefined;
|
||||||
|
|
||||||
init?(value: T, dependencies: D): Raw | undefined;
|
/**
|
||||||
|
* A function to convert deserialized value back to raw value for serialization.
|
||||||
|
*/
|
||||||
|
init?(value: T, dependencies: D): Raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldDeserializeContext<D> {
|
export interface FieldDeserializeContext<D> {
|
||||||
|
@ -44,5 +47,8 @@ export interface FieldDeserializer<T, D> {
|
||||||
export interface FieldOptions<T, OmitInit extends string, D, Raw = T> {
|
export interface FieldOptions<T, OmitInit extends string, D, Raw = T> {
|
||||||
omitInit?: OmitInit;
|
omitInit?: OmitInit;
|
||||||
dependencies?: D;
|
dependencies?: D;
|
||||||
init?: (value: T, dependencies: D) => Raw | undefined;
|
/**
|
||||||
|
* A function to convert deserialized value back to raw value for serialization.
|
||||||
|
*/
|
||||||
|
init?: ((value: T, dependencies: D) => Raw) | undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,9 +132,7 @@ export function struct<
|
||||||
for (const [key, field] of fieldList) {
|
for (const [key, field] of fieldList) {
|
||||||
if (key in temp && "init" in field) {
|
if (key in temp && "init" in field) {
|
||||||
const result = field.init?.(temp[key], temp as never);
|
const result = field.init?.(temp[key], temp as never);
|
||||||
if (result !== undefined) {
|
temp[key] = result;
|
||||||
temp[key] = result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
toolchain/side-effect-test/README.md
Normal file
3
toolchain/side-effect-test/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Side effect test
|
||||||
|
|
||||||
|
Use Rollup's `experimentalLogSideEffects` to log any side effects in exports.
|
34
toolchain/side-effect-test/generate.mjs
Normal file
34
toolchain/side-effect-test/generate.mjs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import { writeFileSync } from "node:fs";
|
||||||
|
import { dirname, resolve } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
async function generateTest(packageName, filename) {
|
||||||
|
const exports = await import(packageName);
|
||||||
|
const names = Object.keys(exports)
|
||||||
|
.filter(
|
||||||
|
(name) =>
|
||||||
|
name !== "default" && name !== "__esModule" && name !== "then",
|
||||||
|
)
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
resolve(dirname(fileURLToPath(import.meta.url)), filename),
|
||||||
|
`
|
||||||
|
// Generated by toolchain/side-effect-test/generate.mjs
|
||||||
|
// DO NOT MODIFY THIS FILE MANUALLY
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import { ${names.join(", ")} } from "${packageName}";
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
console.log(${names.join(", ")})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
generateTest("@yume-chan/scrcpy", "./src/scrcpy.js"),
|
||||||
|
generateTest("@yume-chan/adb", "./src/adb.js"),
|
||||||
|
]);
|
|
@ -1,4 +1,5 @@
|
||||||
import node from "@rollup/plugin-node-resolve";
|
import node from "@rollup/plugin-node-resolve";
|
||||||
|
import terser from "@rollup/plugin-terser";
|
||||||
import typescript from "@rollup/plugin-typescript";
|
import typescript from "@rollup/plugin-typescript";
|
||||||
import { defineConfig } from "rollup";
|
import { defineConfig } from "rollup";
|
||||||
|
|
||||||
|
@ -13,11 +14,15 @@ export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
typescript(),
|
typescript(),
|
||||||
node(),
|
node(),
|
||||||
// terser({
|
terser({
|
||||||
// module: true,
|
module: true,
|
||||||
// format: {
|
format: {
|
||||||
// beautify: true,
|
beautify: true,
|
||||||
// },
|
},
|
||||||
// }),
|
compress: {
|
||||||
|
passes: 10,
|
||||||
|
},
|
||||||
|
mangle: false,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
10
toolchain/side-effect-test/src/adb.js
Normal file
10
toolchain/side-effect-test/src/adb.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
// Generated by toolchain/side-effect-test/generate.mjs
|
||||||
|
// DO NOT MODIFY THIS FILE MANUALLY
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import { ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE, ADB_DAEMON_VERSION_OMIT_CHECKSUM, ADB_SYNC_MAX_PACKET_SIZE, ASN1_NULL, ASN1_OCTET_STRING, ASN1_OID, ASN1_SEQUENCE, Adb, AdbAuthType, AdbBanner, AdbBannerKey, AdbCommand, AdbDaemonSocket, AdbDaemonSocketController, AdbDaemonTransport, AdbDefaultAuthenticator, AdbDeviceFeatures, AdbFeature, AdbFrameBufferError, AdbFrameBufferForbiddenError, AdbFrameBufferUnsupportedVersionError, AdbFrameBufferV1, AdbFrameBufferV2, AdbNoneProtocolProcessImpl, AdbNoneProtocolPtyProcess, AdbNoneProtocolSubprocessService, AdbPacket, AdbPacketDispatcher, AdbPacketHeader, AdbPacketSerializeStream, AdbPower, AdbReverseError, AdbReverseNotSupportedError, AdbReverseService, AdbServerClient, AdbServerDeviceObserverOwner, AdbServerStream, AdbServerTransport, AdbServiceBase, AdbShellProtocolId, AdbShellProtocolPacket, AdbShellProtocolProcessImpl, AdbShellProtocolPtyProcess, AdbShellProtocolSubprocessService, AdbSubprocessService, AdbSync, AdbSyncDataResponse, AdbSyncEntry2Response, AdbSyncEntryResponse, AdbSyncError, AdbSyncFailResponse, AdbSyncLstatResponse, AdbSyncNumberRequest, AdbSyncOkResponse, AdbSyncRequestId, AdbSyncResponseId, AdbSyncSendV2Flags, AdbSyncSendV2Request, AdbSyncSocket, AdbSyncSocketLocked, AdbSyncStatErrorCode, AdbSyncStatResponse, AdbTcpIpService, AutoResetEvent, FAIL, LinuxFileType, NOOP, Ref, SHA1_DIGEST_INFO, SHA1_DIGEST_LENGTH, ToArrayStream, adbGeneratePublicKey, adbGetPublicKeySize, adbNoneProtocolSpawner, adbShellProtocolSpawner, adbSyncLstat, adbSyncOpenDir, adbSyncOpenDirV1, adbSyncOpenDirV2, adbSyncPull, adbSyncPullGenerator, adbSyncPush, adbSyncPushV1, adbSyncPushV2, adbSyncReadResponse, adbSyncReadResponses, adbSyncStat, adbSyncWriteRequest, calculateBase64EncodedLength, calculateChecksum, createLazyPromise, decodeBase64, decodeUtf8, decodeUtf8Chunked, dirname, encodeBase64, encodeUtf8, escapeArg, framebuffer, getBigUint, hexToNumber, modInverse, powMod, raceSignal, rsaParsePrivateKey, rsaSign, sequenceEqual, setBigUint, splitCommand, toLocalUint8Array, unorderedRemove, unreachable, write4HexDigits } from "@yume-chan/adb";
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
console.log(ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE, ADB_DAEMON_VERSION_OMIT_CHECKSUM, ADB_SYNC_MAX_PACKET_SIZE, ASN1_NULL, ASN1_OCTET_STRING, ASN1_OID, ASN1_SEQUENCE, Adb, AdbAuthType, AdbBanner, AdbBannerKey, AdbCommand, AdbDaemonSocket, AdbDaemonSocketController, AdbDaemonTransport, AdbDefaultAuthenticator, AdbDeviceFeatures, AdbFeature, AdbFrameBufferError, AdbFrameBufferForbiddenError, AdbFrameBufferUnsupportedVersionError, AdbFrameBufferV1, AdbFrameBufferV2, AdbNoneProtocolProcessImpl, AdbNoneProtocolPtyProcess, AdbNoneProtocolSubprocessService, AdbPacket, AdbPacketDispatcher, AdbPacketHeader, AdbPacketSerializeStream, AdbPower, AdbReverseError, AdbReverseNotSupportedError, AdbReverseService, AdbServerClient, AdbServerDeviceObserverOwner, AdbServerStream, AdbServerTransport, AdbServiceBase, AdbShellProtocolId, AdbShellProtocolPacket, AdbShellProtocolProcessImpl, AdbShellProtocolPtyProcess, AdbShellProtocolSubprocessService, AdbSubprocessService, AdbSync, AdbSyncDataResponse, AdbSyncEntry2Response, AdbSyncEntryResponse, AdbSyncError, AdbSyncFailResponse, AdbSyncLstatResponse, AdbSyncNumberRequest, AdbSyncOkResponse, AdbSyncRequestId, AdbSyncResponseId, AdbSyncSendV2Flags, AdbSyncSendV2Request, AdbSyncSocket, AdbSyncSocketLocked, AdbSyncStatErrorCode, AdbSyncStatResponse, AdbTcpIpService, AutoResetEvent, FAIL, LinuxFileType, NOOP, Ref, SHA1_DIGEST_INFO, SHA1_DIGEST_LENGTH, ToArrayStream, adbGeneratePublicKey, adbGetPublicKeySize, adbNoneProtocolSpawner, adbShellProtocolSpawner, adbSyncLstat, adbSyncOpenDir, adbSyncOpenDirV1, adbSyncOpenDirV2, adbSyncPull, adbSyncPullGenerator, adbSyncPush, adbSyncPushV1, adbSyncPushV2, adbSyncReadResponse, adbSyncReadResponses, adbSyncStat, adbSyncWriteRequest, calculateBase64EncodedLength, calculateChecksum, createLazyPromise, decodeBase64, decodeUtf8, decodeUtf8Chunked, dirname, encodeBase64, encodeUtf8, escapeArg, framebuffer, getBigUint, hexToNumber, modInverse, powMod, raceSignal, rsaParsePrivateKey, rsaSign, sequenceEqual, setBigUint, splitCommand, toLocalUint8Array, unorderedRemove, unreachable, write4HexDigits)
|
||||||
|
}
|
|
@ -1,42 +1,2 @@
|
||||||
import {
|
export { default as Adb } from "./adb.js";
|
||||||
bipedal,
|
export { default as Scrcpy } from "./scrcpy.js";
|
||||||
buffer,
|
|
||||||
concat,
|
|
||||||
decodeUtf8,
|
|
||||||
encodeUtf8,
|
|
||||||
extend,
|
|
||||||
s16,
|
|
||||||
s32,
|
|
||||||
s64,
|
|
||||||
s8,
|
|
||||||
string,
|
|
||||||
struct,
|
|
||||||
u16,
|
|
||||||
u32,
|
|
||||||
u64,
|
|
||||||
u8,
|
|
||||||
} from "@yume-chan/struct";
|
|
||||||
|
|
||||||
bipedal(function* () {});
|
|
||||||
buffer(u8);
|
|
||||||
decodeUtf8(new Uint8Array());
|
|
||||||
encodeUtf8("");
|
|
||||||
s16(1);
|
|
||||||
s32(1);
|
|
||||||
s64(1);
|
|
||||||
s8(1);
|
|
||||||
string(1);
|
|
||||||
u16(1);
|
|
||||||
u32(1);
|
|
||||||
u64(1);
|
|
||||||
u8(1);
|
|
||||||
struct({}, { littleEndian: true });
|
|
||||||
concat(
|
|
||||||
{ littleEndian: true },
|
|
||||||
struct({ a: u8 }, { littleEndian: true }),
|
|
||||||
struct({ b: u8 }, { littleEndian: true }),
|
|
||||||
);
|
|
||||||
extend(struct({ a: u16 }, { littleEndian: true }), { b: buffer(32) });
|
|
||||||
|
|
||||||
export * from "@yume-chan/scrcpy";
|
|
||||||
export * from "@yume-chan/struct";
|
|
||||||
|
|
10
toolchain/side-effect-test/src/scrcpy.js
Normal file
10
toolchain/side-effect-test/src/scrcpy.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
// Generated by toolchain/side-effect-test/generate.mjs
|
||||||
|
// DO NOT MODIFY THIS FILE MANUALLY
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import { AndroidAvcLevel, AndroidAvcProfile, AndroidHevcLevel, AndroidHevcProfile, AndroidKeyCode, AndroidKeyEventAction, AndroidKeyEventMeta, AndroidKeyNames, AndroidMotionEventAction, AndroidMotionEventButton, AndroidScreenPowerMode, DefaultServerPath, EmptyControlMessage, ScrcpyAudioCodec, ScrcpyBackOrScreenOnControlMessage, ScrcpyCaptureOrientation, ScrcpyCodecOptions, ScrcpyControlMessageSerializer, ScrcpyControlMessageType, ScrcpyControlMessageWriter, ScrcpyCrop, ScrcpyDeviceMessageParsers, ScrcpyInjectKeyCodeControlMessage, ScrcpyInjectScrollControlMessage, ScrcpyInjectTextControlMessage, ScrcpyInjectTouchControlMessage, ScrcpyInstanceId, ScrcpyLockOrientation, ScrcpyNewDisplay, ScrcpyOptions1_15, ScrcpyOptions1_15_1, ScrcpyOptions1_16, ScrcpyOptions1_17, ScrcpyOptions1_18, ScrcpyOptions1_19, ScrcpyOptions1_20, ScrcpyOptions1_21, ScrcpyOptions1_22, ScrcpyOptions1_23, ScrcpyOptions1_24, ScrcpyOptions1_25, ScrcpyOptions2_0, ScrcpyOptions2_1, ScrcpyOptions2_1_1, ScrcpyOptions2_2, ScrcpyOptions2_3, ScrcpyOptions2_3_1, ScrcpyOptions2_4, ScrcpyOptions2_5, ScrcpyOptions2_6, ScrcpyOptions2_6_1, ScrcpyOptions2_7, ScrcpyOptions3_0, ScrcpyOptions3_0_1, ScrcpyOptions3_0_2, ScrcpyOptions3_1, ScrcpyOptions3_2, ScrcpyOptions3_3, ScrcpyOptions3_3_1, ScrcpyOptions3_3_2, ScrcpyOptionsLatest, ScrcpyOrientation, ScrcpyPointerId, ScrcpySetClipboardControlMessage, ScrcpySetDisplayPowerControlMessage, ScrcpyUHidCreateControlMessage, ScrcpyUHidOutputDeviceMessage, ScrcpyVideoCodecId, ScrcpyVideoCodecNameMap, ScrcpyVideoSizeImpl, clamp, isScrcpyOptionValue, omit, toScrcpyOptionValue } from "@yume-chan/scrcpy";
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
console.log(AndroidAvcLevel, AndroidAvcProfile, AndroidHevcLevel, AndroidHevcProfile, AndroidKeyCode, AndroidKeyEventAction, AndroidKeyEventMeta, AndroidKeyNames, AndroidMotionEventAction, AndroidMotionEventButton, AndroidScreenPowerMode, DefaultServerPath, EmptyControlMessage, ScrcpyAudioCodec, ScrcpyBackOrScreenOnControlMessage, ScrcpyCaptureOrientation, ScrcpyCodecOptions, ScrcpyControlMessageSerializer, ScrcpyControlMessageType, ScrcpyControlMessageWriter, ScrcpyCrop, ScrcpyDeviceMessageParsers, ScrcpyInjectKeyCodeControlMessage, ScrcpyInjectScrollControlMessage, ScrcpyInjectTextControlMessage, ScrcpyInjectTouchControlMessage, ScrcpyInstanceId, ScrcpyLockOrientation, ScrcpyNewDisplay, ScrcpyOptions1_15, ScrcpyOptions1_15_1, ScrcpyOptions1_16, ScrcpyOptions1_17, ScrcpyOptions1_18, ScrcpyOptions1_19, ScrcpyOptions1_20, ScrcpyOptions1_21, ScrcpyOptions1_22, ScrcpyOptions1_23, ScrcpyOptions1_24, ScrcpyOptions1_25, ScrcpyOptions2_0, ScrcpyOptions2_1, ScrcpyOptions2_1_1, ScrcpyOptions2_2, ScrcpyOptions2_3, ScrcpyOptions2_3_1, ScrcpyOptions2_4, ScrcpyOptions2_5, ScrcpyOptions2_6, ScrcpyOptions2_6_1, ScrcpyOptions2_7, ScrcpyOptions3_0, ScrcpyOptions3_0_1, ScrcpyOptions3_0_2, ScrcpyOptions3_1, ScrcpyOptions3_2, ScrcpyOptions3_3, ScrcpyOptions3_3_1, ScrcpyOptions3_3_2, ScrcpyOptionsLatest, ScrcpyOrientation, ScrcpyPointerId, ScrcpySetClipboardControlMessage, ScrcpySetDisplayPowerControlMessage, ScrcpyUHidCreateControlMessage, ScrcpyUHidOutputDeviceMessage, ScrcpyVideoCodecId, ScrcpyVideoCodecNameMap, ScrcpyVideoSizeImpl, clamp, isScrcpyOptionValue, omit, toScrcpyOptionValue)
|
||||||
|
}
|
39
toolchain/side-effect-test/src/struct.js
Normal file
39
toolchain/side-effect-test/src/struct.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import {
|
||||||
|
bipedal,
|
||||||
|
buffer,
|
||||||
|
concat,
|
||||||
|
decodeUtf8,
|
||||||
|
encodeUtf8,
|
||||||
|
extend,
|
||||||
|
s16,
|
||||||
|
s32,
|
||||||
|
s64,
|
||||||
|
s8,
|
||||||
|
string,
|
||||||
|
struct,
|
||||||
|
u16,
|
||||||
|
u32,
|
||||||
|
u64,
|
||||||
|
u8,
|
||||||
|
} from "@yume-chan/struct";
|
||||||
|
|
||||||
|
bipedal(function* () {});
|
||||||
|
buffer(u8);
|
||||||
|
decodeUtf8(new Uint8Array());
|
||||||
|
encodeUtf8("");
|
||||||
|
s16(1);
|
||||||
|
s32(1);
|
||||||
|
s64(1);
|
||||||
|
s8(1);
|
||||||
|
string(1);
|
||||||
|
u16(1);
|
||||||
|
u32(1);
|
||||||
|
u64(1);
|
||||||
|
u8(1);
|
||||||
|
struct({}, { littleEndian: true });
|
||||||
|
concat(
|
||||||
|
{ littleEndian: true },
|
||||||
|
struct({ a: u8 }, { littleEndian: true }),
|
||||||
|
struct({ b: u8 }, { littleEndian: true }),
|
||||||
|
);
|
||||||
|
extend(struct({ a: u16 }, { littleEndian: true }), { b: buffer(32) });
|
Loading…
Add table
Add a link
Reference in a new issue