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