### Install libxdo-dev on Ubuntu Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/libs/enigo/README.md On Ubuntu, install the libxdo-dev package to enable X11 input simulation for Enigo. ```Bash apt install libxdo-dev ``` -------------------------------- ### Configure and Install Hoptodesk Library Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/CMakeLists.txt Sets the build type for the library and installs the resulting shared object file to the bundle directory. ```cmake set(RUSTDESK_LIB_BUILD_TYPE $,debug,release>) string(TOLOWER ${CMAKE_BUILD_TYPE} ${RUSTDESK_LIB_BUILD_TYPE}) message(STATUS "hoptodesk lib build type: ${RUSTDESK_LIB_BUILD_TYPE}") set(RUSTDESK_LIB "../../target/${RUSTDESK_LIB_BUILD_TYPE}/liblibhoptodesk.so") install(FILES "${RUSTDESK_LIB}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime RENAME libhoptodesk.so) ``` -------------------------------- ### Install xdotool on Arch Linux Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/libs/enigo/README.md On Arch Linux, install the xdotool package to enable X11 input simulation for Enigo. ```Bash pacman -S xdotool ``` -------------------------------- ### Simulate Mouse and Keyboard Input with Enigo Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/libs/enigo/README.md Initialize Enigo and perform mouse movements, clicks, and parse complex key sequences. Ensure necessary system dependencies are installed for your platform. ```Rust let mut enigo = Enigo::new(); enigo.mouse_move_to(500, 200); enigo.mouse_click(MouseButton::Left); enigo.key_sequence_parse("{+CTRL}a{-CTRL}{+SHIFT}Hello World{-SHIFT}"); ``` -------------------------------- ### Get List of Trusted Devices Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Retrieves and iterates through the list of currently trusted devices, printing their details. Ensure the `hbb_common::config` module is imported. ```rust use hbb_common::config::{Config, TrustedDevice}; use hbb_common::bytes::Bytes; // Get list of trusted devices let devices = Config::get_trusted_devices(); for device in &devices { println!("Device: {} ({}) - {}", device.name, device.platform, device.id); } ``` -------------------------------- ### Conditionally Install AOT Library Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/CMakeLists.txt Installs the AOT library only when the build configuration is not set to Debug. ```cmake if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Find and check GTK, GLIB, and GIO modules Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/flutter/CMakeLists.txt Uses PkgConfig to find and check for the required GTK, GLIB, and GIO modules. This ensures that the necessary development files are available for linking. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Manage Global Application Settings Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Use the Config struct to handle device identification, passwords, proxy settings, and encryption keys. Settings are automatically persisted to TOML files. ```rust use hbb_common::config::{Config, PeerConfig}; // Get the unique device ID let device_id = Config::get_id(); // Set temporary and permanent passwords Config::set_temporary_password("abc123"); Config::set_permanent_password("secure_password"); // Get and set configuration options Config::set_option("custom-rendezvous-server".to_string(), "my.server.com".to_string()); let server = Config::get_option("custom-rendezvous-server"); // Configure SOCKS5 proxy use hbb_common::config::Socks5Server; Config::set_socks(Some(Socks5Server { proxy: "127.0.0.1:1080".to_string(), username: "user".to_string(), password: "pass".to_string(), })); // Access key pair for encryption let (secret_key, public_key) = Config::get_key_pair(); // Check NAT type for connection optimization let nat_type = Config::get_nat_type(); ``` -------------------------------- ### Screen Capture Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Rust implementation for cross-platform screen capture with hardware acceleration support for video encoding. ```APIDOC ## Screen Capture Cross-platform screen capture implementation with hardware acceleration support for video encoding. ### Get All Displays ```rust use scrap::{Capturer, Display, Frame, TraitCapturer, ImageRgb, ImageFormat}; // Get all available displays let displays = Display::all()?; println!("Found {} displays", displays.len()); for (i, display) in displays.iter().enumerate() { println!("Display {}: {}x{} at ({}, {})", i, display.width(), display.height(), display.origin().0, display.origin().1); } ``` ### Capture Frame ```rust // Create a capturer for the primary display let display = Display::primary()?; let mut capturer = Capturer::new(display)?; // Capture a frame with timeout let timeout = std::time::Duration::from_millis(100); match capturer.frame(timeout) { Ok(Frame::PixelBuffer(buffer)) => { let width = buffer.width(); let height = buffer.height(); let data = buffer.data(); println!("Captured {}x{} frame, {} bytes", width, height, data.len()); } Ok(Frame::Texture(texture)) => { // Hardware texture for GPU encoding println!("Captured GPU texture"); } Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { // No new frame available } Err(e) => return Err(e.into()), } ``` ### Convert Frame to YUV ```rust // Convert frame to YUV for encoding let mut yuv_buffer = Vec::new(); let mut mid_data = Vec::new(); let yuv_format = scrap::EncodeYuvFormat::default(); // frame.to(yuv_format, &mut yuv_buffer, &mut mid_data)?; ``` ``` -------------------------------- ### Configure Flutter library and headers Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/flutter/CMakeLists.txt Defines the Flutter library path and includes necessary header files. It also sets up interface include directories and links against system libraries. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "fl_basic_message_channel.h" "fl_binary_codec.h" "fl_binary_messenger.h" "fl_dart_project.h" "fl_engine.h" "fl_json_message_codec.h" "fl_json_method_codec.h" "fl_message_codec.h" "fl_method_call.h" "fl_method_channel.h" "fl_method_codec.h" "fl_method_response.h" "fl_plugin_registrar.h" "fl_plugin_registry.h" "fl_standard_message_codec.h" "fl_standard_method_codec.h" "fl_string_codec.h" "fl_value.h" "fl_view.h" "flutter_linux.h" ) list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO ) add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Add Scrap Dependency Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/libs/scrap/README.md Add this to your Cargo.toml file to include the scrap library in your project. ```toml [dependencies] scrap = "0.5" ``` -------------------------------- ### Scrap API Definitions Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/libs/scrap/README.md These are the core struct and method definitions for the Scrap library, outlining how to interact with screen capturing. ```rust struct Display; /// A screen. struct Frame; /// An array of the pixels that were on-screen. struct Capturer; /// A recording instance. impl Capturer { /// Begin recording. pub fn new(display: Display) -> io::Result; /// Try to get a frame. /// Returns WouldBlock if it's not ready yet. pub fn frame<'a>(&'a mut self) -> io::Result>; pub fn width(&self) -> usize; pub fn height(&self) -> usize; } impl Display { /// The primary screen. pub fn primary() -> io::Result; /// All the screens. pub fn all() -> io::Result>; pub fn width(&self) -> usize; pub fn height(&self) -> usize; } impl<'a> ops::Deref for Frame<'a> { /// A frame is just an array of bytes. type Target = [u8]; } ``` -------------------------------- ### Configure and Execute Video Encoding in Rust Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Uses the scrap crate to configure VP9 encoding and process YUV frame data for transmission. ```rust use scrap::codec::{Encoder, EncoderCfg, Quality}; use scrap::vpxcodec::{VpxEncoder, VpxEncoderConfig}; use hbb_common::message_proto::VideoFrame; // Configure VP9 encoder let encoder_cfg = EncoderCfg::VPX(VpxEncoderConfig { width: 1920, height: 1080, quality: Quality::Balanced, // Best, Balanced, Low, Custom codec: scrap::vpxcodec::VpxVideoCodecId::VP9, }); // Create encoder let mut encoder = Encoder::new(encoder_cfg)?; // Encode YUV frame data let yuv_data: &[u8] = &yuv_buffer; let ms = std::time::Instant::now().elapsed().as_millis() as i64; let frames = encoder.encode(ms, yuv_data, scrap::STRIDE_ALIGN)?; // Process encoded frames for frame in frames { let video_frame = VideoFrame { union: Some(video_frame::Union::Vp9s(frame.data.into())), display: 0, ..Default::default() }; // Send video_frame to client } ``` -------------------------------- ### Add a New Trusted Device Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Adds a new device to the trusted list. Requires hardware ID, a unique ID string, name, platform, and timestamp. The `hwid` should be populated with actual hardware identifier bytes. ```rust let device = TrustedDevice { hwid: Bytes::from(vec![/* hardware ID bytes */]), time: hbb_common::get_time(), id: "987654321".to_string(), name: "Trusted Laptop".to_string(), platform: "Windows".to_string(), }; Config::add_trusted_device(device); ``` -------------------------------- ### Custom command to build Flutter library and headers Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/flutter/CMakeLists.txt This custom command executes the Flutter tool backend script to generate the Flutter library and header files. It uses environment variables and build type for configuration. The `_phony_` target ensures the command runs on every build. ```cmake add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ``` -------------------------------- ### Scrap Library API Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/libs/scrap/README.md Core structures and methods for screen capturing using the Scrap library. ```APIDOC ## Display ### Description Represents a physical screen connected to the system. ### Methods - **Display::primary() -> io::Result** - Returns the primary screen. - **Display::all() -> io::Result>** - Returns a list of all connected screens. - **Display::width(&self) -> usize** - Returns the width of the display. - **Display::height(&self) -> usize** - Returns the height of the display. ## Capturer ### Description Handles the recording instance for a specific display. ### Methods - **Capturer::new(display: Display) -> io::Result** - Initializes a new recording instance for the given display. - **Capturer::frame<'a>(&'a mut self) -> io::Result>** - Attempts to capture a frame. Returns `WouldBlock` if the frame is not yet ready. - **Capturer::width(&self) -> usize** - Returns the width of the capture area. - **Capturer::height(&self) -> usize** - Returns the height of the capture area. ## Frame ### Description Represents an array of pixels captured from the screen. ### Details - **Format**: Packed BGRA. - **Deref**: Implements `ops::Deref` to `[u8]`, allowing access to the raw byte array. - **Dimensions**: Width and height remain constant, though stride may vary between frames. ``` -------------------------------- ### Implement Inter-Process Communication Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Establish communication between the UI and background service using platform-specific IPC mechanisms like named pipes or Unix sockets. ```rust use crate::ipc::{self, Data, FS}; // Start IPC server for a specific postfix #[tokio::main] async fn start_ipc_server() -> hbb_common::ResultType<()> { ipc::start("").await } // Connect to IPC server async fn connect_to_service() -> hbb_common::ResultType<()> { let mut conn = ipc::connect(1000, "").await?; // Send login data conn.send(&Data::Login { id: 1, is_file_transfer: false, is_view_camera: false, is_terminal: false, peer_id: "123456789".to_string(), name: "Remote User".to_string(), authorized: true, port_forward: "".to_string(), keyboard: true, clipboard: true, audio: true, file: true, file_transfer_enabled: true, restart: false, recording: false, block_input: false, from_switch: false, is_invite: false, password_to_connect_to_inviter: "".to_string(), security_numbers: "".to_string(), avatar_image: "".to_string(), }).await?; // File system operations via IPC conn.send(&Data::FS(FS::ReadDir { dir: "/home/user".to_string(), include_hidden: false, })).await?; Ok(()) } ``` -------------------------------- ### Configure Peer-Specific Settings Source: https://context7.com/hoptodesk/hoptodesk/llms.txt The PeerConfig struct manages individual peer preferences, including display quality, feature toggles, and port forwarding rules. ```rust use hbb_common::config::PeerConfig; // Load configuration for a specific peer let peer_id = "123456789"; let mut config = PeerConfig::load(peer_id); // Configure display settings config.view_style = "adaptive".to_string(); // or "original", "shrink" config.image_quality = "balanced".to_string(); // or "best", "low", "custom" config.custom_image_quality = vec![75]; // Quality percentage for custom mode // Enable/disable features per connection config.disable_audio.v = false; config.disable_clipboard.v = false; config.show_remote_cursor.v = true; config.lock_after_session_end.v = true; // Configure port forwarding config.port_forwards = vec![ (8080, "localhost".to_string(), 80), // local_port, host, remote_port ]; // Save peer configuration config.store(peer_id); // List all saved peers sorted by last access time let peers = PeerConfig::peers(None); for (id, modified_time, peer_config) in peers { println!("Peer: {} - {}", id, peer_config.info.hostname); } // Remove a peer configuration PeerConfig::remove(peer_id); ``` -------------------------------- ### TIScript Window Icon and Ready State Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/src/ui/chatbox.html Sets the window icon based on view parameters and configures the window to be topmost upon ready, then disables topmost. ```tiscript view.windowIcon = self.url(p.icon); function self.ready() { view.windowTopmost = true; view.refresh(); view.windowTopmost = false; } ``` -------------------------------- ### Manage Peer Connections and Events in Flutter Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Handles peer session connectivity and event processing via the global FFI instance. ```dart import 'package:flutter_hbb/models/model.dart'; import 'package:flutter_hbb/common.dart'; // Access the global FFI instance final ffi = gFFI; // Connect to a remote peer Future connectToPeer(String peerId) async { await bind.sessionConnect( sessionId: ffi.sessionId, id: peerId, isFileTransfer: false, isPortForward: false, isRdp: false, forceRelay: false, password: '', isSharedPassword: false, ); } // Event handler for peer session events StreamEventHandler eventHandler = (evt) async { var name = evt['name']; if (name == 'peer_info') { // Handle peer information final platform = evt['platform']; final username = evt['username']; final hostname = evt['hostname']; print('Connected to $username@$hostname ($platform)'); } else if (name == 'msgbox') { // Handle message boxes final type = evt['type']; final title = evt['title']; final text = evt['text']; // Show dialog to user } else if (name == 'clipboard') { // Handle clipboard sync Clipboard.setData(ClipboardData(text: evt['content'])); } else if (name == 'permission') { // Handle permission updates final keyboard = evt['keyboard'] == 'true'; final clipboard = evt['clipboard'] == 'true'; } }; // Check connection type final isSecure = ffi.ffiModel.secure ?? false; final isDirect = ffi.ffiModel.direct ?? false; print('Connection: ${isSecure ? "Secure" : "Insecure"}, ${isDirect ? "Direct" : "Relay"}'); // Access peer information final peerInfo = ffi.ffiModel.pi; print('Platform: ${peerInfo.platform}'); print('Displays: ${peerInfo.displays.length}'); ``` -------------------------------- ### CMake Build Configuration for Flutter Windows Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/windows/runner/CMakeLists.txt Defines the executable target and links required Flutter libraries. Ensure BINARY_NAME is defined in the top-level CMakeLists.txt. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Rendezvous Protocol Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Protobuf definitions for the rendezvous protocol used for peer discovery, NAT traversal, and connection establishment. ```APIDOC ## Rendezvous Protocol The protobuf-based protocol for peer discovery, NAT traversal, and connection establishment through the rendezvous server. ### RegisterPeer Message ```protobuf message RegisterPeer { string id = 1; // Unique device ID int32 serial = 2; // Configuration serial number } ``` ### PunchHoleRequest Message ```protobuf message PunchHoleRequest { string id = 1; // Target peer ID NatType nat_type = 2; // Requester's NAT type string licence_key = 3; // License key if applicable ConnType conn_type = 4; // DEFAULT_CONN, FILE_TRANSFER, PORT_FORWARD, etc. string token = 5; // Authentication token string version = 6; // Client version } ``` ### PunchHoleResponse Message ```protobuf message PunchHoleResponse { bytes socket_addr = 1; // Peer's public address bytes pk = 2; // Peer's public key string relay_server = 4; // Fallback relay server NatType nat_type = 5; // Peer's NAT type } ``` ### RequestRelay Message ```protobuf message RequestRelay { string id = 1; string uuid = 2; bytes socket_addr = 3; string relay_server = 4; bool secure = 5; ConnType conn_type = 7; } ``` ``` -------------------------------- ### Configure Local and Remote Session Options in Flutter Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Manages local preferences, global service options, and peer-specific session settings. ```dart import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/common/shared_state.dart'; // Get/set local options final language = bind.mainGetLocalOption(key: 'lang'); bind.mainSetLocalOption(key: 'lang', value: 'en'); // Get/set global options (synced with service) final theme = bind.mainGetOption(key: 'theme'); bind.mainSetOption(key: 'theme', value: 'dark'); // Peer-specific options final peerId = '123456789'; final viewStyle = bind.sessionGetViewStyle(sessionId: sessionId); bind.sessionSetViewStyle(sessionId: sessionId, value: 'adaptive'); // Toggle session features await bind.sessionToggleOption( sessionId: sessionId, value: 'show-remote-cursor', ); // Set image quality bind.sessionSetImageQuality(sessionId: sessionId, value: 'balanced'); // Configure custom FPS bind.sessionSetCustomFps(sessionId: sessionId, fps: 30); // Enable/disable clipboard bind.sessionToggleOption(sessionId: sessionId, value: 'disable-clipboard'); ``` -------------------------------- ### Rust Screen Capture Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Captures frames from available displays using the `scrap` crate. Supports hardware acceleration and conversion to YUV format for encoding. ```rust use scrap::{Capturer, Display, Frame, TraitCapturer, ImageRgb, ImageFormat}; // Get all available displays let displays = Display::all()?; println!("Found {} displays", displays.len()); for (i, display) in displays.iter().enumerate() { println!("Display {}: {}x{} at ({}, {})", i, display.width(), display.height(), display.origin().0, display.origin().1); } // Create a capturer for the primary display let display = Display::primary()?; let mut capturer = Capturer::new(display)?; // Capture a frame with timeout let timeout = std::time::Duration::from_millis(100); match capturer.frame(timeout) { Ok(Frame::PixelBuffer(buffer)) => { let width = buffer.width(); let height = buffer.height(); let data = buffer.data(); println!("Captured {}x{} frame, {} bytes", width, height, data.len()); } Ok(Frame::Texture(texture)) => { // Hardware texture for GPU encoding println!("Captured GPU texture"); } Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { // No new frame available } Err(e) => return Err(e.into()), } // Convert frame to YUV for encoding let mut yuv_buffer = Vec::new(); let mut mid_data = Vec::new(); let yuv_format = scrap::EncodeYuvFormat::default(); // frame.to(yuv_format, &mut yuv_buffer, &mut mid_data)?; ``` -------------------------------- ### Message Protocol Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Protobuf definitions for the main communication protocol used for remote sessions, including video frames, input events, and control messages. ```APIDOC ## Message Protocol The main communication protocol for remote sessions including video frames, input events, and control messages. ### LoginRequest Message ```protobuf message LoginRequest { string username = 1; bytes password = 2; string my_id = 4; string my_name = 5; OptionMessage option = 6; FileTransfer file_transfer = 7; // For file transfer sessions PortForward port_forward = 8; // For port forwarding ViewCamera view_camera = 15; // For camera viewing bool video_ack_required = 9; uint64 session_id = 10; string version = 11; bytes hwid = 14; // Hardware ID for trusted devices } ``` ### PeerInfo Message ```protobuf message PeerInfo { string username = 1; string hostname = 2; string platform = 3; // "Windows", "Linux", "Mac OS", etc. repeated DisplayInfo displays = 4; // Available displays int32 current_display = 5; bool sas_enabled = 6; // Secure Attention Sequence support Features features = 9; // Available features SupportedEncoding encoding = 10; // Supported video codecs } ``` ### VideoFrame Message ```protobuf message VideoFrame { EncodedVideoFrames vp9s = 6; EncodedVideoFrames h264s = 10; EncodedVideoFrames h265s = 11; EncodedVideoFrames vp8s = 12; EncodedVideoFrames av1s = 13; int32 display = 14; // Display index } ``` ### MouseEvent Message ```protobuf message MouseEvent { int32 mask = 1; // Button mask sint32 x = 2; // X coordinate sint32 y = 3; // Y coordinate repeated ControlKey modifiers = 4; // Ctrl, Alt, Shift, etc. } ``` ``` -------------------------------- ### Synchronize Flutter Assets Directory Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/CMakeLists.txt Removes existing flutter assets before copying the new directory to ensure no stale files remain. ```cmake set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### TIScript View Refresh Logic Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/src/ui/chatbox.html Handles the refresh of the chat view, setting the content and focusing the input. Requires 'common.tis' to be included. ```tiscript include "common.tis"; var p = view.parameters; view.refresh = function() { $(body).content(); view.focus = $(input); } ``` -------------------------------- ### Manage Peer Data and Address Book in Flutter Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Handles peer object creation and address book operations including loading, adding, and filtering peers. ```dart import 'package:flutter_hbb/models/peer_model.dart'; import 'package:flutter_hbb/models/ab_model.dart'; // Create a peer instance final peer = Peer( id: '123456789', username: 'john', hostname: 'workstation', platform: 'Windows', alias: 'John\'s PC', tags: ['office', 'development'], hash: '', // Password hash ); // Access address book final abModel = gFFI.abModel; // Load address book entries await abModel.pullAb(); // Get peers from address book final peers = abModel.peers; for (final p in peers) { print('${p.alias ?? p.id}: ${p.platform}'); } // Add peer to address book abModel.addPeer(peer); // Add tags to address book abModel.addTag('servers'); // Filter peers by tag final serverPeers = abModel.getPeersByTag('servers'); ``` -------------------------------- ### Message Protocol Messages Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Defines protobuf messages for the main communication protocol, including login, peer information, video frames, and mouse events. ```protobuf // Login request from client to host message LoginRequest { string username = 1; bytes password = 2; string my_id = 4; string my_name = 5; OptionMessage option = 6; FileTransfer file_transfer = 7; // For file transfer sessions PortForward port_forward = 8; // For port forwarding ViewCamera view_camera = 15; // For camera viewing bool video_ack_required = 9; uint64 session_id = 10; string version = 11; bytes hwid = 14; // Hardware ID for trusted devices } // Peer information returned after successful login message PeerInfo { string username = 1; string hostname = 2; string platform = 3; // "Windows", "Linux", "Mac OS", etc. repeated DisplayInfo displays = 4; // Available displays int32 current_display = 5; bool sas_enabled = 6; // Secure Attention Sequence support Features features = 9; // Available features SupportedEncoding encoding = 10; // Supported video codecs } // Video frame with multiple codec support message VideoFrame { EncodedVideoFrames vp9s = 6; EncodedVideoFrames h264s = 10; EncodedVideoFrames h265s = 11; EncodedVideoFrames vp8s = 12; EncodedVideoFrames av1s = 13; int32 display = 14; // Display index } // Mouse event from client to host message MouseEvent { int32 mask = 1; // Button mask sint32 x = 2; // X coordinate sint32 y = 3; // Y coordinate repeated ControlKey modifiers = 4; // Ctrl, Alt, Shift, etc. } ``` -------------------------------- ### Define list_prepend function in CMake Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/flutter/linux/flutter/CMakeLists.txt This function prepends a prefix to each element in a list. It is used as a fallback for list(TRANSFORM ... PREPEND ...) which is not available in CMake version 3.10. ```cmake function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Conditional CSS Styling Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/src/ui/chatbox.html Applies specific CSS rules based on the platform. Ensure 'common.css' is imported for shared styles. ```css @import url(common.css); @media platform != "OSX" { body { border-top: color(border) solid 1px; } } ``` -------------------------------- ### TIScript Window Closing Handler Source: https://gitlab.com/hoptodesk/hoptodesk/-/blob/main/src/ui/chatbox.html Manages the window state when closing, preventing the default close behavior by returning false. ```tiscript function self.closing() { view.windowState = View.WINDOW_HIDDEN; return false; } ``` -------------------------------- ### Rendezvous Protocol Messages Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Defines protobuf messages for peer registration, connection requests, and responses within the rendezvous protocol. ```protobuf message RegisterPeer { string id = 1; // Unique device ID int32 serial = 2; // Configuration serial number } // Request connection to a peer message PunchHoleRequest { string id = 1; // Target peer ID NatType nat_type = 2; // Requester's NAT type string licence_key = 3; // License key if applicable ConnType conn_type = 4; // DEFAULT_CONN, FILE_TRANSFER, PORT_FORWARD, etc. string token = 5; // Authentication token string version = 6; // Client version } // Response with peer's socket address for direct connection message PunchHoleResponse { bytes socket_addr = 1; // Peer's public address bytes pk = 2; // Peer's public key string relay_server = 4; // Fallback relay server NatType nat_type = 5; // Peer's NAT type } // Request relay connection when direct fails message RequestRelay { string id = 1; string uuid = 2; bytes socket_addr = 3; string relay_server = 4; bool secure = 5; ConnType conn_type = 7; } ``` -------------------------------- ### Rust Connection Handler Message Processing Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Implementations for handling various message types within the Rust server-side connection handler, including login requests, mouse input, and file actions. Requires 'hbb_common' and other crates. ```rust impl Connection { // Handle incoming login request async fn handle_login(&mut self, lr: LoginRequest) -> ResultType<()> { // Verify password let password_verified = self.verify_password(&lr.password)?; if password_verified { // Send peer info on successful login let peer_info = PeerInfo { username: whoami::username(), hostname: whoami::hostname(), platform: std::env::consts::OS.to_string(), displays: self.get_displays(), features: Some(Features { privacy_mode: true, terminal: true, remote_printing: true, }), ..Default::default() }; self.send(LoginResponse { union: Some(login_response::Union::PeerInfo(peer_info)), ..Default::default() }).await?; } Ok(()) } // Handle mouse input async fn handle_mouse(&mut self, evt: MouseEvent) { // Apply input to system // Respects keyboard/mouse permissions } // Handle file transfer request async fn handle_file_action(&mut self, action: FileAction) { // Process file operations with permission checks } } ``` -------------------------------- ### Rust Connection Server Authentication and Session Management Source: https://context7.com/hoptodesk/hoptodesk/llms.txt This Rust code defines authentication types for remote connections and manages authenticated connections using a lazy_static mutex. It's part of the server-side connection handler. ```rust use crate::server::Connection; use hbb_common::message_proto::{Message, LoginRequest, LoginResponse}; // Connection authentication types pub enum AuthConnType { Remote, // Full remote control FileTransfer, // File transfer only PortForward, // TCP port forwarding ViewCamera, // Camera viewing Terminal, // Terminal access } // Session management lazy_static! { pub static ref AUTHED_CONNS: Arc>> = Default::default(); } ``` -------------------------------- ### Check if Device is Trusted Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Determines if a given `incoming_hwid` is present in the list of trusted devices and has not expired. Trusted devices automatically expire after 90 days. ```rust let is_trusted = devices.iter().any(|d| d.hwid == incoming_hwid && !d.outdate()); ``` -------------------------------- ### Dart File Transfer Operations Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Use this code to manage file transfers, including reading directories, sending/receiving files, monitoring progress, creating directories, and removing files. Ensure the 'flutter_hbb' package is imported. ```dart import 'package:flutter_hbb/models/file_model.dart'; // Access file model final fileModel = gFFI.fileModel; // Read remote directory await bind.sessionReadRemoteDir( sessionId: sessionId, path: '/home/user', includeHidden: false, ); // Read local directory await bind.sessionReadLocalDir( sessionId: sessionId, path: '/Users/local/Documents', includeHidden: false, ); // Send files to remote fileModel.jobController.add([ Entry(name: 'file.txt', path: '/local/path/file.txt', isDirectory: false), ], isRemote: false); // Receive files from remote fileModel.jobController.add([ Entry(name: 'remote_file.txt', path: '/remote/path/remote_file.txt', isDirectory: false), ], isRemote: true); // Monitor transfer progress fileModel.jobController.jobTable.forEach((id, job) { print('Job $id: ${job.finishedSize}/${job.totalSize} bytes'); }); // Create remote directory await bind.sessionCreateDir( sessionId: sessionId, actId: 1, path: '/home/user/new_folder', isRemote: true, ); // Remove remote file await bind.sessionRemoveFile( sessionId: sessionId, actId: 2, path: '/home/user/old_file.txt', fileNum: 0, isRemote: true, ); ``` -------------------------------- ### Clear All Trusted Devices Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Removes all devices from the trusted list. This is typically used when security-sensitive information like a password changes. ```rust Config::clear_trusted_devices(); ``` -------------------------------- ### Remove Specific Trusted Devices Source: https://context7.com/hoptodesk/hoptodesk/llms.txt Removes one or more trusted devices from the list based on their hardware IDs. The `hwids_to_remove` vector should contain the `Bytes` representation of the hardware IDs to be deleted. ```rust let hwids_to_remove = vec![ Bytes::from(vec![/* hwid1 */]), Bytes::from(vec![/* hwid2 */]), ]; Config::remove_trusted_devices(&hwids_to_remove); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.