gdk/auto/keymap.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{Display, ModifierIntent, ModifierType};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::{boxed::Box as Box_, fmt, mem, mem::transmute};
12
13glib::wrapper! {
14 /// A [`Keymap`][crate::Keymap] defines the translation from keyboard state
15 /// (including a hardware key, a modifier mask, and active keyboard group)
16 /// to a keyval. This translation has two phases. The first phase is
17 /// to determine the effective keyboard group and level for the keyboard
18 /// state; the second phase is to look up the keycode/group/level triplet
19 /// in the keymap and see what keyval it corresponds to.
20 ///
21 /// ## Signals
22 ///
23 ///
24 /// #### `direction-changed`
25 /// The ::direction-changed signal gets emitted when the direction of
26 /// the keymap changes.
27 ///
28 ///
29 ///
30 ///
31 /// #### `keys-changed`
32 /// The ::keys-changed signal is emitted when the mapping represented by
33 /// `keymap` changes.
34 ///
35 ///
36 ///
37 ///
38 /// #### `state-changed`
39 /// The ::state-changed signal is emitted when the state of the
40 /// keyboard changes, e.g when Caps Lock is turned on or off.
41 /// See [`Keymap::is_caps_locked()`][crate::Keymap::is_caps_locked()].
42 ///
43 ///
44 #[doc(alias = "GdkKeymap")]
45 pub struct Keymap(Object<ffi::GdkKeymap>);
46
47 match fn {
48 type_ => || ffi::gdk_keymap_get_type(),
49 }
50}
51
52impl Keymap {
53 /// Returns whether the Caps Lock modifer is locked.
54 ///
55 /// # Returns
56 ///
57 /// [`true`] if Caps Lock is on
58 #[doc(alias = "gdk_keymap_get_caps_lock_state")]
59 #[doc(alias = "get_caps_lock_state")]
60 pub fn is_caps_locked(&self) -> bool {
61 unsafe { from_glib(ffi::gdk_keymap_get_caps_lock_state(self.to_glib_none().0)) }
62 }
63
64 /// Returns the direction of effective layout of the keymap.
65 ///
66 /// # Returns
67 ///
68 /// [`pango::Direction::Ltr`][crate::pango::Direction::Ltr] or [`pango::Direction::Rtl`][crate::pango::Direction::Rtl]
69 /// if it can determine the direction. [`pango::Direction::Neutral`][crate::pango::Direction::Neutral]
70 /// otherwise.
71 #[doc(alias = "gdk_keymap_get_direction")]
72 #[doc(alias = "get_direction")]
73 pub fn direction(&self) -> pango::Direction {
74 unsafe { from_glib(ffi::gdk_keymap_get_direction(self.to_glib_none().0)) }
75 }
76
77 /// Returns the modifier mask the `self`’s windowing system backend
78 /// uses for a particular purpose.
79 ///
80 /// Note that this function always returns real hardware modifiers, not
81 /// virtual ones (e.g. it will return [`ModifierType::MOD1_MASK`][crate::ModifierType::MOD1_MASK] rather than
82 /// [`ModifierType::META_MASK`][crate::ModifierType::META_MASK] if the backend maps MOD1 to META), so there are use
83 /// cases where the return value of this function has to be transformed
84 /// by [`add_virtual_modifiers()`][Self::add_virtual_modifiers()] in order to contain the
85 /// expected result.
86 /// ## `intent`
87 /// the use case for the modifier mask
88 ///
89 /// # Returns
90 ///
91 /// the modifier mask used for `intent`.
92 #[doc(alias = "gdk_keymap_get_modifier_mask")]
93 #[doc(alias = "get_modifier_mask")]
94 pub fn modifier_mask(&self, intent: ModifierIntent) -> ModifierType {
95 unsafe {
96 from_glib(ffi::gdk_keymap_get_modifier_mask(
97 self.to_glib_none().0,
98 intent.into_glib(),
99 ))
100 }
101 }
102
103 /// Returns the current modifier state.
104 ///
105 /// # Returns
106 ///
107 /// the current modifier state.
108 #[doc(alias = "gdk_keymap_get_modifier_state")]
109 #[doc(alias = "get_modifier_state")]
110 pub fn modifier_state(&self) -> u32 {
111 unsafe { ffi::gdk_keymap_get_modifier_state(self.to_glib_none().0) }
112 }
113
114 /// Returns whether the Num Lock modifer is locked.
115 ///
116 /// # Returns
117 ///
118 /// [`true`] if Num Lock is on
119 #[doc(alias = "gdk_keymap_get_num_lock_state")]
120 #[doc(alias = "get_num_lock_state")]
121 pub fn is_num_locked(&self) -> bool {
122 unsafe { from_glib(ffi::gdk_keymap_get_num_lock_state(self.to_glib_none().0)) }
123 }
124
125 /// Returns whether the Scroll Lock modifer is locked.
126 ///
127 /// # Returns
128 ///
129 /// [`true`] if Scroll Lock is on
130 #[doc(alias = "gdk_keymap_get_scroll_lock_state")]
131 #[doc(alias = "get_scroll_lock_state")]
132 pub fn is_scroll_locked(&self) -> bool {
133 unsafe { from_glib(ffi::gdk_keymap_get_scroll_lock_state(self.to_glib_none().0)) }
134 }
135
136 /// Determines if keyboard layouts for both right-to-left and left-to-right
137 /// languages are in use.
138 ///
139 /// # Returns
140 ///
141 /// [`true`] if there are layouts in both directions, [`false`] otherwise
142 #[doc(alias = "gdk_keymap_have_bidi_layouts")]
143 pub fn have_bidi_layouts(&self) -> bool {
144 unsafe { from_glib(ffi::gdk_keymap_have_bidi_layouts(self.to_glib_none().0)) }
145 }
146
147 /// Translates the contents of a [`EventKey`][crate::EventKey] into a keyval, effective
148 /// group, and level. Modifiers that affected the translation and
149 /// are thus unavailable for application use are returned in
150 /// `consumed_modifiers`.
151 /// See [Groups][key-group-explanation] for an explanation of
152 /// groups and levels. The `effective_group` is the group that was
153 /// actually used for the translation; some keys such as Enter are not
154 /// affected by the active keyboard group. The `level` is derived from
155 /// `state`. For convenience, [`EventKey`][crate::EventKey] already contains the translated
156 /// keyval, so this function isn’t as useful as you might think.
157 ///
158 /// `consumed_modifiers` gives modifiers that should be masked outfrom `state`
159 /// when comparing this key press to a hot key. For instance, on a US keyboard,
160 /// the `plus` symbol is shifted, so when comparing a key press to a
161 /// ``<Control>`plus` accelerator ``<Shift>`` should be masked out.
162 ///
163 ///
164 ///
165 /// **⚠️ The following code is in C ⚠️**
166 ///
167 /// ```C
168 /// // We want to ignore irrelevant modifiers like ScrollLock
169 /// #define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)
170 /// gdk_keymap_translate_keyboard_state (keymap, event->hardware_keycode,
171 /// event->state, event->group,
172 /// &keyval, NULL, NULL, &consumed);
173 /// if (keyval == GDK_PLUS &&
174 /// (event->state & ~consumed & ALL_ACCELS_MASK) == GDK_CONTROL_MASK)
175 /// // Control was pressed
176 /// ```
177 ///
178 /// An older interpretation `consumed_modifiers` was that it contained
179 /// all modifiers that might affect the translation of the key;
180 /// this allowed accelerators to be stored with irrelevant consumed
181 /// modifiers, by doing:
182 ///
183 ///
184 /// **⚠️ The following code is in C ⚠️**
185 ///
186 /// ```C
187 /// // XXX Don’t do this XXX
188 /// if (keyval == accel_keyval &&
189 /// (event->state & ~consumed & ALL_ACCELS_MASK) == (accel_mods & ~consumed))
190 /// // Accelerator was pressed
191 /// ```
192 ///
193 /// However, this did not work if multi-modifier combinations were
194 /// used in the keymap, since, for instance, ``<Control>`` would be
195 /// masked out even if only ``<Control>``<Alt>`` was used in the keymap.
196 /// To support this usage as well as well as possible, all single
197 /// modifier combinations that could affect the key for any combination
198 /// of modifiers will be returned in `consumed_modifiers`; multi-modifier
199 /// combinations are returned only when actually found in `state`. When
200 /// you store accelerators, you should always store them with consumed
201 /// modifiers removed. Store ``<Control>`plus`, not ``<Control>``<Shift>`plus`,
202 /// ## `hardware_keycode`
203 /// a keycode
204 /// ## `state`
205 /// a modifier state
206 /// ## `group`
207 /// active keyboard group
208 ///
209 /// # Returns
210 ///
211 /// [`true`] if there was a keyval bound to the keycode/state/group
212 ///
213 /// ## `keyval`
214 /// return location for keyval, or [`None`]
215 ///
216 /// ## `effective_group`
217 /// return location for effective
218 /// group, or [`None`]
219 ///
220 /// ## `level`
221 /// return location for level, or [`None`]
222 ///
223 /// ## `consumed_modifiers`
224 /// return location for modifiers
225 /// that were used to determine the group or level, or [`None`]
226 #[doc(alias = "gdk_keymap_translate_keyboard_state")]
227 pub fn translate_keyboard_state(
228 &self,
229 hardware_keycode: u32,
230 state: ModifierType,
231 group: i32,
232 ) -> Option<(u32, i32, i32, ModifierType)> {
233 unsafe {
234 let mut keyval = mem::MaybeUninit::uninit();
235 let mut effective_group = mem::MaybeUninit::uninit();
236 let mut level = mem::MaybeUninit::uninit();
237 let mut consumed_modifiers = mem::MaybeUninit::uninit();
238 let ret = from_glib(ffi::gdk_keymap_translate_keyboard_state(
239 self.to_glib_none().0,
240 hardware_keycode,
241 state.into_glib(),
242 group,
243 keyval.as_mut_ptr(),
244 effective_group.as_mut_ptr(),
245 level.as_mut_ptr(),
246 consumed_modifiers.as_mut_ptr(),
247 ));
248 if ret {
249 Some((
250 keyval.assume_init(),
251 effective_group.assume_init(),
252 level.assume_init(),
253 from_glib(consumed_modifiers.assume_init()),
254 ))
255 } else {
256 None
257 }
258 }
259 }
260
261 /// Returns the [`Keymap`][crate::Keymap] attached to `display`.
262 /// ## `display`
263 /// the [`Display`][crate::Display].
264 ///
265 /// # Returns
266 ///
267 /// the [`Keymap`][crate::Keymap] attached to `display`.
268 #[doc(alias = "gdk_keymap_get_for_display")]
269 #[doc(alias = "get_for_display")]
270 pub fn for_display(display: &Display) -> Option<Keymap> {
271 skip_assert_initialized!();
272 unsafe { from_glib_none(ffi::gdk_keymap_get_for_display(display.to_glib_none().0)) }
273 }
274
275 /// The ::direction-changed signal gets emitted when the direction of
276 /// the keymap changes.
277 #[doc(alias = "direction-changed")]
278 pub fn connect_direction_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
279 unsafe extern "C" fn direction_changed_trampoline<F: Fn(&Keymap) + 'static>(
280 this: *mut ffi::GdkKeymap,
281 f: glib::ffi::gpointer,
282 ) {
283 let f: &F = &*(f as *const F);
284 f(&from_glib_borrow(this))
285 }
286 unsafe {
287 let f: Box_<F> = Box_::new(f);
288 connect_raw(
289 self.as_ptr() as *mut _,
290 b"direction-changed\0".as_ptr() as *const _,
291 Some(transmute::<_, unsafe extern "C" fn()>(
292 direction_changed_trampoline::<F> as *const (),
293 )),
294 Box_::into_raw(f),
295 )
296 }
297 }
298
299 /// The ::keys-changed signal is emitted when the mapping represented by
300 /// `keymap` changes.
301 #[doc(alias = "keys-changed")]
302 pub fn connect_keys_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
303 unsafe extern "C" fn keys_changed_trampoline<F: Fn(&Keymap) + 'static>(
304 this: *mut ffi::GdkKeymap,
305 f: glib::ffi::gpointer,
306 ) {
307 let f: &F = &*(f as *const F);
308 f(&from_glib_borrow(this))
309 }
310 unsafe {
311 let f: Box_<F> = Box_::new(f);
312 connect_raw(
313 self.as_ptr() as *mut _,
314 b"keys-changed\0".as_ptr() as *const _,
315 Some(transmute::<_, unsafe extern "C" fn()>(
316 keys_changed_trampoline::<F> as *const (),
317 )),
318 Box_::into_raw(f),
319 )
320 }
321 }
322
323 /// The ::state-changed signal is emitted when the state of the
324 /// keyboard changes, e.g when Caps Lock is turned on or off.
325 /// See [`is_caps_locked()`][Self::is_caps_locked()].
326 #[doc(alias = "state-changed")]
327 pub fn connect_state_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
328 unsafe extern "C" fn state_changed_trampoline<F: Fn(&Keymap) + 'static>(
329 this: *mut ffi::GdkKeymap,
330 f: glib::ffi::gpointer,
331 ) {
332 let f: &F = &*(f as *const F);
333 f(&from_glib_borrow(this))
334 }
335 unsafe {
336 let f: Box_<F> = Box_::new(f);
337 connect_raw(
338 self.as_ptr() as *mut _,
339 b"state-changed\0".as_ptr() as *const _,
340 Some(transmute::<_, unsafe extern "C" fn()>(
341 state_changed_trampoline::<F> as *const (),
342 )),
343 Box_::into_raw(f),
344 )
345 }
346 }
347}
348
349impl fmt::Display for Keymap {
350 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
351 f.write_str("Keymap")
352 }
353}