Skip to main content

gtk/
functions.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4use glib::Slice;
5use std::ptr;
6
7/// Parses a string representing an accelerator, similarly to
8/// [`accelerator_parse()`][crate::accelerator_parse()] but handles keycodes as well. This is only
9/// useful for system-level components, applications should use
10/// [`accelerator_parse()`][crate::accelerator_parse()] instead.
11///
12/// If `accelerator_codes` is given and the result stored in it is non-[`None`],
13/// the result must be freed with `g_free()`.
14///
15/// If a keycode is present in the accelerator and no `accelerator_codes`
16/// is given, the parse will fail.
17///
18/// If the parse fails, `accelerator_key`, `accelerator_mods` and
19/// `accelerator_codes` will be set to 0 (zero).
20/// ## `accelerator`
21/// string representing an accelerator
22///
23/// # Returns
24///
25///
26/// ## `accelerator_key`
27/// return location for accelerator
28///  keyval, or [`None`]
29///
30/// ## `accelerator_codes`
31///
32///  return location for accelerator keycodes, or [`None`]
33///
34/// ## `accelerator_mods`
35/// return location for accelerator
36///  modifier mask, [`None`]
37#[doc(alias = "gtk_accelerator_parse_with_keycode")]
38pub fn accelerator_parse_with_keycode(
39    accelerator: &str,
40) -> Option<(u32, Slice<u32>, gdk::ModifierType)> {
41    assert_initialized_main_thread!();
42    unsafe {
43        let mut accelerator_key = std::mem::MaybeUninit::uninit();
44        let mut accelerator_codes_ptr = ptr::null_mut();
45        let mut accelerator_mods = std::mem::MaybeUninit::uninit();
46        ffi::gtk_accelerator_parse_with_keycode(
47            accelerator.to_glib_none().0,
48            accelerator_key.as_mut_ptr(),
49            &mut accelerator_codes_ptr,
50            accelerator_mods.as_mut_ptr(),
51        );
52        if !accelerator_codes_ptr.is_null() {
53            let mut len = 0;
54            if !accelerator_codes_ptr.is_null() {
55                while ptr::read(accelerator_codes_ptr.add(len)) != 0 {
56                    len += 1;
57                }
58            }
59            let accelerator_codes = Slice::from_glib_full_num(accelerator_codes_ptr, len);
60            Some((
61                accelerator_key.assume_init(),
62                accelerator_codes,
63                from_glib(accelerator_mods.assume_init()),
64            ))
65        } else {
66            None
67        }
68    }
69}