1use std::{
4 ffi::{CStr, CString},
5 os::raw::c_uint,
6};
7
8use crate::{bind, EnumInt, Result, SdlError};
9
10mod observer;
11
12pub use observer::*;
13
14#[must_use]
16pub fn get_hint(key: &str) -> Option<String> {
17 let cstr = CString::new(key).expect("key must not be empty");
18 let hint = unsafe { bind::SDL_GetHint(cstr.as_ptr()) };
19 (!hint.is_null()).then(|| {
20 unsafe { CStr::from_ptr(hint) }
21 .to_string_lossy()
22 .to_string()
23 })
24}
25
26#[must_use]
28pub fn get_hint_bool(key: &str) -> Option<bool> {
29 let cstr = CString::new(key).expect("key must not be empty");
30 let ret = unsafe { bind::SDL_GetHintBoolean(cstr.as_ptr(), 2) };
31 (ret != 2).then(|| ret == bind::SDL_TRUE)
32}
33
34pub fn set_hint(key: &str, value: &str) -> Result<()> {
44 let key_cstr = CString::new(key).expect("key must not be empty");
45 let value_cstr = CString::new(value).expect("value must not be empty");
46 let ret = unsafe { bind::SDL_SetHint(key_cstr.as_ptr(), value_cstr.as_ptr()) };
47 if ret == bind::SDL_TRUE {
48 Ok(())
49 } else {
50 Err(SdlError::UnsupportedFeature)
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56#[non_exhaustive]
57pub enum HintPriority {
58 Default,
60 Normal,
62 Override,
64}
65
66impl HintPriority {
67 fn into_raw(self) -> EnumInt {
68 match self {
69 HintPriority::Default => 0,
70 HintPriority::Normal => 1,
71 HintPriority::Override => 2,
72 }
73 }
74}
75
76impl Default for HintPriority {
77 fn default() -> Self {
78 Self::Default
79 }
80}
81
82pub fn set_hint_with_priority(key: &str, value: &str, priority: HintPriority) -> Result<()> {
88 let key_cstr = CString::new(key).expect("key must not be empty");
89 let value_cstr = CString::new(value).expect("value must not be empty");
90 let ret = unsafe {
91 bind::SDL_SetHintWithPriority(key_cstr.as_ptr(), value_cstr.as_ptr(), priority.into_raw())
92 };
93 if ret == bind::SDL_TRUE {
94 Ok(())
95 } else {
96 Err(SdlError::UnsupportedFeature)
97 }
98}
99
100pub fn clear_hints() {
102 unsafe { bind::SDL_ClearHints() }
103}