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