Skip to main content

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}