1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// MIT/Apache2 License
use Display;
/// Represents an object that contains a Display and can successfully be aliased to a display.
///
/// In certain cases, it becomes necessary for an extension to attach its own data to the display connection.
/// The most notable cases of this are XRender and GLX. Doing this with composition in Rust would entail
/// enclosing the Display inside of the struct. For instance:
///
/// ```
/// use breadx::Display;
///
/// struct MyExtensionDisplay<Conn> {
/// dpy: Display<Conn>,
/// other_data: OtherData,
/// }
/// # struct OtherData;
/// ```
///
/// Of course, this would mean that you could only use one of these extensions at once. It would be nice if you
/// could put the extension display for one extension inside of the extension display of another. `DisplayLike`
/// is the solution to this problem. Extension displays should take objects of type `DisplayLike` and also
/// implement `DisplayLike` if possible.
///
/// `DisplayLike` is implemented for `Display`, as well as any of the extension displays provided by `breadx`.
///
/// # Example
///
/// ```no_run
/// use breadx::{Display, DisplayConnection, DisplayLike};
/// use std::sync::{Arc, Mutex};
///
/// struct Extension1Display<Dpy> {
/// dpy: Dpy,
/// data: u32,
/// }
///
/// struct Extension2Display<Dpy> {
/// // let's say Extension2 needs to work across the FFI boundary and thus needs
/// // to have interior mutability
/// dpy: Arc<Mutex<Dpy>>,
/// }
///
/// impl<Dpy: DisplayLike> DisplayLike for Extension1Display<Dpy> {
/// type Connection = Dpy::Connection;
///
/// #[inline]
/// fn display(&self) -> &Display<Dpy::Connection> {
/// self.dpy.display()
/// }
///
/// #[inline]
/// fn display_mut(&mut self) -> &mut Display<Dpy::Connection> {
/// self.dpy.display_mut()
/// }
/// }
///
/// // since it's impossible to get an &mut Dpy from an Arc<Mutex<Dpy>>, we don't implement
/// // DisplayLike for Extension2Display<Dpy>
/// // essentially, it's a "final consumer" of the Display
///
/// let conn = DisplayConnection::create(None, None).unwrap();
/// let conn = Extension1Display {
/// dpy: conn,
/// data: 14,
/// };
/// let conn = Extension2Display {
/// dpy: Arc::new(Mutex::new(conn)),
/// };
/// ```