use core::mem::MaybeUninit;
use std::ffi::CStr;
use crate::{
CONFIGURE_AXIS, GET_AXIS_DESCRIPTION, GET_DISPLAYS, GET_QUALITY_LEVELS, GET_RESOLUTIONS,
GET_SELECTED_DISPLAY, GET_SELECTED_QUALITY_LEVEL, GET_SELECTED_RESOLUTION,
SET_SELECTED_DISPLAY, SET_SELECTED_QUALITY_LEVEL, SET_SELECTED_RESOLUTION,
};
fn get_axis_description(axis: i32) -> Option<(String, String, String)> {
let func = GET_AXIS_DESCRIPTION.get().unwrap();
let mut control = MaybeUninit::<[i8; 8192]>::uninit();
let mut primary = MaybeUninit::<[i8; 8192]>::uninit();
let mut secondary = MaybeUninit::<[i8; 8200]>::uninit();
let ret = func(
axis,
control.as_mut_ptr() as *mut i8,
primary.as_mut_ptr() as *mut i8,
secondary.as_mut_ptr() as *mut i8,
);
if ret == 0 {
let control = unsafe { control.assume_init() };
let primary = unsafe { primary.assume_init() };
let secondary = unsafe { secondary.assume_init() };
let control = unsafe { CStr::from_ptr(&control as *const i8) }
.to_string_lossy()
.into_owned();
let primary = unsafe { CStr::from_ptr(&primary as *const i8) }
.to_string_lossy()
.into_owned();
let secondary = unsafe { CStr::from_ptr(&secondary as *const i8) }
.to_string_lossy()
.into_owned();
Some((control, primary, secondary))
} else {
None
}
}
pub struct AxisIter {
axis: i32,
}
impl Iterator for AxisIter {
type Item = (String, String, String);
fn next(&mut self) -> Option<Self::Item> {
let ret = get_axis_description(self.axis);
self.axis += 1;
ret
}
}
pub fn iter_axis_description() -> AxisIter {
AxisIter { axis: 0 }
}
pub fn configure_axis(axis: i32, enable: i32) {
let func = CONFIGURE_AXIS.get().unwrap();
func(axis, enable);
}
pub fn get_resolutions(display: u32) -> Vec<(u32, u32)> {
let func = GET_RESOLUTIONS.get().unwrap();
let resolutions = unsafe { &*func(display) };
resolutions.iter().cloned().collect()
}
pub fn get_selected_resolution() -> (u32, u32, bool) {
let mut width = 0;
let mut height = 0;
let mut windowed = false;
let func = GET_SELECTED_RESOLUTION.get().unwrap();
func(&mut width, &mut height, &mut windowed);
(width, height, windowed)
}
pub fn set_selected_resolution(width: u32, height: u32, windowed: bool) {
let func = SET_SELECTED_RESOLUTION.get().unwrap();
func(width, height, windowed);
}
pub fn get_quality_levels() -> Vec<String> {
let func = GET_QUALITY_LEVELS.get().unwrap();
let qualities = unsafe { &*func() };
qualities
.iter()
.map(|name| {
unsafe { CStr::from_ptr(*name) }
.to_string_lossy()
.into_owned()
})
.collect()
}
pub fn get_selected_quality_level() -> i32 {
let func = GET_SELECTED_QUALITY_LEVEL.get().unwrap();
func()
}
pub fn set_selected_quality_level(quality: i32) {
let func = SET_SELECTED_QUALITY_LEVEL.get().unwrap();
func(quality);
}
pub fn get_displays() -> Vec<String> {
let func = GET_DISPLAYS.get().unwrap();
let displays = unsafe { &*func() };
displays
.iter()
.map(|name| {
unsafe { CStr::from_ptr(*name) }
.to_string_lossy()
.into_owned()
})
.collect()
}
pub fn get_selected_display() -> u32 {
let func = GET_SELECTED_DISPLAY.get().unwrap();
func()
}
pub fn set_selected_display(display: u32) {
let func = SET_SELECTED_DISPLAY.get().unwrap();
func(display);
}