TargetHandle

Struct TargetHandle 

Source
pub struct TargetHandle<T> { /* private fields */ }
Expand description

An opaque handle to a plugged-in virtual controller.

This handle is returned when a new target is successfully plugged into the bus. It is used to identify the target for subsequent operations like updating its state, listening for notifications, or removing it.

This handle uses reference counting (Arc). Cloning it is cheap and creates another handle to the same virtual controller. The controller is only unplugged from the bus when the last handle is dropped.

Implementations§

Source§

impl<T> TargetHandle<T>

Source

pub fn is_attached(&self) -> Result<bool, ClientError>

Checks if the virtual controller is still attached to the bus.

This can return false if the controller was manually unplugged or if the client was dropped.

Source

pub fn unplug(&self) -> Result<(), ClientError>

Explicitly unplugs the virtual controller from the bus.

After calling this, any further operations on this TargetHandle (and any of its clones) will fail. The controller is also automatically unplugged when the last TargetHandle is dropped.

Source§

impl TargetHandle<Xbox360>

Source

pub fn get_user_index(&self) -> Result<u32, ClientError>

Gets the user index of a virtual Xbox 360 controller.

It doesn’t seem like this method is reliable for getting the dynamic player index assigned by a game. It often returns 0 even after an index has been assigned.

To reliably get the player index, use TargetHandle<X360>::register_notification and check the led_number field of the received X360Notification.

Source

pub fn wait_for_ready(&self) -> Result<(), ClientError>

Blocks until the virtual controller is fully enumerated and ready to receive updates.

It is recommended to call this after plugging in a new controller if you want to immediately send a report to the controller.

§Example
use vigem_rust::{Client, X360Report};
let client = Client::connect().unwrap();
let x360 = client.new_x360_target().plugin().unwrap();

// Wait for the controller to be ready
x360.wait_for_ready().unwrap();

// Now it's safe to send updates
x360.update(&X360Report::default()).unwrap();
Examples found in repository?
examples/x360.rs (line 18)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let x360 = client.new_x360_target().plugin()?;
13    println!("Plugged in virtual Xbox 360 controller");
14
15    // Wait for the controller to be ready
16    // The virtual controller needs a moment to be recognized
17    // by the system before it can receive updates.
18    x360.wait_for_ready()?;
19    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
20
21    // Set up a notification listener in a separate thread
22    // This allows us to react to feedback from the system, like rumble or LED changes.
23    let notifications = x360.register_notification()?;
24    thread::spawn(move || {
25        println!("Notification Thread Started. Waiting for feedback...");
26        while let Ok(Ok(notification)) = notifications.recv() {
27            println!("Notification Thread Received feedback:");
28            println!(
29                "  - Rumble: Large Motor = {}, Small Motor = {}",
30                notification.large_motor, notification.small_motor
31            );
32            println!("  - LED Number/Player Index: {}", notification.led_number);
33        }
34    });
35
36    // Here, we'll send reports to the controller to simulate input.
37    let mut report = X360Report::default();
38    let mut angle: f64 = 0.0;
39    let mut step = 0;
40
41    loop {
42        // Animate the left thumbstick in a circle
43        angle += 0.1;
44        let (sin, cos) = angle.sin_cos();
45        report.thumb_lx = (sin * 32767.0) as i16;
46        report.thumb_ly = (cos * 32767.0) as i16;
47
48        // Alternate pressing A and B buttons
49        if step % 2 == 0 {
50            report.buttons = X360Button::A;
51        } else {
52            report.buttons = X360Button::B;
53        }
54
55        // Send the updated report to the controller
56        x360.update(&report)?;
57
58        thread::sleep(Duration::from_millis(16));
59        step += 1;
60    }
61}
Source

pub fn register_notification( &self, ) -> Result<Receiver<Result<X360Notification, BusError>>, ClientError>

Registers to receive notifications for this Xbox 360 target.

This returns a Receiver that will yield X360Notifications from the bus, which contain information like rumble data and the controller’s player LED index.

§Important

Calling this function spawns a dedicated background thread that lives as long as the Receiver does.

§Example
let receiver = x360.register_notification().unwrap();

// In a loop or another thread:
if let Ok(Ok(notification)) = receiver.try_recv() {
    println!("Player LED is now {}", notification.led_number);
}
Examples found in repository?
examples/x360.rs (line 23)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let x360 = client.new_x360_target().plugin()?;
13    println!("Plugged in virtual Xbox 360 controller");
14
15    // Wait for the controller to be ready
16    // The virtual controller needs a moment to be recognized
17    // by the system before it can receive updates.
18    x360.wait_for_ready()?;
19    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
20
21    // Set up a notification listener in a separate thread
22    // This allows us to react to feedback from the system, like rumble or LED changes.
23    let notifications = x360.register_notification()?;
24    thread::spawn(move || {
25        println!("Notification Thread Started. Waiting for feedback...");
26        while let Ok(Ok(notification)) = notifications.recv() {
27            println!("Notification Thread Received feedback:");
28            println!(
29                "  - Rumble: Large Motor = {}, Small Motor = {}",
30                notification.large_motor, notification.small_motor
31            );
32            println!("  - LED Number/Player Index: {}", notification.led_number);
33        }
34    });
35
36    // Here, we'll send reports to the controller to simulate input.
37    let mut report = X360Report::default();
38    let mut angle: f64 = 0.0;
39    let mut step = 0;
40
41    loop {
42        // Animate the left thumbstick in a circle
43        angle += 0.1;
44        let (sin, cos) = angle.sin_cos();
45        report.thumb_lx = (sin * 32767.0) as i16;
46        report.thumb_ly = (cos * 32767.0) as i16;
47
48        // Alternate pressing A and B buttons
49        if step % 2 == 0 {
50            report.buttons = X360Button::A;
51        } else {
52            report.buttons = X360Button::B;
53        }
54
55        // Send the updated report to the controller
56        x360.update(&report)?;
57
58        thread::sleep(Duration::from_millis(16));
59        step += 1;
60    }
61}
Source

pub fn update(&self, report: &X360Report) -> Result<(), ClientError>

Submits an input state report for this Xbox 360 target.

This is the primary method for sending controller inputs to the system. The provided X360Report contains the state of all buttons, triggers, and thumbsticks.

§Warning

Calling this method immediately after plugging in the target will likely fail, as the system needs time to enumerate the device.

To reliably send updates right after creation, you must first call [wait_for_ready()].

§Example
let mut report = X360Report::default();
report.buttons = X360Button::A | X360Button::START;
report.thumb_lx = 16384; // Move left stick right

x360.update(&report)?;
Examples found in repository?
examples/x360.rs (line 56)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let x360 = client.new_x360_target().plugin()?;
13    println!("Plugged in virtual Xbox 360 controller");
14
15    // Wait for the controller to be ready
16    // The virtual controller needs a moment to be recognized
17    // by the system before it can receive updates.
18    x360.wait_for_ready()?;
19    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
20
21    // Set up a notification listener in a separate thread
22    // This allows us to react to feedback from the system, like rumble or LED changes.
23    let notifications = x360.register_notification()?;
24    thread::spawn(move || {
25        println!("Notification Thread Started. Waiting for feedback...");
26        while let Ok(Ok(notification)) = notifications.recv() {
27            println!("Notification Thread Received feedback:");
28            println!(
29                "  - Rumble: Large Motor = {}, Small Motor = {}",
30                notification.large_motor, notification.small_motor
31            );
32            println!("  - LED Number/Player Index: {}", notification.led_number);
33        }
34    });
35
36    // Here, we'll send reports to the controller to simulate input.
37    let mut report = X360Report::default();
38    let mut angle: f64 = 0.0;
39    let mut step = 0;
40
41    loop {
42        // Animate the left thumbstick in a circle
43        angle += 0.1;
44        let (sin, cos) = angle.sin_cos();
45        report.thumb_lx = (sin * 32767.0) as i16;
46        report.thumb_ly = (cos * 32767.0) as i16;
47
48        // Alternate pressing A and B buttons
49        if step % 2 == 0 {
50            report.buttons = X360Button::A;
51        } else {
52            report.buttons = X360Button::B;
53        }
54
55        // Send the updated report to the controller
56        x360.update(&report)?;
57
58        thread::sleep(Duration::from_millis(16));
59        step += 1;
60    }
61}
Source§

impl TargetHandle<DualShock4>

Source

pub fn wait_for_ready(&self) -> Result<(), ClientError>

Blocks until the virtual controller is fully enumerated and ready to receive updates.

It is recommended to call this after plugging in a new controller if you want to immediately send a report to the controller.

§Example
use vigem_rust::{Client, Ds4Report};
let client = Client::connect().unwrap();
let ds4 = client.new_ds4_target().plugin().unwrap();

// Wait for the controller to be ready
ds4.wait_for_ready().unwrap();

// Now it's safe to send updates
ds4.update(&Ds4Report::default()).unwrap();
Examples found in repository?
examples/ds4.rs (line 16)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let ds4 = client.new_ds4_target().plugin()?;
13    println!("Plugged in virtual DualShock 4 controller");
14
15    // Wait for the controller to be ready
16    ds4.wait_for_ready()?;
17    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
18
19    // Set up a notification listener in a separate thread
20    // This allows us to react to feedback from the system, like rumble or LED changes.
21    let notifications = ds4.register_notification()?;
22    thread::spawn(move || {
23        println!("Notification Thread Started. Waiting for feedback from the host...");
24        while let Ok(Ok(notification)) = notifications.recv() {
25            println!("Notification Thread Received feedback:");
26            println!(
27                "  - Rumble: Large Motor = {}, Small Motor = {}",
28                notification.large_motor, notification.small_motor
29            );
30            println!(
31                "  - Lightbar Color: R={}, G={}, B={}",
32                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
33            );
34        }
35    });
36
37    // Here, we'll send reports to the controller to simulate input.
38
39    let mut report = Ds4Report::default();
40
41    // Hold the right D-pad button
42    report.set_dpad(Ds4Dpad::East);
43    // Hold the Cross button
44    report.buttons |= Ds4Button::CROSS.bits();
45    // Fully press the right trigger
46    report.trigger_r = 255;
47
48    let mut angle: f64 = 0.0;
49
50    loop {
51        // Animate the right thumbstick in a circle
52        let (sin, cos) = angle.sin_cos();
53
54        // DS4 thumbsticks are 0-255, with 128 as the center.
55        report.thumb_rx = (128.0 + sin * 127.0) as u8;
56        report.thumb_ry = (128.0 + cos * 127.0) as u8;
57
58        // Send the updated report to the controller
59        ds4.update(&report)?;
60
61        thread::sleep(Duration::from_millis(16));
62        angle += 0.05;
63    }
64}
More examples
Hide additional examples
examples/ds4_ex.rs (line 17)
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7    // Connect to the ViGEm bus
8    // This can fail if the ViGEm bus driver is not installed.
9    let client = Client::connect()?;
10    println!("Connected to ViGEm bus");
11
12    // Create and plugin the virtual controller
13    let ds4 = client.new_ds4_target().plugin()?;
14    println!("Plugged in virtual DualShock 4 controller");
15
16    // Wait for the controller to be ready
17    ds4.wait_for_ready()?;
18    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
19
20    let notifications = ds4.register_notification()?;
21    thread::spawn(move || {
22        println!("Notification Thread Started. Waiting for feedback from the host...");
23        while let Ok(Ok(notification)) = notifications.recv() {
24            println!("Notification Thread Received feedback:");
25            println!(
26                "  - Rumble: Large Motor = {}, Small Motor = {}",
27                notification.large_motor, notification.small_motor
28            );
29            println!(
30                "  - Lightbar Color: R={}, G={}, B={}",
31                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
32            );
33        }
34    });
35
36    // Main input loop for extended reports
37    let mut report_ex = Ds4ReportEx::default();
38
39    // Variables to animate the touch point
40    let mut packet_counter: u8 = 0;
41    let mut touch_x: i32 = 0;
42    let mut direction: i32 = 12;
43
44    loop {
45        // Move the touch point back and forth horizontally.
46        if touch_x <= 0 {
47            direction = 12;
48        }
49        if touch_x >= 1919 {
50            direction = -12;
51        }
52        touch_x += direction;
53
54        report_ex.touch_packets_n = 1;
55
56        // Get a mut reference to the touch data struct inside the report.
57        let touch = &mut report_ex.current_touch;
58
59        // This counter should increment for each new packet of touch data (not sure if necessary for functionality).
60        touch.packet_counter = packet_counter;
61        packet_counter = packet_counter.wrapping_add(1);
62
63        touch.set_touch_1(true, 1, touch_x as u16, 471); // Finger 1 is down, centered vertically.
64        touch.set_touch_2(false, 0, 0, 0); // Finger 2 is up (inactive).
65
66        // Send the updated report to the controller
67        ds4.update_ex(&report_ex)?;
68
69        thread::sleep(Duration::from_millis(16));
70    }
71}
Source

pub fn register_notification( &self, ) -> Result<Receiver<Result<Ds4Notification, BusError>>, ClientError>

Registers to receive notifications for this DualShock 4 target.

This returns a Receiver that will yield Ds4Notifications from the bus, which contain information like rumble data and lightbar color commands.

§Important

Calling this function spawns a dedicated background thread that lives as long as the Receiver does.

§Example
let receiver = ds4.register_notification().unwrap();

// In a loop or another thread:
if let Ok(Ok(notification)) = receiver.try_recv() {
    println!("Lightbar color changed to: {:?}", notification.lightbar);
}
Examples found in repository?
examples/ds4.rs (line 21)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let ds4 = client.new_ds4_target().plugin()?;
13    println!("Plugged in virtual DualShock 4 controller");
14
15    // Wait for the controller to be ready
16    ds4.wait_for_ready()?;
17    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
18
19    // Set up a notification listener in a separate thread
20    // This allows us to react to feedback from the system, like rumble or LED changes.
21    let notifications = ds4.register_notification()?;
22    thread::spawn(move || {
23        println!("Notification Thread Started. Waiting for feedback from the host...");
24        while let Ok(Ok(notification)) = notifications.recv() {
25            println!("Notification Thread Received feedback:");
26            println!(
27                "  - Rumble: Large Motor = {}, Small Motor = {}",
28                notification.large_motor, notification.small_motor
29            );
30            println!(
31                "  - Lightbar Color: R={}, G={}, B={}",
32                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
33            );
34        }
35    });
36
37    // Here, we'll send reports to the controller to simulate input.
38
39    let mut report = Ds4Report::default();
40
41    // Hold the right D-pad button
42    report.set_dpad(Ds4Dpad::East);
43    // Hold the Cross button
44    report.buttons |= Ds4Button::CROSS.bits();
45    // Fully press the right trigger
46    report.trigger_r = 255;
47
48    let mut angle: f64 = 0.0;
49
50    loop {
51        // Animate the right thumbstick in a circle
52        let (sin, cos) = angle.sin_cos();
53
54        // DS4 thumbsticks are 0-255, with 128 as the center.
55        report.thumb_rx = (128.0 + sin * 127.0) as u8;
56        report.thumb_ry = (128.0 + cos * 127.0) as u8;
57
58        // Send the updated report to the controller
59        ds4.update(&report)?;
60
61        thread::sleep(Duration::from_millis(16));
62        angle += 0.05;
63    }
64}
More examples
Hide additional examples
examples/ds4_ex.rs (line 20)
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7    // Connect to the ViGEm bus
8    // This can fail if the ViGEm bus driver is not installed.
9    let client = Client::connect()?;
10    println!("Connected to ViGEm bus");
11
12    // Create and plugin the virtual controller
13    let ds4 = client.new_ds4_target().plugin()?;
14    println!("Plugged in virtual DualShock 4 controller");
15
16    // Wait for the controller to be ready
17    ds4.wait_for_ready()?;
18    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
19
20    let notifications = ds4.register_notification()?;
21    thread::spawn(move || {
22        println!("Notification Thread Started. Waiting for feedback from the host...");
23        while let Ok(Ok(notification)) = notifications.recv() {
24            println!("Notification Thread Received feedback:");
25            println!(
26                "  - Rumble: Large Motor = {}, Small Motor = {}",
27                notification.large_motor, notification.small_motor
28            );
29            println!(
30                "  - Lightbar Color: R={}, G={}, B={}",
31                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
32            );
33        }
34    });
35
36    // Main input loop for extended reports
37    let mut report_ex = Ds4ReportEx::default();
38
39    // Variables to animate the touch point
40    let mut packet_counter: u8 = 0;
41    let mut touch_x: i32 = 0;
42    let mut direction: i32 = 12;
43
44    loop {
45        // Move the touch point back and forth horizontally.
46        if touch_x <= 0 {
47            direction = 12;
48        }
49        if touch_x >= 1919 {
50            direction = -12;
51        }
52        touch_x += direction;
53
54        report_ex.touch_packets_n = 1;
55
56        // Get a mut reference to the touch data struct inside the report.
57        let touch = &mut report_ex.current_touch;
58
59        // This counter should increment for each new packet of touch data (not sure if necessary for functionality).
60        touch.packet_counter = packet_counter;
61        packet_counter = packet_counter.wrapping_add(1);
62
63        touch.set_touch_1(true, 1, touch_x as u16, 471); // Finger 1 is down, centered vertically.
64        touch.set_touch_2(false, 0, 0, 0); // Finger 2 is up (inactive).
65
66        // Send the updated report to the controller
67        ds4.update_ex(&report_ex)?;
68
69        thread::sleep(Duration::from_millis(16));
70    }
71}
Source

pub fn register_notification_raw_buffer( &self, ) -> Result<Receiver<Result<Ds4OutputBuffer, BusError>>, ClientError>

Subscribes to raw 64-byte output buffers for a DualShock 4 target.

§Warning

Unlike the register_notification method, this one gets the raw output buffer of all connected Dualshock 4 virtual controllers via a single thread (centralized system.)

§Important

Calling this function spawns a dedicated background thread that lives as long as the Receiver does.

This is an advanced function for applications that need to parse the raw output report from the bus, which may contain more detailed information than the standard Ds4Notification.

Source

pub fn update(&self, report: &Ds4Report) -> Result<(), ClientError>

Submits a standard input state report for this DualShock 4 target.

This method sends a Ds4Report, which covers the state of all buttons, D-Pad, triggers, and thumbsticks. For advanced features like touchpad or motion sensor data, use update_ex instead.

§Warning

Calling this method immediately after plugging in the target will likely fail, as the system needs time to enumerate the device.

To reliably send updates right after creation, you must first call [wait_for_ready()].

§Example
let mut report = Ds4Report::default();
report.buttons = Ds4Button::CROSS.bits();
report.set_dpad(Ds4Dpad::South);
report.trigger_r = 255;

ds4.update(&report)?;
Examples found in repository?
examples/ds4.rs (line 59)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let ds4 = client.new_ds4_target().plugin()?;
13    println!("Plugged in virtual DualShock 4 controller");
14
15    // Wait for the controller to be ready
16    ds4.wait_for_ready()?;
17    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
18
19    // Set up a notification listener in a separate thread
20    // This allows us to react to feedback from the system, like rumble or LED changes.
21    let notifications = ds4.register_notification()?;
22    thread::spawn(move || {
23        println!("Notification Thread Started. Waiting for feedback from the host...");
24        while let Ok(Ok(notification)) = notifications.recv() {
25            println!("Notification Thread Received feedback:");
26            println!(
27                "  - Rumble: Large Motor = {}, Small Motor = {}",
28                notification.large_motor, notification.small_motor
29            );
30            println!(
31                "  - Lightbar Color: R={}, G={}, B={}",
32                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
33            );
34        }
35    });
36
37    // Here, we'll send reports to the controller to simulate input.
38
39    let mut report = Ds4Report::default();
40
41    // Hold the right D-pad button
42    report.set_dpad(Ds4Dpad::East);
43    // Hold the Cross button
44    report.buttons |= Ds4Button::CROSS.bits();
45    // Fully press the right trigger
46    report.trigger_r = 255;
47
48    let mut angle: f64 = 0.0;
49
50    loop {
51        // Animate the right thumbstick in a circle
52        let (sin, cos) = angle.sin_cos();
53
54        // DS4 thumbsticks are 0-255, with 128 as the center.
55        report.thumb_rx = (128.0 + sin * 127.0) as u8;
56        report.thumb_ry = (128.0 + cos * 127.0) as u8;
57
58        // Send the updated report to the controller
59        ds4.update(&report)?;
60
61        thread::sleep(Duration::from_millis(16));
62        angle += 0.05;
63    }
64}
Source

pub fn update_ex(&self, report: &Ds4ReportEx) -> Result<(), ClientError>

Submits an extended input state report for this DualShock 4 target.

This method is used for advanced scenarios that require simulating motion controls (gyroscope/accelerometer) and detailed touchpad activity. It sends a Ds4ReportEx, which is a superset of the standard Ds4Report.

§Warning

Calling this method immediately after plugging in the target will likely fail, as the system needs time to enumerate the device.

To reliably send updates right after creation, you must first call [wait_for_ready()].

§Example
let mut report_ex = Ds4ReportEx::default();


// Set gyro data
report_ex.gyro_x = 12345;

// The standard report fields are also available
report_ex.thumb_lx = 200;

ds4.update_ex(&report_ex)?;
Examples found in repository?
examples/ds4_ex.rs (line 67)
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7    // Connect to the ViGEm bus
8    // This can fail if the ViGEm bus driver is not installed.
9    let client = Client::connect()?;
10    println!("Connected to ViGEm bus");
11
12    // Create and plugin the virtual controller
13    let ds4 = client.new_ds4_target().plugin()?;
14    println!("Plugged in virtual DualShock 4 controller");
15
16    // Wait for the controller to be ready
17    ds4.wait_for_ready()?;
18    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
19
20    let notifications = ds4.register_notification()?;
21    thread::spawn(move || {
22        println!("Notification Thread Started. Waiting for feedback from the host...");
23        while let Ok(Ok(notification)) = notifications.recv() {
24            println!("Notification Thread Received feedback:");
25            println!(
26                "  - Rumble: Large Motor = {}, Small Motor = {}",
27                notification.large_motor, notification.small_motor
28            );
29            println!(
30                "  - Lightbar Color: R={}, G={}, B={}",
31                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
32            );
33        }
34    });
35
36    // Main input loop for extended reports
37    let mut report_ex = Ds4ReportEx::default();
38
39    // Variables to animate the touch point
40    let mut packet_counter: u8 = 0;
41    let mut touch_x: i32 = 0;
42    let mut direction: i32 = 12;
43
44    loop {
45        // Move the touch point back and forth horizontally.
46        if touch_x <= 0 {
47            direction = 12;
48        }
49        if touch_x >= 1919 {
50            direction = -12;
51        }
52        touch_x += direction;
53
54        report_ex.touch_packets_n = 1;
55
56        // Get a mut reference to the touch data struct inside the report.
57        let touch = &mut report_ex.current_touch;
58
59        // This counter should increment for each new packet of touch data (not sure if necessary for functionality).
60        touch.packet_counter = packet_counter;
61        packet_counter = packet_counter.wrapping_add(1);
62
63        touch.set_touch_1(true, 1, touch_x as u16, 471); // Finger 1 is down, centered vertically.
64        touch.set_touch_2(false, 0, 0, 0); // Finger 2 is up (inactive).
65
66        // Send the updated report to the controller
67        ds4.update_ex(&report_ex)?;
68
69        thread::sleep(Duration::from_millis(16));
70    }
71}

Trait Implementations§

Source§

impl<T: Clone> Clone for TargetHandle<T>

Source§

fn clone(&self) -> TargetHandle<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<T> Freeze for TargetHandle<T>

§

impl<T> RefUnwindSafe for TargetHandle<T>
where T: RefUnwindSafe,

§

impl<T> Send for TargetHandle<T>
where T: Sync + Send,

§

impl<T> Sync for TargetHandle<T>
where T: Sync + Send,

§

impl<T> Unpin for TargetHandle<T>

§

impl<T> UnwindSafe for TargetHandle<T>
where T: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.