├── libs ├── rust-sciter │ ├── src │ │ ├── capi │ │ │ ├── scarchive.rs │ │ │ ├── mod.rs │ │ │ ├── sctiscript.rs │ │ │ ├── schandler.rs │ │ │ ├── scvalue.rs │ │ │ └── sctypes.rs │ │ └── types.rs │ ├── .clippy.toml │ ├── .gitignore │ ├── examples │ │ ├── icon.png │ │ ├── archived.rc │ │ ├── extension.htm │ │ ├── archived.rs │ │ ├── extension │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── extension.rs │ │ ├── threads.rs │ │ ├── fire_event.htm │ │ ├── first.rs │ │ ├── som.htm │ │ ├── fire_event.rs │ │ ├── minimal.rs │ │ ├── download.rs │ │ ├── minimal.htm │ │ ├── interop.htm │ │ ├── threads.htm │ │ ├── video.htm │ │ └── clock.htm │ ├── .rustfmt.toml │ ├── .editorconfig │ ├── serde │ │ ├── Cargo.toml │ │ ├── src │ │ │ ├── error.rs │ │ │ └── lib.rs │ │ └── tests │ │ │ ├── deserialization.rs │ │ │ ├── serialization.rs │ │ │ └── both.rs │ ├── LICENSE │ ├── .appveyor.yml │ ├── Cargo.toml │ ├── .travis.yml │ └── .github │ │ └── workflows │ │ └── cargo.yml ├── enigo │ ├── rustfmt.toml │ ├── src │ │ ├── win │ │ │ ├── mod.rs │ │ │ └── keycodes.rs │ │ └── macos │ │ │ ├── mod.rs │ │ │ └── keycodes.rs │ ├── .vscode │ │ └── launch.json │ ├── examples │ │ ├── dsl.rs │ │ ├── key.rs │ │ ├── keyboard.rs │ │ ├── timer.rs │ │ └── mouse.rs │ ├── .gitignore │ ├── .travis.yml │ ├── .github │ │ └── ISSUE_TEMPLATE │ │ │ ├── question.md │ │ │ ├── feature_request.md │ │ │ └── bug_report.md │ ├── LICENSE │ ├── Cargo.toml │ ├── README.md │ └── build.rs ├── magnum-opus │ ├── .gitignore │ ├── opus_ffi.h │ ├── src │ │ └── opus_ffi.rs │ ├── tests │ │ ├── compile-fail │ │ │ └── repacketize.rs │ │ ├── fec.rs │ │ └── opus-padding.rs │ ├── Cargo.toml │ ├── README.md │ ├── LICENSE-MIT │ └── build.rs ├── parity-tokio-ipc │ ├── .gitignore │ ├── examples │ │ ├── spam-clients.sh │ │ ├── client.rs │ │ └── server.rs │ ├── appveyor.yml │ ├── Cargo.toml │ ├── LICENSE-MIT │ ├── README.md │ └── .travis.yml ├── pulsectl │ ├── .gitignore │ ├── Cargo.toml │ ├── LICENSE.md │ ├── examples │ │ └── change_device_vol.rs │ ├── README.md │ ├── src │ │ ├── controllers │ │ │ └── errors.rs │ │ └── errors.rs │ └── Cargo.lock ├── scrap │ ├── .gitignore │ ├── src │ │ ├── x11 │ │ │ ├── mod.rs │ │ │ ├── display.rs │ │ │ ├── iter.rs │ │ │ ├── server.rs │ │ │ └── capturer.rs │ │ ├── quartz │ │ │ ├── mod.rs │ │ │ ├── display.rs │ │ │ ├── config.rs │ │ │ ├── frame.rs │ │ │ └── capturer.rs │ │ ├── lib.rs │ │ └── common │ │ │ ├── mod.rs │ │ │ ├── vpx.rs │ │ │ ├── x11.rs │ │ │ ├── dxgi.rs │ │ │ └── quartz.rs │ ├── vpx_ffi.h │ ├── examples │ │ ├── list.rs │ │ ├── ffplay.rs │ │ └── screenshot.rs │ ├── Cargo.toml │ └── README.md ├── hbb_common │ ├── .gitignore │ ├── build.rs │ ├── Cargo.toml │ ├── src │ │ ├── compress.rs │ │ └── udp.rs │ └── protos │ │ └── rendezvous.proto ├── systray-rs │ ├── resources │ │ └── rust.ico │ ├── .gitignore │ ├── src │ │ └── api │ │ │ ├── mod.rs │ │ │ └── cocoa │ │ │ └── mod.rs │ ├── CHANGELOG.md │ ├── appveyor.yml │ ├── Cargo.toml │ ├── ci │ │ └── before_install.sh │ ├── examples │ │ └── systray-example.rs │ ├── .travis.yml │ ├── LICENSE.txt │ └── README.md └── confy │ ├── .gitignore │ ├── src │ └── utils.rs │ ├── examples │ └── simple.rs │ ├── Cargo.toml │ ├── LICENSE │ └── README.md ├── .github └── FUNDING.yml ├── src ├── tray-icon.ico ├── ui │ ├── index.html │ ├── cm.html │ ├── install.html │ ├── remote.css │ ├── chatbox.html │ ├── remote.html │ ├── header.css │ ├── install.tis │ ├── msgbox.html │ └── port_forward.tis ├── lib.rs ├── server │ └── clipboard_service.rs ├── platform │ └── mod.rs └── cli.rs ├── .gitignore ├── Dockerfile ├── entrypoint ├── CONTRIBUTING.md └── Cargo.toml /libs/rust-sciter/src/capi/scarchive.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/enigo/rustfmt.toml: -------------------------------------------------------------------------------- 1 | wrap_comments = true 2 | -------------------------------------------------------------------------------- /libs/magnum-opus/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [rustdesk] 2 | ko_fi: rustdesk 3 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | .idea -------------------------------------------------------------------------------- /libs/magnum-opus/opus_ffi.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /libs/rust-sciter/.clippy.toml: -------------------------------------------------------------------------------- 1 | doc-valid-idents = ["TIScript"] 2 | -------------------------------------------------------------------------------- /libs/pulsectl/.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | /target 3 | **/*.rs.bk 4 | .idea/ 5 | -------------------------------------------------------------------------------- /libs/rust-sciter/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | .vscode/ 4 | .vs/ 5 | -------------------------------------------------------------------------------- /libs/scrap/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | Cargo.lock 4 | generated/ 5 | -------------------------------------------------------------------------------- /libs/hbb_common/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | src/protos/ 5 | -------------------------------------------------------------------------------- /src/tray-icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmfunc/rustdesk/master/src/tray-icon.ico -------------------------------------------------------------------------------- /libs/enigo/src/win/mod.rs: -------------------------------------------------------------------------------- 1 | mod win_impl; 2 | 3 | pub mod keycodes; 4 | pub use self::win_impl::Enigo; 5 | -------------------------------------------------------------------------------- /libs/enigo/src/macos/mod.rs: -------------------------------------------------------------------------------- 1 | mod macos_impl; 2 | 3 | pub mod keycodes; 4 | pub use self::macos_impl::Enigo; 5 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmfunc/rustdesk/master/libs/rust-sciter/examples/icon.png -------------------------------------------------------------------------------- /libs/systray-rs/resources/rust.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmfunc/rustdesk/master/libs/systray-rs/resources/rust.ico -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .idea 3 | .DS_Store 4 | src/ui/inline.rs 5 | extractor 6 | __pycache__ 7 | src/version.rs 8 | *dmg 9 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/archived.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmfunc/rustdesk/master/libs/rust-sciter/examples/archived.rc -------------------------------------------------------------------------------- /libs/rust-sciter/src/types.rs: -------------------------------------------------------------------------------- 1 | //! Export platform-dependent types used by Sciter. 2 | 3 | pub use capi::sctypes::*; 4 | pub use capi::scdef::*; 5 | pub use capi::scvalue::VALUE; 6 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/examples/spam-clients.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Spawning 100 processes" 4 | for i in {1..100} ; 5 | do 6 | ( cargo run --example client -- /tmp/test.ipc & ) 7 | done -------------------------------------------------------------------------------- /libs/rust-sciter/.rustfmt.toml: -------------------------------------------------------------------------------- 1 | # `rustfmt --config-help` for formatting options 2 | max_width = 140 3 | ideal_width = 120 4 | tab_spaces = 2 5 | hard_tabs = true 6 | blank_lines_upper_bound = 2 7 | -------------------------------------------------------------------------------- /libs/magnum-opus/src/opus_ffi.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | #![allow(non_snake_case)] 4 | #![allow(dead_code)] 5 | 6 | include!(concat!(env!("OUT_DIR"), "/opus_ffi.rs")); 7 | -------------------------------------------------------------------------------- /libs/systray-rs/.gitignore: -------------------------------------------------------------------------------- 1 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 2 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 3 | Cargo.lock 4 | /target/ 5 | 6 | -------------------------------------------------------------------------------- /libs/scrap/src/x11/mod.rs: -------------------------------------------------------------------------------- 1 | pub use self::capturer::*; 2 | pub use self::display::*; 3 | pub use self::iter::*; 4 | pub use self::server::*; 5 | 6 | mod capturer; 7 | mod display; 8 | mod ffi; 9 | mod iter; 10 | mod server; 11 | -------------------------------------------------------------------------------- /libs/systray-rs/src/api/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(target_os = "windows")] 2 | #[path = "win32/mod.rs"] 3 | pub mod api; 4 | 5 | #[cfg(target_os = "linux")] 6 | #[path = "linux/mod.rs"] 7 | pub mod api; 8 | 9 | #[cfg(target_os = "macos")] 10 | #[path = "cocoa/mod.rs"] 11 | pub mod api; 12 | -------------------------------------------------------------------------------- /libs/scrap/vpx_ffi.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include -------------------------------------------------------------------------------- /libs/scrap/src/quartz/mod.rs: -------------------------------------------------------------------------------- 1 | pub use self::capturer::Capturer; 2 | pub use self::config::Config; 3 | pub use self::display::Display; 4 | pub use self::ffi::{CGError, PixelFormat}; 5 | pub use self::frame::Frame; 6 | 7 | mod capturer; 8 | mod config; 9 | mod display; 10 | pub mod ffi; 11 | mod frame; 12 | -------------------------------------------------------------------------------- /libs/rust-sciter/src/capi/mod.rs: -------------------------------------------------------------------------------- 1 | /*! C interface headers */ 2 | 3 | pub mod scapi; 4 | pub mod scbehavior; 5 | pub mod scdef; 6 | pub mod scdom; 7 | pub mod scgraphics; 8 | pub mod screquest; 9 | pub mod sctiscript; 10 | pub mod sctypes; 11 | pub mod scvalue; 12 | pub mod schandler; 13 | pub mod scmsg; 14 | pub mod scom; 15 | -------------------------------------------------------------------------------- /libs/magnum-opus/tests/compile-fail/repacketize.rs: -------------------------------------------------------------------------------- 1 | extern crate opus; 2 | 3 | fn main() { 4 | let mut rp = opus::Repacketizer::new().unwrap(); 5 | let mut wip = rp.begin().cat_move( 6 | &[1, 2, 3] 7 | //~^ ERROR borrowed value does not live long enough 8 | ).unwrap(); 9 | wip.out(&mut []); 10 | } 11 | -------------------------------------------------------------------------------- /libs/enigo/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | 5 | { 6 | "name": "Debug", 7 | "type": "gdb", 8 | "request": "launch", 9 | "target": "./target/debug/examples/keyboard", 10 | "cwd": "${workspaceRoot}" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /libs/hbb_common/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | std::fs::create_dir_all("src/protos").unwrap(); 3 | protobuf_codegen_pure::Codegen::new() 4 | .out_dir("src/protos") 5 | .inputs(&["protos/rendezvous.proto", "protos/message.proto"]) 6 | .include("protos") 7 | .run() 8 | .expect("Codegen failed."); 9 | } 10 | -------------------------------------------------------------------------------- /src/ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /libs/scrap/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(quartz)] 2 | extern crate block; 3 | #[macro_use] 4 | extern crate cfg_if; 5 | pub extern crate libc; 6 | #[cfg(dxgi)] 7 | extern crate winapi; 8 | 9 | pub use common::*; 10 | 11 | #[cfg(quartz)] 12 | pub mod quartz; 13 | 14 | #[cfg(x11)] 15 | pub mod x11; 16 | 17 | #[cfg(dxgi)] 18 | pub mod dxgi; 19 | 20 | mod common; 21 | -------------------------------------------------------------------------------- /libs/enigo/examples/dsl.rs: -------------------------------------------------------------------------------- 1 | use enigo::{Enigo, KeyboardControllable}; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | fn main() { 6 | thread::sleep(Duration::from_secs(2)); 7 | let mut enigo = Enigo::new(); 8 | 9 | // write text and select all 10 | enigo.key_sequence_parse("{+UNICODE}{{Hello World!}} ❤️{-UNICODE}{+CTRL}a{-CTRL}"); 11 | } 12 | -------------------------------------------------------------------------------- /libs/enigo/examples/key.rs: -------------------------------------------------------------------------------- 1 | use enigo::{Enigo, Key, KeyboardControllable}; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | fn main() { 6 | thread::sleep(Duration::from_secs(2)); 7 | let mut enigo = Enigo::new(); 8 | 9 | enigo.key_down(Key::Layout('a')); 10 | thread::sleep(Duration::from_secs(1)); 11 | enigo.key_up(Key::Layout('a')); 12 | } 13 | -------------------------------------------------------------------------------- /libs/enigo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | # Generated by Cargo 3 | # will have compiled files and executables 4 | /target/ 5 | 6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 8 | Cargo.lock 9 | 10 | # RustFmt files 11 | **/*.rs.bk 12 | 13 | # intellij 14 | .idea -------------------------------------------------------------------------------- /libs/enigo/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | matrix: 7 | allow_failures: 8 | - rust: nightly 9 | before_install: 10 | - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -qq update; fi 11 | - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y libxdo-dev; fi 12 | os: 13 | - linux 14 | - osx 15 | 16 | -------------------------------------------------------------------------------- /libs/rust-sciter/src/capi/sctiscript.rs: -------------------------------------------------------------------------------- 1 | //! TIScript Virtual Machine Runtime. 2 | 3 | #![allow(non_camel_case_types, non_snake_case)] 4 | 5 | use capi::sctypes::{LPVOID, UINT64}; 6 | 7 | MAKE_HANDLE!(#[doc = "TIScript VM native handle."] HVM, _HVM); 8 | 9 | pub type tiscript_value = UINT64; 10 | 11 | #[repr(C)] 12 | pub struct tiscript_native_interface 13 | { 14 | create_vm: LPVOID, 15 | } 16 | -------------------------------------------------------------------------------- /libs/scrap/examples/list.rs: -------------------------------------------------------------------------------- 1 | extern crate scrap; 2 | 3 | use scrap::Display; 4 | 5 | fn main() { 6 | let displays = Display::all().unwrap(); 7 | 8 | for (i, display) in displays.iter().enumerate() { 9 | println!( 10 | "Display {} [{}x{}]", 11 | i + 1, 12 | display.width(), 13 | display.height() 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - TARGET: x86_64-pc-windows-msvc 4 | 5 | install: 6 | - curl -sSf -o rustup-init.exe https://win.rustup.rs/ 7 | - rustup-init.exe -y --default-host %TARGET% 8 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin;C:\MinGW\bin 9 | 10 | - rustc -vV 11 | - cargo -vV 12 | 13 | build: false 14 | 15 | test_script: 16 | - cargo test 17 | -------------------------------------------------------------------------------- /libs/confy/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | /target 13 | **/*.rs.bk 14 | Cargo.lock 15 | -------------------------------------------------------------------------------- /libs/magnum-opus/tests/fec.rs: -------------------------------------------------------------------------------- 1 | //! Test that supplying empty packets does forward error correction. 2 | 3 | extern crate magnum_opus; 4 | use magnum_opus::*; 5 | 6 | #[test] 7 | fn blah() { 8 | let mut magnum_opus = Decoder::new(48000, Channels::Mono).unwrap(); 9 | 10 | let mut output = vec![0i16; 5760]; 11 | let size = magnum_opus.decode(&[], &mut output[..], true).unwrap(); 12 | assert_eq!(size, 5760); 13 | } -------------------------------------------------------------------------------- /libs/rust-sciter/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.rs] 10 | indent_style = tab 11 | indent_size = 2 12 | tab_width = 2 13 | 14 | [*.{yml,toml,md}] 15 | indent_style = space 16 | indent_size = 2 17 | tab_width = 2 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /libs/confy/src/utils.rs: -------------------------------------------------------------------------------- 1 | //! Some storage utilities 2 | 3 | use std::fs::File; 4 | use std::io::{Error as IoError, Read}; 5 | 6 | pub trait CheckedStringRead { 7 | fn get_string(&mut self) -> Result; 8 | } 9 | 10 | impl CheckedStringRead for File { 11 | fn get_string(&mut self) -> Result { 12 | let mut s = String::new(); 13 | self.read_to_string(&mut s)?; 14 | Ok(s) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/extension.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | extension test 4 | 6 | 14 | 15 | 16 |

see logs in Inspector

17 | 18 | 19 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/archived.rs: -------------------------------------------------------------------------------- 1 | //! Sciter sample with archived resources. 2 | 3 | extern crate sciter; 4 | 5 | fn main() { 6 | let resources = include_bytes!("archived.rc"); 7 | 8 | let mut frame = sciter::WindowBuilder::main_window() 9 | .fixed() 10 | .with_size((600, 400)) 11 | .create(); 12 | 13 | frame.archive_handler(resources).expect("Invalid archive"); 14 | 15 | frame.load_file("this://app/index.htm"); 16 | frame.run_app(); 17 | } 18 | -------------------------------------------------------------------------------- /libs/enigo/examples/keyboard.rs: -------------------------------------------------------------------------------- 1 | use enigo::{Enigo, Key, KeyboardControllable}; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | fn main() { 6 | thread::sleep(Duration::from_secs(2)); 7 | let mut enigo = Enigo::new(); 8 | 9 | // write text 10 | enigo.key_sequence("Hello World! here is a lot of text ❤️"); 11 | 12 | // select all 13 | enigo.key_down(Key::Control); 14 | enigo.key_click(Key::Layout('a')); 15 | enigo.key_up(Key::Control); 16 | } 17 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/extension/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "extension" 3 | version = "0.1.0" 4 | description = "A simple Sciter extension library" 5 | authors = ["pravic "] 6 | homepage = "https://sciter.com/include-library-name-native-extensions/" 7 | edition = "2018" 8 | publish = false 9 | 10 | [lib] 11 | path = "src/extension.rs" 12 | crate-type = ["cdylib"] 13 | test = false 14 | bench = false 15 | 16 | [dependencies] 17 | sciter-rs = { version = "0.5", path="../../", features = ["extension"] } 18 | -------------------------------------------------------------------------------- /src/ui/cm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /libs/enigo/examples/timer.rs: -------------------------------------------------------------------------------- 1 | use enigo::{Enigo, Key, KeyboardControllable}; 2 | use std::thread; 3 | use std::time::Duration; 4 | use std::time::Instant; 5 | 6 | fn main() { 7 | thread::sleep(Duration::from_secs(2)); 8 | let mut enigo = Enigo::new(); 9 | 10 | let now = Instant::now(); 11 | 12 | // write text 13 | enigo.key_sequence("Hello World! ❤️"); 14 | 15 | let time = now.elapsed(); 16 | println!("{:?}", time); 17 | 18 | // select all 19 | enigo.key_down(Key::Control); 20 | enigo.key_click(Key::Layout('a')); 21 | enigo.key_up(Key::Control); 22 | } 23 | -------------------------------------------------------------------------------- /libs/scrap/src/common/mod.rs: -------------------------------------------------------------------------------- 1 | pub use self::codec::*; 2 | 3 | cfg_if! { 4 | if #[cfg(quartz)] { 5 | mod quartz; 6 | pub use self::quartz::*; 7 | } else if #[cfg(x11)] { 8 | mod x11; 9 | pub use self::x11::*; 10 | } else if #[cfg(dxgi)] { 11 | mod dxgi; 12 | pub use self::dxgi::*; 13 | } else { 14 | //TODO: Fallback implementation. 15 | } 16 | } 17 | 18 | pub mod codec; 19 | mod convert; 20 | pub use self::convert::*; 21 | pub const STRIDE_ALIGN: usize = 16; // commonly used in libvpx vpx_img_alloc caller 22 | 23 | mod vpx; 24 | -------------------------------------------------------------------------------- /src/ui/install.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /libs/systray-rs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.4.0 (2020-02-15) 2 | 3 | ## Features 4 | 5 | - Brought up to Rust 2018 (thanks to https://github.com/udoprog) 6 | 7 | ## Bugfixes 8 | 9 | - Updated libappindicator to compile on modern rust 10 | 11 | # 0.3.0 (2018-04-28) 12 | 13 | ## Bugfixes 14 | 15 | - Update gtk so linux version will run again 16 | 17 | # 0.2.0 (2017-05-04) 18 | 19 | ## Features 20 | 21 | - Add Linux Support 22 | 23 | # 0.1.1 (2017-02-28) 24 | 25 | ## Bugfixes 26 | 27 | - Some cleanup and CI work 28 | 29 | # 0.1.0 (2017-02-22) 30 | 31 | ## Features 32 | 33 | - Basic Win32 systray support 34 | -------------------------------------------------------------------------------- /libs/pulsectl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-pulsectl" 3 | version = "0.2.10" 4 | authors = ["Kristopher Ruzic "] 5 | edition = "2018" 6 | license = "GPL-3.0+" 7 | description = "A higher level API for libpulse_binding" 8 | readme = "README.md" 9 | keywords = ["pulse", "pulseaudio", "binding", "audio", "api"] 10 | categories = ["api-bindings", "multimedia::audio"] 11 | homepage = "https://github.com/krruzic/pulsectl" 12 | repository = "https://github.com/krruzic/pulsectl" 13 | 14 | [lib] 15 | name = "pulsectl" 16 | path = "src/lib.rs" 17 | 18 | [dependencies] 19 | libpulse-binding = "2.21" 20 | -------------------------------------------------------------------------------- /libs/enigo/.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask your Question here 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe your Question** 11 | A clear and concise description of what you want to know. 12 | 13 | **Describe your Goal** 14 | A clear and concise description of what you want to achieve. Consider the [XYProblem](http://xyproblem.info/) 15 | 16 | **Environment (please complete the following information):** 17 | - OS: [e.g. Linux, Windows, macOS ..] 18 | - Rust [e.g. rustc --version] 19 | - Library Version [e.g. enigo 0.0.13 or commit hash fa448be ] 20 | -------------------------------------------------------------------------------- /libs/scrap/src/common/vpx.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | #![allow(non_snake_case)] 3 | #![allow(non_upper_case_globals)] 4 | #![allow(improper_ctypes)] 5 | #![allow(dead_code)] 6 | 7 | impl Default for vpx_codec_enc_cfg { 8 | fn default() -> Self { 9 | unsafe { std::mem::zeroed() } 10 | } 11 | } 12 | 13 | impl Default for vpx_codec_ctx { 14 | fn default() -> Self { 15 | unsafe { std::mem::zeroed() } 16 | } 17 | } 18 | 19 | impl Default for vpx_image_t { 20 | fn default() -> Self { 21 | unsafe { std::mem::zeroed() } 22 | } 23 | } 24 | 25 | include!(concat!(env!("OUT_DIR"), "/vpx_ffi.rs")); 26 | -------------------------------------------------------------------------------- /libs/magnum-opus/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "magnum-opus" 3 | version = "0.3.4" 4 | authors = ["Tad Hardesty ", "Sergey Duck "] 5 | edition = "2018" 6 | description = "Safe Rust bindings for libopus" 7 | readme = "README.md" 8 | license = "MIT/Apache-2.0" 9 | keywords = ["opus", "codec", "voice", "sound", "audio"] 10 | categories = ["api-bindings", "encoding", "compression", 11 | "multimedia::audio", "multimedia::encoding"] 12 | 13 | repository = "https://github.com/DuckerMan/magnum-opus" 14 | documentation = "https://docs.rs/magnum-opus" 15 | 16 | [build-dependencies] 17 | target_build_utils = "0.3" 18 | bindgen = "0.53" 19 | -------------------------------------------------------------------------------- /libs/pulsectl/LICENSE.md: -------------------------------------------------------------------------------- 1 | This program is free software: you can redistribute it and/or modify 2 | it under the terms of the GNU General Public License as published by 3 | the Free Software Foundation, either version 3 of the License, or 4 | (at your option) any later version. 5 | 6 | This program is distributed in the hope that it will be useful, 7 | but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | GNU General Public License for more details. 10 | 11 | You should have received a copy of the GNU General Public License 12 | along with this program. If not, see . 13 | 14 | -------------------------------------------------------------------------------- /libs/confy/examples/simple.rs: -------------------------------------------------------------------------------- 1 | //! The most simplest examples of how to use confy 2 | 3 | extern crate confy; 4 | 5 | #[macro_use] 6 | extern crate serde_derive; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | struct ConfyConfig { 10 | name: String, 11 | comfy: bool, 12 | foo: i64, 13 | } 14 | 15 | impl Default for ConfyConfig { 16 | fn default() -> Self { 17 | ConfyConfig { 18 | name: "Unknown".to_string(), 19 | comfy: true, 20 | foo: 42, 21 | } 22 | } 23 | } 24 | 25 | fn main() -> Result<(), confy::ConfyError> { 26 | let cfg: ConfyConfig = confy::load("confy_simple_app")?; 27 | println!("{:#?}", cfg); 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /libs/confy/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "confy" 3 | version = "0.4.1" 4 | authors = ["Katharina Fey "] 5 | description = "Boilerplate-free configuration management" 6 | license = "MIT/X11 OR Apache-2.0" 7 | documentation = "https://docs.rs/confy" 8 | repository = "https://github.com/rust-clique/confy" 9 | edition = "2018" 10 | 11 | [dependencies] 12 | serde = "^1.0" 13 | toml = { version = "^0.5", optional = true } 14 | directories = "^2.0" 15 | serde_yaml = { version = "0.8", optional = true } 16 | 17 | [features] 18 | default = ["toml_conf"] 19 | toml_conf = ["toml"] 20 | yaml_conf = ["serde_yaml"] 21 | 22 | [[example]] 23 | name = "simple" 24 | 25 | [dev-dependencies] 26 | serde_derive = "^1.0" 27 | -------------------------------------------------------------------------------- /libs/enigo/.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement, needs investigation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/ui/remote.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | color: black; 4 | overflow: scroll-indicator; 5 | } 6 | 7 | div#video-wrapper { 8 | size: *; 9 | background: #212121; 10 | } 11 | 12 | video#handler { 13 | behavior: native-remote video; 14 | size: *; 15 | margin: *; 16 | foreground-size: contain; 17 | position: relative; 18 | } 19 | 20 | img#cursor { 21 | position: absolute; 22 | display: none; 23 | //opacity: 0.66, 24 | //transform: scale(0.8); 25 | } 26 | 27 | .goup { 28 | transform: rotate(90deg); 29 | } 30 | 31 | table#remote-folder-view { 32 | context-menu: selector(menu#remote-folder-view); 33 | } 34 | 35 | table#local-folder-view { 36 | context-menu: selector(menu#local-folder-view); 37 | } -------------------------------------------------------------------------------- /libs/enigo/.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug, needs investigation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps or a minimal code example to reproduce the behavior. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Environment (please complete the following information):** 20 | - OS: [e.g. Linux, Windows, macOS ..] 21 | - Rust [e.g. rustc --version] 22 | - Library Version [e.g. enigo 0.0.13 or commit hash fa448be ] 23 | 24 | **Additional context** 25 | Add any other context about the problem here. 26 | -------------------------------------------------------------------------------- /libs/systray-rs/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "0.1.0.{build}" 2 | environment: 3 | matrix: 4 | - TARGET: nightly-x86_64-pc-windows-msvc 5 | - TARGET: nightly-i686-pc-windows-msvc 6 | - TARGET: nightly-x86_64-pc-windows-gnu 7 | - TARGET: nightly-i686-pc-windows-gnu 8 | install: 9 | - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}.exe" -FileName "rust-install.exe" 10 | - ps: .\rust-install.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null 11 | - ps: $env:PATH="$env:PATH;C:\rust\bin" 12 | - rustc -vV 13 | - cargo -vV 14 | - erase rust-install.exe 15 | build_script: 16 | - cargo build 17 | # Skip packaging step while we're running off a local winapi build 18 | #- cargo package 19 | skip_commits: 20 | files: 21 | - README.md 22 | - .travis.yml 23 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/examples/client.rs: -------------------------------------------------------------------------------- 1 | use tokio::{self, prelude::*}; 2 | use parity_tokio_ipc::Endpoint; 3 | 4 | #[tokio::main] 5 | async fn main() { 6 | let path = std::env::args().nth(1).expect("Run it with server path to connect as argument"); 7 | 8 | let mut client = Endpoint::connect(&path).await 9 | .expect("Failed to connect client."); 10 | 11 | loop { 12 | let mut buf = [0u8; 4]; 13 | println!("SEND: PING"); 14 | client.write_all(b"ping").await.expect("Unable to write message to client"); 15 | client.read_exact(&mut buf[..]).await.expect("Unable to read buffer"); 16 | if let Ok("pong") = std::str::from_utf8(&buf[..]) { 17 | println!("RECEIVED: PONG"); 18 | } else { 19 | break; 20 | } 21 | 22 | tokio::time::delay_for(std::time::Duration::from_secs(2)).await; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libs/systray-rs/src/api/cocoa/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::Error; 2 | use std; 3 | 4 | pub struct Window {} 5 | 6 | impl Window { 7 | pub fn new() -> Result { 8 | Err(Error::NotImplementedError) 9 | } 10 | pub fn quit(&self) { 11 | unimplemented!() 12 | } 13 | pub fn set_tooltip(&self, _: &str) -> Result<(), Error> { 14 | unimplemented!() 15 | } 16 | pub fn add_menu_item(&self, _: &str, _: F) -> Result 17 | where 18 | F: std::ops::Fn(&Window) -> () + 'static, 19 | { 20 | unimplemented!() 21 | } 22 | pub fn wait_for_message(&mut self) { 23 | unimplemented!() 24 | } 25 | pub fn set_icon_from_buffer(&self, _: &[u8], _: u32, _: u32) -> Result<(), Error> { 26 | unimplemented!() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libs/rust-sciter/serde/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sciter-serde" 3 | version = "0.3.2" 4 | description = "Serde support for Sciter engine." 5 | keywords = ["serde", "gui", "gtk", "opengl", "skia"] 6 | categories = ["gui", "web-programming", "rendering::graphics-api", "api-bindings"] 7 | 8 | authors = ["pravic "] 9 | repository = "https://github.com/sciter-sdk/rust-sciter" 10 | documentation = "https://docs.rs/sciter-serde" 11 | license = "MIT" 12 | 13 | exclude = [".gitignore", ".editorconfig", ".appveyor.yml"] 14 | 15 | [badges] 16 | appveyor = { repository = "sciter-sdk/rust-sciter" } 17 | travis-ci = { repository = "sciter-sdk/rust-sciter" } 18 | 19 | [dependencies] 20 | sciter-rs = { version = "0.5" } 21 | serde = "1" 22 | 23 | [dev-dependencies] 24 | serde_derive = "1" 25 | serde_bytes = "0.10" 26 | -------------------------------------------------------------------------------- /libs/scrap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "scrap" 3 | description = "Screen capture made easy." 4 | version = "0.5.0" 5 | repository = "https://github.com/quadrupleslap/scrap" 6 | documentation = "https://docs.rs/scrap" 7 | keywords = ["screen", "capture", "record"] 8 | license = "MIT" 9 | authors = ["Ram "] 10 | edition = "2018" 11 | 12 | [dependencies] 13 | block = "0.1" 14 | cfg-if = "1.0" 15 | libc = "0.2" 16 | num_cpus = "1.13" 17 | 18 | [dependencies.winapi] 19 | version = "0.3" 20 | default-features = true 21 | features = ["dxgi", "dxgi1_2", "dxgi1_5", "d3d11"] 22 | 23 | [dev-dependencies] 24 | repng = "0.2" 25 | docopt = "1.1" 26 | webm = "1.0" 27 | serde = {version="1.0", features=["derive"]} 28 | quest = "0.3" 29 | 30 | [build-dependencies] 31 | target_build_utils = "0.3" 32 | bindgen = "0.53" 33 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parity-tokio-ipc" 3 | version = "0.7.2" 4 | edition = "2018" 5 | authors = ["NikVolf "] 6 | license = "MIT/Apache-2.0" 7 | readme = "README.md" 8 | repository = "https://github.com/nikvolf/parity-tokio-ipc" 9 | homepage = "https://github.com/nikvolf/parity-tokio-ipc" 10 | description = """ 11 | Interprocess communication library for tokio. 12 | """ 13 | 14 | [dependencies] 15 | futures = "0.3" 16 | log = "0.4" 17 | mio-named-pipes = "0.1" 18 | miow = "0.3" 19 | rand = "0.7" 20 | tokio = { version = "0.2", features = ["io-driver", "io-util", "uds", "stream", "rt-core", "macros", "time"] } 21 | libc = "0.2" 22 | 23 | [target.'cfg(windows)'.dependencies] 24 | winapi = { version = "0.3", features = ["winbase", "winnt", "accctrl", "aclapi", "securitybaseapi", "minwinbase", "winbase"] } 25 | -------------------------------------------------------------------------------- /libs/systray-rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "systray" 3 | version = "0.4.1" 4 | authors = ["Kyle Machulis "] 5 | description = "Rust library for making minimal cross-platform systray GUIs" 6 | license = "BSD-3-Clause" 7 | homepage = "http://github.com/qdot/systray-rs" 8 | repository = "https://github.com/qdot/systray-rs.git" 9 | readme = "README.md" 10 | keywords = ["gui"] 11 | edition = "2018" 12 | 13 | [dependencies] 14 | log= "0.4" 15 | 16 | [target.'cfg(target_os = "windows")'.dependencies] 17 | winapi= { version = "0.3", features = ["shellapi", "libloaderapi", "errhandlingapi", "impl-default"] } 18 | libc= "0.2" 19 | 20 | [target.'cfg(target_os = "linux")'.dependencies] 21 | gtk= "0.9" 22 | glib= "0.10" 23 | libappindicator= "0.5" 24 | 25 | # [target.'cfg(target_os = "macos")'.dependencies] 26 | # objc="*" 27 | # cocoa="*" 28 | # core-foundation="*" 29 | -------------------------------------------------------------------------------- /src/ui/chatbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian 2 | 3 | WORKDIR / 4 | RUN apt update -y && apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake unzip zip sudo 5 | 6 | RUN git clone https://github.com/microsoft/vcpkg --branch 2020.11-1 7 | RUN /vcpkg/bootstrap-vcpkg.sh -disableMetrics 8 | RUN /vcpkg/vcpkg --disable-metrics install libvpx libyuv opus 9 | 10 | RUN groupadd -r user && useradd -r -g user user --home /home/user && mkdir -p /home/user && chown user /home/user 11 | WORKDIR /home/user 12 | RUN wget https://github.com/c-smile/sciter-sdk/raw/dc65744b66389cd5a0ff6bdb7c63a8b7b05a708b/bin.lnx/x64/libsciter-gtk.so 13 | USER user 14 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup.sh 15 | RUN chmod +x rustup.sh 16 | RUN ./rustup.sh -y 17 | 18 | USER root 19 | COPY ./entrypoint / 20 | ENTRYPOINT ["/entrypoint"] 21 | -------------------------------------------------------------------------------- /libs/enigo/examples/mouse.rs: -------------------------------------------------------------------------------- 1 | use enigo::{Enigo, MouseButton, MouseControllable}; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | fn main() { 6 | let wait_time = Duration::from_secs(2); 7 | let mut enigo = Enigo::new(); 8 | 9 | thread::sleep(wait_time); 10 | 11 | enigo.mouse_move_to(500, 200); 12 | thread::sleep(wait_time); 13 | 14 | enigo.mouse_down(MouseButton::Left); 15 | thread::sleep(wait_time); 16 | 17 | enigo.mouse_move_relative(100, 100); 18 | thread::sleep(wait_time); 19 | 20 | enigo.mouse_up(MouseButton::Left); 21 | thread::sleep(wait_time); 22 | 23 | enigo.mouse_click(MouseButton::Left); 24 | thread::sleep(wait_time); 25 | 26 | enigo.mouse_scroll_x(2); 27 | thread::sleep(wait_time); 28 | 29 | enigo.mouse_scroll_x(-2); 30 | thread::sleep(wait_time); 31 | 32 | enigo.mouse_scroll_y(2); 33 | thread::sleep(wait_time); 34 | 35 | enigo.mouse_scroll_y(-2); 36 | thread::sleep(wait_time); 37 | } 38 | -------------------------------------------------------------------------------- /libs/magnum-opus/tests/opus-padding.rs: -------------------------------------------------------------------------------- 1 | // Based on libmagnum_opus/tests/test_magnum_opus_padding.c 2 | 3 | /* Check for overflow in reading the padding length. 4 | * http://lists.xiph.org/pipermail/magnum_opus/2012-November/001834.html 5 | */ 6 | 7 | extern crate magnum_opus; 8 | 9 | #[test] 10 | fn test_overflow() { 11 | const PACKETSIZE: usize = 16909318; 12 | const CHANNELS: magnum_opus::Channels = magnum_opus::Channels::Stereo; 13 | const FRAMESIZE: usize = 5760; 14 | 15 | let mut input = vec![0xff; PACKETSIZE]; 16 | let mut output = vec![0i16; FRAMESIZE * 2]; 17 | 18 | input[0] = 0xff; 19 | input[1] = 0x41; 20 | *input.last_mut().unwrap() = 0x0b; 21 | 22 | let mut decoder = magnum_opus::Decoder::new(48000, CHANNELS).unwrap(); 23 | let result = decoder.decode(&input[..], &mut output[..], false); 24 | drop(decoder); 25 | drop(input); 26 | drop(output); 27 | 28 | assert_eq!(result.unwrap_err().code(), magnum_opus::ErrorCode::InvalidPacket); 29 | } 30 | -------------------------------------------------------------------------------- /entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$(id -u)" != "${PUID:-1000}" ] || [ "$(id -g)" != "${PGID:-1000}" ]; then 4 | usermod -o -u "${PUID:-1000}" user 5 | groupmod -o -g "${PGID:-1000}" user 6 | chown -R user /home/user 7 | sudo -u user /entrypoint $@ 8 | exit 0 9 | fi 10 | 11 | cd $HOME/rustdesk 12 | . $HOME/.cargo/env 13 | 14 | argv=$@ 15 | 16 | while test $# -gt 0; do 17 | case "$1" in 18 | --release) 19 | mkdir -p target/release 20 | test -f target/release/libsciter-gtk.so || cp $HOME/libsciter-gtk.so target/release/ 21 | release=1 22 | shift 23 | ;; 24 | --target) 25 | shift 26 | if test $# -gt 0; then 27 | rustup target add $1 28 | shift 29 | fi 30 | ;; 31 | *) 32 | shift 33 | ;; 34 | esac 35 | done 36 | 37 | if [ -z $release ]; then 38 | mkdir -p target/debug 39 | test -f target/debug/libsciter-gtk.so || cp $HOME/libsciter-gtk.so target/debug/ 40 | fi 41 | 42 | VCPKG_ROOT=/vcpkg cargo build $argv 43 | -------------------------------------------------------------------------------- /libs/magnum-opus/README.md: -------------------------------------------------------------------------------- 1 | # magnum-opus [![](https://meritbadge.herokuapp.com/magnum-opus)](https://crates.io/crates/magnum-opus) [![](https://img.shields.io/badge/docs-online-2020ff.svg)](https://docs.rs/magnum-opus) 2 | 3 | ### This is the fork of @SpaceManiac repo, which now is abandoned 4 | 5 | Safe Rust bindings for libopus. The rustdoc (available through `cargo doc`) 6 | includes brief descriptions for methods, and detailed API information can be 7 | found at the [libopus documentation](https://opus-codec.org/docs/opus_api-1.1.2/). 8 | 9 | ## License 10 | 11 | Licensed under either of 12 | 13 | * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 14 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 15 | 16 | at your option. 17 | 18 | ### Contribution 19 | 20 | Unless you explicitly state otherwise, any contribution intentionally submitted 21 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 22 | dual licensed as above, without any additional terms or conditions. 23 | -------------------------------------------------------------------------------- /src/ui/remote.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 17 | 18 |
19 | 20 | 21 | 22 | 23 |
24 | 25 |
26 | 29 |
30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /libs/pulsectl/examples/change_device_vol.rs: -------------------------------------------------------------------------------- 1 | extern crate pulsectl; 2 | 3 | use std::io; 4 | 5 | use pulsectl::controllers::DeviceControl; 6 | use pulsectl::controllers::SinkController; 7 | 8 | fn main() { 9 | // create handler that calls functions on playback devices and apps 10 | let mut handler = SinkController::create().unwrap(); 11 | let devices = handler 12 | .list_devices() 13 | .expect("Could not get list of playback devices"); 14 | 15 | println!("Playback Devices"); 16 | for dev in devices.clone() { 17 | println!( 18 | "[{}] {}, [Volume: {}]", 19 | dev.index, 20 | dev.description.as_ref().unwrap(), 21 | dev.volume.print() 22 | ); 23 | } 24 | let mut selection = String::new(); 25 | 26 | io::stdin() 27 | .read_line(&mut selection) 28 | .expect("error: unable to read user input"); 29 | for dev in devices.clone() { 30 | if let true = selection.trim() == dev.index.to_string() { 31 | handler.increase_device_volume_by_percent(dev.index, 0.05); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/threads.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate sciter; 3 | use sciter::Value; 4 | 5 | struct EventHandler; 6 | 7 | impl EventHandler { 8 | // script handler 9 | fn exec_task(&self, task_no: i32, progress: sciter::Value, done: sciter::Value) -> bool { 10 | 11 | use std::{thread, time}; 12 | thread::spawn(move || { 13 | 14 | for i in 1..100 { 15 | // call `onProgress` callback 16 | thread::sleep(time::Duration::from_millis(100)); 17 | progress.call(None, &make_args!(i), None).unwrap(); 18 | } 19 | 20 | // call `onDone` callback 21 | done.call(None, &make_args!(task_no), None).unwrap(); 22 | }); 23 | true 24 | } 25 | } 26 | 27 | impl sciter::EventHandler for EventHandler { 28 | // route script calls to our handler 29 | dispatch_script_call! { 30 | fn exec_task(i32, Value, Value); 31 | } 32 | } 33 | 34 | fn main() { 35 | let html = include_bytes!("threads.htm"); 36 | let mut frame = sciter::WindowBuilder::main_window() 37 | .with_size((1200, 900)) 38 | .create(); 39 | frame.event_handler(EventHandler); 40 | frame.load_html(html, None); 41 | frame.run_app(); 42 | } 43 | -------------------------------------------------------------------------------- /libs/systray-rs/ci/before_install.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | pushd ~ 3 | 4 | # Workaround for Travis CI macOS bug (https://github.com/travis-ci/travis-ci/issues/6307) 5 | if [ "${TRAVIS_OS_NAME}" == "osx" ]; then 6 | rvm get head || true 7 | fi 8 | 9 | function llvm_version_triple() { 10 | if [ "$1" == "3.8" ]; then 11 | echo "3.8.0" 12 | elif [ "$1" == "3.9" ]; then 13 | echo "3.9.0" 14 | fi 15 | } 16 | 17 | function llvm_download() { 18 | export LLVM_VERSION_TRIPLE=`llvm_version_triple ${LLVM_VERSION}` 19 | export LLVM=clang+llvm-${LLVM_VERSION_TRIPLE}-x86_64-$1 20 | 21 | wget http://llvm.org/releases/${LLVM_VERSION_TRIPLE}/${LLVM}.tar.xz 22 | mkdir llvm 23 | tar -xf ${LLVM}.tar.xz -C llvm --strip-components=1 24 | 25 | export LLVM_CONFIG_PATH=`pwd`/llvm/bin/llvm-config 26 | if [ "${TRAVIS_OS_NAME}" == "osx" ]; then 27 | cp llvm/lib/libclang.dylib /usr/local/lib/libclang.dylib 28 | fi 29 | } 30 | 31 | 32 | if [ "${TRAVIS_OS_NAME}" == "linux" ]; then 33 | llvm_download linux-gnu-ubuntu-14.04 34 | else 35 | llvm_download apple-darwin 36 | fi 37 | 38 | popd 39 | set +e 40 | -------------------------------------------------------------------------------- /libs/magnum-opus/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Tad Hardesty 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /libs/confy/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 rust-clique 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/enigo/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 pythoneer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/rust-sciter/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2019 pravic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Nikolay Volf 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/README.md: -------------------------------------------------------------------------------- 1 | # parity-tokio-ipc 2 | 3 | [![Build Status](https://travis-ci.org/NikVolf/parity-tokio-ipc.svg?branch=master)](https://travis-ci.org/NikVolf/parity-tokio-ipc) 4 | 5 | [Documentation](https://nikvolf.github.io/parity-tokio-ipc) 6 | 7 | This crate abstracts interprocess transport for UNIX/Windows. On UNIX it utilizes unix sockets (`tokio_uds` crate) and named pipe on windows (experimental `tokio-named-pipes` crate). 8 | 9 | Endpoint is transport-agnostic interface for incoming connections: 10 | ```rust 11 | let endpoint = Endpoint::new(endpoint_addr, handle).unwrap(); 12 | endpoint.incoming().for_each(|_| println!("Connection received!")); 13 | ``` 14 | 15 | And IpcStream is transport-agnostic io: 16 | ```rust 17 | let endpoint = Endpoint::new(endpoint_addr, handle).unwrap(); 18 | endpoint.incoming().for_each(|(ipc_stream: IpcStream, _)| io::write_all(ipc_stream, b"Hello!")); 19 | ``` 20 | 21 | 22 | # License 23 | 24 | `parity-tokio-ipc` is primarily distributed under the terms of both the MIT 25 | license and the Apache License (Version 2.0), with portions covered by various 26 | BSD-like licenses. 27 | 28 | See LICENSE-APACHE, and LICENSE-MIT for details. 29 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 2 | pub mod platform; 3 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 4 | pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service}; 5 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 6 | mod server; 7 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 8 | pub use self::server::*; 9 | mod client; 10 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 11 | mod rendezvous_mediator; 12 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 13 | pub use self::rendezvous_mediator::*; 14 | pub mod common; 15 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 16 | pub mod ipc; 17 | #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] 18 | pub mod ui; 19 | mod version; 20 | pub use version::*; 21 | #[cfg(any(target_os = "android", target_os = "ios"))] 22 | pub mod mobile; 23 | #[cfg(any(target_os = "android", target_os = "ios"))] 24 | pub mod mobile_ffi; 25 | use common::*; 26 | #[cfg(feature = "cli")] 27 | pub mod cli; 28 | #[cfg(not(any(target_os = "android", target_os = "ios")))] 29 | mod port_forward; 30 | -------------------------------------------------------------------------------- /libs/confy/README.md: -------------------------------------------------------------------------------- 1 | # confy 2 | 3 | Chat with us: [Discord](https://discord.gg/dwq4Zme) 4 | 5 | Zero-boilerplate configuration management. 6 | 7 | Focus on storing the right data, instead of worrying about how or where to store it. 8 | 9 | ```rust 10 | use serde_derive::{Serialize, Deserialize}; 11 | 12 | #[derive(Default, Debug, Serialize, Deserialize)] 13 | struct MyConfig { 14 | version: u8, 15 | api_key: String, 16 | } 17 | 18 | fn main() -> Result<(), ::std::io::Error> { 19 | let cfg: MyConfig = confy::load("my-app-name")?; 20 | dbg!(cfg); 21 | Ok(()) 22 | } 23 | ``` 24 | 25 | ## Using yaml 26 | Enabling the `yaml_conf` feature while disabling the default `toml_conf` 27 | feature causes confy to use a YAML config file instead of TOML. 28 | 29 | ``` 30 | [dependencies.confy] 31 | features = ["yaml_conf"] 32 | default-features = false 33 | ``` 34 | 35 | ## Breakings changes 36 | Starting with version 0.4.0 the configuration file are stored in the expected place for your system. See the [`directories`] crates for more information. 37 | Before version 0.4.0, the configuration file was written in the current directory. 38 | 39 | [`directories`]: https://crates.io/crates/directories 40 | -------------------------------------------------------------------------------- /libs/scrap/src/x11/display.rs: -------------------------------------------------------------------------------- 1 | use std::rc::Rc; 2 | 3 | use super::ffi::*; 4 | use super::Server; 5 | 6 | #[derive(Debug)] 7 | pub struct Display { 8 | server: Rc, 9 | default: bool, 10 | rect: Rect, 11 | root: xcb_window_t, 12 | } 13 | 14 | #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] 15 | pub struct Rect { 16 | pub x: i16, 17 | pub y: i16, 18 | pub w: u16, 19 | pub h: u16, 20 | } 21 | 22 | impl Display { 23 | pub unsafe fn new( 24 | server: Rc, 25 | default: bool, 26 | rect: Rect, 27 | root: xcb_window_t, 28 | ) -> Display { 29 | Display { 30 | server, 31 | default, 32 | rect, 33 | root, 34 | } 35 | } 36 | 37 | pub fn server(&self) -> &Rc { 38 | &self.server 39 | } 40 | pub fn is_default(&self) -> bool { 41 | self.default 42 | } 43 | pub fn rect(&self) -> Rect { 44 | self.rect 45 | } 46 | pub fn w(&self) -> usize { 47 | self.rect.w as _ 48 | } 49 | pub fn h(&self) -> usize { 50 | self.rect.h as _ 51 | } 52 | pub fn root(&self) -> xcb_window_t { 53 | self.root 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | matrix: 7 | allow_failures: 8 | - rust: nightly 9 | after_success: 10 | - |- 11 | [ $TRAVIS_BRANCH = master ] && 12 | [ $TRAVIS_PULL_REQUEST = false ] && 13 | cargo doc --all --no-deps && 14 | echo '' > target/doc/index.html && 15 | pip install --user ghp-import && 16 | /home/travis/.local/bin/ghp-import -n target/doc && 17 | git push -fq https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages 18 | env: 19 | global: 20 | secure: eUHPLjVMSVclRcEgwgybIKZQJTBW8QDjcjgIsEhOHZn7Kpzw0+rwJVoKkvr/uqyJwyY7pHy36mWX31J8YDSbSiM3W8jXeI97sk+FTUkleqUffPzXnbnR1D4kHZlKndFIbcuO5Z+rtVgsAv5E/u1w9XR+mvgK2lfaIEay+26gBl6dl/1TxWvrwDBeMvfq1JGVDQH4Etubncpi3LSWhbRkie1AKnVnsDIY9sUYVKSnIqjxx0qW6Z7EiCdwZ8gf04LNnqyIoKDpyldotL+nJ67ZlVI2O2DrbOOt55nliFHsH4BcWZIZOyIAM4PxIwhDl8g9E55FLkkUX9VUpVtqjTu9RWkVl7rzyrSxLoBUEjguIPrpFWBwLo0FSDvplB2XCXt8x035Io5PEg6m5dVxx5iytTIbI6HQwcA0ESTuDPuAdRJMNvJS/9e2UzPukdYYaaxF6g8wSmiIQjLuZU/nGBdmAl7Uw6cFlQnyLc/GXQg0oZ+B/J8sc4W2C/Z64oB8jK72RLNTKeeWs/XSOt8NxQiNkWeFIhGqiYOPJgjBiTCLSKJPY3CUTiBT8QpAcpj1x1gsWi+5fRoXYxNig/CmeTwZjuxKNxfQIu3J+lJbNdt44x7whnwhZ/AKVuLFPNNiC2OBNpa738UY60VYDoNZyhomWSdBnz3E6i1VtdiSnujFFnc= 21 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/fire_event.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Fire event demo 4 | 23 | 37 | 38 | 39 | 40 |

Fire event

41 |

Running on machine

42 | 43 | 44 | 45 | 46 | 47 |
48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/extension/src/extension.rs: -------------------------------------------------------------------------------- 1 | //! Sciter extension library example. 2 | //! 3 | //! See the [blog post](https://sciter.com/include-library-name-native-extensions/). 4 | 5 | #[macro_use] 6 | extern crate sciter; 7 | 8 | use sciter::types::{BOOL, VALUE}; 9 | use sciter::Value; 10 | 11 | /// Extension entry point. 12 | #[no_mangle] 13 | pub extern "system" fn SciterLibraryInit(api: &'static sciter::ISciterAPI, exported: &mut VALUE) -> BOOL { 14 | sciter::set_host_api(api); 15 | 16 | let ext_api = vmap! { 17 | "add" => add, 18 | "sub" => sub, 19 | }; 20 | 21 | ext_api.pack_to(exported); 22 | 23 | true as BOOL 24 | } 25 | 26 | /// Calculate the sum of all the given arguments. 27 | pub fn add(args: &[Value]) -> Value { 28 | let sum: i32 = args 29 | .iter() 30 | .map(|v| v.to_int()) 31 | .filter(|v| v.is_some()) 32 | .map(|v| v.unwrap()) 33 | .sum(); 34 | 35 | sum.into() 36 | } 37 | 38 | /// `function sub(a, b) { return a - b; }` 39 | pub fn sub(args: &[Value]) -> std::result::Result { 40 | if let [a, b] = args { 41 | let a = a.to_int().ok_or("`a` is not an int")?; 42 | let b = b.to_int().ok_or("`b` is not an int")?; 43 | 44 | let result = a - b; 45 | 46 | Ok(result.into()) 47 | } else { 48 | Err(format!("sub(a,b) expects 2 parameters, given {} instead.", args.len())) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ui/header.css: -------------------------------------------------------------------------------- 1 | header #screens { 2 | background: white; 3 | border: #A9A9A9 1px solid; 4 | height: 22px; 5 | border-radius: 4px; 6 | flow: horizontal; 7 | border-spacing: 0.5em; 8 | padding-right: 1em; 9 | position: relative; 10 | } 11 | 12 | header #screen { 13 | text-align: center; 14 | margin: 3px 0; 15 | width: 18px; 16 | height: 14px; 17 | border: color(border) solid 1px; 18 | font-size: 11px; 19 | color: color(light-text); 20 | } 21 | 22 | header #secure { 23 | position: absolute; 24 | left: -10px; 25 | top: -2px; 26 | } 27 | 28 | header #secure svg { 29 | size: 18px; 30 | } 31 | 32 | header .remote-id { 33 | width: *; 34 | padding-left: 30px; 35 | padding-right: 4em; 36 | margin: * 0; 37 | } 38 | 39 | header span:active, header #screen:active { 40 | color: black; 41 | background: color(gray-bg); 42 | } 43 | 44 | div#global-screens { 45 | position: relative; 46 | margin: 2px 0; 47 | } 48 | 49 | div#global-screens > div { 50 | position: absolute; 51 | border: color(border) solid 1px; 52 | text-align: center; 53 | color: color(light-text); 54 | } 55 | 56 | header #screen.current, div#global-screens > div.current { 57 | background: #666; 58 | color: white; 59 | } 60 | 61 | span#fullscreen.active { 62 | border: color(border) solid 1px; 63 | } 64 | 65 | button:disabled { 66 | opacity: 0.3; 67 | } -------------------------------------------------------------------------------- /libs/parity-tokio-ipc/examples/server.rs: -------------------------------------------------------------------------------- 1 | use futures::StreamExt as _; 2 | use tokio::{ 3 | prelude::*, 4 | self, 5 | io::split, 6 | }; 7 | 8 | use parity_tokio_ipc::{Endpoint, SecurityAttributes}; 9 | 10 | async fn run_server(path: String) { 11 | let mut endpoint = Endpoint::new(path); 12 | endpoint.set_security_attributes(SecurityAttributes::allow_everyone_create().unwrap()); 13 | 14 | let mut incoming = endpoint.incoming().expect("failed to open new socket"); 15 | 16 | while let Some(result) = incoming.next().await 17 | { 18 | match result { 19 | Ok(stream) => { 20 | let (mut reader, mut writer) = split(stream); 21 | 22 | tokio::spawn(async move { 23 | loop { 24 | let mut buf = [0u8; 4]; 25 | let pong_buf = b"pong"; 26 | if let Err(_) = reader.read_exact(&mut buf).await { 27 | println!("Closing socket"); 28 | break; 29 | } 30 | if let Ok("ping") = std::str::from_utf8(&buf[..]) { 31 | println!("RECIEVED: PING"); 32 | writer.write_all(pong_buf).await.expect("unable to write to socket"); 33 | println!("SEND: PONG"); 34 | } 35 | } 36 | }); 37 | } 38 | _ => unreachable!("ideally") 39 | } 40 | }; 41 | } 42 | 43 | #[tokio::main] 44 | async fn main() { 45 | let path = std::env::args().nth(1).expect("Run it with server path as argument"); 46 | run_server(path).await 47 | } -------------------------------------------------------------------------------- /libs/rust-sciter/serde/src/error.rs: -------------------------------------------------------------------------------- 1 | use std; 2 | use std::fmt::{self, Display}; 3 | 4 | use serde::{ser, de}; 5 | 6 | 7 | /// Result type for serialization. 8 | pub type Result = std::result::Result; 9 | 10 | /// Error type for serialization. 11 | #[derive(Debug, Clone, PartialEq)] 12 | pub enum Error { 13 | Message(String), 14 | Unimplemented, 15 | UnsupportedType, 16 | ExpectedType(String), 17 | } 18 | 19 | impl ser::Error for Error { 20 | fn custom(msg: T) -> Self { 21 | Error::Message(msg.to_string()) 22 | } 23 | } 24 | 25 | impl de::Error for Error { 26 | fn custom(msg: T) -> Self { 27 | Error::Message(msg.to_string()) 28 | } 29 | } 30 | 31 | impl std::error::Error for Error { 32 | fn description(&self) -> &str { 33 | match *self { 34 | Error::Message(ref msg) => msg, 35 | Error::ExpectedType(ref msg) => msg, 36 | Error::Unimplemented => "unimplemented", 37 | Error::UnsupportedType => "unsupported", 38 | } 39 | } 40 | } 41 | 42 | impl Display for Error { 43 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 44 | match self { 45 | Error::Message(ref msg) => write!(f, "error: {}", msg), 46 | Error::ExpectedType(ref msg) => write!(f, "expected: {}", msg), 47 | Error::UnsupportedType => write!(f, "unsupported type"), 48 | Error::Unimplemented => write!(f, "unimplemented"), 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/first.rs: -------------------------------------------------------------------------------- 1 | //! An example showing various information about Sciter. 2 | 3 | extern crate sciter; 4 | 5 | fn main() { 6 | // can be called as `examples/first ~/lib/libsciter.so` 7 | if cfg!(feature = "dynamic") { 8 | if let Some(arg) = std::env::args().nth(1) { 9 | println!("using {:?}", arg); 10 | if let Err(e) = sciter::set_library(&arg) { 11 | panic!("Invalid library path specified: {}", e); 12 | } 13 | } 14 | } 15 | 16 | let arch = if cfg!(target_arch = "x86_64") { "x64" } else { "x86" }; 17 | println!("calling SciterAPI {}", arch); 18 | 19 | // bypass the ABI compatability checks (e.g. in windowless builds) 20 | let scapi = sciter::SciterAPI_unchecked(); 21 | 22 | let abi_version = scapi.version; 23 | println!("sciter abi version: {:#0x}, windowless: {}", abi_version, abi_version >= 0x0001_0001); 24 | 25 | let class_name = sciter::utf::w2s((scapi.SciterClassName)()); 26 | println!("sciter class name: {:?}", class_name); 27 | 28 | // Sciter library version 29 | use sciter::types::BOOL; 30 | let v1 = (scapi.SciterVersion)(true as BOOL); 31 | let v2 = (scapi.SciterVersion)(false as BOOL); 32 | let num = [v1 >> 16, v1 & 0xFFFF, v2 >> 16, v2 & 0xFFFF]; 33 | let version = num.iter().map(|&x| x.to_string()).collect::>().join("."); 34 | println!("sciter version: {} {:?}", version, num); 35 | } 36 | -------------------------------------------------------------------------------- /libs/systray-rs/examples/systray-example.rs: -------------------------------------------------------------------------------- 1 | #![windows_subsystem = "windows"] 2 | 3 | //#[cfg(target_os = "windows")] 4 | fn main() -> Result<(), systray::Error> { 5 | let mut app; 6 | match systray::Application::new() { 7 | Ok(w) => app = w, 8 | Err(_) => panic!("Can't create window!"), 9 | } 10 | // w.set_icon_from_file(&"C:\\Users\\qdot\\code\\git-projects\\systray-rs\\resources\\rust.ico".to_string()); 11 | // w.set_tooltip(&"Whatever".to_string()); 12 | app.set_icon_from_file("/usr/share/gxkb/flags/ua.png")?; 13 | 14 | app.add_menu_item("Print a thing", |_| { 15 | println!("Printing a thing!"); 16 | Ok::<_, systray::Error>(()) 17 | })?; 18 | 19 | app.add_menu_item("Add Menu Item", |window| { 20 | window.add_menu_item("Interior item", |_| { 21 | println!("what"); 22 | Ok::<_, systray::Error>(()) 23 | })?; 24 | window.add_menu_separator()?; 25 | Ok::<_, systray::Error>(()) 26 | })?; 27 | 28 | app.add_menu_separator()?; 29 | 30 | app.add_menu_item("Quit", |window| { 31 | window.quit(); 32 | Ok::<_, systray::Error>(()) 33 | })?; 34 | 35 | println!("Waiting on message!"); 36 | app.wait_for_message()?; 37 | Ok(()) 38 | } 39 | 40 | // #[cfg(not(target_os = "windows"))] 41 | // fn main() { 42 | // panic!("Not implemented on this platform!"); 43 | // } 44 | -------------------------------------------------------------------------------- /libs/hbb_common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hbb_common" 3 | version = "0.1.0" 4 | authors = ["rustdesk"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | protobuf = { version = "3.0.0-pre", git = "https://github.com/stepancheg/rust-protobuf" } 11 | tokio = { version = "0.2", features = ["full"] } 12 | tokio-util = { version = "0.3", features = ["full"] } 13 | futures = "0.3" 14 | bytes = "0.5" 15 | log = "0.4" 16 | env_logger = "0.8" 17 | socket2 = { version = "0.3", features = ["reuseport"] } 18 | zstd = "0.5" 19 | quinn = {version = "0.6", optional = true } 20 | anyhow = "1.0" 21 | futures-util = "0.3" 22 | directories-next = "2.0" 23 | rand = "0.7" 24 | serde_derive = "1.0" 25 | serde = "1.0" 26 | lazy_static = "1.4" 27 | confy = { path = "../confy" } 28 | dirs-next = "2.0" 29 | filetime = "0.2" 30 | sodiumoxide = "0.2" 31 | 32 | [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 33 | mac_address = "1.1" 34 | 35 | [features] 36 | quic = ["quinn"] 37 | 38 | [build-dependencies] 39 | protobuf-codegen-pure = { version = "3.0.0-pre", git = "https://github.com/stepancheg/rust-protobuf" } 40 | 41 | [target.'cfg(target_os = "windows")'.dependencies] 42 | winapi = { version = "0.3", features = ["winuser"] } 43 | 44 | [dev-dependencies] 45 | toml = "0.5" 46 | serde_json = "1.0" 47 | -------------------------------------------------------------------------------- /libs/enigo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "enigo" 3 | version = "0.0.14" 4 | authors = ["Dustin Bensing "] 5 | edition = "2018" 6 | build = "build.rs" 7 | 8 | description = "Enigo lets you control your mouse and keyboard in an abstract way on different operating systems (currently only Linux, macOS, Win – Redox and *BSD planned)" 9 | documentation = "https://docs.rs/enigo/" 10 | homepage = "https://github.com/enigo-rs/enigo" 11 | repository = "https://github.com/enigo-rs/enigo" 12 | readme = "README.md" 13 | keywords = ["input", "mouse", "testing", "keyboard", "automation"] 14 | categories = ["development-tools::testing", "api-bindings", "hardware-support"] 15 | license = "MIT" 16 | 17 | [badges] 18 | travis-ci = { repository = "enigo-rs/enigo" } 19 | appveyor = { repository = "pythoneer/enigo-85xiy" } 20 | 21 | [dependencies] 22 | serde = { version = "1.0", optional = true } 23 | serde_derive = { version = "1.0", optional = true } 24 | log = "0.4" 25 | 26 | [features] 27 | with_serde = ["serde", "serde_derive"] 28 | 29 | [target.'cfg(target_os = "windows")'.dependencies] 30 | winapi = { version = "0.3", features = ["winuser", "winbase"] } 31 | 32 | [target.'cfg(target_os = "macos")'.dependencies] 33 | core-graphics = "0.22" 34 | objc = "0.2" 35 | unicode-segmentation = "1.6" 36 | 37 | [target.'cfg(target_os = "linux")'.dependencies] 38 | libc = "0.2" 39 | 40 | [build-dependencies] 41 | pkg-config = "0.3" 42 | -------------------------------------------------------------------------------- /libs/systray-rs/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | 3 | rust: 4 | - stable 5 | - beta 6 | - nightly 7 | 8 | matrix: 9 | allow_failures: 10 | - rust: nightly 11 | 12 | addons: 13 | apt: 14 | sources: 15 | - ubuntu-toolchain-r-test 16 | packages: 17 | - build-essential 18 | - libgtk-3-dev 19 | - libappindicator3-dev 20 | - gcc-5 21 | 22 | before_install: . ./ci/before_install.sh 23 | 24 | script: 25 | - RUST_BACKTRACE=1 PKG_CONFIG_PATH=$HOME/local/lib/pkgconfig LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH cargo build --verbose 26 | - RUST_BACKTRACE=1 PKG_CONFIG_PATH=$HOME/local/lib/pkgconfig LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH cargo test --verbose 27 | 28 | global_env: 29 | secure: O40C4FadE2C8yApgCbQNYmeWQuytrhu4W3a2HKRvGgB39LP0ysMU2UKXQIyZqlZUS9mP9qi5HYN+GTt83aE3Ac0eAwRqq+9zMjC2qMaiZ1JBSfCJI5wiiIXP0HpbsxXipG2Z21aqupVfu0HjNP4RVkaZ7ONKAeLAieI06+7VHbMPw6mcJd4Drv8VTyKn89VvB4lxKexLcURfagoic3fzeFKaIIVBSqGHiXrURbpD5tffOnzc5YFWxeGKTVFl8WqQVrRk2gnl/39UhSsOHGuSExw5GSxh+OaNHTiAkvOaSQLa05Y5mkNlHAsMyqg1mW3mI2xuzCQaFFT5G5JF7uxvZsa4GfROaEG8r1CZvpWxG2NtpupXvIC25nN+QQeeMZv5PHaxlk9OkG0k+2+z1Tu0Yd05x/o3+52YFo3geVwDmI3zx4Zgg9u9nIwGhdtzqbKV2fQNnKbNWVQH6D5M1DlBMYyY25jpkehcazqUbLsJXJFIoMkXhdkjTIpZg4w+CQ617WCnoDhXh6+Iqkw+iBBJJugaf2D6qBpXNiLZNJwbv2M5fj8uDsDtsUvjg56qBw+g+TeHJDKjzpEId/zFrAe4lmuFjN4/SlDk3n5xjZ5eY4PGRp1K8DGgeBQI5gyvHR3H7lm4GE2NCEvNILYFjpANZsiWwDepb2/rHvYNiLK+jhc= 30 | 31 | env: 32 | - LLVM_VERSION=3.9 CLANG_VERSION=clang_3_9 33 | -------------------------------------------------------------------------------- /src/server/clipboard_service.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | pub use crate::common::{ 3 | check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL as INTERVAL, CLIPBOARD_NAME as NAME, 4 | CONTENT, 5 | }; 6 | 7 | struct State { 8 | ctx: Option, 9 | } 10 | 11 | impl Default for State { 12 | fn default() -> Self { 13 | let ctx = match ClipboardContext::new() { 14 | Ok(ctx) => Some(ctx), 15 | Err(err) => { 16 | log::error!("Failed to start {}: {}", NAME, err); 17 | None 18 | } 19 | }; 20 | Self { ctx } 21 | } 22 | } 23 | 24 | impl super::service::Reset for State { 25 | fn reset(&mut self) { 26 | *CONTENT.lock().unwrap() = Default::default(); 27 | } 28 | } 29 | 30 | pub fn new() -> GenericService { 31 | let sp = GenericService::new(NAME, true); 32 | sp.repeat::(INTERVAL, run); 33 | sp 34 | } 35 | 36 | fn run(sp: GenericService, state: &mut State) -> ResultType<()> { 37 | if let Some(ctx) = state.ctx.as_mut() { 38 | if let Some(msg) = check_clipboard(ctx, None) { 39 | sp.send(msg); 40 | } 41 | sp.snapshot(|sps| { 42 | let txt = crate::CONTENT.lock().unwrap().clone(); 43 | if !txt.is_empty() { 44 | let msg_out = crate::create_clipboard_msg(txt); 45 | sps.send_shared(Arc::new(msg_out)); 46 | } 47 | Ok(()) 48 | })?; 49 | } 50 | Ok(()) 51 | } 52 | -------------------------------------------------------------------------------- /libs/pulsectl/README.md: -------------------------------------------------------------------------------- 1 | Rust PulsecAudio API 2 | ==================== 3 | 4 | `pulsectl-rust` is a API wrapper for `libpulse_binding` to make pulseaudio application development easier. 5 | This is a wrapper around the introspector, and thus this library is only capable of modifying PulseAudio data (changing volume, routing applications and muting right now). 6 | 7 | ### Usage 8 | 9 | Add this to your `Cargo.toml`: 10 | ```toml 11 | [dependencies] 12 | rust-pulsectl = "0.2.6" 13 | ``` 14 | 15 | Then, connect to PulseAudio by creating a `SinkController` for audio playback devices and apps or a `SourceController` for audio recording devices and apps. 16 | 17 | ```rust 18 | // Simple application that lists all playback devices and their status 19 | // See examples/change_device_vol.rs for a more complete example 20 | extern crate pulsectl; 21 | 22 | use std::io; 23 | 24 | use pulsectl::controllers::SinkController; 25 | use pulsectl::controllers::DeviceControl; 26 | fn main() { 27 | // create handler that calls functions on playback devices and apps 28 | let mut handler = SinkController::create(); 29 | let devices = handler 30 | .list_devices() 31 | .expect("Could not get list of playback devices"); 32 | println!("Playback Devices"); 33 | for dev in devices.clone() { 34 | println!( 35 | "[{}] {}, [Volume: {}]", 36 | dev.index, 37 | dev.description.as_ref().unwrap(), 38 | dev.volume.print() 39 | ); 40 | } 41 | } 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/som.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | SOM test 4 | 7 | 61 | 62 | 63 |
Hello, body
64 |

but open Inspector to see the logs

65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /libs/enigo/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/enigo-rs/enigo.svg?branch=master)](https://travis-ci.org/enigo-rs/enigo) 2 | [![Build status](https://ci.appveyor.com/api/projects/status/6cd00pajx4tvvl3e?svg=true)](https://ci.appveyor.com/project/pythoneer/enigo-85xiy) 3 | [![Dependency Status](https://dependencyci.com/github/pythoneer/enigo/badge)](https://dependencyci.com/github/pythoneer/enigo) 4 | [![Docs](https://docs.rs/enigo/badge.svg)](https://docs.rs/enigo) 5 | [![Crates.io](https://img.shields.io/crates/v/enigo.svg)](https://crates.io/crates/enigo) 6 | [![Discord chat](https://img.shields.io/discord/315925376486342657.svg)](https://discord.gg/Eb8CsnN) 7 | [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/enigo-rs/Lobby) 8 | 9 | 10 | # enigo 11 | Cross platform input simulation in Rust! 12 | 13 | - [x] Linux (X11) mouse 14 | - [x] Linux (X11) text 15 | - [ ] Linux (Wayland) mouse 16 | - [ ] Linux (Wayland) text 17 | - [x] MacOS mouse 18 | - [x] MacOS text 19 | - [x] Win mouse 20 | - [x] Win text 21 | - [x] Custom Parser 22 | 23 | 24 | ```Rust 25 | let mut enigo = Enigo::new(); 26 | 27 | enigo.mouse_move_to(500, 200); 28 | enigo.mouse_click(MouseButton::Left); 29 | enigo.key_sequence_parse("{+CTRL}a{-CTRL}{+SHIFT}Hello World{-SHIFT}"); 30 | ``` 31 | 32 | for more look at examples 33 | 34 | Runtime dependencies 35 | -------------------- 36 | 37 | Linux users may have to install libxdo-dev. For example, on Ubuntu: 38 | 39 | ```Bash 40 | apt install libxdo-dev 41 | ``` 42 | On Arch: 43 | 44 | ```Bash 45 | pacman -S xdotool 46 | ``` 47 | -------------------------------------------------------------------------------- /libs/scrap/examples/ffplay.rs: -------------------------------------------------------------------------------- 1 | extern crate scrap; 2 | 3 | fn main() { 4 | use scrap::{Capturer, Display}; 5 | use std::io::ErrorKind::WouldBlock; 6 | use std::io::Write; 7 | use std::process::{Command, Stdio}; 8 | 9 | let d = Display::primary().unwrap(); 10 | let (w, h) = (d.width(), d.height()); 11 | 12 | let child = Command::new("ffplay") 13 | .args(&[ 14 | "-f", 15 | "rawvideo", 16 | "-pixel_format", 17 | "bgr0", 18 | "-video_size", 19 | &format!("{}x{}", w, h), 20 | "-framerate", 21 | "60", 22 | "-", 23 | ]) 24 | .stdin(Stdio::piped()) 25 | .spawn() 26 | .expect("This example requires ffplay."); 27 | 28 | let mut capturer = Capturer::new(d, false).unwrap(); 29 | let mut out = child.stdin.unwrap(); 30 | 31 | loop { 32 | match capturer.frame(0) { 33 | Ok(frame) => { 34 | // Write the frame, removing end-of-row padding. 35 | let stride = frame.len() / h; 36 | let rowlen = 4 * w; 37 | for row in frame.chunks(stride) { 38 | let row = &row[..rowlen]; 39 | out.write_all(row).unwrap(); 40 | } 41 | } 42 | Err(ref e) if e.kind() == WouldBlock => { 43 | // Wait for the frame. 44 | } 45 | Err(_) => { 46 | // We're done here. 47 | break; 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libs/systray-rs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Kyle Machulis 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the project nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /src/platform/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(target_os = "linux")] 2 | pub use linux::*; 3 | #[cfg(target_os = "macos")] 4 | pub use macos::*; 5 | #[cfg(windows)] 6 | pub use windows::*; 7 | 8 | #[cfg(windows)] 9 | pub mod windows; 10 | 11 | #[cfg(target_os = "macos")] 12 | pub mod macos; 13 | 14 | #[cfg(target_os = "linux")] 15 | pub mod linux; 16 | 17 | use hbb_common::{message_proto::CursorData, ResultType}; 18 | const SERVICE_INTERVAL: u64 = 300; 19 | 20 | pub fn is_xfce() -> bool { 21 | #[cfg(target_os = "linux")] 22 | { 23 | return std::env::var_os("XDG_CURRENT_DESKTOP") == Some(std::ffi::OsString::from("XFCE")); 24 | } 25 | #[cfg(not(target_os = "linux"))] 26 | { 27 | return false; 28 | } 29 | } 30 | 31 | #[cfg(test)] 32 | mod tests { 33 | use super::*; 34 | #[test] 35 | fn test_cursor_data() { 36 | for _ in 0..30 { 37 | if let Some(hc) = get_cursor().unwrap() { 38 | let cd = get_cursor_data(hc).unwrap(); 39 | repng::encode( 40 | std::fs::File::create("cursor.png").unwrap(), 41 | cd.width as _, 42 | cd.height as _, 43 | &cd.colors[..], 44 | ) 45 | .unwrap(); 46 | } 47 | #[cfg(target_os = "macos")] 48 | macos::is_process_trusted(false); 49 | } 50 | } 51 | #[test] 52 | fn test_get_cursor_pos() { 53 | for _ in 0..30 { 54 | assert!(!get_cursor_pos().is_none()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /libs/scrap/README.md: -------------------------------------------------------------------------------- 1 | # scrap 2 | 3 | Scrap records your screen! At least it does if you're on Windows, macOS, or Linux. 4 | 5 | ## Usage 6 | 7 | ```toml 8 | [dependencies] 9 | scrap = "0.5" 10 | ``` 11 | 12 | Its API is as simple as it gets! 13 | 14 | ```rust 15 | struct Display; /// A screen. 16 | struct Frame; /// An array of the pixels that were on-screen. 17 | struct Capturer; /// A recording instance. 18 | 19 | impl Capturer { 20 | /// Begin recording. 21 | pub fn new(display: Display) -> io::Result; 22 | 23 | /// Try to get a frame. 24 | /// Returns WouldBlock if it's not ready yet. 25 | pub fn frame<'a>(&'a mut self) -> io::Result>; 26 | 27 | pub fn width(&self) -> usize; 28 | pub fn height(&self) -> usize; 29 | } 30 | 31 | impl Display { 32 | /// The primary screen. 33 | pub fn primary() -> io::Result; 34 | 35 | /// All the screens. 36 | pub fn all() -> io::Result>; 37 | 38 | pub fn width(&self) -> usize; 39 | pub fn height(&self) -> usize; 40 | } 41 | 42 | impl<'a> ops::Deref for Frame<'a> { 43 | /// A frame is just an array of bytes. 44 | type Target = [u8]; 45 | } 46 | ``` 47 | 48 | ## The Frame Format 49 | 50 | - The frame format is guaranteed to be **packed BGRA**. 51 | - The width and height are guaranteed to remain constant. 52 | - The stride might be greater than the width, and it may also vary between frames. 53 | 54 | ## System Requirements 55 | 56 | OS | Minimum Requirements 57 | --------|--------------------- 58 | macOS | macOS 10.8 59 | Linux | XCB + SHM + RandR 60 | Windows | DirectX 11.1 61 | -------------------------------------------------------------------------------- /libs/pulsectl/src/controllers/errors.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use crate::PulseCtlError; 4 | 5 | /// if the error occurs within the Mainloop, we bubble up the error with 6 | /// this conversion 7 | impl From for ControllerError { 8 | fn from(error: super::errors::PulseCtlError) -> Self { 9 | ControllerError { 10 | error: ControllerErrorType::PulseCtlError, 11 | message: format!("{:?}", error), 12 | } 13 | } 14 | } 15 | 16 | impl fmt::Debug for ControllerError { 17 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 18 | let mut error_string = String::new(); 19 | match self.error { 20 | ControllerErrorType::PulseCtlError => { 21 | error_string.push_str("PulseCtlError"); 22 | } 23 | ControllerErrorType::GetInfoError => { 24 | error_string.push_str("GetInfoError"); 25 | } 26 | } 27 | write!(f, "[{}]: {}", error_string, self.message) 28 | } 29 | } 30 | 31 | pub(crate) enum ControllerErrorType { 32 | PulseCtlError, 33 | GetInfoError, 34 | } 35 | 36 | /// Error thrown while fetching data from pulseaudio, 37 | /// has two variants: PulseCtlError for when PulseAudio returns an error code 38 | /// and GetInfoError when a request for data fails for whatever reason 39 | pub struct ControllerError { 40 | error: ControllerErrorType, 41 | message: String, 42 | } 43 | 44 | impl ControllerError { 45 | pub(crate) fn new(err: ControllerErrorType, msg: &str) -> Self { 46 | ControllerError { 47 | error: err, 48 | message: msg.to_string(), 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libs/scrap/src/quartz/display.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | use super::ffi::*; 4 | 5 | #[derive(PartialEq, Eq, Debug, Clone, Copy)] 6 | #[repr(C)] 7 | pub struct Display(u32); 8 | 9 | impl Display { 10 | pub fn primary() -> Display { 11 | Display(unsafe { CGMainDisplayID() }) 12 | } 13 | 14 | pub fn online() -> Result, CGError> { 15 | unsafe { 16 | let mut arr: [u32; 16] = mem::MaybeUninit::uninit().assume_init(); 17 | let mut len: u32 = 0; 18 | 19 | match CGGetOnlineDisplayList(16, arr.as_mut_ptr(), &mut len) { 20 | CGError::Success => (), 21 | x => return Err(x), 22 | } 23 | 24 | let mut res = Vec::with_capacity(16); 25 | for i in 0..len as usize { 26 | res.push(Display(*arr.get_unchecked(i))); 27 | } 28 | Ok(res) 29 | } 30 | } 31 | 32 | pub fn id(self) -> u32 { 33 | self.0 34 | } 35 | 36 | pub fn width(self) -> usize { 37 | unsafe { CGDisplayPixelsWide(self.0) } 38 | } 39 | 40 | pub fn height(self) -> usize { 41 | unsafe { CGDisplayPixelsHigh(self.0) } 42 | } 43 | 44 | pub fn is_builtin(self) -> bool { 45 | unsafe { CGDisplayIsBuiltin(self.0) != 0 } 46 | } 47 | 48 | pub fn is_primary(self) -> bool { 49 | unsafe { CGDisplayIsMain(self.0) != 0 } 50 | } 51 | 52 | pub fn is_active(self) -> bool { 53 | unsafe { CGDisplayIsActive(self.0) != 0 } 54 | } 55 | 56 | pub fn is_online(self) -> bool { 57 | unsafe { CGDisplayIsOnline(self.0) != 0 } 58 | } 59 | 60 | pub fn bounds(self) -> CGRect { 61 | unsafe { CGDisplayBounds(self.0) } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /libs/hbb_common/src/compress.rs: -------------------------------------------------------------------------------- 1 | use std::cell::RefCell; 2 | use zstd::block::{Compressor, Decompressor}; 3 | 4 | thread_local! { 5 | static COMPRESSOR: RefCell = RefCell::new(Compressor::new()); 6 | static DECOMPRESSOR: RefCell = RefCell::new(Decompressor::new()); 7 | } 8 | 9 | /// The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), 10 | /// which is currently 22. Levels >= 20 11 | /// Default level is ZSTD_CLEVEL_DEFAULT==3. 12 | /// value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT 13 | pub fn compress(data: &[u8], level: i32) -> Vec { 14 | let mut out = Vec::new(); 15 | COMPRESSOR.with(|c| { 16 | if let Ok(mut c) = c.try_borrow_mut() { 17 | match c.compress(data, level) { 18 | Ok(res) => out = res, 19 | Err(err) => { 20 | crate::log::debug!("Failed to compress: {}", err); 21 | } 22 | } 23 | } 24 | }); 25 | out 26 | } 27 | 28 | pub fn decompress(data: &[u8]) -> Vec { 29 | let mut out = Vec::new(); 30 | DECOMPRESSOR.with(|d| { 31 | if let Ok(mut d) = d.try_borrow_mut() { 32 | const MAX: usize = 1024 * 1024 * 64; 33 | const MIN: usize = 1024 * 1024; 34 | let mut n = 30 * data.len(); 35 | if n > MAX { 36 | n = MAX; 37 | } 38 | if n < MIN { 39 | n = MIN; 40 | } 41 | match d.decompress(data, n) { 42 | Ok(res) => out = res, 43 | Err(err) => { 44 | crate::log::debug!("Failed to decompress: {}", err); 45 | } 46 | } 47 | } 48 | }); 49 | out 50 | } 51 | -------------------------------------------------------------------------------- /src/ui/install.tis: -------------------------------------------------------------------------------- 1 | function self.ready() { 2 | centerize(800, 600); 3 | } 4 | 5 | class Install: Reactor.Component { 6 | function render() { 7 | return
8 |
Installation
9 |
Installation Path:
10 |
Create start menu shortcuts
11 |
Create desktop icon
12 |
End-user license agreement
13 |
By starting the installation, you accept the license agreement.
14 |
15 |
16 | 17 | 18 | 19 |
20 |
; 21 | } 22 | 23 | event click $(#cancel) { 24 | view.close(); 25 | } 26 | 27 | event click $(#aggrement) { 28 | view.open_url("http://rustdesk.com/privacy"); 29 | } 30 | 31 | event click $(#submit) { 32 | for (var el in $$(button)) el.state.disabled = true; 33 | $(progress).style.set{ display: "inline-block" }; 34 | var args = ""; 35 | if ($(#startmenu).value) { 36 | args += "startmenu "; 37 | } 38 | if ($(#desktopicon).value) { 39 | args += "desktopicon "; 40 | } 41 | view.install_me(args); 42 | } 43 | } 44 | 45 | $(body).content(); -------------------------------------------------------------------------------- /libs/enigo/build.rs: -------------------------------------------------------------------------------- 1 | #[cfg(target_os = "windows")] 2 | fn main() {} 3 | 4 | #[cfg(target_os = "macos")] 5 | fn main() {} 6 | 7 | #[cfg(target_os = "linux")] 8 | use pkg_config; 9 | #[cfg(target_os = "linux")] 10 | use std::env; 11 | #[cfg(target_os = "linux")] 12 | use std::fs::File; 13 | #[cfg(target_os = "linux")] 14 | use std::io::Write; 15 | #[cfg(target_os = "linux")] 16 | use std::path::Path; 17 | 18 | #[cfg(target_os = "linux")] 19 | fn main() { 20 | let libraries = [ 21 | "xext", 22 | "gl", 23 | "xcursor", 24 | "xxf86vm", 25 | "xft", 26 | "xinerama", 27 | "xi", 28 | "x11", 29 | "xlib_xcb", 30 | "xmu", 31 | "xrandr", 32 | "xtst", 33 | "xrender", 34 | "xscrnsaver", 35 | "xt", 36 | ]; 37 | 38 | let mut config = String::new(); 39 | for lib in libraries.iter() { 40 | let libdir = match pkg_config::get_variable(lib, "libdir") { 41 | Ok(libdir) => format!("Some(\"{}\")", libdir), 42 | Err(_) => "None".to_string(), 43 | }; 44 | config.push_str(&format!( 45 | "pub const {}: Option<&'static str> = {};\n", 46 | lib, libdir 47 | )); 48 | } 49 | let config = format!("pub mod config {{ pub mod libdir {{\n{}}}\n}}", config); 50 | let out_dir = env::var("OUT_DIR").unwrap(); 51 | let dest_path = Path::new(&out_dir).join("config.rs"); 52 | let mut f = File::create(&dest_path).unwrap(); 53 | f.write_all(&config.into_bytes()).unwrap(); 54 | 55 | let target = env::var("TARGET").unwrap(); 56 | if target.contains("linux") { 57 | println!("cargo:rustc-link-lib=dl"); 58 | } else if target.contains("freebsd") || target.contains("dragonfly") { 59 | println!("cargo:rustc-link-lib=c"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/fire_event.rs: -------------------------------------------------------------------------------- 1 | //! Fire event Sciter sample. 2 | #![allow(unused_variables)] 3 | #![allow(non_snake_case)] 4 | 5 | extern crate sciter; 6 | 7 | use sciter::Element; 8 | use self::sciter::dom::event::*; 9 | use self::sciter::dom::HELEMENT; 10 | use self::sciter::value::Value; 11 | 12 | struct FireEvent; 13 | 14 | impl sciter::EventHandler for FireEvent { 15 | 16 | fn on_event(&mut self, root: HELEMENT, source: HELEMENT, target: HELEMENT, code: BEHAVIOR_EVENTS, phase: PHASE_MASK, reason: EventReason) -> bool { 17 | if phase != PHASE_MASK::BUBBLING { 18 | return false; 19 | } 20 | 21 | if code == BEHAVIOR_EVENTS::BUTTON_CLICK { 22 | 23 | // `root` points to attached element, usually it is an ``. 24 | 25 | let root = Element::from(root).root(); 26 | 27 | let message = root.find_first("#message").unwrap().expect("div#message not found"); 28 | let source = Element::from(source); 29 | 30 | println!("our root is {:?}, message is {:?} and source is {:?}", root, message, source); 31 | 32 | if let Some(id) = source.get_attribute("id") { 33 | if id == "send" { 34 | 35 | // just send a simple event 36 | source.send_event(BEHAVIOR_EVENTS::CHANGE, None, Some(message.as_ptr())).expect("Failed to send event"); 37 | return true; 38 | 39 | } else if id == "fire" { 40 | 41 | // fire event with specified params 42 | let data = Value::from("Rusty param"); 43 | 44 | source.fire_event(BEHAVIOR_EVENTS::CHANGE, None, Some(message.as_ptr()), false, Some(data)).expect("Failed to fire event"); 45 | return true; 46 | } 47 | }; 48 | }; 49 | 50 | false 51 | } 52 | } 53 | 54 | fn main() { 55 | let html = include_bytes!("fire_event.htm"); 56 | let mut frame = sciter::Window::new(); 57 | frame.event_handler(FireEvent); 58 | frame.load_html(html, Some("example://fire_event.htm")); 59 | frame.run_app(); 60 | } 61 | -------------------------------------------------------------------------------- /libs/pulsectl/src/errors.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use pulse::error::{PAErr}; 4 | 5 | impl From for PulseCtlError { 6 | fn from(error: PAErr) -> Self { 7 | PulseCtlError { 8 | error: PulseCtlErrorType::PulseAudioError, 9 | message: format!("PulseAudio returned error: {}", error.to_string().unwrap_or("Unknown".to_owned())), 10 | } 11 | } 12 | } 13 | 14 | impl fmt::Debug for PulseCtlError { 15 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 16 | let mut error_string = String::new(); 17 | match self.error { 18 | PulseCtlErrorType::ConnectError => { 19 | error_string.push_str("ConnectError"); 20 | } 21 | PulseCtlErrorType::OperationError => { 22 | error_string.push_str("OperationError"); 23 | } 24 | PulseCtlErrorType::PulseAudioError => { 25 | error_string.push_str("PulseAudioError"); 26 | } 27 | } 28 | write!(f, "[{}]: {}", error_string, self.message) 29 | } 30 | } 31 | 32 | pub(crate) enum PulseCtlErrorType { 33 | ConnectError, 34 | OperationError, 35 | PulseAudioError, 36 | } 37 | 38 | /// Error thrown when PulseAudio throws an error code, there are 3 variants 39 | /// `PulseCtlErrorType::ConnectError` when there's an error establishing a connection 40 | /// `PulseCtlErrorType::OperationError` when the requested operation quis unexpecdatly or is cancelled 41 | /// `PulseCtlErrorType::PulseAudioError` when PulseAudio returns an error code in any circumstance 42 | pub struct PulseCtlError { 43 | error: PulseCtlErrorType, 44 | message: String, 45 | } 46 | 47 | impl PulseCtlError { 48 | pub(crate) fn new(err: PulseCtlErrorType, msg: &str) -> Self { 49 | PulseCtlError { 50 | error: err, 51 | message: msg.to_string(), 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/minimal.rs: -------------------------------------------------------------------------------- 1 | //! Minimalistic Sciter sample. 2 | 3 | // Specify the Windows subsystem to eliminate console window. 4 | // Requires Rust 1.18. 5 | #![windows_subsystem="windows"] 6 | 7 | extern crate sciter; 8 | 9 | fn main() { 10 | // Step 1: Include the 'minimal.html' file as a byte array. 11 | // Hint: Take a look into 'minimal.html' which contains some tiscript code. 12 | let html = include_bytes!("minimal.htm"); 13 | 14 | // Step 2: Enable the features we need in our tiscript code. 15 | sciter::set_options(sciter::RuntimeOptions::ScriptFeatures( 16 | sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_SYSINFO as u8 // Enables `Sciter.machineName()` 17 | | sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_FILE_IO as u8 // Enables opening file dialog (`view.selectFile()`) 18 | )).unwrap(); 19 | 20 | // Enable debug mode for all windows, so that we can inspect them via Inspector. 21 | sciter::set_options(sciter::RuntimeOptions::DebugMode(true)).unwrap(); 22 | 23 | // Step 3: Create a new main sciter window of type `sciter::Window`. 24 | // Hint: The sciter Window wrapper (src/window.rs) contains more 25 | // interesting functions to open or attach to another existing window. 26 | let mut frame = sciter::Window::new(); 27 | 28 | if cfg!(target_os="macos") { 29 | // a temporary workaround for OSX, see 30 | // https://sciter.com/forums/topic/global-sciter_set_debug_mode-does-not-work-in-osx/ 31 | frame.set_options(sciter::window::Options::DebugMode(true)).unwrap(); 32 | } 33 | 34 | // Step 4: Load HTML byte array from memory to `sciter::Window`. 35 | // Hint: second parameter is an optional uri, it can be `None` in simple cases, 36 | // but it is useful for debugging purposes (check the Inspector tool from the Sciter SDK). 37 | // Also you can use a `load_file` method, but it requires an absolute path 38 | // of the main document to resolve HTML resources properly. 39 | frame.load_html(html, Some("example://minimal.htm")); 40 | 41 | // Step 5: Show window and run the main app message loop until window been closed. 42 | frame.run_app(); 43 | } 44 | -------------------------------------------------------------------------------- /src/ui/msgbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 63 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/download.rs: -------------------------------------------------------------------------------- 1 | //! Download http content (Go sciter example port). 2 | #![allow(dead_code)] 3 | 4 | extern crate sciter; 5 | 6 | use sciter::dom::HELEMENT; 7 | use sciter::host; 8 | use sciter::utf; 9 | use std::rc::{Rc, Weak}; 10 | 11 | struct Handler { 12 | host: Weak, 13 | } 14 | 15 | impl sciter::EventHandler for Handler { 16 | fn document_complete(&mut self, _root: HELEMENT, _target: HELEMENT) { 17 | if let Some(host) = self.host.upgrade() { 18 | // eval script inside the document to receive a "user@machine" string. 19 | let result = host.eval_script("[Sciter.userName(), Sciter.machineName(true)].join(`@`)"); 20 | match result { 21 | Ok(name) => { 22 | println!("running on {}", name); 23 | } 24 | Err(e) => { 25 | println!("error! {}", e.as_string().unwrap_or("?".to_string())); 26 | } 27 | } 28 | } 29 | } 30 | } 31 | 32 | impl sciter::HostHandler for Handler { 33 | fn on_data_loaded(&mut self, pnm: &host::SCN_DATA_LOADED) { 34 | println!("data loaded, uri: `{}`, {} bytes.", utf::w2s(pnm.uri), pnm.dataSize); 35 | } 36 | 37 | fn on_attach_behavior(&mut self, pnm: &mut host::SCN_ATTACH_BEHAVIOR) -> bool { 38 | let el = sciter::Element::from(pnm.element); 39 | let name = utf::u2s(pnm.name); 40 | println!("{}: behavior {}", el, name); 41 | false 42 | } 43 | } 44 | 45 | impl Drop for Handler { 46 | fn drop(&mut self) { 47 | // called 2 times because it is created 2 times 48 | println!("Good bye, window"); 49 | } 50 | } 51 | 52 | fn main() { 53 | let mut frame = sciter::WindowBuilder::main_window().with_size((1024, 768)).create(); 54 | 55 | // Can't use something like `frame.sciter_handler(Rc::new(handler))` yet. 56 | let handler = Handler { 57 | host: Rc::downgrade(&frame.get_host()), 58 | }; 59 | frame.sciter_handler(handler); 60 | 61 | let handler = Handler { 62 | host: Rc::downgrade(&frame.get_host()), 63 | }; 64 | frame.event_handler(handler); 65 | 66 | frame.set_title("Download sample"); 67 | frame.load_file("http://httpbin.org/html"); 68 | frame.run_app(); 69 | } 70 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to RustDesk 2 | 3 | RustDesk welcomes contribution from everyone. Here are the guidelines if you are 4 | thinking of helping us: 5 | 6 | 7 | ## Contributions 8 | 9 | Contributions to RustDesk or its dependencies should be made in the form of GitHub 10 | pull requests. Each pull request will be reviewed by a core contributor 11 | (someone with permission to land patches) and either landed in the main tree or 12 | given feedback for changes that would be required. All contributions should 13 | follow this format, even those from core contributors. 14 | 15 | Should you wish to work on an issue, please claim it first by commenting on 16 | the GitHub issue that you want to work on it. This is to prevent duplicated 17 | efforts from contributors on the same issue. 18 | 19 | ## Pull Request Checklist 20 | 21 | - Branch from the master branch and, if needed, rebase to the current master 22 | branch before submitting your pull request. If it doesn't merge cleanly with 23 | master you may be asked to rebase your changes. 24 | 25 | - Commits should be as small as possible, while ensuring that each commit is 26 | correct independently (i.e., each commit should compile and pass tests). 27 | 28 | - Commits should be accompanied by a Developer Certificate of Origin 29 | (http://developercertificate.org) sign-off, which indicates that you (and 30 | your employer if applicable) agree to be bound by the terms of the 31 | [project license](LICENSE.md). In git, this is the `-s` option to `git commit` 32 | 33 | - If your patch is not getting reviewed or you need a specific person to review 34 | it, you can @-reply a reviewer asking for a review in the pull request or a 35 | comment, or you can ask for a review via [email](mailto:info@rustdesk.com). 36 | 37 | - Add tests relevant to the fixed bug or new feature. 38 | 39 | For specific git instructions, see [GitHub workflow 101](https://github.com/servo/servo/wiki/Github-workflow). 40 | 41 | ## Conduct 42 | 43 | We follow the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct). 44 | 45 | 46 | ## Communication 47 | 48 | RustDesk contributors frequent the [Discord](https://discord.gg/nDceKgxnkV). 49 | 50 | -------------------------------------------------------------------------------- /libs/scrap/src/quartz/config.rs: -------------------------------------------------------------------------------- 1 | use std::ptr; 2 | 3 | use libc::c_void; 4 | 5 | use super::ffi::*; 6 | 7 | //TODO: Color space, YCbCr matrix. 8 | pub struct Config { 9 | /// Whether the cursor is visible. 10 | pub cursor: bool, 11 | /// Whether it should letterbox or stretch. 12 | pub letterbox: bool, 13 | /// Minimum seconds per frame. 14 | pub throttle: f64, 15 | /// How many frames are allocated. 16 | /// 3 is the recommended value. 17 | /// 8 is the maximum value. 18 | pub queue_length: i8, 19 | } 20 | 21 | impl Config { 22 | /// Don't forget to CFRelease this! 23 | pub fn build(self) -> CFDictionaryRef { 24 | unsafe { 25 | let throttle = CFNumberCreate( 26 | ptr::null_mut(), 27 | CFNumberType::Float64, 28 | &self.throttle as *const _ as *const c_void, 29 | ); 30 | let queue_length = CFNumberCreate( 31 | ptr::null_mut(), 32 | CFNumberType::SInt8, 33 | &self.queue_length as *const _ as *const c_void, 34 | ); 35 | 36 | let keys: [CFStringRef; 4] = [ 37 | kCGDisplayStreamShowCursor, 38 | kCGDisplayStreamPreserveAspectRatio, 39 | kCGDisplayStreamMinimumFrameTime, 40 | kCGDisplayStreamQueueDepth, 41 | ]; 42 | let values: [*mut c_void; 4] = [ 43 | cfbool(self.cursor), 44 | cfbool(self.letterbox), 45 | throttle, 46 | queue_length, 47 | ]; 48 | 49 | let res = CFDictionaryCreate( 50 | ptr::null_mut(), 51 | keys.as_ptr(), 52 | values.as_ptr(), 53 | 4, 54 | &kCFTypeDictionaryKeyCallBacks, 55 | &kCFTypeDictionaryValueCallBacks, 56 | ); 57 | 58 | CFRelease(throttle); 59 | CFRelease(queue_length); 60 | 61 | res 62 | } 63 | } 64 | } 65 | 66 | impl Default for Config { 67 | fn default() -> Config { 68 | Config { 69 | cursor: false, 70 | letterbox: true, 71 | throttle: 0.0, 72 | queue_length: 3, 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /libs/scrap/src/quartz/frame.rs: -------------------------------------------------------------------------------- 1 | use std::{ops, ptr, slice}; 2 | 3 | use super::ffi::*; 4 | 5 | pub struct Frame { 6 | surface: IOSurfaceRef, 7 | inner: &'static [u8], 8 | i420: *mut u8, 9 | i420_len: usize, 10 | } 11 | 12 | impl Frame { 13 | pub unsafe fn new(surface: IOSurfaceRef) -> Frame { 14 | CFRetain(surface); 15 | IOSurfaceIncrementUseCount(surface); 16 | 17 | IOSurfaceLock(surface, SURFACE_LOCK_READ_ONLY, ptr::null_mut()); 18 | 19 | let inner = slice::from_raw_parts( 20 | IOSurfaceGetBaseAddress(surface) as *const u8, 21 | IOSurfaceGetAllocSize(surface), 22 | ); 23 | 24 | Frame { 25 | surface, 26 | inner, 27 | i420: ptr::null_mut(), 28 | i420_len: 0, 29 | } 30 | } 31 | 32 | pub fn nv12_to_i420<'a>(&'a mut self, w: usize, h: usize, i420: &'a mut Vec) { 33 | if self.inner.is_empty() { 34 | return; 35 | } 36 | unsafe { 37 | let plane0 = IOSurfaceGetBaseAddressOfPlane(self.surface, 0); 38 | let stride0 = IOSurfaceGetBytesPerRowOfPlane(self.surface, 0); 39 | let plane1 = IOSurfaceGetBaseAddressOfPlane(self.surface, 1); 40 | let stride1 = IOSurfaceGetBytesPerRowOfPlane(self.surface, 1); 41 | crate::common::nv12_to_i420( 42 | plane0 as _, 43 | stride0 as _, 44 | plane1 as _, 45 | stride1 as _, 46 | w, 47 | h, 48 | i420, 49 | ); 50 | self.i420 = i420.as_mut_ptr() as _; 51 | self.i420_len = i420.len(); 52 | } 53 | } 54 | } 55 | 56 | impl ops::Deref for Frame { 57 | type Target = [u8]; 58 | fn deref<'a>(&'a self) -> &'a [u8] { 59 | if self.i420.is_null() { 60 | self.inner 61 | } else { 62 | unsafe { 63 | let inner = slice::from_raw_parts(self.i420 as *const u8, self.i420_len); 64 | inner 65 | } 66 | } 67 | } 68 | } 69 | 70 | impl Drop for Frame { 71 | fn drop(&mut self) { 72 | unsafe { 73 | IOSurfaceUnlock(self.surface, SURFACE_LOCK_READ_ONLY, ptr::null_mut()); 74 | 75 | IOSurfaceDecrementUseCount(self.surface); 76 | CFRelease(self.surface); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /libs/hbb_common/src/udp.rs: -------------------------------------------------------------------------------- 1 | use crate::{bail, ResultType}; 2 | use bytes::BytesMut; 3 | use futures::SinkExt; 4 | use protobuf::Message; 5 | use std::{ 6 | io::Error, 7 | net::SocketAddr, 8 | ops::{Deref, DerefMut}, 9 | }; 10 | use tokio::{net::ToSocketAddrs, net::UdpSocket, stream::StreamExt}; 11 | use tokio_util::{codec::BytesCodec, udp::UdpFramed}; 12 | 13 | pub struct FramedSocket(UdpFramed); 14 | 15 | impl Deref for FramedSocket { 16 | type Target = UdpFramed; 17 | 18 | fn deref(&self) -> &Self::Target { 19 | &self.0 20 | } 21 | } 22 | 23 | impl DerefMut for FramedSocket { 24 | fn deref_mut(&mut self) -> &mut Self::Target { 25 | &mut self.0 26 | } 27 | } 28 | 29 | impl FramedSocket { 30 | pub async fn new(addr: T) -> ResultType { 31 | let socket = UdpSocket::bind(addr).await?; 32 | Ok(Self(UdpFramed::new(socket, BytesCodec::new()))) 33 | } 34 | 35 | #[allow(clippy::never_loop)] 36 | pub async fn new_reuse(addr: T) -> ResultType { 37 | for addr in addr.to_socket_addrs().await? { 38 | return Ok(Self(UdpFramed::new( 39 | UdpSocket::from_std(super::new_socket(addr, false, true)?.into_udp_socket())?, 40 | BytesCodec::new(), 41 | ))); 42 | } 43 | bail!("could not resolve to any address"); 44 | } 45 | 46 | #[inline] 47 | pub async fn send(&mut self, msg: &impl Message, addr: SocketAddr) -> ResultType<()> { 48 | self.0 49 | .send((bytes::Bytes::from(msg.write_to_bytes().unwrap()), addr)) 50 | .await?; 51 | Ok(()) 52 | } 53 | 54 | #[inline] 55 | pub async fn send_raw(&mut self, msg: &'static [u8], addr: SocketAddr) -> ResultType<()> { 56 | self.0.send((bytes::Bytes::from(msg), addr)).await?; 57 | Ok(()) 58 | } 59 | 60 | #[inline] 61 | pub async fn next(&mut self) -> Option> { 62 | self.0.next().await 63 | } 64 | 65 | #[inline] 66 | pub async fn next_timeout(&mut self, ms: u64) -> Option> { 67 | if let Ok(res) = 68 | tokio::time::timeout(std::time::Duration::from_millis(ms), self.0.next()).await 69 | { 70 | res 71 | } else { 72 | None 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /libs/rust-sciter/serde/tests/deserialization.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | extern crate sciter; 4 | extern crate sciter_serde; 5 | 6 | #[macro_use] 7 | extern crate serde_derive; 8 | extern crate serde_bytes; 9 | extern crate serde; 10 | 11 | use sciter::{Value}; 12 | use sciter_serde::{from_value, to_value}; 13 | 14 | 15 | #[test] 16 | fn basic_types() { 17 | // bool 18 | let v: bool = from_value(&Value::from(true)).unwrap(); 19 | assert_eq!(v, true); 20 | 21 | // integer types 22 | let v: i32 = from_value(&Value::from(0)).unwrap(); 23 | assert_eq!(v, 0); 24 | 25 | let v: i32 = from_value(&Value::from(7i32)).unwrap(); 26 | assert_eq!(v, 7i32); 27 | 28 | // float 29 | let v: f32 = from_value(&Value::from(7.0)).unwrap(); 30 | assert_eq!(v, 7.0); 31 | 32 | let v: f64 = from_value(&Value::from(7.0)).unwrap(); 33 | assert_eq!(v, 7.0); 34 | 35 | // Option 36 | let v = Value::null(); 37 | let v: Option = from_value(&v).unwrap(); 38 | assert_eq!(v, None); 39 | 40 | let v = Value::from(7); 41 | let v: Option = from_value(&v).unwrap(); 42 | assert_eq!(v, Some(7)); 43 | } 44 | 45 | #[test] 46 | fn strings() { 47 | let v: char = from_value(&Value::from("7")).unwrap(); 48 | assert_eq!(v, '7'); 49 | 50 | let v: String = from_value(&Value::from("7")).unwrap(); 51 | assert_eq!(v, "7"); 52 | 53 | let v: serde_bytes::ByteBuf = from_value(&Value::from(b"hello".as_ref())).unwrap(); 54 | let v: &[u8] = &v; 55 | assert_eq!(v, b"hello".as_ref()); 56 | } 57 | 58 | #[test] 59 | fn arrays() { 60 | let it = [1,2,3].iter(); 61 | let v: Value = it.cloned().collect(); 62 | let v: Vec = from_value(&v).unwrap(); 63 | assert_eq!(v, &[1,2,3]); 64 | } 65 | 66 | #[test] 67 | fn structs() { 68 | #[derive(Serialize, Deserialize, PartialEq, Debug)] 69 | struct Test { 70 | int: u32, 71 | seq: Vec, 72 | } 73 | 74 | println!(""); 75 | 76 | let a = Test { int: 7, seq: vec!["a".to_owned(), "b".to_owned()]}; 77 | 78 | let v: Value = to_value(&a).unwrap(); 79 | println!("serialized Test:\n {:?}", v); 80 | 81 | println!("keys:"); 82 | v.keys().inspect(|i| println!(" {:?}", i)).count(); 83 | 84 | println!("values:"); 85 | v.values().inspect(|i| println!(" {:?}", i)).count(); 86 | 87 | println!("items:"); 88 | v.items().iter().inspect(|i| println!(" {:?}", i)).count(); 89 | 90 | let e: Test = from_value(&v).unwrap(); 91 | println!("deserialized Test:\n {:?}", e); 92 | 93 | assert_eq!(a, e); 94 | } 95 | -------------------------------------------------------------------------------- /libs/scrap/src/common/x11.rs: -------------------------------------------------------------------------------- 1 | use crate::x11; 2 | use std::{io, ops}; 3 | 4 | pub struct Capturer(x11::Capturer); 5 | 6 | impl Capturer { 7 | pub fn new(display: Display, yuv: bool) -> io::Result { 8 | x11::Capturer::new(display.0, yuv).map(Capturer) 9 | } 10 | 11 | pub fn width(&self) -> usize { 12 | self.0.display().rect().w as usize 13 | } 14 | 15 | pub fn height(&self) -> usize { 16 | self.0.display().rect().h as usize 17 | } 18 | 19 | pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result> { 20 | Ok(Frame(self.0.frame())) 21 | } 22 | } 23 | 24 | pub struct Frame<'a>(&'a [u8]); 25 | 26 | impl<'a> ops::Deref for Frame<'a> { 27 | type Target = [u8]; 28 | fn deref(&self) -> &[u8] { 29 | self.0 30 | } 31 | } 32 | 33 | pub struct Display(x11::Display); 34 | 35 | impl Display { 36 | pub fn primary() -> io::Result { 37 | let server = match x11::Server::default() { 38 | Ok(server) => server, 39 | Err(_) => return Err(io::ErrorKind::ConnectionRefused.into()), 40 | }; 41 | 42 | let mut displays = x11::Server::displays(server); 43 | let mut best = displays.next(); 44 | if best.as_ref().map(|x| x.is_default()) == Some(false) { 45 | best = displays.find(|x| x.is_default()).or(best); 46 | } 47 | 48 | match best { 49 | Some(best) => Ok(Display(best)), 50 | None => Err(io::ErrorKind::NotFound.into()), 51 | } 52 | } 53 | 54 | pub fn all() -> io::Result> { 55 | let server = match x11::Server::default() { 56 | Ok(server) => server, 57 | Err(_) => return Err(io::ErrorKind::ConnectionRefused.into()), 58 | }; 59 | 60 | Ok(x11::Server::displays(server).map(Display).collect()) 61 | } 62 | 63 | pub fn width(&self) -> usize { 64 | self.0.rect().w as usize 65 | } 66 | 67 | pub fn height(&self) -> usize { 68 | self.0.rect().h as usize 69 | } 70 | 71 | pub fn origin(&self) -> (i32, i32) { 72 | let r = self.0.rect(); 73 | (r.x as _, r.y as _) 74 | } 75 | 76 | pub fn is_online(&self) -> bool { 77 | true 78 | } 79 | 80 | pub fn is_primary(&self) -> bool { 81 | self.0.is_default() 82 | } 83 | 84 | pub fn name(&self) -> String { 85 | "".to_owned() 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /libs/rust-sciter/.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.5.0.{build} 2 | 3 | branches: 4 | only: 5 | - master 6 | - travis 7 | 8 | image: 9 | - Visual Studio 2017 10 | 11 | environment: 12 | matrix: 13 | - TARGET: x86_64-pc-windows-msvc 14 | CHANNEL: stable 15 | ARCH: 64 16 | 17 | - TARGET: i686-pc-windows-msvc 18 | CHANNEL: stable 19 | ARCH: 32 20 | 21 | - TARGET: x86_64-pc-windows-msvc 22 | CHANNEL: stable 23 | ARCH: 64skia 24 | 25 | - TARGET: i686-pc-windows-msvc 26 | CHANNEL: stable 27 | ARCH: 32skia 28 | 29 | - TARGET: x86_64-pc-windows-msvc 30 | CHANNEL: stable 31 | ARCH: 64 32 | FEATURES: --features "dynamic" 33 | 34 | - TARGET: i686-pc-windows-msvc 35 | CHANNEL: stable 36 | ARCH: 32 37 | FEATURES: --features "dynamic" 38 | 39 | - TARGET: x86_64-pc-windows-msvc 40 | CHANNEL: nightly 41 | ARCH: 64 42 | 43 | - TARGET: i686-pc-windows-msvc 44 | CHANNEL: nightly 45 | ARCH: 32 46 | 47 | - TARGET: x86_64-pc-windows-msvc 48 | CHANNEL: 1.38.0 49 | ARCH: 64 50 | 51 | - TARGET: i686-pc-windows-msvc 52 | CHANNEL: 1.38.0 53 | ARCH: 32 54 | 55 | - TARGET: x86_64-pc-windows-msvc 56 | CHANNEL: 1.38.0 57 | ARCH: 64 58 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 59 | 60 | 61 | cache: 62 | - C:\Users\appveyor\.cargo\registry 63 | #- C:\projects\deps -> appveyor.yml 64 | #- target 65 | 66 | install: 67 | - cmd: echo Testing sciter%ARCH% with Rust %CHANNEL%. 68 | - cmd: echo Current directory is %APPVEYOR_BUILD_FOLDER% 69 | - cmd: mkdir ..\deps 70 | - curl -sSLo "..\deps\sciter.dll" "https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x%ARCH%/sciter.dll" 71 | - curl -sSLo "..\deps\rustup-init.exe" "https://win.rustup.rs/" 72 | - ..\deps\rustup-init.exe -y --default-host %TARGET% --default-toolchain %CHANNEL% 73 | - cmd: set PATH=%PATH%;C:\Users\appveyor\.cargo\bin;C:\projects\deps 74 | 75 | before_build: 76 | - cmd: cd 77 | - rustc --version 78 | - cargo update 79 | 80 | build_script: 81 | - cmd: echo Building library 82 | - cargo build --release --all %FEATURES% 83 | 84 | - cmd: echo Building examples 85 | - cargo build --example first --verbose 86 | - cargo build --example windowless --features windowless 87 | - cargo build --release --examples %FEATURES% 88 | 89 | test_script: 90 | - cargo run --example first %FEATURES% 91 | - cargo run --example first %FEATURES% 92 | - cargo run --example first %FEATURES% -- C:/projects/deps/sciter.dll 93 | 94 | - cargo test -p sciter-rs %FEATURES% 95 | - cargo test -p sciter-rs %FEATURES% --release 96 | 97 | - cargo test -p sciter-serde %FEATURES% 98 | - cargo test -p sciter-serde %FEATURES% --release 99 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/minimal.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Minimalistic Sciter demo 4 | 19 | 66 | 67 | 68 | 69 |

Minimal Sciter Application

70 |

Running on machine

71 |

Sciter version rev

72 | 73 | 74 | 75 | 80 | 81 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /libs/enigo/src/macos/keycodes.rs: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/questions/3202629/where-can-i-find-a-list-of-mac-virtual-key-codes 2 | 3 | /* keycodes for keys that are independent of keyboard layout */ 4 | 5 | #![allow(non_upper_case_globals)] 6 | #![allow(dead_code)] 7 | 8 | pub const kVK_Return: u16 = 0x24; 9 | pub const kVK_Tab: u16 = 0x30; 10 | pub const kVK_Space: u16 = 0x31; 11 | pub const kVK_Delete: u16 = 0x33; 12 | pub const kVK_Escape: u16 = 0x35; 13 | pub const kVK_Command: u16 = 0x37; 14 | pub const kVK_Shift: u16 = 0x38; 15 | pub const kVK_CapsLock: u16 = 0x39; 16 | pub const kVK_Option: u16 = 0x3A; 17 | pub const kVK_Control: u16 = 0x3B; 18 | pub const kVK_RightShift: u16 = 0x3C; 19 | pub const kVK_RightOption: u16 = 0x3D; 20 | pub const kVK_RightControl: u16 = 0x3E; 21 | pub const kVK_Function: u16 = 0x3F; 22 | pub const kVK_F17: u16 = 0x40; 23 | pub const kVK_VolumeUp: u16 = 0x48; 24 | pub const kVK_VolumeDown: u16 = 0x49; 25 | pub const kVK_Mute: u16 = 0x4A; 26 | pub const kVK_F18: u16 = 0x4F; 27 | pub const kVK_F19: u16 = 0x50; 28 | pub const kVK_F20: u16 = 0x5A; 29 | pub const kVK_F5: u16 = 0x60; 30 | pub const kVK_F6: u16 = 0x61; 31 | pub const kVK_F7: u16 = 0x62; 32 | pub const kVK_F3: u16 = 0x63; 33 | pub const kVK_F8: u16 = 0x64; 34 | pub const kVK_F9: u16 = 0x65; 35 | pub const kVK_F11: u16 = 0x67; 36 | pub const kVK_F13: u16 = 0x69; 37 | pub const kVK_F16: u16 = 0x6A; 38 | pub const kVK_F14: u16 = 0x6B; 39 | pub const kVK_F10: u16 = 0x6D; 40 | pub const kVK_F12: u16 = 0x6F; 41 | pub const kVK_F15: u16 = 0x71; 42 | pub const kVK_Help: u16 = 0x72; 43 | pub const kVK_Home: u16 = 0x73; 44 | pub const kVK_PageUp: u16 = 0x74; 45 | pub const kVK_ForwardDelete: u16 = 0x75; 46 | pub const kVK_F4: u16 = 0x76; 47 | pub const kVK_End: u16 = 0x77; 48 | pub const kVK_F2: u16 = 0x78; 49 | pub const kVK_PageDown: u16 = 0x79; 50 | pub const kVK_F1: u16 = 0x7A; 51 | pub const kVK_LeftArrow: u16 = 0x7B; 52 | pub const kVK_RightArrow: u16 = 0x7C; 53 | pub const kVK_DownArrow: u16 = 0x7D; 54 | pub const kVK_UpArrow: u16 = 0x7E; 55 | pub const kVK_ANSI_Keypad0: u16 = 0x52; 56 | pub const kVK_ANSI_Keypad1: u16 = 0x53; 57 | pub const kVK_ANSI_Keypad2: u16 = 0x54; 58 | pub const kVK_ANSI_Keypad3: u16 = 0x55; 59 | pub const kVK_ANSI_Keypad4: u16 = 0x56; 60 | pub const kVK_ANSI_Keypad5: u16 = 0x57; 61 | pub const kVK_ANSI_Keypad6: u16 = 0x58; 62 | pub const kVK_ANSI_Keypad7: u16 = 0x59; 63 | pub const kVK_ANSI_Keypad8: u16 = 0x5B; 64 | pub const kVK_ANSI_Keypad9: u16 = 0x5C; 65 | pub const kVK_ANSI_KeypadClear: u16 = 0x47; 66 | pub const kVK_ANSI_KeypadDecimal: u16 = 0x41; 67 | pub const kVK_ANSI_KeypadMultiply: u16 = 0x43; 68 | pub const kVK_ANSI_KeypadPlus: u16 = 0x45; 69 | pub const kVK_ANSI_KeypadDivide: u16 = 0x4B; 70 | pub const kVK_ANSI_KeypadEnter: u16 = 0x4C; 71 | pub const kVK_ANSI_KeypadMinus: u16 = 0x4E; 72 | pub const kVK_ANSI_KeypadEquals: u16 = 0x51; 73 | pub const kVK_RIGHT_COMMAND: u16 = 0x36; 74 | -------------------------------------------------------------------------------- /libs/enigo/src/win/keycodes.rs: -------------------------------------------------------------------------------- 1 | // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731 2 | 3 | pub const EVK_RETURN: u16 = 0x0D; 4 | pub const EVK_TAB: u16 = 0x09; 5 | pub const EVK_SPACE: u16 = 0x20; 6 | pub const EVK_BACK: u16 = 0x08; 7 | pub const EVK_ESCAPE: u16 = 0x1b; 8 | pub const EVK_LWIN: u16 = 0x5b; 9 | pub const EVK_SHIFT: u16 = 0x10; 10 | //pub const EVK_LSHIFT: u16 = 0xa0; 11 | pub const EVK_RSHIFT: u16 = 0xa1; 12 | //pub const EVK_LMENU: u16 = 0xa4; 13 | pub const EVK_RMENU: u16 = 0xa5; 14 | pub const EVK_CAPITAL: u16 = 0x14; 15 | pub const EVK_MENU: u16 = 0x12; 16 | pub const EVK_LCONTROL: u16 = 0xa2; 17 | pub const EVK_RCONTROL: u16 = 0xa3; 18 | pub const EVK_HOME: u16 = 0x24; 19 | pub const EVK_PRIOR: u16 = 0x21; 20 | pub const EVK_NEXT: u16 = 0x22; 21 | pub const EVK_END: u16 = 0x23; 22 | pub const EVK_LEFT: u16 = 0x25; 23 | pub const EVK_RIGHT: u16 = 0x27; 24 | pub const EVK_UP: u16 = 0x26; 25 | pub const EVK_DOWN: u16 = 0x28; 26 | pub const EVK_DELETE: u16 = 0x2E; 27 | pub const EVK_F1: u16 = 0x70; 28 | pub const EVK_F2: u16 = 0x71; 29 | pub const EVK_F3: u16 = 0x72; 30 | pub const EVK_F4: u16 = 0x73; 31 | pub const EVK_F5: u16 = 0x74; 32 | pub const EVK_F6: u16 = 0x75; 33 | pub const EVK_F7: u16 = 0x76; 34 | pub const EVK_F8: u16 = 0x77; 35 | pub const EVK_F9: u16 = 0x78; 36 | pub const EVK_F10: u16 = 0x79; 37 | pub const EVK_F11: u16 = 0x7a; 38 | pub const EVK_F12: u16 = 0x7b; 39 | pub const EVK_NUMPAD0: u16 = 0x60; 40 | pub const EVK_NUMPAD1: u16 = 0x61; 41 | pub const EVK_NUMPAD2: u16 = 0x62; 42 | pub const EVK_NUMPAD3: u16 = 0x63; 43 | pub const EVK_NUMPAD4: u16 = 0x64; 44 | pub const EVK_NUMPAD5: u16 = 0x65; 45 | pub const EVK_NUMPAD6: u16 = 0x66; 46 | pub const EVK_NUMPAD7: u16 = 0x67; 47 | pub const EVK_NUMPAD8: u16 = 0x68; 48 | pub const EVK_NUMPAD9: u16 = 0x69; 49 | pub const EVK_CANCEL: u16 = 0x03; 50 | pub const EVK_CLEAR: u16 = 0x0C; 51 | pub const EVK_PAUSE: u16 = 0x13; 52 | pub const EVK_KANA: u16 = 0x15; 53 | pub const EVK_HANGUL: u16 = 0x15; 54 | pub const EVK_JUNJA: u16 = 0x17; 55 | pub const EVK_FINAL: u16 = 0x18; 56 | pub const EVK_HANJA: u16 = 0x19; 57 | pub const EVK_KANJI: u16 = 0x19; 58 | pub const EVK_CONVERT: u16 = 0x1C; 59 | pub const EVK_SELECT: u16 = 0x29; 60 | pub const EVK_PRINT: u16 = 0x2A; 61 | pub const EVK_EXECUTE: u16 = 0x2B; 62 | pub const EVK_SNAPSHOT: u16 = 0x2C; 63 | pub const EVK_INSERT: u16 = 0x2D; 64 | pub const EVK_HELP: u16 = 0x2F; 65 | pub const EVK_SLEEP: u16 = 0x5F; 66 | pub const EVK_SEPARATOR: u16 = 0x6C; 67 | pub const EVK_VOLUME_MUTE: u16 = 0xAD; 68 | pub const EVK_VOLUME_DOWN: u16 = 0xAE; 69 | pub const EVK_VOLUME_UP: u16 = 0xAF; 70 | pub const EVK_NUMLOCK: u16 = 0x90; 71 | pub const EVK_SCROLL: u16 = 0x91; 72 | pub const EVK_RWIN: u16 = 0x5C; 73 | pub const EVK_APPS: u16 = 0x5D; 74 | pub const EVK_ADD: u16 = 0x6B; 75 | pub const EVK_MULTIPLY: u16 = 0x6A; 76 | pub const EVK_SUBTRACT: u16 = 0x6D; 77 | pub const EVK_DECIMAL: u16 = 0x6E; 78 | pub const EVK_DIVIDE: u16 = 0x6F; 79 | -------------------------------------------------------------------------------- /libs/rust-sciter/src/capi/schandler.rs: -------------------------------------------------------------------------------- 1 | //! Native handler wrappers. 2 | 3 | #![allow(dead_code)] 4 | 5 | use capi::sctypes::{LPCVOID, LPVOID}; 6 | 7 | type Opaque = LPCVOID; 8 | 9 | 10 | /// Native wrapper for handlers which can be passed to foreign functions. 11 | #[repr(C)] 12 | #[derive(Debug)] 13 | pub struct NativeHandler { 14 | // pointer to handler 15 | handler: Opaque, 16 | 17 | // pointer to handler destructor 18 | dtor: fn(param: Opaque), 19 | } 20 | 21 | impl Drop for NativeHandler { 22 | fn drop(&mut self) { 23 | if !self.handler.is_null() { 24 | (self.dtor)(self.handler); 25 | } 26 | } 27 | } 28 | 29 | impl Default for NativeHandler { 30 | fn default() -> Self { 31 | NativeHandler { handler: ::std::ptr::null(), dtor: NativeHandler::drop_it:: } 32 | } 33 | } 34 | 35 | impl NativeHandler { 36 | 37 | /// Construct boxed wrapper from handler object. 38 | pub fn from(handler: T) -> NativeHandler { 39 | let boxed = Box::new(handler); 40 | let ptr = Box::into_raw(boxed); 41 | let dtor = NativeHandler::drop_it::; 42 | return NativeHandler { handler: ptr as Opaque, dtor: dtor }; 43 | } 44 | 45 | /// Return a native pointer to handler wrapper. 46 | pub fn as_ptr(&self) -> LPCVOID { 47 | self.handler as LPCVOID 48 | } 49 | 50 | /// Return a native pointer to handler wrapper. 51 | pub fn as_mut_ptr(&self) -> LPVOID { 52 | self.handler as LPVOID 53 | } 54 | 55 | /// Access handler by reference. 56 | pub fn as_ref(&self) -> &T { 57 | let pobj = self.handler as *const T; 58 | let boxed = unsafe { &*pobj }; 59 | return boxed; 60 | } 61 | 62 | /// Access handler by mutable reference. 63 | pub fn as_mut(&mut self) -> &mut T { 64 | let pobj = self.handler as *mut T; 65 | let boxed = unsafe { &mut *pobj }; 66 | return boxed; 67 | } 68 | 69 | #[allow(clippy::mut_from_ref)] 70 | pub fn get_data(ptr: &LPVOID) -> &mut T { 71 | assert!(!ptr.is_null()); 72 | let obj = *ptr as *mut T; 73 | unsafe { &mut *obj} 74 | } 75 | 76 | // Call destructor of handler. 77 | fn drop_it(param: Opaque) { 78 | // reconstruct pointer to Box 79 | let pobj = param as *mut T; 80 | if !pobj.is_null() { 81 | // and drop it 82 | unsafe { Box::from_raw(pobj) }; 83 | } 84 | } 85 | } 86 | 87 | #[cfg(test)] 88 | mod test { 89 | use super::NativeHandler; 90 | 91 | struct Handler { 92 | pub i: i32, 93 | } 94 | 95 | impl Drop for Handler { 96 | fn drop(&mut self) { 97 | println!("Handler::drop"); 98 | } 99 | } 100 | 101 | 102 | 103 | #[test] 104 | fn test1() { 105 | { 106 | println!("\ncreate"); 107 | let h = Handler { i: 7 }; 108 | let p = NativeHandler::from(h); 109 | 110 | println!("handler i {:?}", p.as_ref::().i); 111 | println!("quit"); 112 | } 113 | println!("done."); 114 | 115 | // assert!(false); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /libs/rust-sciter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sciter-rs" 3 | version = "0.5.53" 4 | description = "Rust bindings for Sciter - Embeddable HTML/CSS/script engine (cross-platform desktop GUI toolkit). Also capable with DirectX / OpenGL." 5 | keywords = ["gui", "gtk", "cocoa", "opengl", "skia"] 6 | categories = ["gui", "web-programming", "rendering::graphics-api", "api-bindings"] 7 | 8 | authors = ["pravic "] 9 | repository = "https://github.com/sciter-sdk/rust-sciter" 10 | documentation = "https://docs.rs/sciter-rs" 11 | readme = "README.md" 12 | license = "MIT" 13 | 14 | exclude = [".gitignore", ".editorconfig", ".appveyor.yml", "clippy.toml"] 15 | 16 | [badges] 17 | appveyor = { repository = "sciter-sdk/rust-sciter" } 18 | travis-ci = { repository = "sciter-sdk/rust-sciter" } 19 | 20 | maintenance = { status = "passively-maintained" } 21 | 22 | [lib] 23 | name = "sciter" 24 | path = "src/lib.rs" 25 | crate-type = ["rlib"] 26 | 27 | [features] 28 | default = ["dynamic"] 29 | 30 | # Enable nightly compiler features (currently doesn't use any). 31 | nightly = [] 32 | 33 | # Build as a Sciter extension library. 34 | # see "examples/extension" 35 | # note: this feature can't be tested. 36 | extension = [] 37 | 38 | # Load Sciter DLL dynamically from the path specified by `sciter::set_library`. 39 | # Otherwise, links statically to `libsciter-gtk.so` or `sciter-osx-64.dylib`. 40 | dynamic = [] 41 | 42 | # Build this crate specifically for Sciter.Lite versions 43 | # which are incompatible with the regular ones. 44 | windowless = [] 45 | 46 | 47 | [dependencies] 48 | libc = "0.2" 49 | lazy_static = "1.0" 50 | 51 | [target.x86_64-apple-darwin.dependencies] 52 | objc = "0.2" 53 | objc-foundation = "0.1" 54 | 55 | [dev-dependencies] 56 | winit = "0.19" 57 | winapi = { version = "0.3", features = [ 58 | "impl-default", 59 | "winuser", 60 | "wingdi", 61 | "sysinfoapi", 62 | ] } 63 | raw-window-handle = "0.3" 64 | 65 | [[example]] 66 | name = "first" 67 | path = "examples/first.rs" 68 | 69 | [[example]] 70 | name = "minimal" 71 | path = "examples/minimal.rs" 72 | 73 | [[example]] 74 | name = "download" 75 | path = "examples/download.rs" 76 | 77 | [[example]] 78 | name = "dom" 79 | path = "examples/dom.rs" 80 | 81 | [[example]] 82 | name = "fire_event" 83 | path = "examples/fire_event.rs" 84 | 85 | [[example]] 86 | name = "interop" 87 | path = "examples/interop.rs" 88 | 89 | [[example]] 90 | name = "threads" 91 | path = "examples/threads.rs" 92 | 93 | [[example]] 94 | name = "archived" 95 | path = "examples/archived.rs" 96 | 97 | [[example]] 98 | name = "video" 99 | path = "examples/video.rs" 100 | 101 | [[example]] 102 | name = "clock" 103 | path = "examples/clock.rs" 104 | 105 | [[example]] 106 | name = "windowless" 107 | path = "examples/windowless.rs" 108 | 109 | [[example]] 110 | name = "som" 111 | path = "examples/som.rs" 112 | -------------------------------------------------------------------------------- /libs/systray-rs/README.md: -------------------------------------------------------------------------------- 1 | # systray-rs 2 | 3 | [![Crates.io](https://img.shields.io/crates/v/systray)](https://crates.io/crates/systray) [![Crates.io](https://img.shields.io/crates/d/systray)](https://crates.io/crates/systray) 4 | 5 | [![Build Status](https://travis-ci.org/qdot/systray-rs.svg?branch=master)](https://travis-ci.org/qdot/systray-rs) [![Build status](https://ci.appveyor.com/api/projects/status/lhqm3lucb5w5559b?svg=true)](https://ci.appveyor.com/project/qdot/systray-rs) 6 | 7 | systray-rs is a Rust library that makes it easy for applications to 8 | have minimal UI in a platform specific way. It wraps the platform 9 | specific calls required to show an icon in the system tray, as well as 10 | add menu entries. 11 | 12 | systray-rs is heavily influenced by 13 | [the systray library for the Go Language](https://github.com/getlantern/systray). 14 | 15 | systray-rs currently supports: 16 | 17 | - Linux GTK 18 | - Win32 19 | 20 | Cocoa core still needed! 21 | 22 | # License 23 | 24 | systray-rs includes some code 25 | from [winapi-rs, by retep998](https://github.com/retep998/winapi-rs). 26 | This code is covered under the MIT license. This code will be removed 27 | once winapi-rs has a 0.3 crate available. 28 | 29 | systray-rs is BSD licensed. 30 | 31 | Copyright (c) 2016-2020, Nonpolynomial Labs, LLC 32 | All rights reserved. 33 | 34 | Redistribution and use in source and binary forms, with or without 35 | modification, are permitted provided that the following conditions are met: 36 | 37 | * Redistributions of source code must retain the above copyright notice, this 38 | list of conditions and the following disclaimer. 39 | 40 | * Redistributions in binary form must reproduce the above copyright notice, 41 | this list of conditions and the following disclaimer in the documentation 42 | and/or other materials provided with the distribution. 43 | 44 | * Neither the name of the project nor the names of its 45 | contributors may be used to endorse or promote products derived from 46 | this software without specific prior written permission. 47 | 48 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 49 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 51 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 52 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 54 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 55 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 56 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 57 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 58 | 59 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/interop.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Rust-sciter sample 4 | 16 | 77 | 78 | 79 | 80 |

Rust Sciter Application

81 |

Running on machine via ().

82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /libs/rust-sciter/serde/tests/serialization.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | extern crate sciter; 4 | extern crate sciter_serde; 5 | 6 | #[macro_use] 7 | extern crate serde_derive; 8 | extern crate serde_bytes; 9 | extern crate serde; 10 | 11 | use sciter::{Value}; 12 | use sciter_serde::{to_value}; 13 | 14 | 15 | #[test] 16 | fn basic_types() { 17 | // bool 18 | let v = to_value(&true).unwrap(); 19 | assert!(v.is_bool()); 20 | assert_eq!(v, Value::from(true)); 21 | 22 | // integer types 23 | let v = to_value(&0).unwrap(); 24 | assert!(v.is_int()); 25 | assert_eq!(v.to_int(), Some(0)); 26 | 27 | let v = to_value(&7u8).unwrap(); 28 | assert_eq!(v, Value::from(7)); 29 | 30 | let v = to_value(&7u16).unwrap(); 31 | assert_eq!(v, Value::from(7)); 32 | 33 | let v = to_value(&7u32).unwrap(); 34 | assert_eq!(v, Value::from(7)); 35 | 36 | let v = to_value(&7i8).unwrap(); 37 | assert_eq!(v, Value::from(7)); 38 | 39 | let v = to_value(&7i16).unwrap(); 40 | assert_eq!(v, Value::from(7)); 41 | 42 | let v = to_value(&7i32).unwrap(); 43 | assert_eq!(v, Value::from(7)); 44 | 45 | let v = to_value(&7.0).unwrap(); 46 | assert!(v.is_float()); 47 | 48 | // 64-bit 49 | // let v = to_value(&7u64).unwrap(); 50 | // assert!(v.is_float()); 51 | // assert_eq!(v, Value::from(7.0)); 52 | 53 | // Option 54 | // let v = to_value(&Some(7)).unwrap(); 55 | // assert!(v.is_int()); 56 | 57 | // let v = to_value(&None).unwrap(); 58 | // assert!(v.is_null()); 59 | } 60 | 61 | #[test] 62 | fn strings() { 63 | // strings 64 | let v = to_value(&'h').unwrap(); 65 | assert!(v.is_string()); 66 | assert_eq!(v, Value::from("h")); 67 | 68 | let v = to_value("hello").unwrap(); 69 | assert!(v.is_string()); 70 | assert_eq!(v, Value::from("hello")); 71 | 72 | // doesn't work because Rust doesn't have specialization yet (https://github.com/rust-lang/rust#31844) 73 | // let v = to_value(b"hello").unwrap(); 74 | // println!("b'hello': {:?}", v); 75 | // assert!(v.is_bytes()); 76 | // assert_eq!(v.as_bytes(), Some(b"hello".as_ref())); 77 | 78 | use serde_bytes::Bytes; 79 | 80 | let v = to_value(&Bytes::new(b"hello")).unwrap(); 81 | assert!(v.is_bytes()); 82 | assert_eq!(v.as_bytes(), Some(b"hello".as_ref())); 83 | } 84 | 85 | #[test] 86 | fn arrays() { 87 | let a = [1,2,3]; 88 | let v = to_value(&a).unwrap(); 89 | assert!(v.is_array()); 90 | assert_eq!(v.len(), a.len()); 91 | 92 | let a = vec![1,2,3]; 93 | let v = to_value(&a).unwrap(); 94 | assert!(v.is_array()); 95 | assert_eq!(v.len(), a.len()); 96 | } 97 | 98 | #[test] 99 | fn structs() { 100 | 101 | #[derive(Serialize)] 102 | struct Test { 103 | int: u32, 104 | seq: Vec<&'static str>, 105 | } 106 | 107 | let a = Test { int: 7, seq: vec!["a", "b"]}; 108 | let v = to_value(&a).unwrap(); 109 | assert!(v.is_map()); 110 | assert_eq!(v.len(), 2); 111 | assert_eq!(v.get_item("int"), Value::from(7) ); 112 | assert_eq!(v.get_item("seq").len(), 2); 113 | } 114 | -------------------------------------------------------------------------------- /libs/scrap/src/x11/iter.rs: -------------------------------------------------------------------------------- 1 | use std::ptr; 2 | use std::rc::Rc; 3 | 4 | use libc; 5 | 6 | use super::ffi::*; 7 | use super::{Display, Rect, Server}; 8 | 9 | //TODO: Do I have to free the displays? 10 | 11 | pub struct DisplayIter { 12 | outer: xcb_screen_iterator_t, 13 | inner: Option<(xcb_randr_monitor_info_iterator_t, xcb_window_t)>, 14 | server: Rc, 15 | } 16 | 17 | impl DisplayIter { 18 | pub unsafe fn new(server: Rc) -> DisplayIter { 19 | let mut outer = xcb_setup_roots_iterator(server.setup()); 20 | let inner = Self::next_screen(&mut outer, &server); 21 | DisplayIter { 22 | outer, 23 | inner, 24 | server, 25 | } 26 | } 27 | 28 | fn next_screen( 29 | outer: &mut xcb_screen_iterator_t, 30 | server: &Server, 31 | ) -> Option<(xcb_randr_monitor_info_iterator_t, xcb_window_t)> { 32 | if outer.rem == 0 { 33 | return None; 34 | } 35 | 36 | unsafe { 37 | let root = (*outer.data).root; 38 | 39 | let cookie = xcb_randr_get_monitors_unchecked( 40 | server.raw(), 41 | root, 42 | 1, //TODO: I don't know if this should be true or false. 43 | ); 44 | 45 | let response = xcb_randr_get_monitors_reply(server.raw(), cookie, ptr::null_mut()); 46 | 47 | let inner = xcb_randr_get_monitors_monitors_iterator(response); 48 | 49 | libc::free(response as *mut _); 50 | xcb_screen_next(outer); 51 | 52 | Some((inner, root)) 53 | } 54 | } 55 | } 56 | 57 | impl Iterator for DisplayIter { 58 | type Item = Display; 59 | 60 | fn next(&mut self) -> Option { 61 | loop { 62 | if let Some((ref mut inner, root)) = self.inner { 63 | // If there is something in the current screen, return that. 64 | if inner.rem != 0 { 65 | unsafe { 66 | let data = &*inner.data; 67 | 68 | let display = Display::new( 69 | self.server.clone(), 70 | data.primary != 0, 71 | Rect { 72 | x: data.x, 73 | y: data.y, 74 | w: data.width, 75 | h: data.height, 76 | }, 77 | root, 78 | ); 79 | 80 | xcb_randr_monitor_info_next(inner); 81 | return Some(display); 82 | } 83 | } 84 | } else { 85 | // If there is no current screen, the screen iterator is empty. 86 | return None; 87 | } 88 | 89 | // The current screen was empty, so try the next screen. 90 | self.inner = Self::next_screen(&mut self.outer, &self.server); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /libs/rust-sciter/.travis.yml: -------------------------------------------------------------------------------- 1 | # Based on the "trust" template v0.1.2 2 | # https://github.com/japaric/trust/tree/v0.1.2 3 | 4 | dist: xenial 5 | sudo: false 6 | language: rust 7 | compiler: gcc 8 | 9 | os: 10 | - linux 11 | - osx 12 | 13 | rust: 14 | - stable 15 | - nightly 16 | - 1.40.0 17 | 18 | matrix: 19 | include: 20 | - os: osx 21 | osx_image: xcode8 22 | - os: osx 23 | osx_image: xcode11 24 | 25 | branches: 26 | only: 27 | - master 28 | - travis 29 | 30 | notifications: 31 | email: change 32 | 33 | 34 | cache: cargo 35 | before_cache: 36 | # Travis can't cache files that are not readable by "others" 37 | - chmod -R a+r $HOME/.cargo 38 | 39 | addons: 40 | apt: 41 | sources: 42 | - ubuntu-toolchain-r-test 43 | 44 | packages: 45 | - libgtk-3-dev 46 | - libgtk-3-0 47 | - libstdc++-6-pic 48 | 49 | 50 | before_install: 51 | - set -e 52 | - rustup self update 53 | 54 | install: 55 | - source ~/.cargo/env || true 56 | - export SDK_URL=https://raw.githubusercontent.com/c-smile/sciter-sdk/master 57 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export SDK_DLL="$TRAVIS_BUILD_DIR/sciter-osx-64.dylib"; fi 58 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then export SDK_DLL="$TRAVIS_BUILD_DIR/libsciter-gtk.so"; fi 59 | 60 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then curl -so "$SDK_DLL" $SDK_URL/bin.osx/sciter-osx-64.dylib; fi 61 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -so "$SDK_DLL" $SDK_URL/bin.lnx/x64/libsciter-gtk.so; fi 62 | 63 | before_script: 64 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$TRAVIS_BUILD_DIR"; fi 65 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then cp "$TRAVIS_BUILD_DIR/sciter-osx-64.dylib" "$TRAVIS_BUILD_DIR/libsciter-osx-64.dylib"; fi 66 | 67 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$TRAVIS_BUILD_DIR"; fi 68 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then export RUSTFLAGS='-C link-arg=-Wl,--unresolved-symbols=ignore-in-shared-libs'; fi 69 | 70 | - export PATH="$PATH:$TRAVIS_BUILD_DIR" 71 | - export LIBRARY_PATH="$LIBRARY_PATH:$TRAVIS_BUILD_DIR" 72 | - export RUST_BACKTRACE=full 73 | 74 | - #ls /usr/lib/x86_64-linux-gnu/libstdc++* 75 | - #strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBC 76 | - #file $SDK_DLL 77 | - gcc --version 78 | - rustc --version 79 | 80 | script: 81 | - cargo update 82 | 83 | - cargo build --example first --verbose 84 | - cargo run --example first 85 | - cargo run --example first --features "dynamic" 86 | - cargo run --example first --features "dynamic" -- "$SDK_DLL" 87 | 88 | - cargo build --all 89 | - cargo build --all --release 90 | - cargo build --examples --release 91 | - cargo build --example windowless --features windowless 92 | 93 | - cargo test -p sciter-rs 94 | - cargo test -p sciter-rs --release 95 | 96 | - cargo test -p sciter-serde 97 | - cargo test -p sciter-serde --release 98 | 99 | after_script: set +e 100 | -------------------------------------------------------------------------------- /libs/magnum-opus/build.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | env, 3 | path::{Path, PathBuf}, 4 | }; 5 | 6 | fn find_package(name: &str) -> Vec { 7 | let vcpkg_root = std::env::var("VCPKG_ROOT").unwrap(); 8 | let mut path: PathBuf = vcpkg_root.into(); 9 | let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); 10 | let mut target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); 11 | if target_arch == "x86_64" { 12 | target_arch = "x64".to_owned(); 13 | } else if target_arch == "aarch64" { 14 | target_arch = "arm64".to_owned(); 15 | } else { 16 | target_arch = "arm".to_owned(); 17 | } 18 | let target = if target_os == "macos" { 19 | "x64-osx".to_owned() 20 | } else if target_os == "windows" { 21 | "x64-windows-static".to_owned() 22 | } else if target_os == "android" { 23 | format!("{}-android-static", target_arch) 24 | } else { 25 | "x64-linux".to_owned() 26 | }; 27 | println!("cargo:info={}", target); 28 | path.push("installed"); 29 | path.push(target); 30 | println!( 31 | "{}", 32 | format!("cargo:rustc-link-lib={}", name.trim_start_matches("lib")) 33 | ); 34 | println!( 35 | "{}", 36 | format!( 37 | "cargo:rustc-link-search={}", 38 | path.join("lib").to_str().unwrap() 39 | ) 40 | ); 41 | let include = path.join("include"); 42 | println!("{}", format!("cargo:include={}", include.to_str().unwrap())); 43 | vec![include] 44 | } 45 | 46 | fn generate_bindings(ffi_header: &Path, include_paths: &[PathBuf], ffi_rs: &Path) { 47 | #[derive(Debug)] 48 | struct ParseCallbacks; 49 | impl bindgen::callbacks::ParseCallbacks for ParseCallbacks { 50 | fn int_macro(&self, name: &str, _value: i64) -> Option { 51 | if name.starts_with("OPUS") { 52 | Some(bindgen::callbacks::IntKind::Int) 53 | } else { 54 | None 55 | } 56 | } 57 | } 58 | let mut b = bindgen::Builder::default() 59 | .header(ffi_header.to_str().unwrap()) 60 | .parse_callbacks(Box::new(ParseCallbacks)) 61 | .generate_comments(false); 62 | 63 | for dir in include_paths { 64 | b = b.clang_arg(format!("-I{}", dir.display())); 65 | } 66 | 67 | b.generate().unwrap().write_to_file(ffi_rs).unwrap(); 68 | } 69 | 70 | fn gen_opus() { 71 | let includes = find_package("opus"); 72 | let src_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); 73 | let src_dir = Path::new(&src_dir); 74 | let out_dir = env::var_os("OUT_DIR").unwrap(); 75 | let out_dir = Path::new(&out_dir); 76 | 77 | let ffi_header = src_dir.join("opus_ffi.h"); 78 | println!("rerun-if-changed={}", ffi_header.display()); 79 | for dir in &includes { 80 | println!("rerun-if-changed={}", dir.display()); 81 | } 82 | 83 | let ffi_rs = out_dir.join("opus_ffi.rs"); 84 | generate_bindings(&ffi_header, &includes, &ffi_rs); 85 | } 86 | 87 | fn main() { 88 | gen_opus() 89 | } 90 | -------------------------------------------------------------------------------- /src/ui/port_forward.tis: -------------------------------------------------------------------------------- 1 | class PortForward: Reactor.Component { 2 | function render() { 3 | var args = handler.get_args(); 4 | var is_rdp = handler.is_rdp(); 5 | if (is_rdp) { 6 | this.pfs = [["", "", "RDP"]]; 7 | args = ["rdp"]; 8 | } else if (args.length) { 9 | this.pfs = [args]; 10 | } else { 11 | this.pfs = handler.get_port_forwards(); 12 | } 13 | var pfs = this.pfs.map(function(pf, i) { 14 | return 15 | {is_rdp ? : pf[0]} 16 | {args.length ? svg_arrow : ""} 17 | {pf[1] || "localhost"} 18 | {pf[2]} 19 | {args.length ? "" : {svg_cancel}} 20 | ; 21 | }); 22 | return
23 | {pfs.length ?
24 | Listening ...
25 | Don't close this window while you are using the tunnel 26 |
: ""} 27 | 28 | 29 | 30 | 31 | 33 | 34 | {args.length ? "" : } 35 | 36 | 37 | 38 | {args.length ? "" : 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | } 47 | {pfs} 48 | 49 |
Local Port 32 | Remote HostRemote PortAction
{svg_arrow}
; 50 | } 51 | 52 | event click $(#add) () { 53 | var port = ($(#port).value || "").toInteger() || 0; 54 | var remote_host = $(#remote-host).value || ""; 55 | var remote_port = ($(#remote-port).value || "").toInteger() || 0; 56 | if (port <= 0 || remote_port <= 0) return; 57 | handler.add_port_forward(port, remote_host, remote_port); 58 | this.update(); 59 | } 60 | 61 | event click $(#new-rdp) { 62 | handler.new_rdp(); 63 | } 64 | 65 | event click $(.remove svg) (_, me) { 66 | var pf = this.pfs[me.parent.parent.index - 1]; 67 | handler.remove_port_forward(pf[0]); 68 | this.update(); 69 | } 70 | } 71 | 72 | function initializePortForward() 73 | { 74 | $(#file-transfer-wrapper).content(); 75 | $(#video-wrapper).style.set { visibility: "hidden", position: "absolute" }; 76 | $(#file-transfer-wrapper).style.set { display: "block" }; 77 | } 78 | -------------------------------------------------------------------------------- /libs/rust-sciter/src/capi/scvalue.rs: -------------------------------------------------------------------------------- 1 | //! Sciter value, native C interface. 2 | 3 | #![allow(non_snake_case, non_camel_case_types)] 4 | #![allow(dead_code)] 5 | 6 | use capi::sctypes::*; 7 | 8 | /// A JSON value. 9 | /// 10 | /// An opaque union that can hold different types of values: numbers, strings, arrays, objects, etc. 11 | #[repr(C)] 12 | #[derive(Debug, Clone)] 13 | pub struct VALUE 14 | { 15 | /// Value type. 16 | pub t: VALUE_TYPE, 17 | 18 | /// Value unit type. 19 | pub u: UINT, 20 | 21 | /// Value data. 22 | pub d: UINT64, 23 | } 24 | 25 | impl Default for VALUE { 26 | fn default() -> Self { 27 | VALUE { t: VALUE_TYPE::T_UNDEFINED, u: 0, d: 0 } 28 | } 29 | } 30 | 31 | #[repr(C)] 32 | #[derive(Debug, PartialOrd, PartialEq)] 33 | pub enum VALUE_RESULT 34 | { 35 | OK_TRUE = -1, 36 | OK = 0, 37 | BAD_PARAMETER = 1, 38 | INCOMPATIBLE_TYPE = 2, 39 | } 40 | 41 | impl std::error::Error for VALUE_RESULT {} 42 | 43 | impl std::fmt::Display for VALUE_RESULT { 44 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 45 | write!(f, "{:?}", self) 46 | } 47 | } 48 | 49 | 50 | #[repr(C)] 51 | #[derive(Debug, PartialOrd, PartialEq)] 52 | pub enum VALUE_STRING_CVT_TYPE { 53 | SIMPLE = 0, 54 | JSON_LITERAL = 1, 55 | JSON_MAP = 2, 56 | XJSON_LITERAL = 3, 57 | } 58 | 59 | 60 | /// Type identifier of the value. 61 | #[repr(C)] 62 | #[derive(Debug, Copy, Clone, PartialOrd, PartialEq)] 63 | pub enum VALUE_TYPE { 64 | T_UNDEFINED = 0, 65 | T_NULL = 1, 66 | T_BOOL, 67 | T_INT, 68 | T_FLOAT, 69 | T_STRING, 70 | T_DATE, 71 | T_CURRENCY, 72 | T_LENGTH, 73 | T_ARRAY, 74 | T_MAP, 75 | T_FUNCTION, 76 | T_BYTES, 77 | T_OBJECT, 78 | T_DOM_OBJECT, 79 | T_RESOURCE, 80 | T_RANGE, 81 | T_DURATION, 82 | T_ANGLE, 83 | T_COLOR, 84 | T_ENUM, 85 | T_ASSET, 86 | 87 | T_UNKNOWN, 88 | } 89 | 90 | #[repr(C)] 91 | #[derive(Debug, PartialOrd, PartialEq)] 92 | pub enum VALUE_UNIT_UNDEFINED 93 | { 94 | UT_NOTHING = 1, 95 | } 96 | 97 | #[repr(C)] 98 | #[derive(Debug, PartialOrd, PartialEq)] 99 | pub enum VALUE_UNIT_TYPE_STRING 100 | { 101 | STRING = 0, // string 102 | ERROR = 1, // is an error string 103 | SECURE = 2, // secure string ("wiped" on destroy) 104 | URL = 3, // url(...) 105 | SELECTOR = 4, // selector(...) 106 | FILE = 0xfffe, // file name 107 | SYMBOL = 0xffff, // symbol in tiscript sense 108 | } 109 | 110 | // Sciter or TIScript specific 111 | #[repr(C)] 112 | #[derive(Debug, PartialOrd, PartialEq)] 113 | pub enum VALUE_UNIT_TYPE_OBJECT 114 | { 115 | ARRAY = 0, // type T_OBJECT of type Array 116 | OBJECT = 1, // type T_OBJECT of type Object 117 | CLASS = 2, // type T_OBJECT of type Class (class or namespace) 118 | NATIVE = 3, // type T_OBJECT of native Type with data slot (LPVOID) 119 | FUNCTION = 4, // type T_OBJECT of type Function 120 | ERROR = 5, // type T_OBJECT of type Error 121 | } 122 | 123 | pub type NATIVE_FUNCTOR_INVOKE = extern "C" fn (tag: LPVOID, argc: UINT, argv: *const VALUE, retval: * mut VALUE); 124 | pub type NATIVE_FUNCTOR_RELEASE = extern "C" fn (tag: LPVOID); 125 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/threads.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Threads demo 4 | 13 | 32 | 33 | 34 |

Sciter UI, threads demo

35 |
36 |
37 | 38 | 39 |
40 |
41 |

The Start Task onClick handler is defined as

42 |
43 | $(#start-task).onClick = function()
44 | {
45 |   var taskElem = $(div#tasks > select)
46 |       .$append(<option>Task { ++taskNo }
47 |                <progress max=100 />
48 |                <span.result /></option>);
49 |   function onProgress(p100) {
50 |     taskElem.$(progress).value = p100;
51 |   }
52 |   function onDone(taskId) {
53 |     taskElem.$(span.result).text = "Done!";
54 |     taskElem.$(progress).remove();
55 |   }
56 |   view.exec_task(taskId, onProgress, onDone);
57 | }
58 |       
59 | 60 |

It defines couple of callback functions and calls view.exec_task() with them.

61 |

The view.exec_task() native method is implemented in EventHandler::exec_task().

62 |

The EventHandler::exec_task() starts worker thread passing taskNo, onProgress and 63 | onDone parameters to it.

64 |

Worker thread body is defined in Rust code as:

65 |
66 | // worker thread body, simulate time consuming task
67 | fn thread_body(task_no: i32, progress: Value, done: Value)
68 | {
69 |   for i in 1..100 {
70 |     std::thread::sleep(std::time::Duration::from_millis(100));
71 |     progress.call(None, &make_args!(i), None).unwrap(); // report task progress
72 |   }
73 |   // report task completion,
74 |   // we can pass some result data here, for now just taskId
75 |   done.call(None, &make_args!(task_no), None).unwrap();
76 | }
77 |       
78 |

As you see it calls passed callback functions.

79 |
80 |
81 | 82 | 83 | -------------------------------------------------------------------------------- /libs/rust-sciter/src/capi/sctypes.rs: -------------------------------------------------------------------------------- 1 | //! Sciter platform-dependent types. 2 | 3 | #![allow(non_camel_case_types, non_snake_case)] 4 | 5 | extern crate libc; 6 | 7 | use self::libc::*; 8 | 9 | 10 | // common 11 | MAKE_HANDLE!(#[doc = "Window native handle."] HWINDOW, _HWINDOW); // HWND or NSView* or GtkWidget* 12 | MAKE_HANDLE!(#[doc = "Archive native handle."] HSARCHIVE, _HSARCHIVE); 13 | 14 | pub type BYTE = u8; 15 | pub type INT = i32; 16 | pub type LONG = i32; 17 | pub type UINT = u32; 18 | pub type INT64 = i64; 19 | pub type UINT64 = u64; 20 | 21 | pub type FLOAT_VALUE = f64; 22 | 23 | pub type WPARAM = size_t; 24 | pub type LPARAM = ssize_t; 25 | 26 | pub type UINT_PTR = uintptr_t; 27 | pub type LRESULT = ssize_t; 28 | 29 | pub type CHAR = c_char; 30 | pub type LPSTR = *mut CHAR; 31 | pub type LPCSTR = *const CHAR; 32 | 33 | pub type WCHAR = u16; 34 | pub type LPWSTR = *mut WCHAR; 35 | pub type LPCWSTR = *const WCHAR; 36 | 37 | pub type LPCBYTE = *const BYTE; 38 | pub type LPUINT = *mut UINT; 39 | 40 | pub type VOID = c_void; 41 | pub type LPVOID = *mut VOID; 42 | pub type LPCVOID = *const VOID; 43 | 44 | #[cfg(windows)] 45 | pub type BOOL = i32; 46 | 47 | #[cfg(not(windows))] 48 | pub type BOOL = i8; 49 | 50 | pub type PBOOL = *mut BOOL; 51 | 52 | /// Defines the coordinates of the upper-left and lower-right corners of a rectangle. 53 | #[repr(C)] 54 | #[derive(Clone, Copy, PartialEq)] 55 | #[derive(Default, Debug)] 56 | pub struct RECT { 57 | pub left: LONG, 58 | pub top: LONG, 59 | pub right: LONG, 60 | pub bottom: LONG, 61 | } 62 | pub type LPRECT = *mut RECT; 63 | pub type LPCRECT = *const RECT; 64 | 65 | impl RECT { 66 | /// Calculate the height of the rect. 67 | pub fn height(&self) -> LONG { 68 | self.bottom - self.top 69 | } 70 | 71 | /// Calculate the width of the rect. 72 | pub fn width(&self) -> LONG { 73 | self.right - self.left 74 | } 75 | 76 | /// Return the size of the rect in width and height form. 77 | pub fn size(&self) -> SIZE { 78 | SIZE { 79 | cx: self.width(), 80 | cy: self.height(), 81 | } 82 | } 83 | 84 | /// Returns the top-left point of the rect. 85 | pub fn topleft(&self) -> POINT { 86 | POINT { 87 | x: self.left, 88 | y: self.top, 89 | } 90 | } 91 | } 92 | 93 | /// Defines the `x` and `y` coordinates of a point. 94 | #[repr(C)] 95 | #[derive(Clone, Copy, PartialEq)] 96 | #[derive(Default, Debug)] 97 | pub struct POINT { 98 | pub x: LONG, 99 | pub y: LONG, 100 | } 101 | pub type LPPOINT = *mut POINT; 102 | 103 | /// Specifies the width and height of a rectangle. 104 | #[repr(C)] 105 | #[derive(Clone, Copy, PartialEq)] 106 | #[derive(Default, Debug)] 107 | pub struct SIZE { 108 | pub cx: LONG, 109 | pub cy: LONG, 110 | } 111 | pub type LPSIZE = *mut SIZE; 112 | 113 | 114 | #[cfg(windows)] 115 | #[repr(C)] 116 | #[derive(Debug)] 117 | pub struct MSG { 118 | pub hwnd: HWINDOW, 119 | pub message: UINT, 120 | pub wParam: WPARAM, 121 | pub lParam: LPARAM, 122 | pub time: UINT, 123 | pub pt: POINT, 124 | } 125 | #[cfg(windows)] 126 | pub type LPMSG = *mut MSG; 127 | 128 | -------------------------------------------------------------------------------- /libs/scrap/src/common/dxgi.rs: -------------------------------------------------------------------------------- 1 | use crate::dxgi; 2 | use std::io::ErrorKind::{NotFound, TimedOut, WouldBlock}; 3 | use std::{io, ops}; 4 | 5 | pub struct Capturer { 6 | inner: dxgi::Capturer, 7 | width: usize, 8 | height: usize, 9 | } 10 | 11 | impl Capturer { 12 | pub fn new(display: Display, yuv: bool) -> io::Result { 13 | let width = display.width(); 14 | let height = display.height(); 15 | let inner = dxgi::Capturer::new(display.0, yuv)?; 16 | Ok(Capturer { 17 | inner, 18 | width, 19 | height, 20 | }) 21 | } 22 | 23 | pub fn is_gdi(&self) -> bool { 24 | self.inner.is_gdi() 25 | } 26 | 27 | pub fn set_gdi(&mut self) -> bool { 28 | self.inner.set_gdi() 29 | } 30 | 31 | pub fn cancel_gdi(&mut self) { 32 | self.inner.cancel_gdi() 33 | } 34 | 35 | pub fn width(&self) -> usize { 36 | self.width 37 | } 38 | 39 | pub fn height(&self) -> usize { 40 | self.height 41 | } 42 | 43 | pub fn frame<'a>(&'a mut self, timeout_ms: u32) -> io::Result> { 44 | match self.inner.frame(timeout_ms) { 45 | Ok(frame) => Ok(Frame(frame)), 46 | Err(ref error) if error.kind() == TimedOut => Err(WouldBlock.into()), 47 | Err(error) => Err(error), 48 | } 49 | } 50 | } 51 | 52 | pub struct Frame<'a>(&'a [u8]); 53 | 54 | impl<'a> ops::Deref for Frame<'a> { 55 | type Target = [u8]; 56 | fn deref(&self) -> &[u8] { 57 | self.0 58 | } 59 | } 60 | 61 | pub struct Display(dxgi::Display); 62 | 63 | impl Display { 64 | pub fn primary() -> io::Result { 65 | // not implemented yet 66 | Err(NotFound.into()) 67 | } 68 | 69 | pub fn all() -> io::Result> { 70 | let tmp = Self::all_().unwrap_or(Default::default()); 71 | if tmp.is_empty() { 72 | println!("Display got from gdi"); 73 | return Ok(dxgi::Displays::get_from_gdi() 74 | .drain(..) 75 | .map(Display) 76 | .collect::>()); 77 | } 78 | Ok(tmp) 79 | } 80 | 81 | fn all_() -> io::Result> { 82 | Ok(dxgi::Displays::new()?.map(Display).collect::>()) 83 | } 84 | 85 | pub fn width(&self) -> usize { 86 | self.0.width() as usize 87 | } 88 | 89 | pub fn height(&self) -> usize { 90 | self.0.height() as usize 91 | } 92 | 93 | pub fn name(&self) -> String { 94 | use std::ffi::OsString; 95 | use std::os::windows::prelude::*; 96 | OsString::from_wide(self.0.name()) 97 | .to_string_lossy() 98 | .to_string() 99 | } 100 | 101 | pub fn is_online(&self) -> bool { 102 | self.0.is_online() 103 | } 104 | 105 | pub fn origin(&self) -> (i32, i32) { 106 | self.0.origin() 107 | } 108 | 109 | pub fn is_primary(&self) -> bool { 110 | // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-devmodea 111 | self.origin() == (0, 0) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /libs/scrap/src/quartz/capturer.rs: -------------------------------------------------------------------------------- 1 | use std::ptr; 2 | 3 | use block::{Block, ConcreteBlock}; 4 | use libc::c_void; 5 | use std::sync::{Arc, Mutex}; 6 | 7 | use super::config::Config; 8 | use super::display::Display; 9 | use super::ffi::*; 10 | use super::frame::Frame; 11 | 12 | pub struct Capturer { 13 | stream: CGDisplayStreamRef, 14 | queue: DispatchQueue, 15 | 16 | width: usize, 17 | height: usize, 18 | format: PixelFormat, 19 | display: Display, 20 | stopped: Arc>, 21 | } 22 | 23 | impl Capturer { 24 | pub fn new( 25 | display: Display, 26 | width: usize, 27 | height: usize, 28 | format: PixelFormat, 29 | config: Config, 30 | handler: F, 31 | ) -> Result { 32 | let stopped = Arc::new(Mutex::new(false)); 33 | let cloned_stopped = stopped.clone(); 34 | let handler: FrameAvailableHandler = ConcreteBlock::new(move |status, _, surface, _| { 35 | use self::CGDisplayStreamFrameStatus::*; 36 | if status == Stopped { 37 | let mut lock = cloned_stopped.lock().unwrap(); 38 | *lock = true; 39 | return; 40 | } 41 | if status == FrameComplete { 42 | handler(unsafe { Frame::new(surface) }); 43 | } 44 | }) 45 | .copy(); 46 | 47 | let queue = unsafe { 48 | dispatch_queue_create( 49 | b"quadrupleslap.scrap\0".as_ptr() as *const i8, 50 | ptr::null_mut(), 51 | ) 52 | }; 53 | 54 | let stream = unsafe { 55 | let config = config.build(); 56 | let stream = CGDisplayStreamCreateWithDispatchQueue( 57 | display.id(), 58 | width, 59 | height, 60 | format, 61 | config, 62 | queue, 63 | &*handler as *const Block<_, _> as *const c_void, 64 | ); 65 | CFRelease(config); 66 | stream 67 | }; 68 | 69 | match unsafe { CGDisplayStreamStart(stream) } { 70 | CGError::Success => Ok(Capturer { 71 | stream, 72 | queue, 73 | width, 74 | height, 75 | format, 76 | display, 77 | stopped, 78 | }), 79 | x => Err(x), 80 | } 81 | } 82 | 83 | pub fn width(&self) -> usize { 84 | self.width 85 | } 86 | pub fn height(&self) -> usize { 87 | self.height 88 | } 89 | pub fn format(&self) -> PixelFormat { 90 | self.format 91 | } 92 | pub fn display(&self) -> Display { 93 | self.display 94 | } 95 | } 96 | 97 | impl Drop for Capturer { 98 | fn drop(&mut self) { 99 | unsafe { 100 | let _ = CGDisplayStreamStop(self.stream); 101 | loop { 102 | if *self.stopped.lock().unwrap() { 103 | break; 104 | } 105 | std::thread::sleep(std::time::Duration::from_millis(30)); 106 | } 107 | CFRelease(self.stream); 108 | dispatch_release(self.queue); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use crate::client::*; 2 | use hbb_common::{ 3 | config::PeerConfig, 4 | log, 5 | message_proto::*, 6 | protobuf::Message as _, 7 | tokio::{self, sync::mpsc}, 8 | Stream, 9 | }; 10 | use std::sync::{Arc, RwLock}; 11 | 12 | #[derive(Clone)] 13 | pub struct Session { 14 | id: String, 15 | lc: Arc>, 16 | sender: mpsc::UnboundedSender, 17 | password: String, 18 | } 19 | 20 | impl Session { 21 | pub fn new(id: &str, sender: mpsc::UnboundedSender) -> Self { 22 | let mut password = "".to_owned(); 23 | if PeerConfig::load(id).password.is_empty() { 24 | password = rpassword::read_password_from_tty(Some("Enter password: ")).unwrap(); 25 | } 26 | let session = Self { 27 | id: id.to_owned(), 28 | sender, 29 | password, 30 | lc: Default::default(), 31 | }; 32 | session 33 | .lc 34 | .write() 35 | .unwrap() 36 | .initialize(id.to_owned(), false, true); 37 | session 38 | } 39 | } 40 | 41 | #[async_trait] 42 | impl Interface for Session { 43 | fn msgbox(&self, msgtype: &str, title: &str, text: &str) { 44 | if msgtype == "input-password" { 45 | self.sender 46 | .send(Data::Login((self.password.clone(), true))) 47 | .ok(); 48 | } else if msgtype == "re-input-password" { 49 | log::error!("{}: {}", title, text); 50 | let pass = rpassword::read_password_from_tty(Some("Enter password: ")).unwrap(); 51 | self.sender.send(Data::Login((pass, true))).ok(); 52 | } else if msgtype.contains("error") { 53 | log::error!("{}: {}: {}", msgtype, title, text); 54 | } else { 55 | log::info!("{}: {}: {}", msgtype, title, text); 56 | } 57 | } 58 | 59 | fn handle_login_error(&mut self, err: &str) -> bool { 60 | self.lc.write().unwrap().handle_login_error(err, self) 61 | } 62 | 63 | fn handle_peer_info(&mut self, pi: PeerInfo) { 64 | let username = self.lc.read().unwrap().get_username(&pi); 65 | self.lc.write().unwrap().handle_peer_info(username, pi); 66 | } 67 | 68 | async fn handle_hash(&mut self, hash: Hash, peer: &mut Stream) { 69 | handle_hash(self.lc.clone(), hash, self, peer).await; 70 | } 71 | 72 | async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream) { 73 | handle_login_from_ui(self.lc.clone(), password, remember, peer).await; 74 | } 75 | 76 | async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) { 77 | handle_test_delay(t, peer).await; 78 | } 79 | } 80 | 81 | #[tokio::main(basic_scheduler)] 82 | pub async fn start_one_port_forward(id: String, port: i32, remote_host: String, remote_port: i32) { 83 | crate::common::test_rendezvous_server(); 84 | crate::common::test_nat_type(); 85 | let (sender, mut receiver) = mpsc::unbounded_channel::(); 86 | let handler = Session::new(&id, sender); 87 | handler.lc.write().unwrap().port_forward = (remote_host, remote_port); 88 | if let Err(err) = 89 | crate::port_forward::listen(handler.id.clone(), port, handler.clone(), receiver).await 90 | { 91 | log::error!("Failed to listen on {}: {}", port, err); 92 | } 93 | log::info!("port forward (:{}) exit", port); 94 | } 95 | -------------------------------------------------------------------------------- /libs/hbb_common/protos/rendezvous.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package hbb; 3 | 4 | message RegisterPeer { 5 | string id = 1; 6 | int32 serial = 2; 7 | } 8 | 9 | message RegisterPeerResponse { bool request_pk = 2; } 10 | 11 | message PunchHoleRequest { 12 | string id = 1; 13 | NatType nat_type = 2; 14 | } 15 | 16 | message PunchHole { 17 | bytes socket_addr = 1; 18 | string relay_server = 2; 19 | NatType nat_type = 3; 20 | } 21 | 22 | message TestNatRequest { 23 | int32 serial = 1; 24 | } 25 | 26 | // per my test, uint/int has no difference in encoding, int not good for negative, use sint for negative 27 | message TestNatResponse { 28 | int32 port = 1; 29 | ConfigUpdate cu = 2; // for mobile 30 | } 31 | 32 | enum NatType { 33 | UNKNOWN_NAT = 0; 34 | ASYMMETRIC = 1; 35 | SYMMETRIC = 2; 36 | } 37 | 38 | message PunchHoleSent { 39 | bytes socket_addr = 1; 40 | string id = 2; 41 | string relay_server = 3; 42 | NatType nat_type = 4; 43 | } 44 | 45 | message RegisterPk { 46 | string id = 1; 47 | bytes uuid = 2; 48 | bytes pk = 3; 49 | } 50 | 51 | message RegisterPkResponse { 52 | enum Result { 53 | OK = 1; 54 | UUID_MISMATCH = 2; 55 | } 56 | Result result = 1; 57 | } 58 | 59 | message PunchHoleResponse { 60 | bytes socket_addr = 1; 61 | bytes pk = 2; 62 | enum Failure { 63 | ID_NOT_EXIST = 1; 64 | OFFLINE = 2; 65 | } 66 | Failure failure = 3; 67 | string relay_server = 4; 68 | oneof union { 69 | NatType nat_type = 5; 70 | bool is_local = 6; 71 | } 72 | } 73 | 74 | message ConfigUpdate { 75 | int32 serial = 1; 76 | repeated string rendezvous_servers = 2; 77 | } 78 | 79 | message RequestRelay { 80 | string id = 1; 81 | string uuid = 2; 82 | bytes socket_addr = 3; 83 | string relay_server = 4; 84 | bool secure = 5; 85 | } 86 | 87 | message RelayResponse { 88 | bytes socket_addr = 1; 89 | string uuid = 2; 90 | string relay_server = 3; 91 | oneof union { 92 | string id = 4; 93 | bytes pk = 5; 94 | } 95 | } 96 | 97 | message SoftwareUpdate { string url = 1; } 98 | 99 | // if in same intranet, punch hole won't work both for udp and tcp, 100 | // even some router has below connection error if we connect itself, 101 | // { kind: Other, error: "could not resolve to any address" }, 102 | // so we request local address to connect. 103 | message FetchLocalAddr { 104 | bytes socket_addr = 1; 105 | string relay_server = 2; 106 | } 107 | 108 | message LocalAddr { 109 | bytes socket_addr = 1; 110 | bytes local_addr = 2; 111 | string relay_server = 3; 112 | string id = 4; 113 | } 114 | 115 | message RendezvousMessage { 116 | oneof union { 117 | RegisterPeer register_peer = 6; 118 | RegisterPeerResponse register_peer_response = 7; 119 | PunchHoleRequest punch_hole_request = 8; 120 | PunchHole punch_hole = 9; 121 | PunchHoleSent punch_hole_sent = 10; 122 | PunchHoleResponse punch_hole_response = 11; 123 | FetchLocalAddr fetch_local_addr = 12; 124 | LocalAddr local_addr = 13; 125 | ConfigUpdate configure_update = 14; 126 | RegisterPk register_pk = 15; 127 | RegisterPkResponse register_pk_response = 16; 128 | SoftwareUpdate software_update = 17; 129 | RequestRelay request_relay = 18; 130 | RelayResponse relay_response = 19; 131 | TestNatRequest test_nat_request = 20; 132 | TestNatResponse test_nat_response = 21; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustdesk" 3 | version = "1.1.2" 4 | authors = ["rustdesk "] 5 | edition = "2018" 6 | build= "build.rs" 7 | description = "A remote control software." 8 | 9 | [lib] 10 | crate-type = ["cdylib", "staticlib", "rlib"] 11 | 12 | [features] 13 | inline = [] 14 | cli = [] 15 | 16 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 17 | 18 | [dependencies] 19 | whoami = "0.9" 20 | scrap = { path = "libs/scrap" } 21 | hbb_common = { path = "libs/hbb_common" } 22 | enigo = { path = "libs/enigo" } 23 | serde_derive = "1.0" 24 | serde = "1.0" 25 | serde_json = "1.0" 26 | cfg-if = "1.0" 27 | lazy_static = "1.4" 28 | sha2 = "0.9" 29 | repng = "0.2" 30 | libc = "0.2" 31 | parity-tokio-ipc = { path = "libs/parity-tokio-ipc" } 32 | flexi_logger = "0.16" 33 | runas = "0.2" 34 | magnum-opus = { path = "libs/magnum-opus" } 35 | dasp = { version = "0.11", features = ["signal", "interpolate-linear", "interpolate"] } 36 | async-trait = "0.1" 37 | crc32fast = "1.2" 38 | uuid = { version = "0.8", features = ["v4"] } 39 | copypasta = "0.7" 40 | clap = "2.33" 41 | rpassword = "5.0" 42 | 43 | [target.'cfg(not(any(target_os = "android")))'.dependencies] 44 | cpal = { git = "https://github.com/rustaudio/cpal" } 45 | 46 | [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 47 | machine-uid = "0.2" 48 | mac_address = "1.1" 49 | sciter-rs = { path = "libs/rust-sciter" } 50 | 51 | [target.'cfg(target_os = "windows")'.dependencies] 52 | systray = { path = "libs/systray-rs" } 53 | winapi = { version = "0.3", features = ["winuser"] } 54 | winreg = "0.7" 55 | windows-service = { git = 'https://github.com/mullvad/windows-service-rs.git' } 56 | 57 | [target.'cfg(target_os = "macos")'.dependencies] 58 | objc = "0.2" 59 | cocoa = "0.24" 60 | dispatch = "0.2" 61 | core-foundation = "0.9" 62 | core-graphics = "0.22" 63 | 64 | [target.'cfg(target_os = "linux")'.dependencies] 65 | libpulse-simple-binding = "2.16" 66 | libpulse-binding = "2.16" 67 | rust-pulsectl = { path = "libs/pulsectl" } 68 | ctrlc = "3.1" 69 | 70 | [target.'cfg(not(any(target_os = "windows", target_os = "android", target_os = "ios")))'.dependencies] 71 | psutil = "3.2" 72 | 73 | [target.'cfg(target_os = "android")'.dependencies] 74 | android_logger = "0.9" 75 | 76 | [workspace] 77 | members = ["libs/scrap", "libs/hbb_common", "libs/enigo"] 78 | 79 | [package.metadata.winres] 80 | LegalCopyright = "Copyright © 2020" 81 | # this FileDescription overrides package.description 82 | FileDescription = "RustDesk" 83 | 84 | [target.'cfg(target_os="windows")'.build-dependencies] 85 | winres = "0.1" 86 | winapi = { version = "0.3", features = [ "winnt" ] } 87 | 88 | [build-dependencies] 89 | cc = "1.0" 90 | hbb_common = { path = "libs/hbb_common" } 91 | 92 | [dev-dependencies] 93 | hound = "3.4" 94 | 95 | [package.metadata.bundle] 96 | name = "RustDesk" 97 | identifier = "com.carriez.rustdesk" 98 | icon = ["32x32.png", "128x128.png", "128x128@2x.png"] 99 | deb_depends = ["libgtk-3-0", "libxcb-randr0", "libxdo3", "libxfixes3", "libxcb-shape0", "libxcb-xfixes0", "libasound2", "libsystemd0", "pulseaudio"] 100 | osx_minimum_system_version = "10.14" 101 | 102 | #https://github.com/johnthagen/min-sized-rust 103 | #!!! rembember call "strip target/release/rustdesk" 104 | # which reduce binary size a lot 105 | [profile.release] 106 | #lto = true 107 | #codegen-units = 1 108 | #panic = 'abort' 109 | #opt-level = 'z' # only have smaller size after strip 110 | -------------------------------------------------------------------------------- /libs/scrap/src/x11/server.rs: -------------------------------------------------------------------------------- 1 | use std::ptr; 2 | use std::rc::Rc; 3 | 4 | use super::ffi::*; 5 | use super::DisplayIter; 6 | 7 | #[derive(Debug)] 8 | pub struct Server { 9 | raw: *mut xcb_connection_t, 10 | screenp: i32, 11 | setup: *const xcb_setup_t, 12 | } 13 | 14 | /* 15 | use std::cell::RefCell; 16 | thread_local! { 17 | static SERVER: RefCell>> = RefCell::new(None); 18 | } 19 | */ 20 | 21 | impl Server { 22 | pub fn displays(slf: Rc) -> DisplayIter { 23 | unsafe { DisplayIter::new(slf) } 24 | } 25 | 26 | pub fn default() -> Result, Error> { 27 | Ok(Rc::new(Server::connect(ptr::null())?)) 28 | /* 29 | let mut res = Err(Error::from(0)); 30 | SERVER.with(|xdo| { 31 | if let Ok(mut server) = xdo.try_borrow_mut() { 32 | if server.is_some() { 33 | unsafe { 34 | if 0 != xcb_connection_has_error(server.as_ref().unwrap().raw) { 35 | *server = None; 36 | println!("Reset x11 connection"); 37 | } 38 | } 39 | } 40 | if server.is_none() { 41 | println!("New x11 connection"); 42 | match Server::connect(ptr::null()) { 43 | Ok(s) => { 44 | let s = Rc::new(s); 45 | res = Ok(s.clone()); 46 | *server = Some(s); 47 | } 48 | Err(err) => { 49 | res = Err(err); 50 | } 51 | } 52 | } else { 53 | res = Ok(server.as_ref().map(|x| x.clone()).unwrap()); 54 | } 55 | } 56 | }); 57 | res 58 | */ 59 | } 60 | 61 | pub fn connect(addr: *const i8) -> Result { 62 | unsafe { 63 | let mut screenp = 0; 64 | let raw = xcb_connect(addr, &mut screenp); 65 | 66 | let error = xcb_connection_has_error(raw); 67 | if error != 0 { 68 | xcb_disconnect(raw); 69 | Err(Error::from(error)) 70 | } else { 71 | let setup = xcb_get_setup(raw); 72 | Ok(Server { 73 | raw, 74 | screenp, 75 | setup, 76 | }) 77 | } 78 | } 79 | } 80 | 81 | pub fn raw(&self) -> *mut xcb_connection_t { 82 | self.raw 83 | } 84 | pub fn screenp(&self) -> i32 { 85 | self.screenp 86 | } 87 | pub fn setup(&self) -> *const xcb_setup_t { 88 | self.setup 89 | } 90 | } 91 | 92 | impl Drop for Server { 93 | fn drop(&mut self) { 94 | unsafe { 95 | xcb_disconnect(self.raw); 96 | } 97 | } 98 | } 99 | 100 | #[derive(Clone, Copy, Debug)] 101 | pub enum Error { 102 | Generic, 103 | UnsupportedExtension, 104 | InsufficientMemory, 105 | RequestTooLong, 106 | ParseError, 107 | InvalidScreen, 108 | } 109 | 110 | impl From for Error { 111 | fn from(x: i32) -> Error { 112 | use self::Error::*; 113 | match x { 114 | 2 => UnsupportedExtension, 115 | 3 => InsufficientMemory, 116 | 4 => RequestTooLong, 117 | 5 => ParseError, 118 | 6 => InvalidScreen, 119 | _ => Generic, 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /libs/scrap/src/common/quartz.rs: -------------------------------------------------------------------------------- 1 | use crate::quartz; 2 | use std::marker::PhantomData; 3 | use std::sync::{Arc, Mutex, TryLockError}; 4 | use std::{io, mem, ops}; 5 | 6 | pub struct Capturer { 7 | inner: quartz::Capturer, 8 | frame: Arc>>, 9 | use_yuv: bool, 10 | i420: Vec, 11 | } 12 | 13 | impl Capturer { 14 | pub fn new(display: Display, use_yuv: bool) -> io::Result { 15 | let frame = Arc::new(Mutex::new(None)); 16 | 17 | let f = frame.clone(); 18 | let inner = quartz::Capturer::new( 19 | display.0, 20 | display.width(), 21 | display.height(), 22 | if use_yuv { 23 | quartz::PixelFormat::YCbCr420Full 24 | } else { 25 | quartz::PixelFormat::Argb8888 26 | }, 27 | Default::default(), 28 | move |inner| { 29 | if let Ok(mut f) = f.lock() { 30 | *f = Some(inner); 31 | } 32 | }, 33 | ) 34 | .map_err(|_| io::Error::from(io::ErrorKind::Other))?; 35 | 36 | Ok(Capturer { 37 | inner, 38 | frame, 39 | use_yuv, 40 | i420: Vec::new(), 41 | }) 42 | } 43 | 44 | pub fn width(&self) -> usize { 45 | self.inner.width() 46 | } 47 | 48 | pub fn height(&self) -> usize { 49 | self.inner.height() 50 | } 51 | 52 | pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result> { 53 | match self.frame.try_lock() { 54 | Ok(mut handle) => { 55 | let mut frame = None; 56 | mem::swap(&mut frame, &mut handle); 57 | 58 | match frame { 59 | Some(mut frame) => { 60 | if self.use_yuv { 61 | frame.nv12_to_i420(self.width(), self.height(), &mut self.i420); 62 | } 63 | Ok(Frame(frame, PhantomData)) 64 | } 65 | 66 | None => Err(io::ErrorKind::WouldBlock.into()), 67 | } 68 | } 69 | 70 | Err(TryLockError::WouldBlock) => Err(io::ErrorKind::WouldBlock.into()), 71 | 72 | Err(TryLockError::Poisoned(..)) => Err(io::ErrorKind::Other.into()), 73 | } 74 | } 75 | } 76 | 77 | pub struct Frame<'a>(quartz::Frame, PhantomData<&'a [u8]>); 78 | 79 | impl<'a> ops::Deref for Frame<'a> { 80 | type Target = [u8]; 81 | fn deref(&self) -> &[u8] { 82 | &*self.0 83 | } 84 | } 85 | 86 | pub struct Display(quartz::Display); 87 | 88 | impl Display { 89 | pub fn primary() -> io::Result { 90 | Ok(Display(quartz::Display::primary())) 91 | } 92 | 93 | pub fn all() -> io::Result> { 94 | Ok(quartz::Display::online() 95 | .map_err(|_| io::Error::from(io::ErrorKind::Other))? 96 | .into_iter() 97 | .map(Display) 98 | .collect()) 99 | } 100 | 101 | pub fn width(&self) -> usize { 102 | self.0.width() 103 | } 104 | 105 | pub fn height(&self) -> usize { 106 | self.0.height() 107 | } 108 | 109 | pub fn name(&self) -> String { 110 | self.0.id().to_string() 111 | } 112 | 113 | pub fn is_online(&self) -> bool { 114 | self.0.is_online() 115 | } 116 | 117 | pub fn origin(&self) -> (i32, i32) { 118 | let o = self.0.bounds().origin; 119 | (o.x as _, o.y as _) 120 | } 121 | 122 | pub fn is_primary(&self) -> bool { 123 | self.0.is_primary() 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /libs/scrap/src/x11/capturer.rs: -------------------------------------------------------------------------------- 1 | use std::{io, ptr, slice}; 2 | 3 | use libc; 4 | 5 | use super::ffi::*; 6 | use super::Display; 7 | 8 | pub struct Capturer { 9 | display: Display, 10 | shmid: i32, 11 | xcbid: u32, 12 | buffer: *const u8, 13 | 14 | size: usize, 15 | use_yuv: bool, 16 | yuv: Vec, 17 | } 18 | 19 | impl Capturer { 20 | pub fn new(display: Display, use_yuv: bool) -> io::Result { 21 | // Calculate dimensions. 22 | 23 | let pixel_width = 4; 24 | let rect = display.rect(); 25 | let size = (rect.w as usize) * (rect.h as usize) * pixel_width; 26 | 27 | // Create a shared memory segment. 28 | 29 | let shmid = unsafe { 30 | libc::shmget( 31 | libc::IPC_PRIVATE, 32 | size, 33 | // Everyone can do anything. 34 | libc::IPC_CREAT | 0o777, 35 | ) 36 | }; 37 | 38 | if shmid == -1 { 39 | return Err(io::Error::last_os_error()); 40 | } 41 | 42 | // Attach the segment to a readable address. 43 | 44 | let buffer = unsafe { libc::shmat(shmid, ptr::null(), libc::SHM_RDONLY) } as *mut u8; 45 | 46 | if buffer as isize == -1 { 47 | return Err(io::Error::last_os_error()); 48 | } 49 | 50 | // Attach the segment to XCB. 51 | 52 | let server = display.server().raw(); 53 | let xcbid = unsafe { xcb_generate_id(server) }; 54 | unsafe { 55 | xcb_shm_attach( 56 | server, 57 | xcbid, 58 | shmid as u32, 59 | 0, // False, i.e. not read-only. 60 | ); 61 | } 62 | 63 | let c = Capturer { 64 | display, 65 | shmid, 66 | xcbid, 67 | buffer, 68 | size, 69 | use_yuv, 70 | yuv: Vec::new(), 71 | }; 72 | Ok(c) 73 | } 74 | 75 | pub fn display(&self) -> &Display { 76 | &self.display 77 | } 78 | 79 | fn get_image(&self) { 80 | let rect = self.display.rect(); 81 | unsafe { 82 | let request = xcb_shm_get_image_unchecked( 83 | self.display.server().raw(), 84 | self.display.root(), 85 | rect.x, 86 | rect.y, 87 | rect.w, 88 | rect.h, 89 | !0, 90 | XCB_IMAGE_FORMAT_Z_PIXMAP, 91 | self.xcbid, 92 | 0, 93 | ); 94 | let response = 95 | xcb_shm_get_image_reply(self.display.server().raw(), request, ptr::null_mut()); 96 | libc::free(response as *mut _); 97 | } 98 | } 99 | 100 | pub fn frame<'b>(&'b mut self) -> &'b [u8] { 101 | self.get_image(); 102 | let result = unsafe { slice::from_raw_parts(self.buffer, self.size) }; 103 | if self.use_yuv { 104 | crate::common::bgra_to_i420(self.display.w(), self.display.h(), &result, &mut self.yuv); 105 | &self.yuv[..] 106 | } else { 107 | result 108 | } 109 | } 110 | } 111 | 112 | impl Drop for Capturer { 113 | fn drop(&mut self) { 114 | unsafe { 115 | // Detach segment from XCB. 116 | xcb_shm_detach(self.display.server().raw(), self.xcbid); 117 | // Detach segment from our space. 118 | libc::shmdt(self.buffer as *mut _); 119 | // Destroy the shared memory segment. 120 | libc::shmctl(self.shmid, libc::IPC_RMID, ptr::null_mut()); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /libs/scrap/examples/screenshot.rs: -------------------------------------------------------------------------------- 1 | extern crate repng; 2 | extern crate scrap; 3 | 4 | use std::fs::File; 5 | use std::io::ErrorKind::WouldBlock; 6 | use std::thread; 7 | use std::time::Duration; 8 | 9 | use scrap::{i420_to_rgb, Capturer, Display}; 10 | 11 | fn main() { 12 | let n = Display::all().unwrap().len(); 13 | for i in 0..n { 14 | record(i); 15 | } 16 | } 17 | 18 | fn get_display(i: usize) -> Display { 19 | Display::all().unwrap().remove(i) 20 | } 21 | 22 | fn record(i: usize) { 23 | let one_second = Duration::new(1, 0); 24 | let one_frame = one_second / 60; 25 | 26 | let display = get_display(i); 27 | let mut capturer = Capturer::new(display, false).expect("Couldn't begin capture."); 28 | let (w, h) = (capturer.width(), capturer.height()); 29 | 30 | loop { 31 | // Wait until there's a frame. 32 | 33 | let buffer = match capturer.frame(0) { 34 | Ok(buffer) => buffer, 35 | Err(error) => { 36 | if error.kind() == WouldBlock { 37 | // Keep spinning. 38 | thread::sleep(one_frame); 39 | continue; 40 | } else { 41 | panic!("Error: {}", error); 42 | } 43 | } 44 | }; 45 | 46 | println!("Captured! Saving..."); 47 | 48 | // Flip the BGRA image into a RGBA image. 49 | 50 | let mut bitflipped = Vec::with_capacity(w * h * 4); 51 | let stride = buffer.len() / h; 52 | 53 | for y in 0..h { 54 | for x in 0..w { 55 | let i = stride * y + 4 * x; 56 | bitflipped.extend_from_slice(&[buffer[i + 2], buffer[i + 1], buffer[i], 255]); 57 | } 58 | } 59 | 60 | // Save the image. 61 | 62 | let name = format!("screenshot{}_1.png", i); 63 | repng::encode( 64 | File::create(name.clone()).unwrap(), 65 | w as u32, 66 | h as u32, 67 | &bitflipped, 68 | ) 69 | .unwrap(); 70 | 71 | println!("Image saved to `{}`.", name); 72 | break; 73 | } 74 | 75 | drop(capturer); 76 | let display = get_display(i); 77 | let mut capturer = Capturer::new(display, true).expect("Couldn't begin capture."); 78 | let (w, h) = (capturer.width(), capturer.height()); 79 | 80 | loop { 81 | // Wait until there's a frame. 82 | 83 | let buffer = match capturer.frame(0) { 84 | Ok(buffer) => buffer, 85 | Err(error) => { 86 | if error.kind() == WouldBlock { 87 | // Keep spinning. 88 | thread::sleep(one_frame); 89 | continue; 90 | } else { 91 | panic!("Error: {}", error); 92 | } 93 | } 94 | }; 95 | 96 | println!("Captured! Saving..."); 97 | 98 | let mut frame = Default::default(); 99 | i420_to_rgb(w, h, &buffer, &mut frame); 100 | 101 | let mut bitflipped = Vec::with_capacity(w * h * 4); 102 | let stride = frame.len() / h; 103 | 104 | for y in 0..h { 105 | for x in 0..w { 106 | let i = stride * y + 3 * x; 107 | bitflipped.extend_from_slice(&[frame[i], frame[i + 1], frame[i + 2], 255]); 108 | } 109 | } 110 | let name = format!("screenshot{}_2.png", i); 111 | repng::encode( 112 | File::create(name.clone()).unwrap(), 113 | w as u32, 114 | h as u32, 115 | &bitflipped, 116 | ) 117 | .unwrap(); 118 | 119 | println!("Image saved to `{}`.", name); 120 | break; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /libs/rust-sciter/serde/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This component uses Sciter Engine, 2 | // copyright Terra Informatica Software, Inc. 3 | // (http://terrainformatica.com/). 4 | 5 | /*! 6 | 7 | [Serde](https://docs.rs/serde) support for [Sciter](https://docs.rs/sciter-rs) engine. 8 | 9 | While technically you could just use the `serde_json` crate and perform serialization via 10 | an intermediate string (something like `sciter::Value::from_str(&serde_json::to_string()?)?`), 11 | you can also use direct serialization between your data and `sciter::Value`. 12 | 13 | ## Supported types of Sciter value 14 | 15 | + Bool (`bool`) 16 | + Integer (`i8`-`i32`) 17 | + Float (`f32`-`f64`) 18 | + String (`&str`, `String`) 19 | + Bytes (`&[u8]`) 20 | + Array (`&[T]`, `Vec`) 21 | + Object (key-value mapping like `struct` or `HashMap`, `BTreeMap`, etc.) 22 | 23 | Unsupported: 24 | 25 | - Date 26 | - Currency 27 | - Length 28 | - Range 29 | - Duration 30 | - Angle 31 | - Color 32 | 33 | ## Supported types of the Serde data model 34 | 35 | * [x] `bool` 36 | * [x] integer types except the following: 37 | * [-] `i64`/`u64` - 64-bit integers stored as `f64` in Sciter 38 | * [x] strings 39 | * [x] byte arrays 40 | * [x] option 41 | * [x] unit (stored as `null`) 42 | * [x] unit struct (stored as `null`) 43 | * [x] unit variant (aka `enum`, stored just as enum index of `i32` type) 44 | * [x] newtype struct (aka `struct Io(u32)`, stored as underlaying value) 45 | * [-] newtype variant 46 | * [x] seq, like vector (stored as array) 47 | * [x] tuple (stored as array) 48 | * [x] tuple struct (stored as array) 49 | * [-] tuple variant 50 | * [x] map (stored as map) 51 | * [x] struct (stored as map) 52 | * [-] struct variant 53 | 54 | See the [Serde data model](https://serde.rs/data-model.html) for reference. 55 | 56 | # Examples 57 | 58 | ```rust 59 | extern crate sciter; 60 | extern crate sciter_serde; 61 | 62 | use sciter::Value; 63 | use sciter_serde::{from_value, to_value}; 64 | 65 | fn back_and_forth() { 66 | let v: Value = to_value(&true).unwrap(); 67 | let b: bool = from_value(&v).unwrap(); 68 | assert_eq!(b, true); 69 | } 70 | 71 | fn main() { 72 | 73 | // bool 74 | let v: Value = to_value(&true).unwrap(); 75 | assert!(v.is_bool()); 76 | assert_eq!(v, Value::from(true)); 77 | 78 | // numbers 79 | let v = to_value(&12u32).unwrap(); 80 | assert_eq!(v, 12.into()); 81 | 82 | let v = to_value(& 42.0f64).unwrap(); 83 | assert_eq!(v, 42.0f64.into()); 84 | 85 | // strings 86 | let v = to_value("hello").unwrap(); 87 | assert_eq!(v, "hello".into()); 88 | 89 | // arrays 90 | let a = [1,2,3]; 91 | let v = to_value(&a).unwrap(); 92 | assert_eq!(v, a.iter().cloned().collect()); 93 | 94 | // maps 95 | let m = { 96 | use std::collections::BTreeMap; 97 | let mut m = BTreeMap::new(); 98 | m.insert("17", 17); 99 | m.insert("42", 42); 100 | m 101 | }; 102 | let v = to_value(&m).unwrap(); 103 | assert_eq!(v, Value::parse(r#"{ "17": 17, "42": 42 }"#).unwrap()); 104 | } 105 | ``` 106 | 107 | With derived serialization: 108 | 109 | ```rust 110 | # #![doc(test(no_crate_inject))] 111 | #[macro_use] 112 | extern crate serde_derive; 113 | extern crate serde; 114 | 115 | extern crate sciter; 116 | extern crate sciter_serde; 117 | 118 | use sciter::Value; 119 | use sciter_serde::to_value; 120 | 121 | fn main() { 122 | 123 | // structs 124 | #[derive(Serialize)] 125 | struct Test { 126 | x: i32, 127 | y: i32, 128 | } 129 | 130 | let v = to_value(&Test {x: 1, y: 2}).unwrap(); 131 | assert_eq!(v, Value::parse(r#"{ "x": 1, "y": 2 }"#).unwrap()); 132 | } 133 | 134 | ``` 135 | 136 | */ 137 | #![allow(clippy::redundant_field_names)] 138 | #![allow(clippy::tabs_in_doc_comments)] 139 | 140 | #[macro_use] 141 | extern crate serde; 142 | extern crate sciter; 143 | 144 | 145 | mod error; 146 | mod ser; 147 | mod de; 148 | 149 | #[doc(inline)] 150 | pub use ser::to_value; 151 | 152 | #[doc(inline)] 153 | pub use de::from_value; 154 | 155 | pub use error::{Result, Error}; 156 | -------------------------------------------------------------------------------- /libs/pulsectl/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "autocfg" 5 | version = "1.0.1" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 8 | 9 | [[package]] 10 | name = "libc" 11 | version = "0.2.65" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" 14 | 15 | [[package]] 16 | name = "libpulse-binding" 17 | version = "2.18.1" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "fe925a4d3a96961316c9c1488f97a95938a6093f0d4691eec888776057ce965e" 20 | dependencies = [ 21 | "libc", 22 | "libpulse-sys", 23 | "num-derive", 24 | "num-traits", 25 | "winapi", 26 | ] 27 | 28 | [[package]] 29 | name = "libpulse-sys" 30 | version = "1.15.1" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "2d9073c83dda6aff9b611dc368e8db6e0aa29027546d8800a18b4417e182b4d5" 33 | dependencies = [ 34 | "libc", 35 | "num-derive", 36 | "num-traits", 37 | "pkg-config", 38 | "winapi", 39 | ] 40 | 41 | [[package]] 42 | name = "num-derive" 43 | version = "0.3.3" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 46 | dependencies = [ 47 | "proc-macro2", 48 | "quote", 49 | "syn", 50 | ] 51 | 52 | [[package]] 53 | name = "num-traits" 54 | version = "0.2.14" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 57 | dependencies = [ 58 | "autocfg", 59 | ] 60 | 61 | [[package]] 62 | name = "pkg-config" 63 | version = "0.3.17" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 66 | 67 | [[package]] 68 | name = "proc-macro2" 69 | version = "1.0.24" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" 72 | dependencies = [ 73 | "unicode-xid", 74 | ] 75 | 76 | [[package]] 77 | name = "quote" 78 | version = "1.0.7" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 81 | dependencies = [ 82 | "proc-macro2", 83 | ] 84 | 85 | [[package]] 86 | name = "rust-pulsectl" 87 | version = "0.2.9" 88 | dependencies = [ 89 | "libpulse-binding", 90 | ] 91 | 92 | [[package]] 93 | name = "syn" 94 | version = "1.0.51" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "3b4f34193997d92804d359ed09953e25d5138df6bcc055a71bf68ee89fdf9223" 97 | dependencies = [ 98 | "proc-macro2", 99 | "quote", 100 | "unicode-xid", 101 | ] 102 | 103 | [[package]] 104 | name = "unicode-xid" 105 | version = "0.2.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 108 | 109 | [[package]] 110 | name = "winapi" 111 | version = "0.3.9" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 114 | dependencies = [ 115 | "winapi-i686-pc-windows-gnu", 116 | "winapi-x86_64-pc-windows-gnu", 117 | ] 118 | 119 | [[package]] 120 | name = "winapi-i686-pc-windows-gnu" 121 | version = "0.4.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 124 | 125 | [[package]] 126 | name = "winapi-x86_64-pc-windows-gnu" 127 | version = "0.4.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 130 | -------------------------------------------------------------------------------- /libs/rust-sciter/.github/workflows/cargo.yml: -------------------------------------------------------------------------------- 1 | name: Build-n-Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - travis 8 | 9 | pull_request: 10 | branches: 11 | - master 12 | 13 | # Look: 14 | # https://github.com/actions/starter-workflows/blob/master/ci/rust.yml 15 | # 16 | # Simple, right? Right. 17 | # But we need to: 18 | # * download a specific Sciter library matching the running OS 19 | # * figure out where to save it 20 | # * add it to the $PATH 21 | # 22 | # yet, 23 | # * in case of macOS realize that it doesn't have Rust installed, so 24 | # * install it manually and don't forget to add cargo and rustc to the $PATH on each step 25 | # * and in case of Linux install additional packages for GTK3 26 | # 27 | # So, now we're ended up with this ugly script. 28 | 29 | jobs: 30 | fetch: 31 | name: Fetch dependencies 32 | 33 | runs-on: ${{ matrix.os }} 34 | strategy: 35 | matrix: 36 | # macOS doesn't have Rust installed 37 | # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners#macos-1015 38 | # we will try to install it manually below. 39 | os: [macos-latest, ubuntu-latest, windows-latest] 40 | 41 | steps: 42 | - name: Environment 43 | shell: bash 44 | env: 45 | RUNNER_CONTEXT: ${{ toJson(runner) }} 46 | SCITER_DEPS: ${{ runner.workspace }} 47 | run: | 48 | echo HOME is "$HOME" 49 | echo workspace is "$SCITER_DEPS" 50 | echo temp is "$TEMP" 51 | echo runner is "$RUNNER_CONTEXT" 52 | echo cargo is at `which cargo` 53 | echo rustc is at `which rustc` 54 | command -v cargo && rustc -vV 55 | echo done 56 | 57 | build: 58 | needs: [fetch] 59 | name: Build and test 60 | 61 | runs-on: ${{ matrix.os }} 62 | strategy: 63 | fail-fast: false 64 | matrix: 65 | os: [macos-latest, ubuntu-latest, windows-latest] 66 | 67 | steps: 68 | - uses: actions/checkout@v2 69 | 70 | - name: Windows deps 71 | if: runner.os == 'Windows' 72 | # Windows: download sciter library 73 | run: curl -sSLo "%SCITER_DEPS%/sciter.dll" "https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll" 74 | shell: cmd 75 | env: 76 | SCITER_DEPS: ${{ runner.workspace }} 77 | 78 | - name: Linux deps 79 | if: runner.os == 'Linux' 80 | # Linux: download sciter library && install libgtk-3-dev 81 | run: | 82 | curl -so "$SCITER_DEPS/libsciter-gtk.so" "https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so" 83 | sudo apt-get update -y && sudo apt-get install libgtk-3-dev libgtk-3-0 libstdc++-6-pic -y 84 | env: 85 | SCITER_DEPS: ${{ runner.workspace }} 86 | 87 | - name: macOS deps 88 | if: runner.os == 'macOS' 89 | # OSX: download sciter library && install rustup 90 | run: | 91 | curl -so "$SCITER_DEPS/sciter-osx-64.dylib" "https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.osx/sciter-osx-64.dylib" 92 | curl https://sh.rustup.rs -sSf | sh -s -- --profile minimal -y 93 | test -f $HOME/.cargo/env && source $HOME/.cargo/env 94 | echo cargo is at `which cargo` 95 | echo rustc is at `which rustc` 96 | env: 97 | SCITER_DEPS: ${{ runner.workspace }} 98 | 99 | - name: Build 100 | shell: bash 101 | run: | 102 | test -f $HOME/.cargo/env && source $HOME/.cargo/env 103 | cargo build --all 104 | cargo build --examples 105 | 106 | - name: Tests 107 | shell: bash 108 | run: | 109 | test -f $HOME/.cargo/env && source $HOME/.cargo/env 110 | export PATH="$PATH:$SCITER_DEPS" 111 | cargo run --example first 112 | cargo test -p sciter-rs 113 | cargo test -p sciter-serde 114 | env: 115 | SCITER_DEPS: ${{ runner.workspace }} 116 | -------------------------------------------------------------------------------- /libs/rust-sciter/examples/video.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Video behavior demo 4 | 19 | 81 | 82 | 103 | 104 | 105 | 106 | 107 |

This demo simulates partial video frame update. 108 | On each frame (24 FPS) it updates another portion of the frame.

109 | 110 |
111 | 112 | 113 |
114 | 115 |
116 |
frame size: x 117 |
118 | 119 |