use new event channel for mobile and web
This commit is contained in:
parent
85a2a7cd44
commit
a7af7967f6
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,3 +19,4 @@ flutter_hbb
|
|||||||
web_hbb
|
web_hbb
|
||||||
sciter.dll
|
sciter.dll
|
||||||
**pdb
|
**pdb
|
||||||
|
src/bridge_generated.rs
|
211
Cargo.lock
generated
211
Cargo.lock
generated
@ -38,6 +38,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allo-isolate"
|
||||||
|
version = "0.1.13-beta.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c1a52c9b965fdaf940102bcb1a0aef4bc2f56489056f5872cef705651c7972e"
|
||||||
|
dependencies = [
|
||||||
|
"atomic",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alsa"
|
name = "alsa"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@ -226,6 +235,15 @@ dependencies = [
|
|||||||
"system-deps 6.0.2",
|
"system-deps 6.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -401,6 +419,56 @@ dependencies = [
|
|||||||
"nix 0.18.0",
|
"nix 0.18.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "camino"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07fd178c5af4d59e83498ef15cf3f154e1a6f9d091270cb86283c65ef44e9ef0"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.136",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo-platform"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.136",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
||||||
|
dependencies = [
|
||||||
|
"camino",
|
||||||
|
"cargo-platform",
|
||||||
|
"semver 1.0.9",
|
||||||
|
"serde 1.0.136",
|
||||||
|
"serde_json 1.0.79",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cbindgen"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b6d248e3ca02f3fbfabcb9284464c596baec223a26d91bbf44a5a62ddb0d900"
|
||||||
|
dependencies = [
|
||||||
|
"clap 3.1.12",
|
||||||
|
"heck 0.4.0",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde 1.0.136",
|
||||||
|
"serde_json 1.0.79",
|
||||||
|
"syn",
|
||||||
|
"tempfile",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.73"
|
||||||
@ -631,6 +699,12 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -1250,6 +1324,18 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum_dispatch"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eb359f1476bf611266ac1f5355bc14aeca37b299d0ebccc038ee7058891c9cb"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@ -1374,6 +1460,52 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flutter_rust_bridge"
|
||||||
|
version = "1.30.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7e7e4af55d6a36aad9573737a12fba774999e4d6dd5e668e29c25bb473f85f3"
|
||||||
|
dependencies = [
|
||||||
|
"allo-isolate",
|
||||||
|
"anyhow",
|
||||||
|
"flutter_rust_bridge_macros",
|
||||||
|
"lazy_static",
|
||||||
|
"parking_lot 0.12.0",
|
||||||
|
"threadpool",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flutter_rust_bridge_codegen"
|
||||||
|
version = "1.30.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3209735fd687b06b8d770ec008874119b91f7f46b4a73d17226d5c337435bb74"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"cargo_metadata",
|
||||||
|
"cbindgen",
|
||||||
|
"convert_case",
|
||||||
|
"enum_dispatch",
|
||||||
|
"env_logger 0.9.0",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"pathdiff",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"serde 1.0.136",
|
||||||
|
"serde_yaml",
|
||||||
|
"structopt",
|
||||||
|
"syn",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flutter_rust_bridge_macros"
|
||||||
|
version = "1.30.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69ffbd9713edad524e45f415a997dd05af6a67fd2ed3aa19fa85159835d85fbc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -2438,6 +2570,12 @@ dependencies = [
|
|||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
@ -3175,6 +3313,12 @@ version = "1.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
|
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peeking_take_while"
|
name = "peeking_take_while"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@ -3894,7 +4038,7 @@ version = "0.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver",
|
"semver 0.11.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3919,6 +4063,8 @@ dependencies = [
|
|||||||
"dispatch",
|
"dispatch",
|
||||||
"enigo",
|
"enigo",
|
||||||
"flexi_logger",
|
"flexi_logger",
|
||||||
|
"flutter_rust_bridge",
|
||||||
|
"flutter_rust_bridge_codegen",
|
||||||
"hbb_common",
|
"hbb_common",
|
||||||
"hound",
|
"hound",
|
||||||
"include_dir",
|
"include_dir",
|
||||||
@ -4167,6 +4313,15 @@ dependencies = [
|
|||||||
"semver-parser",
|
"semver-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.136",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver-parser"
|
name = "semver-parser"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
@ -4237,6 +4392,18 @@ dependencies = [
|
|||||||
"serde 1.0.136",
|
"serde 1.0.136",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.8.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"ryu",
|
||||||
|
"serde 1.0.136",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
@ -4391,6 +4558,30 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structopt"
|
||||||
|
version = "0.3.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||||
|
dependencies = [
|
||||||
|
"clap 2.34.0",
|
||||||
|
"lazy_static",
|
||||||
|
"structopt-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structopt-derive"
|
||||||
|
version = "0.4.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||||
|
dependencies = [
|
||||||
|
"heck 0.3.3",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
@ -4566,6 +4757,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "threadpool"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||||
|
dependencies = [
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@ -5456,6 +5656,15 @@ version = "0.8.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.9.2+zstd.1.5.1"
|
version = "0.9.2+zstd.1.5.1"
|
||||||
|
@ -99,6 +99,9 @@ async-process = "1.3"
|
|||||||
android_logger = "0.11"
|
android_logger = "0.11"
|
||||||
jni = "0.19.0"
|
jni = "0.19.0"
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
|
||||||
|
flutter_rust_bridge = "1.30.0"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display"]
|
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display"]
|
||||||
|
|
||||||
@ -114,6 +117,7 @@ winapi = { version = "0.3", features = [ "winnt" ] }
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0"
|
cc = "1.0"
|
||||||
hbb_common = { path = "libs/hbb_common" }
|
hbb_common = { path = "libs/hbb_common" }
|
||||||
|
flutter_rust_bridge_codegen = "1.30.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hound = "3.4"
|
hound = "3.4"
|
||||||
|
17
build.rs
17
build.rs
@ -62,12 +62,29 @@ fn install_oboe() {
|
|||||||
//cc::Build::new().file("oboe.cc").include(include).compile("oboe_wrapper");
|
//cc::Build::new().file("oboe.cc").include(include).compile("oboe_wrapper");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_flutter_rust_bridge() {
|
||||||
|
// Tell Cargo that if the given file changes, to rerun this build script.
|
||||||
|
println!("cargo:rerun-if-changed=src/mobile_ffi.rs");
|
||||||
|
// settings for fbr_codegen
|
||||||
|
let opts = lib_flutter_rust_bridge_codegen::Opts {
|
||||||
|
// Path of input Rust code
|
||||||
|
rust_input: "src/mobile_ffi.rs".to_string(),
|
||||||
|
// Path of output generated Dart code
|
||||||
|
dart_output: "flutter/lib/generated_bridge.dart".to_string(),
|
||||||
|
// for other options lets use default
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
// run fbr_codegen
|
||||||
|
lib_flutter_rust_bridge_codegen::frb_codegen(opts).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
hbb_common::gen_version();
|
hbb_common::gen_version();
|
||||||
install_oboe();
|
install_oboe();
|
||||||
// there is problem with cfg(target_os) in build.rs, so use our workaround
|
// there is problem with cfg(target_os) in build.rs, so use our workaround
|
||||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||||
if target_os == "android" || target_os == "ios" {
|
if target_os == "android" || target_os == "ios" {
|
||||||
|
gen_flutter_rust_bridge();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#[cfg(all(windows, feature = "inline"))]
|
#[cfg(all(windows, feature = "inline"))]
|
||||||
|
3
flutter/.gitignore
vendored
3
flutter/.gitignore
vendored
@ -42,3 +42,6 @@ app.*.map.json
|
|||||||
jniLibs
|
jniLibs
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# flutter rust bridge
|
||||||
|
lib/generated_bridge.dart
|
@ -120,11 +120,9 @@ class FfiModel with ChangeNotifier {
|
|||||||
_permissions.clear();
|
_permissions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(String peerId) {
|
void updateEventListener(String peerId) {
|
||||||
var pos;
|
final void Function(Map<String, dynamic>) cb = (evt) {
|
||||||
for (;;) {
|
var pos;
|
||||||
var evt = FFI.popEvent();
|
|
||||||
if (evt == null) break;
|
|
||||||
var name = evt['name'];
|
var name = evt['name'];
|
||||||
if (name == 'msgbox') {
|
if (name == 'msgbox') {
|
||||||
handleMsgBox(evt, peerId);
|
handleMsgBox(evt, peerId);
|
||||||
@ -165,31 +163,33 @@ class FfiModel with ChangeNotifier {
|
|||||||
} else if (name == 'on_client_remove') {
|
} else if (name == 'on_client_remove') {
|
||||||
FFI.serverModel.onClientRemove(evt);
|
FFI.serverModel.onClientRemove(evt);
|
||||||
}
|
}
|
||||||
}
|
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
|
||||||
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
|
if (!_decoding) {
|
||||||
if (!_decoding) {
|
var rgba = PlatformFFI.getRgba();
|
||||||
var rgba = PlatformFFI.getRgba();
|
if (rgba != null) {
|
||||||
if (rgba != null) {
|
if (_waitForImage) {
|
||||||
if (_waitForImage) {
|
_waitForImage = false;
|
||||||
_waitForImage = false;
|
SmartDialog.dismiss();
|
||||||
SmartDialog.dismiss();
|
|
||||||
}
|
|
||||||
_decoding = true;
|
|
||||||
final pid = FFI.id;
|
|
||||||
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
|
|
||||||
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888, (image) {
|
|
||||||
PlatformFFI.clearRgbaFrame();
|
|
||||||
_decoding = false;
|
|
||||||
if (FFI.id != pid) return;
|
|
||||||
try {
|
|
||||||
// my throw exception, because the listener maybe already dispose
|
|
||||||
FFI.imageModel.update(image);
|
|
||||||
} catch (e) {
|
|
||||||
print('update image: $e');
|
|
||||||
}
|
}
|
||||||
});
|
_decoding = true;
|
||||||
|
final pid = FFI.id;
|
||||||
|
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
|
||||||
|
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888,
|
||||||
|
(image) {
|
||||||
|
PlatformFFI.clearRgbaFrame();
|
||||||
|
_decoding = false;
|
||||||
|
if (FFI.id != pid) return;
|
||||||
|
try {
|
||||||
|
// my throw exception, because the listener maybe already dispose
|
||||||
|
FFI.imageModel.update(image);
|
||||||
|
} catch (e) {
|
||||||
|
print('update image: $e');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
PlatformFFI.setEventCallback(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSwitchDisplay(Map<String, dynamic> evt) {
|
void handleSwitchDisplay(Map<String, dynamic> evt) {
|
||||||
@ -214,7 +214,6 @@ class FfiModel with ChangeNotifier {
|
|||||||
enterPasswordDialog(id);
|
enterPasswordDialog(id);
|
||||||
} else {
|
} else {
|
||||||
var hasRetry = evt['hasRetry'] == 'true';
|
var hasRetry = evt['hasRetry'] == 'true';
|
||||||
print(evt);
|
|
||||||
showMsgBox(type, title, text, hasRetry);
|
showMsgBox(type, title, text, hasRetry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
@ -7,6 +8,7 @@ import 'package:device_info/device_info.dart';
|
|||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info/package_info.dart';
|
||||||
import 'package:external_path/external_path.dart';
|
import 'package:external_path/external_path.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import '../generated_bridge.dart';
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
|
|
||||||
class RgbaFrame extends Struct {
|
class RgbaFrame extends Struct {
|
||||||
@ -28,6 +30,7 @@ class PlatformFFI {
|
|||||||
static F3? _setByName;
|
static F3? _setByName;
|
||||||
static F4? _freeRgba;
|
static F4? _freeRgba;
|
||||||
static F5? _getRgba;
|
static F5? _getRgba;
|
||||||
|
static void Function(Map<String, dynamic>)? _eventCallback;
|
||||||
|
|
||||||
static void clearRgbaFrame() {
|
static void clearRgbaFrame() {
|
||||||
if (_lastRgbaFrame != null &&
|
if (_lastRgbaFrame != null &&
|
||||||
@ -86,6 +89,7 @@ class PlatformFFI {
|
|||||||
.lookupFunction<Void Function(Pointer<RgbaFrame>), F4>('free_rgba');
|
.lookupFunction<Void Function(Pointer<RgbaFrame>), F4>('free_rgba');
|
||||||
_getRgba = dylib.lookupFunction<F5, F5>('get_rgba');
|
_getRgba = dylib.lookupFunction<F5, F5>('get_rgba');
|
||||||
_dir = (await getApplicationDocumentsDirectory()).path;
|
_dir = (await getApplicationDocumentsDirectory()).path;
|
||||||
|
_startListenEvent(RustdeskImpl(dylib));
|
||||||
try {
|
try {
|
||||||
_homeDir = (await ExternalPath.getExternalStorageDirectories())[0];
|
_homeDir = (await ExternalPath.getExternalStorageDirectories())[0];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -115,6 +119,23 @@ class PlatformFFI {
|
|||||||
version = await getVersion();
|
version = await getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _startListenEvent(RustdeskImpl rustdeskImpl) async {
|
||||||
|
await for (final message in rustdeskImpl.startEventStream()) {
|
||||||
|
if (_eventCallback != null) {
|
||||||
|
try {
|
||||||
|
Map<String, dynamic> event = json.decode(message);
|
||||||
|
_eventCallback!(event);
|
||||||
|
} catch (e) {
|
||||||
|
print('json.decode fail(): $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
|
||||||
|
_eventCallback = fun;
|
||||||
|
}
|
||||||
|
|
||||||
static void startDesktopWebListener() {}
|
static void startDesktopWebListener() {}
|
||||||
|
|
||||||
static void stopDesktopWebListener() {}
|
static void stopDesktopWebListener() {}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:dash_chat/dash_chat.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
@ -11,7 +10,6 @@ const loginDialogTag = "LOGIN";
|
|||||||
final _emptyIdShow = translate("Generating ...");
|
final _emptyIdShow = translate("Generating ...");
|
||||||
|
|
||||||
class ServerModel with ChangeNotifier {
|
class ServerModel with ChangeNotifier {
|
||||||
Timer? _interval;
|
|
||||||
bool _isStart = false; // Android MainService status
|
bool _isStart = false; // Android MainService status
|
||||||
bool _mediaOk = false;
|
bool _mediaOk = false;
|
||||||
bool _inputOk = false;
|
bool _inputOk = false;
|
||||||
@ -201,10 +199,7 @@ class ServerModel with ChangeNotifier {
|
|||||||
_isStart = true;
|
_isStart = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
FFI.setByName("ensure_init_event_queue");
|
FFI.setByName("ensure_init_event_queue");
|
||||||
_interval?.cancel();
|
FFI.ffiModel.updateEventListener("");
|
||||||
_interval = Timer.periodic(Duration(milliseconds: 30), (timer) {
|
|
||||||
FFI.ffiModel.update("");
|
|
||||||
});
|
|
||||||
await FFI.invokeMethod("init_service");
|
await FFI.invokeMethod("init_service");
|
||||||
FFI.setByName("start_service");
|
FFI.setByName("start_service");
|
||||||
getIDPasswd();
|
getIDPasswd();
|
||||||
@ -214,8 +209,6 @@ class ServerModel with ChangeNotifier {
|
|||||||
|
|
||||||
Future<Null> stopService() async {
|
Future<Null> stopService() async {
|
||||||
_isStart = false;
|
_isStart = false;
|
||||||
_interval?.cancel();
|
|
||||||
_interval = null;
|
|
||||||
FFI.serverModel.closeAll();
|
FFI.serverModel.closeAll();
|
||||||
await FFI.invokeMethod("stop_service");
|
await FFI.invokeMethod("stop_service");
|
||||||
FFI.setByName("stop_service");
|
FFI.setByName("stop_service");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:js' as js;
|
import 'dart:js';
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
@ -7,39 +8,46 @@ import 'dart:async';
|
|||||||
|
|
||||||
final List<StreamSubscription<MouseEvent>> mouseListeners = [];
|
final List<StreamSubscription<MouseEvent>> mouseListeners = [];
|
||||||
final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
|
final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
|
||||||
int lastMouseDownButtons = 0;
|
|
||||||
bool mouseIn = false;
|
|
||||||
|
|
||||||
class PlatformFFI {
|
class PlatformFFI {
|
||||||
static void clearRgbaFrame() {}
|
static void clearRgbaFrame() {}
|
||||||
|
|
||||||
static Uint8List? getRgba() {
|
static Uint8List? getRgba() {
|
||||||
return js.context.callMethod('getRgba');
|
return context.callMethod('getRgba');
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getByName(String name, [String arg = '']) {
|
static String getByName(String name, [String arg = '']) {
|
||||||
return js.context.callMethod('getByName', [name, arg]);
|
return context.callMethod('getByName', [name, arg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setByName(String name, [String value = '']) {
|
static void setByName(String name, [String value = '']) {
|
||||||
js.context.callMethod('setByName', [name, value]);
|
context.callMethod('setByName', [name, value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Null> init() async {
|
static Future<Null> init() async {
|
||||||
isWeb = true;
|
isWeb = true;
|
||||||
isDesktop = !js.context.callMethod('isMobile');
|
isDesktop = !context.callMethod('isMobile');
|
||||||
js.context.callMethod('init');
|
context.callMethod('init');
|
||||||
version = getByName('version');
|
version = getByName('version');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
|
||||||
|
context["onGlobalEvent"] = (String message) {
|
||||||
|
try {
|
||||||
|
Map<String, dynamic> event = json.decode(message);
|
||||||
|
fun(event);
|
||||||
|
} catch (e) {
|
||||||
|
print('json.decode fail(): $e');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static void startDesktopWebListener() {
|
static void startDesktopWebListener() {
|
||||||
mouseIn = true;
|
|
||||||
mouseListeners.add(
|
mouseListeners.add(
|
||||||
window.document.onContextMenu.listen((evt) => evt.preventDefault()));
|
window.document.onContextMenu.listen((evt) => evt.preventDefault()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stopDesktopWebListener() {
|
static void stopDesktopWebListener() {
|
||||||
mouseIn = true;
|
|
||||||
mouseListeners.forEach((l) {
|
mouseListeners.forEach((l) {
|
||||||
l.cancel();
|
l.cancel();
|
||||||
});
|
});
|
||||||
|
@ -22,25 +22,19 @@ class FileManagerPage extends StatefulWidget {
|
|||||||
class _FileManagerPageState extends State<FileManagerPage> {
|
class _FileManagerPageState extends State<FileManagerPage> {
|
||||||
final model = FFI.fileModel;
|
final model = FFI.fileModel;
|
||||||
final _selectedItems = SelectedItems();
|
final _selectedItems = SelectedItems();
|
||||||
Timer? _interval;
|
|
||||||
final _breadCrumbScroller = ScrollController();
|
final _breadCrumbScroller = ScrollController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
FFI.connect(widget.id, isFileTransfer: true);
|
FFI.connect(widget.id, isFileTransfer: true);
|
||||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
FFI.ffiModel.updateEventListener(widget.id);
|
||||||
showLoading(translate('Connecting...'));
|
|
||||||
_interval = Timer.periodic(Duration(milliseconds: 30),
|
|
||||||
(timer) => FFI.ffiModel.update(widget.id));
|
|
||||||
});
|
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
model.onClose();
|
model.onClose();
|
||||||
_interval?.cancel();
|
|
||||||
FFI.close();
|
FFI.close();
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
Wakelock.disable();
|
Wakelock.disable();
|
||||||
|
@ -53,6 +53,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
});
|
});
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
_physicalFocusNode.requestFocus();
|
_physicalFocusNode.requestFocus();
|
||||||
|
FFI.ffiModel.updateEventListener(widget.id);
|
||||||
FFI.listenToMouse(true);
|
FFI.listenToMouse(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +100,6 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
FFI.ffiModel.update(widget.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void interval() {
|
void interval() {
|
||||||
|
@ -223,6 +223,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6"
|
version: "2.0.6"
|
||||||
|
flutter_rust_bridge:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_rust_bridge
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.30.0"
|
||||||
flutter_smart_dialog:
|
flutter_smart_dialog:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -738,5 +745,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.0"
|
version: "0.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.16.0 <3.0.0"
|
dart: ">=2.16.1 <3.0.0"
|
||||||
flutter: ">=2.10.0"
|
flutter: ">=2.10.0"
|
||||||
|
@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.1.10+27
|
version: 1.1.10+27
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.16.1 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
@ -53,6 +53,7 @@ dependencies:
|
|||||||
flutter_smart_dialog:
|
flutter_smart_dialog:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Heap-Hop/flutter_smart_dialog.git
|
url: https://github.com/Heap-Hop/flutter_smart_dialog.git
|
||||||
|
flutter_rust_bridge: ^1.30.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_launcher_icons: ^0.9.1
|
flutter_launcher_icons: ^0.9.1
|
||||||
|
5
flutter/web/.gitignore
vendored
5
flutter/web/.gitignore
vendored
@ -2,3 +2,8 @@ assets
|
|||||||
js/src/gen_js_from_hbb.ts
|
js/src/gen_js_from_hbb.ts
|
||||||
js/src/message.ts
|
js/src/message.ts
|
||||||
js/src/rendezvous.ts
|
js/src/rendezvous.ts
|
||||||
|
ogvjs-1.8.6
|
||||||
|
libopus.js
|
||||||
|
libopus.wasm
|
||||||
|
yuv-canvas-1.2.6.js
|
||||||
|
.yarn
|
@ -1 +0,0 @@
|
|||||||
<svg viewBox="0 0 375 375" style="width:32px;height:32px;margin:0 4px 4px 0" xmlns="http://www.w3.org/2000/svg"><rect transform="matrix(.91553 0 0 .91553 -152.92 116.76)" x="167.03" y="-127.54" width="409.6" height="409.6" rx="64" ry="64" fill="#0071ff"></rect><path d="M150.428 322.264c-29.063-6.202-53.897-22.439-73.115-47.804-19.507-25.746-27.838-55.355-25.723-91.414 6.655-62.013 47.667-106.753 99.687-120.411 4.509-.989 8.353-3.462 12.55-1.322 3.22 1.64 6.028 4.467 7.206 7.251 1.25 2.955 1.877 21.54.99 29.331-1.076 9.46-3.877 12.418-14.566 15.388-29.723 10.195-48.105 34.07-53.697 61.017-4.8 29.668 2.951 59.729 21.528 78.727 8.966 8.993 17.92 14.24 30.869 18.086 8.646 2.57 13.393 5.758 15.036 10.102 1.085 2.867 1.63 22.984.779 28.772-1.33 9.046-1.702 9.796-5.792 11.667-5.029 2.3-7.404 2.392-15.752.61zm50.708.29c-3.092-1.402-5.673-4.83-6.73-8.94-.134-9.408-2.366-25.754 1.02-33.373 1.88-4.128 4.65-5.999 12.433-8.396 21.267-6.551 37.593-19.88 46.806-38.213 11.11-22.108 11.877-55.183 1.808-77.975-9.154-20.723-25.7-35.217-48.555-42.534-8.872-2.84-12.004-5.065-12.968-9.21-1.002-4.31-1.435-19.87-.785-28.218.682-8.766 1.249-9.99 6.162-13.318 3.701-2.505 5.482-2.446 17.223.575 36.718 10.077 65.97 33.597 83.026 66.68 18.495 37.034 19.191 86.11 1.742 122.655-17.233 36.09-50.591 62.511-88.622 70.194-8.172 1.65-9.07 1.656-12.56.073z" fill="#fff"></path></svg>
|
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1 +0,0 @@
|
|||||||
#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50;margin-top:60px}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -33,8 +33,8 @@
|
|||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<script src="ogvjs-1.8.6/ogv.js"></script>
|
<script src="ogvjs-1.8.6/ogv.js"></script>
|
||||||
<script src="yuv.js"></script>
|
<script src="yuv.js"></script>
|
||||||
<script type="module" crossorigin src="assets/index.a0538fcc.js"></script>
|
<script type="module" crossorigin src="js/dist/index.js"></script>
|
||||||
<link rel="modulepreload" href="assets/vendor.32e42528.js">
|
<link rel="modulepreload" href="js/dist/vendor.js">
|
||||||
<script src="yuv-canvas-1.2.6.js"></script>
|
<script src="yuv-canvas-1.2.6.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.loading {
|
.loading {
|
||||||
|
1
flutter/web/js/.yarnrc.yml
Normal file
1
flutter/web/js/.yarnrc.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
nodeLinker: node-modules
|
@ -7,7 +7,6 @@ import { initZstd, translate } from "./common";
|
|||||||
import PCMPlayer from "pcm-player";
|
import PCMPlayer from "pcm-player";
|
||||||
|
|
||||||
var currentFrame = undefined;
|
var currentFrame = undefined;
|
||||||
var events = [];
|
|
||||||
|
|
||||||
window.curConn = undefined;
|
window.curConn = undefined;
|
||||||
window.getRgba = () => {
|
window.getRgba = () => {
|
||||||
@ -25,11 +24,10 @@ export function isDesktop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function msgbox(type, title, text) {
|
export function msgbox(type, title, text) {
|
||||||
if (!events) return;
|
|
||||||
if (!type || (type == 'error' && !text)) return;
|
if (!type || (type == 'error' && !text)) return;
|
||||||
const text2 = text.toLowerCase();
|
const text2 = text.toLowerCase();
|
||||||
var hasRetry = checkIfRetry(type, title, text) ? 'true' : '';
|
var hasRetry = checkIfRetry(type, title, text) ? 'true' : '';
|
||||||
events.push({ name: 'msgbox', type, title, text, hasRetry });
|
onGlobalEvent(JSON.stringify({ name: 'msgbox', type, title, text, hasRetry }));
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsonfyForDart(payload) {
|
function jsonfyForDart(payload) {
|
||||||
@ -42,10 +40,9 @@ function jsonfyForDart(payload) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function pushEvent(name, payload) {
|
export function pushEvent(name, payload) {
|
||||||
if (!events) return;
|
|
||||||
payload = jsonfyForDart(payload);
|
payload = jsonfyForDart(payload);
|
||||||
payload.name = name;
|
payload.name = name;
|
||||||
events.push(payload);
|
onGlobalEvent(JSON.stringify(payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
let yuvWorker;
|
let yuvWorker;
|
||||||
@ -120,7 +117,6 @@ export function getConn() {
|
|||||||
|
|
||||||
export async function startConn(id) {
|
export async function startConn(id) {
|
||||||
currentFrame = undefined;
|
currentFrame = undefined;
|
||||||
events = [];
|
|
||||||
setByName('remote_id', id);
|
setByName('remote_id', id);
|
||||||
await curConn.start(id);
|
await curConn.start(id);
|
||||||
}
|
}
|
||||||
@ -129,7 +125,6 @@ export function close() {
|
|||||||
getConn()?.close();
|
getConn()?.close();
|
||||||
setConn(undefined);
|
setConn(undefined);
|
||||||
currentFrame = undefined;
|
currentFrame = undefined;
|
||||||
events = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function newConn() {
|
export function newConn() {
|
||||||
@ -310,13 +305,6 @@ function _getByName(name, arg) {
|
|||||||
return localStorage.getItem('remote-id');
|
return localStorage.getItem('remote-id');
|
||||||
case 'remember':
|
case 'remember':
|
||||||
return curConn.getRemember();
|
return curConn.getRemember();
|
||||||
case 'event':
|
|
||||||
if (events && events.length) {
|
|
||||||
const e = events[0];
|
|
||||||
events.splice(0, 1);
|
|
||||||
return JSON.stringify(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'toggle_option':
|
case 'toggle_option':
|
||||||
return curConn.getOption(arg) || false;
|
return curConn.getOption(arg) || false;
|
||||||
case 'option':
|
case 'option':
|
||||||
|
14
flutter/web/js/vite.config.js
Normal file
14
flutter/web/js/vite.config.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
manifest: false,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
entryFileNames: `[name].js`,
|
||||||
|
chunkFileNames: `[name].js`,
|
||||||
|
assetFileNames: `[name].[ext]`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
File diff suppressed because it is too large
Load Diff
13
src/lib.rs
13
src/lib.rs
@ -1,8 +1,10 @@
|
|||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
|
/// cbindgen:ignore
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service};
|
pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service};
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
|
/// cbindgen:ignore
|
||||||
mod server;
|
mod server;
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
pub use self::server::*;
|
pub use self::server::*;
|
||||||
@ -11,29 +13,32 @@ mod client;
|
|||||||
mod rendezvous_mediator;
|
mod rendezvous_mediator;
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
pub use self::rendezvous_mediator::*;
|
pub use self::rendezvous_mediator::*;
|
||||||
|
/// cbindgen:ignore
|
||||||
pub mod common;
|
pub mod common;
|
||||||
#[cfg(not(any( target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
pub mod ipc;
|
pub mod ipc;
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
mod version;
|
mod version;
|
||||||
pub use version::*;
|
pub use version::*;
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
mod bridge_generated;
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
pub mod mobile;
|
pub mod mobile;
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
pub mod mobile_ffi;
|
pub mod mobile_ffi;
|
||||||
use common::*;
|
use common::*;
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
|
||||||
mod port_forward;
|
|
||||||
#[cfg(all(windows, feature = "hbbs"))]
|
#[cfg(all(windows, feature = "hbbs"))]
|
||||||
mod hbbs;
|
mod hbbs;
|
||||||
|
mod lang;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod license;
|
mod license;
|
||||||
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
mod port_forward;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod tray;
|
mod tray;
|
||||||
mod lang;
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub mod clipboard_file;
|
pub mod clipboard_file;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::client::*;
|
use crate::client::*;
|
||||||
|
use flutter_rust_bridge::StreamSink;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err,
|
allow_err,
|
||||||
compress::decompress,
|
compress::decompress,
|
||||||
@ -21,6 +22,7 @@ use std::{
|
|||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref SESSION: Arc<RwLock<Option<Session>>> = Default::default();
|
static ref SESSION: Arc<RwLock<Option<Session>>> = Default::default();
|
||||||
|
pub static ref EVENT_STREAM: RwLock<Option<StreamSink<String>>> = Default::default(); // rust to dart channel
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -214,10 +216,10 @@ impl Session {
|
|||||||
let mut h: HashMap<&str, &str> = event.iter().cloned().collect();
|
let mut h: HashMap<&str, &str> = event.iter().cloned().collect();
|
||||||
assert!(h.get("name").is_none());
|
assert!(h.get("name").is_none());
|
||||||
h.insert("name", name);
|
h.insert("name", name);
|
||||||
self.events2ui
|
|
||||||
.write()
|
if let Some(s) = EVENT_STREAM.read().unwrap().as_ref() {
|
||||||
.unwrap()
|
s.add(serde_json::ser::to_string(&h).unwrap_or("".to_owned()));
|
||||||
.push_back(serde_json::ser::to_string(&h).unwrap_or("".to_owned()));
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -255,7 +257,15 @@ impl Session {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_key(name: &str, down: bool, press: bool, alt: bool, ctrl: bool, shift: bool, command: bool) {
|
pub fn input_key(
|
||||||
|
name: &str,
|
||||||
|
down: bool,
|
||||||
|
press: bool,
|
||||||
|
alt: bool,
|
||||||
|
ctrl: bool,
|
||||||
|
shift: bool,
|
||||||
|
command: bool,
|
||||||
|
) {
|
||||||
if let Some(session) = SESSION.read().unwrap().as_ref() {
|
if let Some(session) = SESSION.read().unwrap().as_ref() {
|
||||||
let chars: Vec<char> = name.chars().collect();
|
let chars: Vec<char> = name.chars().collect();
|
||||||
if chars.len() == 1 {
|
if chars.len() == 1 {
|
||||||
@ -277,7 +287,16 @@ impl Session {
|
|||||||
Self::send_msg_static(msg_out);
|
Self::send_msg_static(msg_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _input_key(&self, key: Key, down: bool, press: bool, alt: bool, ctrl: bool, shift: bool, command: bool) {
|
fn _input_key(
|
||||||
|
&self,
|
||||||
|
key: Key,
|
||||||
|
down: bool,
|
||||||
|
press: bool,
|
||||||
|
alt: bool,
|
||||||
|
ctrl: bool,
|
||||||
|
shift: bool,
|
||||||
|
command: bool,
|
||||||
|
) {
|
||||||
let v = if press {
|
let v = if press {
|
||||||
3
|
3
|
||||||
} else if down {
|
} else if down {
|
||||||
@ -946,16 +965,21 @@ pub fn make_fd_to_json(fd: FileDirectory) -> String {
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub mod connection_manager {
|
pub mod connection_manager {
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
|
sync::{Mutex, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use crate::ipc;
|
use crate::ipc;
|
||||||
use crate::ipc::Data;
|
use crate::ipc::Data;
|
||||||
use crate::server::Connection as Conn;
|
use crate::server::Connection as Conn;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err, log,
|
allow_err,
|
||||||
|
config::Config,
|
||||||
|
fs, log,
|
||||||
|
message_proto::*,
|
||||||
|
protobuf::Message as _,
|
||||||
tokio::{
|
tokio::{
|
||||||
self,
|
self,
|
||||||
sync::mpsc::{UnboundedReceiver, UnboundedSender},
|
sync::mpsc::{UnboundedReceiver, UnboundedSender},
|
||||||
@ -965,6 +989,8 @@ pub mod connection_manager {
|
|||||||
use scrap::android::call_main_service_set_by_name;
|
use scrap::android::call_main_service_set_by_name;
|
||||||
use serde_derive::Serialize;
|
use serde_derive::Serialize;
|
||||||
|
|
||||||
|
use super::EVENT_STREAM;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
struct Client {
|
struct Client {
|
||||||
id: i32,
|
id: i32,
|
||||||
@ -1030,10 +1056,7 @@ pub mod connection_manager {
|
|||||||
log::debug!("call_service_set_by_name fail,{}", e);
|
log::debug!("call_service_set_by_name fail,{}", e);
|
||||||
}
|
}
|
||||||
// send to UI,refresh widget
|
// send to UI,refresh widget
|
||||||
if let Some(session) = Session::get().read().unwrap().as_ref() {
|
push_event("on_client_authorized", vec![("client", &client_json)]);
|
||||||
session
|
|
||||||
.push_event("on_client_authorized", vec![("client", &client_json)]);
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
let client_json = serde_json::to_string(&client).unwrap_or("".into());
|
let client_json = serde_json::to_string(&client).unwrap_or("".into());
|
||||||
// send to Android service,active notification no matter UI is shown or not.
|
// send to Android service,active notification no matter UI is shown or not.
|
||||||
@ -1045,12 +1068,7 @@ pub mod connection_manager {
|
|||||||
log::debug!("call_service_set_by_name fail,{}", e);
|
log::debug!("call_service_set_by_name fail,{}", e);
|
||||||
}
|
}
|
||||||
// send to UI,refresh widget
|
// send to UI,refresh widget
|
||||||
if let Some(session) = Session::get().read().unwrap().as_ref() {
|
push_event("try_start_without_auth", vec![("client", &client_json)]);
|
||||||
session.push_event(
|
|
||||||
"try_start_without_auth",
|
|
||||||
vec![("client", &client_json)],
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
CLIENTS.write().unwrap().insert(id, client);
|
CLIENTS.write().unwrap().insert(id, client);
|
||||||
}
|
}
|
||||||
@ -1072,6 +1090,16 @@ pub mod connection_manager {
|
|||||||
remove_connection(current_id);
|
remove_connection(current_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_event(name: &str, event: Vec<(&str, &str)>) {
|
||||||
|
let mut h: HashMap<&str, &str> = event.iter().cloned().collect();
|
||||||
|
assert!(h.get("name").is_none());
|
||||||
|
h.insert("name", name);
|
||||||
|
|
||||||
|
if let Some(s) = EVENT_STREAM.read().unwrap().as_ref() {
|
||||||
|
s.add(serde_json::ser::to_string(&h).unwrap_or("".to_owned()));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_clients_state() -> String {
|
pub fn get_clients_state() -> String {
|
||||||
let clients = CLIENTS.read().unwrap();
|
let clients = CLIENTS.read().unwrap();
|
||||||
let res = Vec::from_iter(clients.values().cloned());
|
let res = Vec::from_iter(clients.values().cloned());
|
||||||
@ -1115,19 +1143,15 @@ pub mod connection_manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(session) = Session::get().read().unwrap().as_ref() {
|
push_event("on_client_remove", vec![("id", &id.to_string())]);
|
||||||
session.push_event("on_client_remove", vec![("id", &id.to_string())]);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// server mode handle chat from other peers
|
// server mode handle chat from other peers
|
||||||
fn handle_chat(id: i32, text: String) {
|
fn handle_chat(id: i32, text: String) {
|
||||||
if let Some(session) = Session::get().read().unwrap().as_ref() {
|
push_event(
|
||||||
session.push_event(
|
"chat_server_mode",
|
||||||
"chat_server_mode",
|
vec![("id", &id.to_string()), ("text", &text)],
|
||||||
vec![("id", &id.to_string()), ("text", &text)],
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// server mode send chat to peer
|
// server mode send chat to peer
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use crate::client::file_trait::FileManager;
|
use crate::client::file_trait::FileManager;
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
use crate::mobile::connection_manager::{self, get_clients_length, get_clients_state};
|
use crate::mobile::connection_manager::{self, get_clients_length, get_clients_state};
|
||||||
use crate::mobile::{make_fd_to_json, Session};
|
use crate::mobile::{self, make_fd_to_json, Session};
|
||||||
|
use flutter_rust_bridge::StreamSink;
|
||||||
|
use hbb_common::ResultType;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
config::{self, Config, PeerConfig, ONLINE, LocalConfig},
|
config::{self, Config, LocalConfig, PeerConfig, ONLINE},
|
||||||
fs, log,
|
fs, log,
|
||||||
};
|
};
|
||||||
use serde_json::{Number, Value};
|
use serde_json::{Number, Value};
|
||||||
@ -34,6 +35,11 @@ fn initialize(app_dir: &str) {
|
|||||||
crate::common::check_software_update();
|
crate::common::check_software_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn start_event_stream(s: StreamSink<String>) -> ResultType<()> {
|
||||||
|
let _ = mobile::EVENT_STREAM.write().unwrap().insert(s);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *const c_char {
|
unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *const c_char {
|
||||||
let mut res = "".to_owned();
|
let mut res = "".to_owned();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user