1use {
2 std::{
3 mem,
4 cell::Cell,
5 rc::Rc,
6 os::raw::{c_ulong, c_long, c_void, c_char},
7 ptr,
8 ffi::{CStr,CString},
9 },
10 self::super::{
11 x11_sys,
12 xlib_event::XlibEvent,
13 xlib_app::*,
14 },
15 crate::{
16 area::Area,
17 window::WindowId,
18 makepad_math::{DVec2},
19 event::*,
20 cursor::MouseCursor,
21 },
22};
23
24#[derive(Clone)]
25pub struct XlibWindow {
26 pub window: Option<c_ulong>,
27 pub xic: Option<x11_sys::XIC>,
28 pub attributes: Option<x11_sys::XSetWindowAttributes>,
29 pub visual_info: Option<x11_sys::XVisualInfo>,
30 pub last_nc_mode: Option<c_long>,
33 pub window_id: WindowId,
34 pub last_window_geom: WindowGeom,
35
36 pub ime_spot: DVec2,
37 pub current_cursor: MouseCursor,
38 pub last_mouse_pos: DVec2,
39}
40impl XlibWindow {
52
53 pub fn new(window_id: WindowId) -> XlibWindow {
54
55 XlibWindow {
56 window: None,
57 xic: None,
58 attributes: None,
59 visual_info: None,
60 window_id,
62 last_window_geom: WindowGeom::default(),
63 last_nc_mode: None,
64 ime_spot: DVec2::default(),
65 current_cursor: MouseCursor::Default,
66 last_mouse_pos: DVec2::default(),
67 }
68 }
69
70 pub fn init(&mut self, title: &str, size: DVec2, position: Option<DVec2>, visual_info: x11_sys::XVisualInfo, custom_window_chrome: bool) {
71 unsafe {
72 let display = get_xlib_app_global().display;
73
74 let default_screen = x11_sys::XDefaultScreen(display);
76
77 let root_window = x11_sys::XRootWindow(display, default_screen);
79
80 let mut attributes = mem::zeroed::<x11_sys::XSetWindowAttributes>();
81
82 attributes.border_pixel = 0;
83 attributes.colormap =
85 x11_sys::XCreateColormap(display, root_window, visual_info.visual, x11_sys::AllocNone as i32);
86 attributes.event_mask = (
87 x11_sys::ExposureMask
88 | x11_sys::StructureNotifyMask
89 | x11_sys::ButtonMotionMask
90 | x11_sys::PointerMotionMask
91 | x11_sys::ButtonPressMask
92 | x11_sys::ButtonReleaseMask
93 | x11_sys::KeyPressMask
94 | x11_sys::KeyReleaseMask
95 | x11_sys::VisibilityChangeMask
96 | x11_sys::FocusChangeMask
97 | x11_sys::EnterWindowMask
98 | x11_sys::LeaveWindowMask
99 ) as c_long;
100
101 let dpi_factor = self.get_dpi_factor();
102 let window = x11_sys::XCreateWindow(
104 display,
105 root_window,
106 if position.is_some() {position.unwrap().x}else {150.0} as i32,
107 if position.is_some() {position.unwrap().y}else {60.0} as i32,
108 (size.x * dpi_factor) as u32,
109 (size.y * dpi_factor) as u32,
110 0,
111 visual_info.depth,
112 x11_sys::InputOutput as u32,
113 visual_info.visual,
114 (x11_sys::CWBorderPixel | x11_sys::CWColormap | x11_sys::CWEventMask) as c_ulong, &mut attributes,
116 );
117
118 x11_sys::XSetWMProtocols(display, window, &mut get_xlib_app_global().atoms.wm_delete_window, 1);
120
121 if custom_window_chrome {
122 let hints = MwmHints {
123 flags: MWM_HINTS_DECORATIONS,
124 functions: 0,
125 decorations: 0,
126 input_mode: 0,
127 status: 0,
128 };
129
130 let atom_motif_wm_hints = get_xlib_app_global().atoms.motif_wm_hints;
131
132 x11_sys::XChangeProperty(
133 display,
134 window,
135 atom_motif_wm_hints,
136 atom_motif_wm_hints,
137 32,
138 x11_sys::PropModeReplace as i32,
139 &hints as *const _ as *const u8,
140 5
141 );
142 }
143
144 get_xlib_app_global().dnd.enable_for_window(window);
145
146 x11_sys::XMapWindow(display, window);
148 x11_sys::XFlush(display);
149
150 let title_bytes = format!("{}\0", title);
151 x11_sys::XStoreName(display, window, title_bytes.as_bytes().as_ptr() as *const c_char);
152
153 let xic = x11_sys::XCreateIC(
154 get_xlib_app_global().xim,
155 x11_sys::XNInputStyle.as_ptr(),
156 (x11_sys::XIMPreeditNothing | x11_sys::XIMStatusNothing) as i32,
157 x11_sys::XNClientWindow.as_ptr(),
158 window,
159 x11_sys::XNFocusWindow.as_ptr(),
160 window,
161 ptr::null_mut() as *mut c_void
162 );
163
164 get_xlib_app_global().window_map.insert(window, self);
166
167 self.attributes = Some(attributes);
168 self.visual_info = Some(visual_info);
169 self.window = Some(window);
170 self.xic = Some(xic);
171 self.last_window_geom = self.get_window_geom();
172
173 let new_geom = self.get_window_geom();
174 self.do_callback(XlibEvent::WindowGeomChange(WindowGeomChangeEvent {
175 window_id: self.window_id,
176 old_geom: new_geom.clone(),
177 new_geom: new_geom
178 })
179 );
180 }
181 }
182
183 fn restore_or_maximize(&self, add_remove: c_long) {
184 unsafe {
185 let default_screen = x11_sys::XDefaultScreen(get_xlib_app_global().display);
186 let root_window = x11_sys::XRootWindow(get_xlib_app_global().display, default_screen);
187 let mut xclient = x11_sys::XClientMessageEvent {
188 type_: x11_sys::ClientMessage as i32,
189 serial: 0,
190 send_event: 0,
191 display: get_xlib_app_global().display,
192 window: self.window.unwrap(),
193 message_type: get_xlib_app_global().atoms.net_wm_state,
194 format: 32,
195 data: {
196 let mut msg = mem::zeroed::<x11_sys::XClientMessageEvent__bindgen_ty_1>();
197 msg.l[0] = add_remove;
198 msg.l[1] = get_xlib_app_global().atoms.new_wm_state_maximized_horz as c_long;
199 msg.l[2] = get_xlib_app_global().atoms.new_wm_state_maximized_vert as c_long;
200 msg
201 }
202 };
203 x11_sys::XSendEvent(
204 get_xlib_app_global().display,
205 root_window,
206 0,
207 (x11_sys::SubstructureNotifyMask | x11_sys::SubstructureRedirectMask) as c_long,
208 &mut xclient as *mut _ as *mut x11_sys::XEvent
209 );
210 }
211 }
212
213 pub fn restore(&self) {
214 self.restore_or_maximize(_NET_WM_STATE_REMOVE);
215 }
216
217 pub fn maximize(&self) {
218 self.restore_or_maximize(_NET_WM_STATE_ADD);
219 }
220
221 pub fn close_window(&mut self) {
222 unsafe {
223 x11_sys::XDestroyWindow(get_xlib_app_global().display, self.window.unwrap());
224 self.window = None;
225 }
228 }
229
230 pub fn minimize(&self) {
231 unsafe {
232 let default_screen = x11_sys::XDefaultScreen(get_xlib_app_global().display);
233 x11_sys::XIconifyWindow(get_xlib_app_global().display, self.window.unwrap(), default_screen);
234 x11_sys::XFlush(get_xlib_app_global().display);
235 }
236 }
237
238 pub fn set_topmost(&self, _topmost: bool) {
239 }
240
241 pub fn get_is_topmost(&self) -> bool {
242 false
243 }
244
245 pub fn get_window_geom(&self) -> WindowGeom {
246 WindowGeom {
247 xr_is_presenting: false,
248 can_fullscreen: false,
249 is_topmost: self.get_is_topmost(),
250 is_fullscreen: self.get_is_maximized(),
251 inner_size: self.get_inner_size(),
252 outer_size: self.get_outer_size(),
253 dpi_factor: self.get_dpi_factor(),
254 position: self.get_position()
255 }
256 }
257
258 pub fn get_is_maximized(&self) -> bool {
259 let mut maximized = false;
260 unsafe {
261 let mut prop_type = mem::MaybeUninit::uninit();
262 let mut format = mem::MaybeUninit::uninit();
263 let mut n_item = mem::MaybeUninit::uninit();
264 let mut bytes_after = mem::MaybeUninit::uninit();
265 let mut properties = mem::MaybeUninit::uninit();
266 let result = x11_sys::XGetWindowProperty(
267 get_xlib_app_global().display,
268 self.window.unwrap(),
269 get_xlib_app_global().atoms.net_wm_state,
270 0,
271 !0,
272 0,
273 x11_sys::AnyPropertyType as c_ulong,
274 prop_type.as_mut_ptr(),
275 format.as_mut_ptr(),
276 n_item.as_mut_ptr(),
277 bytes_after.as_mut_ptr(),
278 properties.as_mut_ptr()
279 );
280 let n_item = n_item.assume_init();
283 let properties = properties.assume_init();
285 if result == 0 && properties != ptr::null_mut() {
286 let items = std::slice::from_raw_parts::<c_ulong>(properties as *mut _, n_item as usize);
287 for item in items {
288 if *item == get_xlib_app_global().atoms.new_wm_state_maximized_horz
289 || *item == get_xlib_app_global().atoms.new_wm_state_maximized_vert {
290 maximized = true;
291 break;
292 }
293 }
294 x11_sys::XFree(properties as *mut _);
295 }
296 }
297 maximized
298 }
299
300 pub fn set_ime_spot(&mut self, spot: DVec2) {
301 self.ime_spot = spot;
302 }
303
304 pub fn get_position(&self) -> DVec2 {
305 unsafe {
306 let mut xwa = mem::MaybeUninit::uninit();
307 let display = get_xlib_app_global().display;
308 x11_sys::XGetWindowAttributes(
309 display,
310 self.window.unwrap(),
311 xwa.as_mut_ptr()
312 );
313 let xwa = xwa.assume_init();
314 return DVec2 {x: xwa.x as f64, y: xwa.y as f64}
315 }
324 }
325
326 pub fn get_inner_size(&self) -> DVec2 {
327 let dpi_factor = self.get_dpi_factor();
328 unsafe {
329 let mut xwa = mem::MaybeUninit::uninit();
330 let display = get_xlib_app_global().display;
331 x11_sys::XGetWindowAttributes(display, self.window.unwrap(), xwa.as_mut_ptr());
332 let xwa = xwa.assume_init();
333 return DVec2 {x: xwa.width as f64 / dpi_factor, y: xwa.height as f64 / dpi_factor}
334 }
335 }
336
337 pub fn get_outer_size(&self) -> DVec2 {
338 unsafe {
339 let mut xwa = mem::MaybeUninit::uninit();
340 let display = get_xlib_app_global().display;
341 x11_sys::XGetWindowAttributes(display, self.window.unwrap(), xwa.as_mut_ptr());
342 let xwa = xwa.assume_init();
343 return DVec2 {x: xwa.width as f64, y: xwa.height as f64}
344 }
345 }
346
347 pub fn set_position(&mut self, _pos: DVec2) {
348 }
349
350 pub fn set_outer_size(&self, _size: DVec2) {
351 }
352
353 pub fn set_inner_size(&self, _size: DVec2) {
354 }
355
356 pub fn get_dpi_factor(&self) -> f64 {
357 unsafe {
358 let display = get_xlib_app_global().display;
360 let resource_string = x11_sys::XResourceManagerString(display);
361 if resource_string == std::ptr::null_mut() {
362 return 1.0
363 }
364 let db = x11_sys::XrmGetStringDatabase(resource_string);
365 let mut ty = mem::MaybeUninit::uninit();
366 let mut value = mem::MaybeUninit::uninit();
367 x11_sys::XrmGetResource(
368 db,
369 "Xft.dpi\0".as_ptr() as * const _,
370 "String\0".as_ptr() as * const _,
371 ty.as_mut_ptr(),
372 value.as_mut_ptr()
373 );
374 let value = value.assume_init();
376 if value.addr == std::ptr::null_mut() {
377 return 1.0; }
379 else {
380 let dpi: f64 = CStr::from_ptr(value.addr).to_str().unwrap().parse().unwrap();
381 return dpi / 96.0;
382 }
383 }
384 }
385
386 pub fn time_now(&self) -> f64 {
387 get_xlib_app_global().time_now()
388 }
389
390 pub fn do_callback(&mut self, event: XlibEvent) {
391 get_xlib_app_global().do_callback(event);
392 }
393
394 pub fn send_change_event(&mut self) {
395
396 let mut new_geom = self.get_window_geom();
397 if new_geom.inner_size.x < self.last_window_geom.inner_size.x ||
398 new_geom.inner_size.y < self.last_window_geom.inner_size.y {
399 new_geom.is_fullscreen = false;
400 }
401 let old_geom = self.last_window_geom.clone();
402 self.last_window_geom = new_geom.clone();
403
404 self.do_callback(XlibEvent::WindowGeomChange(WindowGeomChangeEvent {
405 window_id: self.window_id,
406 old_geom: old_geom,
407 new_geom: new_geom
408 }));
409 self.do_callback(XlibEvent::Paint);
410 }
411
412 pub fn send_focus_event(&mut self) {
413 self.do_callback(XlibEvent::AppGotFocus);
414 }
415
416 pub fn send_focus_lost_event(&mut self) {
417 self.do_callback(XlibEvent::AppLostFocus);
418 }
419
420 pub fn send_mouse_down(&mut self, button: usize, modifiers: KeyModifiers) {
421 self.do_callback(XlibEvent::MouseDown(MouseDownEvent {
422 button,
423 modifiers,
424 window_id: self.window_id,
425 abs: self.last_mouse_pos,
426 time: self.time_now(),
427 handled: Cell::new(Area::Empty),
428 }));
429 }
430
431 pub fn send_mouse_up(&mut self, button: usize, modifiers: KeyModifiers) {
432 self.do_callback(XlibEvent::MouseUp(MouseUpEvent {
433 button,
434 modifiers,
435 window_id: self.window_id,
436 abs: self.last_mouse_pos,
437 time: self.time_now()
438 }));
439 }
440
441 pub fn send_mouse_move(&mut self, pos: DVec2, modifiers: KeyModifiers) {
442 self.last_mouse_pos = pos;
443 self.do_callback(XlibEvent::MouseMove(MouseMoveEvent {
444 window_id: self.window_id,
445 abs: pos,
446 modifiers: modifiers,
447 time: self.time_now(),
448 handled: Cell::new(Area::Empty),
449 }));
450
451 }
452
453 pub fn send_close_requested_event(&mut self) -> bool {
454 let accept_close = Rc::new(Cell::new(true));
455 self.do_callback(XlibEvent::WindowCloseRequested(WindowCloseRequestedEvent {
456 window_id: self.window_id,
457 accept_close: accept_close.clone()
458 }));
459 if !accept_close.get() {
460 return false
461 }
462 true
463 }
464
465 pub fn send_text_input(&mut self, input: String, replace_last: bool) {
466 self.do_callback(XlibEvent::TextInput(TextInputEvent {
467 input: input,
468 was_paste: false,
469 replace_last: replace_last
470 }))
471 }
472
473}
474
475
476#[derive(Clone, Copy, PartialEq)]
477#[repr(C)]
478struct MwmHints {
479 pub flags: c_ulong,
480 pub functions: c_ulong,
481 pub decorations: c_ulong,
482 pub input_mode: c_long,
483 pub status: c_ulong,
484}
485
486pub const MWM_HINTS_FUNCTIONS: c_ulong = 1 << 0;
487pub const MWM_HINTS_DECORATIONS: c_ulong = 1 << 1;
488
489pub const MWM_FUNC_ALL: c_ulong = 1 << 0;
490pub const MWM_FUNC_RESIZE: c_ulong = 1 << 1;
491pub const MWM_FUNC_MOVE: c_ulong = 1 << 2;
492pub const MWM_FUNC_MINIMIZE: c_ulong = 1 << 3;
493pub const MWM_FUNC_MAXIMIZE: c_ulong = 1 << 4;
494pub const MWM_FUNC_CLOSE: c_ulong = 1 << 5;
495pub const _NET_WM_MOVERESIZE_SIZE_TOPLEFT: c_long = 0;
496pub const _NET_WM_MOVERESIZE_SIZE_TOP: c_long = 1;
497pub const _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: c_long = 2;
498pub const _NET_WM_MOVERESIZE_SIZE_RIGHT: c_long = 3;
499pub const _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: c_long = 4;
500pub const _NET_WM_MOVERESIZE_SIZE_BOTTOM: c_long = 5;
501pub const _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: c_long = 6;
502pub const _NET_WM_MOVERESIZE_SIZE_LEFT: c_long = 7;
503pub const _NET_WM_MOVERESIZE_MOVE: c_long = 8;pub const _NET_WM_MOVERESIZE_SIZE_KEYBOARD: c_long = 9;pub const _NET_WM_MOVERESIZE_MOVE_KEYBOARD: c_long = 10;
506
507pub const _NET_WM_STATE_REMOVE: c_long = 0;pub const _NET_WM_STATE_ADD: c_long = 1;pub const _NET_WM_STATE_TOGGLE: c_long = 2;pub struct Dnd {
514 pub atoms: DndAtoms,
515 pub display: *mut x11_sys::Display,
516 pub type_list: Option<Vec<x11_sys::Atom >>,
517 pub selection: Option<CString>,
518}
519
520impl Dnd {
521 pub unsafe fn new(display: *mut x11_sys::Display) -> Dnd {
522 Dnd {
523 atoms: DndAtoms::new(display),
524 display,
525 type_list: None,
526 selection: None,
527 }
528 }
529
530 pub unsafe fn enable_for_window(&mut self, window: x11_sys::Window) {
532 let version = 5 as c_ulong;
538
539 x11_sys::XChangeProperty(
540 self.display,
541 window,
542 self.atoms.aware,
543 4, 32,
545 x11_sys::PropModeReplace as std::os::raw::c_int,
546 &version as *const c_ulong as *const std::os::raw::c_uchar,
547 1
548 );
549 }
550
551 pub unsafe fn handle_enter_event(&mut self, event: &x11_sys::XClientMessageEvent) {
553 let source_window = event.data.l[0] as x11_sys::Window;
558 let has_more_types = event.data.l[1] & (1 << 0) != 0;
559
560 self.type_list = Some(if has_more_types {
564 self.get_type_list_property(source_window)
565 } else {
566 event.data.l[2..4]
567 .iter()
568 .map( | &l | l as x11_sys::Atom)
569 .filter( | &atom | atom != x11_sys::None as x11_sys::Atom)
570 .collect()
571 });
572 }
573
574 pub unsafe fn handle_drop_event(&mut self, event: &x11_sys::XClientMessageEvent) {
576 let target_window = event.window as x11_sys::Window;
584 self.convert_selection(target_window);
585 self.type_list = None;
586 }
587
588 pub unsafe fn handle_leave_event(&mut self, _event: &x11_sys::XClientMessageEvent) {
590 self.type_list = None;
595 }
596
597 pub unsafe fn handle_position_event(&mut self, event: &x11_sys::XClientMessageEvent) {
599 let target_window = event.window as x11_sys::Window;
604 let source_window = event.data.l[0] as x11_sys::Window;
605
606 let accepted = self.type_list.as_ref().map_or(false, | type_list | type_list.contains(&self.atoms.uri_list));
611
612 self.send_status_event(source_window, target_window, accepted);
614
615 if accepted && self.selection.is_none() {
623 }
624 }
625
626 pub unsafe fn handle_selection_event(&mut self, _event: &x11_sys::XSelectionEvent) {
628 }
638
639 pub unsafe fn get_selection_property(&mut self, source_window: x11_sys::Window) -> Vec< std::os::raw::c_uchar> {
641 let mut selection = Vec::new();
642 let mut offset = 0;
643 let length = 1024;
644 let mut actual_type = 0;
645 let mut actual_format = 0;
646 let mut nitems = 0;
647 let mut bytes_after = 0;
648 let mut prop = ptr::null_mut();
649 loop {
650 x11_sys::XGetWindowProperty(
651 self.display,
652 source_window,
653 self.atoms.selection,
654 offset,
655 length,
656 x11_sys::False as std::os::raw::c_int,
657 self.atoms.uri_list,
658 &mut actual_type,
659 &mut actual_format,
660 &mut nitems,
661 &mut bytes_after,
662 &mut prop,
663 );
664 selection.extend_from_slice(std::slice::from_raw_parts(prop as *mut std::os::raw::c_uchar, nitems as usize));
665 x11_sys::XFree(prop as *mut c_void);
666 if bytes_after == 0 {
667 break;
668 }
669 offset += length;
670 };
671 selection
672 }
673
674 pub unsafe fn get_type_list_property(&mut self, source_window: x11_sys::Window) -> Vec<x11_sys::Atom> {
676 let mut type_list = Vec::new();
677 let mut offset = 0;
678 let length = 1024;
679 let mut actual_type = 0;
680 let mut actual_format = 0;
681 let mut nitems = 0;
682 let mut bytes_after = 0;
683 let mut prop = ptr::null_mut();
684 loop {
685 x11_sys::XGetWindowProperty(
686 self.display,
687 source_window,
688 self.atoms.type_list,
689 offset,
690 length,
691 x11_sys::False as std::os::raw::c_int,
692 4, &mut actual_type,
694 &mut actual_format,
695 &mut nitems,
696 &mut bytes_after,
697 &mut prop,
698 );
699 type_list.extend_from_slice(std::slice::from_raw_parts(prop as *mut x11_sys::Atom, nitems as usize));
700 x11_sys::XFree(prop as *mut c_void);
701 if bytes_after == 0 {
702 break;
703 }
704 offset += length;
705 };
706 type_list
707 }
708
709 pub unsafe fn send_status_event(&mut self, source_window: x11_sys::Window, target_window: x11_sys::Window, accepted: bool) {
711 x11_sys::XSendEvent(
712 self.display,
713 source_window,
714 x11_sys::False as std::os::raw::c_int,
715 x11_sys::NoEventMask as std::os::raw::c_long,
716 &mut x11_sys::XClientMessageEvent {
717 type_: x11_sys::ClientMessage as std::os::raw::c_int,
718 serial: 0,
719 send_event: 0,
720 display: self.display,
721 window: source_window,
722 message_type: self.atoms.status,
723 format: 32,
724 data: {
725 let mut data = mem::zeroed::<x11_sys::XClientMessageEvent__bindgen_ty_1>();
726 data.l[0] = target_window as c_long;
727 data.l[1] = if accepted {1 << 0} else {0};
728 data.l[2] = 0;
729 data.l[3] = 0;
730 data.l[4] = if accepted {self.atoms.action_private} else {self.atoms.none} as c_long;
731 data
732 }
733 } as *mut x11_sys::XClientMessageEvent as *mut x11_sys::XEvent
734 );
735 x11_sys::XFlush(self.display);
736 }
737
738 pub unsafe fn convert_selection(&self, target_window: x11_sys::Window) {
741 x11_sys::XConvertSelection(
742 self.display,
743 self.atoms.selection,
744 self.atoms.uri_list,
745 self.atoms.selection,
746 target_window,
747 x11_sys::CurrentTime as x11_sys::Time,
748 );
749 }
750}
751
752pub struct DndAtoms {
753 pub action_private: x11_sys::Atom,
754 pub aware: x11_sys::Atom,
755 pub drop: x11_sys::Atom,
756 pub enter: x11_sys::Atom,
757 pub leave: x11_sys::Atom,
758 pub none: x11_sys::Atom,
759 pub position: x11_sys::Atom,
760 pub selection: x11_sys::Atom,
761 pub status: x11_sys::Atom,
762 pub type_list: x11_sys::Atom,
763 pub uri_list: x11_sys::Atom,
764}
765
766impl DndAtoms {
767 pub unsafe fn new(display: *mut x11_sys::Display) -> DndAtoms {
768 DndAtoms {
769 action_private: x11_sys::XInternAtom(display, "XdndActionPrivate\0".as_ptr() as *const _, 0),
770 aware: x11_sys::XInternAtom(display, "XdndAware\0".as_ptr() as *const _, 0),
771 drop: x11_sys::XInternAtom(display, "XdndDrop\0".as_ptr() as *const _, 0),
772 enter: x11_sys::XInternAtom(display, "XdndEnter\0".as_ptr() as *const _, 0),
773 leave: x11_sys::XInternAtom(display, "XdndLeave\0".as_ptr() as *const _, 0),
774 none: x11_sys::XInternAtom(display, "None\0".as_ptr() as *const _, 0),
775 position: x11_sys::XInternAtom(display, "XdndPosition\0".as_ptr() as *const _, 0),
776 selection: x11_sys::XInternAtom(display, "XdndSelection\0".as_ptr() as *const _, 0),
777 status: x11_sys::XInternAtom(display, "XdndStatus\0".as_ptr() as *const _, 0),
778 type_list: x11_sys::XInternAtom(display, "XdndTypeList\0".as_ptr() as *const _, 0),
779 uri_list: x11_sys::XInternAtom(display, "text/uri-list\0".as_ptr() as *const _, 0),
780 }
781 }
782}