Skip to main content

gdk/
atom.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::ffi;
4use glib::GString;
5use glib::translate::*;
6use std::mem;
7use std::ptr;
8
9/// An opaque type representing a string as an index into a table
10/// of strings on the X server.
11#[derive(Copy, Clone, PartialEq, Eq)]
12#[doc(alias = "GdkAtom")]
13pub struct Atom(ffi::GdkAtom);
14
15#[allow(clippy::zero_ptr)]
16pub const NONE: Atom = Atom(0 as *mut _);
17#[allow(clippy::manual_dangling_ptr)]
18pub const SELECTION_PRIMARY: Atom = Atom(1 as *mut _);
19pub const SELECTION_SECONDARY: Atom = Atom(2 as *mut _);
20pub const SELECTION_CLIPBOARD: Atom = Atom(69 as *mut _);
21pub const TARGET_BITMAP: Atom = Atom(5 as *mut _);
22pub const TARGET_COLORMAP: Atom = Atom(7 as *mut _);
23pub const TARGET_DRAWABLE: Atom = Atom(17 as *mut _);
24pub const TARGET_PIXMAP: Atom = Atom(20 as *mut _);
25pub const TARGET_STRING: Atom = Atom(31 as *mut _);
26pub const SELECTION_TYPE_ATOM: Atom = Atom(4 as *mut _);
27pub const SELECTION_TYPE_BITMAP: Atom = Atom(5 as *mut _);
28pub const SELECTION_TYPE_COLORMAP: Atom = Atom(7 as *mut _);
29pub const SELECTION_TYPE_DRAWABLE: Atom = Atom(17 as *mut _);
30pub const SELECTION_TYPE_INTEGER: Atom = Atom(19 as *mut _);
31pub const SELECTION_TYPE_PIXMAP: Atom = Atom(20 as *mut _);
32pub const SELECTION_TYPE_WINDOW: Atom = Atom(33 as *mut _);
33pub const SELECTION_TYPE_STRING: Atom = Atom(31 as *mut _);
34
35impl Atom {
36    /// Finds or creates an atom corresponding to a given string.
37    /// ## `atom_name`
38    /// a string.
39    /// ## `only_if_exists`
40    /// if [`true`], GDK is allowed to not create a new atom, but
41    ///  just return `GDK_NONE` if the requested atom doesn’t already
42    ///  exists. Currently, the flag is ignored, since checking the
43    ///  existance of an atom is as expensive as creating it.
44    ///
45    /// # Returns
46    ///
47    /// the atom corresponding to `atom_name`.
48    #[doc(alias = "gdk_atom_intern")]
49    pub fn intern(atom_name: &str) -> Atom {
50        assert_initialized_main_thread!();
51        unsafe {
52            Atom(ffi::gdk_atom_intern(
53                atom_name.to_glib_none().0,
54                false.into_glib(),
55            ))
56        }
57    }
58
59    /// Determines the string corresponding to an atom.
60    ///
61    /// # Returns
62    ///
63    /// a newly-allocated string containing the string
64    ///  corresponding to `self`. When you are done with the
65    ///  return value, you should free it using `g_free()`.
66    #[doc(alias = "gdk_atom_name")]
67    pub fn name(self) -> GString {
68        unsafe { from_glib_full(ffi::gdk_atom_name(self.0)) }
69    }
70
71    pub fn value(self) -> usize {
72        self.0 as usize
73    }
74}
75
76impl GlibPtrDefault for Atom {
77    type GlibType = ffi::GdkAtom;
78}
79
80unsafe impl glib::translate::TransparentPtrType for Atom {}
81
82#[doc(hidden)]
83impl Uninitialized for Atom {
84    #[inline]
85    unsafe fn uninitialized() -> Self {
86        unsafe { mem::zeroed() }
87    }
88}
89
90impl<'a> ToGlibPtr<'a, ffi::GdkAtom> for Atom {
91    type Storage = ();
92
93    #[inline]
94    fn to_glib_none(&self) -> Stash<'a, ffi::GdkAtom, Atom> {
95        Stash(self.0, ())
96    }
97}
98
99impl<'a> ToGlibPtrMut<'a, *mut ffi::GdkAtom> for Atom {
100    type Storage = ();
101
102    #[inline]
103    fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::GdkAtom, Atom> {
104        StashMut(&mut self.0, ())
105    }
106}
107
108impl<'a> ToGlibContainerFromSlice<'a, *mut ffi::GdkAtom> for Atom {
109    type Storage = (
110        Vec<Stash<'a, ffi::GdkAtom, Atom>>,
111        Option<Vec<ffi::GdkAtom>>,
112    );
113
114    fn to_glib_none_from_slice(t: &'a [Atom]) -> (*mut ffi::GdkAtom, Self::Storage) {
115        skip_assert_initialized!();
116
117        let v: Vec<_> = t.iter().map(|s| s.to_glib_none()).collect();
118        let mut v_ptr: Vec<_> = v.iter().map(|s| s.0).collect();
119        v_ptr.push(ptr::null_mut());
120
121        (v_ptr.as_ptr() as *mut ffi::GdkAtom, (v, Some(v_ptr)))
122    }
123
124    fn to_glib_container_from_slice(t: &'a [Atom]) -> (*mut ffi::GdkAtom, Self::Storage) {
125        skip_assert_initialized!();
126
127        let v: Vec<_> = t.iter().map(|s| s.to_glib_none()).collect();
128
129        let v_ptr = unsafe {
130            let v_ptr = glib::ffi::g_malloc0(mem::size_of::<ffi::GdkAtom>() * (t.len() + 1))
131                as *mut ffi::GdkAtom;
132
133            for (i, s) in v.iter().enumerate() {
134                ptr::write(v_ptr.add(i), s.0);
135            }
136
137            v_ptr
138        };
139
140        (v_ptr, (v, None))
141    }
142
143    fn to_glib_full_from_slice(_: &[Atom]) -> *mut ffi::GdkAtom {
144        skip_assert_initialized!();
145
146        unimplemented!()
147    }
148}
149
150impl<'a> ToGlibContainerFromSlice<'a, *const ffi::GdkAtom> for Atom {
151    type Storage = (
152        Vec<Stash<'a, ffi::GdkAtom, Atom>>,
153        Option<Vec<ffi::GdkAtom>>,
154    );
155
156    fn to_glib_none_from_slice(t: &'a [Atom]) -> (*const ffi::GdkAtom, Self::Storage) {
157        skip_assert_initialized!();
158
159        let v: Vec<_> = t.iter().map(|s| s.to_glib_none()).collect();
160        let mut v_ptr: Vec<_> = v.iter().map(|s| s.0).collect();
161        v_ptr.push(ptr::null_mut());
162
163        (v_ptr.as_ptr() as *const ffi::GdkAtom, (v, Some(v_ptr)))
164    }
165
166    fn to_glib_container_from_slice(t: &'a [Atom]) -> (*const ffi::GdkAtom, Self::Storage) {
167        skip_assert_initialized!();
168
169        let v: Vec<_> = t.iter().map(|s| s.to_glib_none()).collect();
170
171        let v_ptr = unsafe {
172            let v_ptr = glib::ffi::g_malloc0(mem::size_of::<ffi::GdkAtom>() * (t.len() + 1))
173                as *mut ffi::GdkAtom;
174
175            for (i, s) in v.iter().enumerate() {
176                ptr::write(v_ptr.add(i), s.0);
177            }
178
179            v_ptr as *const ffi::GdkAtom
180        };
181
182        (v_ptr, (v, None))
183    }
184
185    fn to_glib_full_from_slice(_: &[Atom]) -> *const ffi::GdkAtom {
186        skip_assert_initialized!();
187
188        unimplemented!()
189    }
190}
191
192impl FromGlibPtrNone<ffi::GdkAtom> for Atom {
193    #[inline]
194    unsafe fn from_glib_none(ptr: ffi::GdkAtom) -> Atom {
195        Atom(ptr)
196    }
197}
198
199impl FromGlibPtrBorrow<ffi::GdkAtom> for Atom {
200    #[inline]
201    unsafe fn from_glib_borrow(ptr: ffi::GdkAtom) -> glib::translate::Borrowed<Atom> {
202        glib::translate::Borrowed::new(Atom(ptr))
203    }
204}
205
206impl FromGlibPtrFull<ffi::GdkAtom> for Atom {
207    #[inline]
208    unsafe fn from_glib_full(_: ffi::GdkAtom) -> Atom {
209        unimplemented!()
210    }
211}
212
213impl FromGlibContainerAsVec<ffi::GdkAtom, *mut ffi::GdkAtom> for Atom {
214    unsafe fn from_glib_none_num_as_vec(ptr: *mut ffi::GdkAtom, num: usize) -> Vec<Self> {
215        unsafe {
216            if num == 0 || ptr.is_null() {
217                return Vec::new();
218            }
219
220            let mut res = Vec::with_capacity(num);
221            for i in 0..num {
222                res.push(from_glib_none(ptr::read(ptr.add(i))));
223            }
224            res
225        }
226    }
227
228    unsafe fn from_glib_container_num_as_vec(ptr: *mut ffi::GdkAtom, num: usize) -> Vec<Self> {
229        unsafe {
230            let res = FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num);
231            glib::ffi::g_free(ptr as *mut _);
232            res
233        }
234    }
235
236    unsafe fn from_glib_full_num_as_vec(ptr: *mut ffi::GdkAtom, num: usize) -> Vec<Self> {
237        unsafe {
238            if num == 0 || ptr.is_null() {
239                return Vec::new();
240            }
241
242            let mut res = Vec::with_capacity(num);
243            for i in 0..num {
244                res.push(from_glib_full(ptr::read(ptr.add(i))));
245            }
246            glib::ffi::g_free(ptr as *mut _);
247            res
248        }
249    }
250}
251
252impl FromGlibPtrArrayContainerAsVec<ffi::GdkAtom, *mut ffi::GdkAtom> for Atom {
253    unsafe fn from_glib_none_as_vec(ptr: *mut ffi::GdkAtom) -> Vec<Self> {
254        unsafe { FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, c_ptr_array_len(ptr)) }
255    }
256
257    unsafe fn from_glib_container_as_vec(ptr: *mut ffi::GdkAtom) -> Vec<Self> {
258        unsafe { FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, c_ptr_array_len(ptr)) }
259    }
260
261    unsafe fn from_glib_full_as_vec(ptr: *mut ffi::GdkAtom) -> Vec<Self> {
262        unsafe { FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, c_ptr_array_len(ptr)) }
263    }
264}
265
266impl<'a> From<&'a str> for Atom {
267    fn from(r: &'a str) -> Atom {
268        skip_assert_initialized!();
269        Atom::intern(r)
270    }
271}