diff --git a/src/sdl2/audio.rs b/src/sdl2/audio.rs index 46eaa68a..0c625e33 100644 --- a/src/sdl2/audio.rs +++ b/src/sdl2/audio.rs @@ -200,6 +200,54 @@ impl FromPrimitive for AudioStatus { fn from_u64(n: u64) -> Option { FromPrimitive::from_i64(n as i64) } } +#[derive(Copy, Clone)] +pub struct DriverIterator { + length: i32, + index: i32 +} + +impl Iterator for DriverIterator { + type Item = &'static str; + + #[inline] + fn next(&mut self) -> Option<&'static str> { + if self.index >= self.length { + None + } else { + use std::str; + + unsafe { + let buf = ll::SDL_GetAudioDriver(self.index); + assert!(!buf.is_null()); + self.index += 1; + + Some(str::from_utf8(CStr::from_ptr(buf).to_bytes()).unwrap()) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let l = self.length as usize; + (l, Some(l)) + } +} + +impl ExactSizeIterator for DriverIterator { } + +/// Gets an iterator of all audio drivers compiled into the SDL2 library. +#[inline] +pub fn drivers() -> DriverIterator { + // This function is thread-safe and doesn't require the audio subsystem to be initialized. + // The list of drivers are read-only and statically compiled into SDL2, varying by platform. + + // SDL_GetNumAudioDrivers can never return a negative value. + DriverIterator { + length: unsafe { ll::SDL_GetNumAudioDrivers() }, + index: 0 + } +} + pub struct AudioSpecWAV { pub freq: i32, pub format: AudioFormat, diff --git a/src/sdl2/render.rs b/src/sdl2/render.rs index 8e302fe7..9a56cc18 100644 --- a/src/sdl2/render.rs +++ b/src/sdl2/render.rs @@ -75,7 +75,7 @@ impl FromPrimitive for TextureAccess { /// or the current render context. #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct RendererInfo { - pub name: String, + pub name: &'static str, pub flags: u32, pub texture_formats: Vec, pub max_texture_width: u32, @@ -108,12 +108,17 @@ impl FromPrimitive for BlendMode { impl RendererInfo { pub unsafe fn from_ll(info: &ll::SDL_RendererInfo) -> RendererInfo { + use std::str; + let texture_formats: Vec = info.texture_formats[0..(info.num_texture_formats as usize)].iter().map(|&format| { FromPrimitive::from_i64(format as i64).unwrap() }).collect(); + // The driver name is always a static string, compiled into SDL2. + let name = str::from_utf8(CStr::from_ptr(info.name).to_bytes()).unwrap(); + RendererInfo { - name: String::from_utf8_lossy(CStr::from_ptr(info.name).to_bytes()).to_string(), + name: name, flags: info.flags, texture_formats: texture_formats, max_texture_width: info.max_texture_width as u32, @@ -1205,24 +1210,48 @@ impl Texture { pub unsafe fn raw(&self) -> *mut ll::SDL_Texture { self.raw } } +#[derive(Copy, Clone)] +pub struct DriverIterator { + length: i32, + index: i32 +} -pub fn get_num_render_drivers() -> SdlResult { - let result = unsafe { ll::SDL_GetNumRenderDrivers() }; - if result > 0 { - Ok(result as u32) - } else { - Err(get_error()) +impl Iterator for DriverIterator { + type Item = RendererInfo; + + #[inline] + fn next(&mut self) -> Option { + if self.index >= self.length { + None + } else { + let mut out = unsafe { mem::uninitialized() }; + let result = unsafe { ll::SDL_GetRenderDriverInfo(self.index, &mut out) == 0 }; + assert!(result, 0); + self.index += 1; + + unsafe { Some(RendererInfo::from_ll(&out)) } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let l = self.length as usize; + (l, Some(l)) } } -pub fn get_render_driver_info(index: u32) -> SdlResult { - let mut out = unsafe { mem::uninitialized() }; - let index = try!(u32_to_int!(index)); - let result = unsafe { ll::SDL_GetRenderDriverInfo(index, &mut out) == 0 }; - if result { - unsafe { Ok(RendererInfo::from_ll(&out)) } - } else { - Err(get_error()) +impl ExactSizeIterator for DriverIterator { } + +/// Gets an iterator of all render drivers compiled into the SDL2 library. +#[inline] +pub fn drivers() -> DriverIterator { + // This function is thread-safe and doesn't require the video subsystem to be initialized. + // The list of drivers are read-only and statically compiled into SDL2, varying by platform. + + // SDL_GetNumRenderDrivers can never return a negative value. + DriverIterator { + length: unsafe { ll::SDL_GetNumRenderDrivers() }, + index: 0 } } diff --git a/src/sdl2/video.rs b/src/sdl2/video.rs index 37ee211d..4cfebc35 100644 --- a/src/sdl2/video.rs +++ b/src/sdl2/video.rs @@ -1133,3 +1133,51 @@ impl<'a> WindowProperties<'a> { } } } + +#[derive(Copy, Clone)] +pub struct DriverIterator { + length: i32, + index: i32 +} + +impl Iterator for DriverIterator { + type Item = &'static str; + + #[inline] + fn next(&mut self) -> Option<&'static str> { + if self.index >= self.length { + None + } else { + use std::str; + + unsafe { + let buf = ll::SDL_GetVideoDriver(self.index); + assert!(!buf.is_null()); + self.index += 1; + + Some(str::from_utf8(CStr::from_ptr(buf).to_bytes()).unwrap()) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let l = self.length as usize; + (l, Some(l)) + } +} + +impl ExactSizeIterator for DriverIterator { } + +/// Gets an iterator of all video drivers compiled into the SDL2 library. +#[inline] +pub fn drivers() -> DriverIterator { + // This function is thread-safe and doesn't require the video subsystem to be initialized. + // The list of drivers are read-only and statically compiled into SDL2, varying by platform. + + // SDL_GetNumVideoDrivers can never return a negative value. + DriverIterator { + length: unsafe { ll::SDL_GetNumVideoDrivers() }, + index: 0 + } +}