Skip to content

Conversation

@jagprog5
Copy link
Contributor

@jagprog5 jagprog5 commented Oct 27, 2025

closes #1504

preemptive: if sdl_bindings.rs shouldn't be modified manually then please suggest an alternative. note that this is a tricky? case

@jagprog5 jagprog5 requested review from Cobrand and antonilol October 27, 2025 16:14
@jagprog5 jagprog5 self-assigned this Oct 27, 2025
Comment on lines 15497 to 15498
#[doc = "< flip vertically and horizontally"]
SDL_FLIP_BOTH = 3,
Copy link
Contributor

Choose a reason for hiding this comment

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

preemptive: if sdl_bindings.rs shouldn't be modified manually then please suggest an alternative. note that this is a tricky? case

sdl_bindings.rs shouldn't be modified, it is generated and adds a lot of work if we need to do manual changes everytime we generate it again.

SDL_RendererFlip should not generate a Rust enum, enum members in C are just constants and the enum type itself an alias for int.
enum style is configured in bindgen here:

.default_enum_style(bindgen::EnumVariation::Rust {

We should at least not make SDL_RendererFlip a Rust enum, but I would go further not use Rust enum style at all in bindings, these are bindings to the C code so the function signatures should be as close as possible to the C function signatures in the header files. SDL_RendererFlip should be c_int (std::ffi::c_int) or any alias or repr(transparent) wrapper, because the C standard says that enums are int.

In the general case you can't fix an enum that is actually used as bit flags by adding a new variant. What if the C enum has many more variants (each a different bit and they can be combined)? It would be nice have a type that restricts values to valid bit flags but currently this would require enums with hundreds of variants, so just using c_int is also for consistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks. that follows what I mentioned in the issue, regarding what sdl3-sys does.

I looked through the rest of sdl_bindings.rs and found that everything else was ok, except for SDL_Keymod:

bitflags! {
    pub struct Mod: u16 {
        const NOMOD = 0x0000;
        const LSHIFTMOD = 0x0001;
        const RSHIFTMOD = 0x0002;
        const LCTRLMOD = 0x0040;
        const RCTRLMOD = 0x0080;
        const LALTMOD = 0x0100;
        const RALTMOD = 0x0200;
        const LGUIMOD = 0x0400;
        const RGUIMOD = 0x0800;
        const NUMMOD = 0x1000;
        const CAPSMOD = 0x2000;
        const MODEMOD = 0x4000;
        const RESERVEDMOD = 0x8000;
    }
}

#[doc(alias = "SDL_SetModState")]
pub fn set_mod_state(&self, flags: Mod) {
    unsafe {
        // BOOM
        sys::SDL_SetModState(transmute::<u32, sys::SDL_Keymod>(flags.bits() as u32));
    }
}

Honourable mention for SDL_WindowFlags, which we convert to an int before ORing, so it's ok.


Perhaps: we can update bindgen to change the representation of SDL_RendererFlip and SDL_Keymod enums only.

Copy link
Contributor

Choose a reason for hiding this comment

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

SDL_WindowFlags is a weird case, the functions that use it take u32, not SDL_WindowFlags like:
https://github.com/Rust-SDL2/rust-sdl2/blob/1fac15ba89a2c0a8735d6725ae74e9bb57c4457b/sdl2-sys/sdl_bindings.rs#L6981
https://wiki.libsdl.org/SDL2/SDL_CreateWindow

Perhaps: we can update bindgen to change the representation of SDL_RendererFlip and SDL_Keymod enums only.

That keymod thing is definitely UB too and should be fixed.

I just found this: https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.bitfield_enum, this fits exactly I would say. I don't know exactly what code it generates.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

can you try bitfield_enum instead of constified_enum

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for sharing bitfield_enum.

looks pretty cool. took a look at the generated code with that instead and it looks like:

impl SDL_RendererFlip {
    #[doc = "< Do not flip"]
    pub const SDL_FLIP_NONE: SDL_RendererFlip = SDL_RendererFlip(0);
}
impl SDL_RendererFlip {
    #[doc = "< flip horizontally"]
    pub const SDL_FLIP_HORIZONTAL: SDL_RendererFlip = SDL_RendererFlip(1);
}
impl SDL_RendererFlip {
    #[doc = "< flip vertically"]
    pub const SDL_FLIP_VERTICAL: SDL_RendererFlip = SDL_RendererFlip(2);
}
impl ::core::ops::BitOr<SDL_RendererFlip> for SDL_RendererFlip {
    type Output = Self;
    #[inline]
    fn bitor(self, other: Self) -> Self {
        SDL_RendererFlip(self.0 | other.0)
    }
}
impl ::core::ops::BitOrAssign for SDL_RendererFlip {
    #[inline]
    fn bitor_assign(&mut self, rhs: SDL_RendererFlip) {
        self.0 |= rhs.0;
    }
}
...

imo not necessary since we are are mapping that to public API Mod which does the bitflags over there instead

Copy link
Contributor

Choose a reason for hiding this comment

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

imo not necessary since we are are mapping that to public API Mod which does the bitflags over there instead

right

I do like that the constants are defined in an impl of a new type, can you try newtype_enum then?

Copy link
Contributor Author

@jagprog5 jagprog5 Oct 28, 2025

Choose a reason for hiding this comment

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

4d61d9a

ok so I'm using bitfield for flip, because I need to do OR when using. and newtype_enum for KeyMod, since we do the OR with the public API (not needed in the binds)

@jagprog5 jagprog5 requested a review from antonilol October 28, 2025 14:30
Copy link
Contributor

@antonilol antonilol left a comment

Choose a reason for hiding this comment

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

LGTM

there is a lot of "useless diff" in sdl_bindings.rs which I aim to fix in #1506, will ignore that here

@jagprog5 jagprog5 merged commit 4583b3d into Rust-SDL2:master Oct 28, 2025
11 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SDL_RendererFlip invalid enum variant

2 participants