diff --git a/src/input/composite_device/mod.rs b/src/input/composite_device/mod.rs index 65cec891..fb0acf75 100644 --- a/src/input/composite_device/mod.rs +++ b/src/input/composite_device/mod.rs @@ -647,7 +647,9 @@ impl CompositeDevice { continue; }; log::debug!("Updating effect {source_effect_id} from {source_id}"); - source.update_effect(*source_effect_id, *data).await?; + if let Err(e) = source.update_effect(*source_effect_id, *data).await { + log::error!("Error updating effect '{id}' on {source_id}: {e:?}"); + } } target_dev.send(Some(*id))?; return Ok(()); @@ -659,11 +661,16 @@ impl CompositeDevice { log::debug!("Uploading effect to {source_id}"); match source.upload_effect(*data).await { Ok(source_effect_id) => { - log::debug!("Successfully uploaded effect with source effect id {source_effect_id}"); + // An effect ID of -1 indicates the device does not support + // FF events. + if source_effect_id == -1 { + continue; + } + log::debug!("Successfully uploaded effect to {source_id} with source effect id {source_effect_id}"); source_effect_ids.insert(source_id.clone(), source_effect_id); } Err(e) => { - log::error!("Error uploading effect: {:?}", e); + log::error!("Error uploading effect to {source_id}: {e:?}"); } } } @@ -696,7 +703,7 @@ impl CompositeDevice { }; log::debug!("Erasing effect from {source_id}"); if let Err(e) = source.erase_effect(*source_effect_id).await { - log::debug!("Failed to erase FF effect from {source_id}: {:?}", e); + log::warn!("Failed to erase FF effect from {source_id}: {:?}", e); } } } diff --git a/src/input/source/client.rs b/src/input/source/client.rs index ea3901ae..d0efcefd 100644 --- a/src/input/source/client.rs +++ b/src/input/source/client.rs @@ -66,7 +66,7 @@ impl SourceDeviceClient { pub async fn upload_effect(&self, effect: FFEffectData) -> Result { let (tx, rx) = channel(); self.tx.try_send(SourceCommand::UploadEffect(effect, tx))?; - match rx.recv_timeout(Duration::from_secs(1)) { + match rx.recv_timeout(Duration::from_millis(200)) { Ok(result) => match result { Ok(id) => Ok(id), Err(err) => Err(ClientError::ServiceError(err)), diff --git a/src/input/source/evdev/gamepad.rs b/src/input/source/evdev/gamepad.rs index 8d7434db..70929e96 100644 --- a/src/input/source/evdev/gamepad.rs +++ b/src/input/source/evdev/gamepad.rs @@ -325,6 +325,10 @@ impl SourceOutputDevice for GamepadEventDevice { /// a device-specific id of the uploaded effect if it is successful. fn upload_effect(&mut self, effect: FFEffectData) -> Result { log::debug!("Uploading FF effect data"); + if self.device.supported_ff().is_none() { + log::debug!("Device does not support FF effects"); + return Ok(-1); + } match self.device.upload_ff_effect(effect) { Ok(effect) => { let id = effect.id() as i16; @@ -338,6 +342,10 @@ impl SourceOutputDevice for GamepadEventDevice { /// Update the effect with the given id using the given effect data. fn update_effect(&mut self, effect_id: i16, effect: FFEffectData) -> Result<(), OutputError> { log::debug!("Update FF effect {effect_id}"); + if self.device.supported_ff().is_none() { + log::debug!("Device does not support FF effects"); + return Ok(()); + } let Some(current_effect) = self.ff_effects.get_mut(&effect_id) else { log::warn!("Unable to find existing FF effect with id {effect_id}"); return Ok(()); @@ -353,6 +361,10 @@ impl SourceOutputDevice for GamepadEventDevice { /// Erase the effect with the given id from the source device. fn erase_effect(&mut self, effect_id: i16) -> Result<(), OutputError> { log::debug!("Erasing FF effect data"); + if self.device.supported_ff().is_none() { + log::debug!("Device does not support FF effects"); + return Ok(()); + } self.ff_effects.remove(&effect_id); Ok(()) } diff --git a/src/input/source/mod.rs b/src/input/source/mod.rs index c648235a..d18a422c 100644 --- a/src/input/source/mod.rs +++ b/src/input/source/mod.rs @@ -121,11 +121,12 @@ pub trait SourceOutputDevice { } /// Upload the given force feedback effect data to the source device. Returns - /// a device-specific id of the uploaded effect if it is successful. + /// a device-specific id of the uploaded effect if it is successful. Return + /// -1 if this device does not support FF events. fn upload_effect(&mut self, effect: FFEffectData) -> Result { //log::trace!("Received upload effect: {effect:?}"); let _ = effect; - Err(OutputError::NotImplemented) + Ok(-1) } /// Update the effect with the given id using the given effect data. diff --git a/src/input/target/xb360.rs b/src/input/target/xb360.rs index 823fd20d..c025ab53 100644 --- a/src/input/target/xb360.rs +++ b/src/input/target/xb360.rs @@ -255,7 +255,7 @@ impl TargetOutputDevice for XBox360Controller { let Some(composite_device) = composite_device else { log::debug!("No composite device to upload effect to!"); event.set_retval(-1); - return Ok(vec![]); + continue; }; // Send the effect data to be uploaded to the device and wait @@ -274,7 +274,8 @@ impl TargetOutputDevice for XBox360Controller { Ok(id) => id, Err(e) => { event.set_retval(-1); - return Err(e.to_string().into()); + log::error!("Failed to receive FF upload response: {e:?}"); + continue; } }; diff --git a/src/input/target/xbox_elite.rs b/src/input/target/xbox_elite.rs index 7de0d8bd..cbdde458 100644 --- a/src/input/target/xbox_elite.rs +++ b/src/input/target/xbox_elite.rs @@ -266,7 +266,7 @@ impl TargetOutputDevice for XboxEliteController { let Some(composite_device) = composite_device else { log::debug!("No composite device to upload effect to!"); event.set_retval(-1); - return Ok(vec![]); + continue; }; // Send the effect data to be uploaded to the device and wait @@ -285,7 +285,8 @@ impl TargetOutputDevice for XboxEliteController { Ok(id) => id, Err(e) => { event.set_retval(-1); - return Err(e.to_string().into()); + log::error!("Failed to receive FF upload response: {e:?}"); + continue; } }; diff --git a/src/input/target/xbox_series.rs b/src/input/target/xbox_series.rs index 9a0f4208..542abe20 100644 --- a/src/input/target/xbox_series.rs +++ b/src/input/target/xbox_series.rs @@ -257,7 +257,7 @@ impl TargetOutputDevice for XboxSeriesController { let Some(composite_device) = composite_device else { log::debug!("No composite device to upload effect to!"); event.set_retval(-1); - return Ok(vec![]); + continue; }; // Send the effect data to be uploaded to the device and wait @@ -276,7 +276,8 @@ impl TargetOutputDevice for XboxSeriesController { Ok(id) => id, Err(e) => { event.set_retval(-1); - return Err(e.to_string().into()); + log::error!("Failed to receive FF upload response: {e:?}"); + continue; } };