1use glib::translate::*;
4
5use crate::{ffi, prelude::*, Display, Key, KeymapKey, ModifierType};
6
7#[derive(Debug, PartialEq, Eq, Ord, PartialOrd)]
8pub enum Backend {
9 Wayland,
10 X11,
11 Win32,
12 MacOS,
13 Broadway,
14}
15
16impl Backend {
17 #[doc(alias = "GDK_IS_WAYLAND_DISPLAY")]
20 pub fn is_wayland(&self) -> bool {
21 matches!(self, Self::Wayland)
22 }
23
24 #[doc(alias = "GDK_IS_X11_DISPLAY")]
27 pub fn is_x11(&self) -> bool {
28 matches!(self, Self::X11)
29 }
30
31 #[doc(alias = "GDK_IS_WIN32_DISPLAY")]
34 pub fn is_win32(&self) -> bool {
35 matches!(self, Self::Win32)
36 }
37
38 #[doc(alias = "GDK_IS_MACOS_DISPLAY")]
41 pub fn is_macos(&self) -> bool {
42 matches!(self, Self::MacOS)
43 }
44
45 #[doc(alias = "GDK_IS_BROADWAY_DISPLAY")]
48 pub fn is_broadway(&self) -> bool {
49 matches!(self, Self::Broadway)
50 }
51}
52
53pub trait DisplayExtManual: IsA<Display> + 'static {
57 #[doc(alias = "gdk_display_translate_key")]
58 fn translate_key(
59 &self,
60 keycode: u32,
61 state: ModifierType,
62 group: i32,
63 ) -> Option<(Key, i32, i32, ModifierType)> {
64 unsafe {
65 let mut keyval = std::mem::MaybeUninit::uninit();
66 let mut effective_group = std::mem::MaybeUninit::uninit();
67 let mut level = std::mem::MaybeUninit::uninit();
68 let mut consumed = std::mem::MaybeUninit::uninit();
69 let ret = from_glib(ffi::gdk_display_translate_key(
70 self.as_ref().to_glib_none().0,
71 keycode,
72 state.into_glib(),
73 group,
74 keyval.as_mut_ptr(),
75 effective_group.as_mut_ptr(),
76 level.as_mut_ptr(),
77 consumed.as_mut_ptr(),
78 ));
79 if ret {
80 let keyval = keyval.assume_init();
81 let effective_group = effective_group.assume_init();
82 let level = level.assume_init();
83 let consumed = consumed.assume_init();
84 Some((
85 from_glib(keyval),
86 effective_group,
87 level,
88 from_glib(consumed),
89 ))
90 } else {
91 None
92 }
93 }
94 }
95
96 #[doc(alias = "gdk_display_get_setting")]
97 fn get_setting(&self, name: impl IntoGStr) -> Option<glib::Value> {
98 unsafe {
99 name.run_with_gstr(|name| {
100 let mut value = glib::Value::uninitialized();
101 let ret = ffi::gdk_display_get_setting(
102 self.as_ref().to_glib_none().0,
103 name.as_ptr(),
104 value.to_glib_none_mut().0,
105 );
106 if from_glib(ret) {
107 Some(value)
108 } else {
109 None
110 }
111 })
112 }
113 }
114
115 #[doc(alias = "gdk_display_map_keyval")]
116 fn map_keyval(&self, keyval: Key) -> Option<Vec<KeymapKey>> {
117 unsafe {
118 let mut keys = std::ptr::null_mut();
119 let mut n_keys = std::mem::MaybeUninit::uninit();
120 let ret = from_glib(ffi::gdk_display_map_keyval(
121 self.as_ref().to_glib_none().0,
122 keyval.into_glib(),
123 &mut keys,
124 n_keys.as_mut_ptr(),
125 ));
126 if ret {
127 Some(FromGlibContainer::from_glib_full_num(
128 keys,
129 n_keys.assume_init() as usize,
130 ))
131 } else {
132 None
133 }
134 }
135 }
136
137 #[doc(alias = "gdk_display_map_keycode")]
138 fn map_keycode(&self, keycode: u32) -> Option<Vec<(KeymapKey, Key)>> {
139 unsafe {
140 let mut keys = std::ptr::null_mut();
141 let mut keyvals = std::ptr::null_mut();
142 let mut n_entries = std::mem::MaybeUninit::uninit();
143 let ret = from_glib(ffi::gdk_display_map_keycode(
144 self.as_ref().to_glib_none().0,
145 keycode,
146 &mut keys,
147 &mut keyvals,
148 n_entries.as_mut_ptr(),
149 ));
150 if ret {
151 let n_keys = n_entries.assume_init() as usize;
152 let keyvals: Vec<u32> = FromGlibContainer::from_glib_full_num(keyvals, n_keys);
153 let keyvals = keyvals.into_iter().map(|k| from_glib(k));
154 let keys: Vec<KeymapKey> = FromGlibContainer::from_glib_full_num(keys, n_keys);
155
156 Some(keys.into_iter().zip(keyvals).collect())
157 } else {
158 None
159 }
160 }
161 }
162
163 fn backend(&self) -> Backend {
166 match self.as_ref().type_().name() {
167 "GdkWaylandDisplay" => Backend::Wayland,
168 "GdkX11Display" => Backend::X11,
169 "GdkMacosDisplay" => Backend::MacOS,
170 "GdkWin32Display" => Backend::Win32,
171 "GdkBroadwayDisplay" => Backend::Broadway,
172 e => panic!("Unsupported display backend {e}"),
173 }
174 }
175}
176
177impl<O: IsA<Display>> DisplayExtManual for O {}