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