Skip to content

Fluke/zotac zone dials #339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 25, 2025
Merged

Conversation

flukejones
Copy link
Contributor

No description provided.

@flukejones flukejones marked this pull request as draft April 18, 2025 11:51
@flukejones
Copy link
Contributor Author

WIP. Needs help

@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch 2 times, most recently from 49036c0 to b9776ed Compare April 19, 2025 08:08
@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch 2 times, most recently from a7829a8 to 5b0af67 Compare April 19, 2025 10:56
@flukejones
Copy link
Contributor Author

I'm at a loss as to why I'm getting a dual event:

[src/input/composite_device/mod.rs:329:25] &device_id = "evdev://event11"
[src/input/composite_device/mod.rs:329:25] &event = Native(
    NativeEvent {
        capability: Gamepad(
            Dial(
                RightStickDial,
            ),
        ),
        source_capability: None,
        value: Vector2 {
            x: Some(
                -1.0,
            ),
            y: None,
        },
    },
)
[src/input/event/value.rs:1009:17] direction.as_str() = "counter-clockwise"
[src/input/event/value.rs:1009:17] direction.as_str() = "clockwise"
[2025-04-19T10:53:53Z DEBUG inputplumber::input::composite_device] Checking single intercept event.
[2025-04-19T10:53:53Z DEBUG inputplumber::input::composite_device] Checking single intercept event.
[src/input/composite_device/mod.rs:329:25] &device_id = "evdev://event11"
[src/input/composite_device/mod.rs:329:25] &event = Native(
    NativeEvent {
        capability: Gamepad(
            Dial(
                RightStickDial,
            ),
        ),
        source_capability: None,
        value: Vector2 {
            x: Some(
                -1.0,
            ),
            y: None,
        },
    },
)
[src/input/event/value.rs:1009:17] direction.as_str() = "counter-clockwise"
[src/input/event/value.rs:1009:17] direction.as_str() = "clockwise"
[2025-04-19T10:53:53Z DEBUG inputplumber::input::composite_device] Checking single intercept event.
[2025-04-19T10:53:53Z DEBUG inputplumber::input::composite_device] Checking single intercept event.

Doesn't make sense at all. Kernel driver ouputs a single event.

@pastaq
Copy link
Contributor

pastaq commented Apr 19, 2025

Are you mapping the evdev and the hidraw?

@pastaq
Copy link
Contributor

pastaq commented Apr 19, 2025

You have the x axis of the dial mapped to two events, so it will trigger on both. You should translate the InputValue for that capability to clockwise/counterclockwise based on the axis value being > 0 / < 0 instead.

@flukejones
Copy link
Contributor Author

@pastaq can you walk me through this please? There is just too much repetitive code for me to follow around here.

@flukejones
Copy link
Contributor Author

Hmm no I think I understand now.

@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch 2 times, most recently from 61ce07d to 28163d3 Compare April 19, 2025 12:23
@flukejones
Copy link
Contributor Author

Alright so everything works now except for this particular problem:

The driver emits and re-emits either 1 or -1. These events are seen fine for the raw event handling. But when it gets to event/value.rs translate() it falls over.

I'm not really all that sure how best to handle translate_dial_to_button(). What happens is that due to the above a release event is never seen, and when you turn the dial the opposite way we then get a 0 due to changed direction and value. If I change translate_dial_to_button() to:

return match direction.as_str() {
    "clockwise" => {
        if let Some(x) = x {
            if x > 0.0 {
                Ok(InputValue::Bool(true))
            } else {
                Ok(InputValue::None)
            }
        } else {
            Ok(InputValue::None)
        }
    }
    "counter-clockwise" => {
        if let Some(x) = x {
            if x < 0.0 {
                Ok(InputValue::Bool(true))
            } else {
                Ok(InputValue::None)
            }
        } else {
            Ok(InputValue::None)
        }
    }

I never get another event from IP on these. They are stuck on true. So i assume the values get cached? At the very least I think REL_WHEEL and such need to ignore that there is no 0 event.

@ShadowApex
Copy link
Contributor

ShadowApex commented Apr 19, 2025

Looking at this more, since these events do not have a "button up" state, you'll need to emulate that yourself when encountering a dial -> button translation. It seems like what you want to do is send a "button down" + "button up" event for each "tick" of the dial. So we'll need to translate that single dial event into "button down" + "button up" events.

There may be a more elegant way to do this, but what first comes to mind is you could handle this in the translate_event() function in composite_device/mod.rs. In that function, you can check to see if this is a dial -> button translation and create the button up/down events to emit there.

E.g.

                // Translate the event into the defined target event(s)
                for target_event in mapping.target_events.iter() {
                    // TODO: We can cache this conversion for faster translation
                    let target_cap: Capability = target_event.clone().into();
                    let result = event.get_value().translate(
                        &source_cap,
                        &mapping.source_event,
                        &target_cap,
                        target_event,
                    );
                    let value = match result {
                        Ok(v) => v,
                        ...
                    };
                    if matches!(value, InputValue::None) {
                        continue;
                    }

                    // If the the event translation should result in a button pulse, return the
                    // translated pulse events.
                    if source_cap.is_button_pulse_translation(target_cap) {
                        let event = NativeEvent::new_translated(source_cap.clone(), target_cap, InputValue::Bool(true));
                        events.push(event);
                        let event = NativeEvent::new_translated(source_cap.clone(), target_cap, InputValue::Bool(false));
                        events.push(event);
                        continue;
                    }

                    let event = NativeEvent::new_translated(source_cap.clone(), target_cap, value);
                    events.push(event);
                }
  ...

@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch 2 times, most recently from 650e614 to 3300b3d Compare April 22, 2025 08:16
@flukejones
Copy link
Contributor Author

Alright, this is working now. So cleanup is required.

@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch 6 times, most recently from e1b0222 to 7810744 Compare April 22, 2025 09:19
Full support for the driver to enable the majority of use-cases.
Does not include proper support of dial/wheels or touchpads.

Signed-off-by: Luke Jones <[email protected]>
@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch 2 times, most recently from 7d60e03 to 6d9d451 Compare April 24, 2025 01:19
@flukejones flukejones marked this pull request as ready for review April 24, 2025 01:19
@flukejones
Copy link
Contributor Author

Cleaned up extraneous formatting. Tested. Should be good to go pending review.

Copy link
Contributor

@pastaq pastaq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comment cleanup, otherwise LGTM, thanks!

@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch from 6d9d451 to b9981ba Compare April 24, 2025 02:22
Copy link
Contributor

@ShadowApex ShadowApex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also some small suggestions in addition to @pastaq 's. Otherwise looks good!

@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch from b9981ba to 7cf5b5d Compare April 25, 2025 02:23
Add ability to output the screen-brightness keycode events which can
enable screen brightness controls if the environment uses them.

Also map the Zotac Zone dials to emit volume control + screen brightness.

Signed-off-by: Luke Jones <[email protected]>
@flukejones flukejones force-pushed the fluke/zotac-zone-dials branch from 7cf5b5d to 354229e Compare April 25, 2025 02:45
Copy link
Contributor

@ShadowApex ShadowApex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks!

@ShadowApex ShadowApex merged commit 1638889 into ShadowBlip:main Apr 25, 2025
1 check passed
Copy link

🎉 This PR is included in version 0.55.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants