1use crate::{ffi, RenderNode};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::boxed::Box as Box_;
12
13glib::wrapper! {
14 #[doc(alias = "GskRenderer")]
15 pub struct Renderer(Object<ffi::GskRenderer, ffi::GskRendererClass>);
16
17 match fn {
18 type_ => || ffi::gsk_renderer_get_type(),
19 }
20}
21
22impl Renderer {
23 pub const NONE: Option<&'static Renderer> = None;
24
25 #[doc(alias = "gsk_renderer_new_for_surface")]
26 #[doc(alias = "new_for_surface")]
27 pub fn for_surface(surface: &gdk::Surface) -> Option<Renderer> {
28 assert_initialized_main_thread!();
29 unsafe { from_glib_full(ffi::gsk_renderer_new_for_surface(surface.to_glib_none().0)) }
30 }
31}
32
33pub trait GskRendererExt: IsA<Renderer> + 'static {
34 #[doc(alias = "gsk_renderer_get_surface")]
35 #[doc(alias = "get_surface")]
36 fn surface(&self) -> Option<gdk::Surface> {
37 unsafe {
38 from_glib_none(ffi::gsk_renderer_get_surface(
39 self.as_ref().to_glib_none().0,
40 ))
41 }
42 }
43
44 #[doc(alias = "gsk_renderer_is_realized")]
45 #[doc(alias = "realized")]
46 fn is_realized(&self) -> bool {
47 unsafe {
48 from_glib(ffi::gsk_renderer_is_realized(
49 self.as_ref().to_glib_none().0,
50 ))
51 }
52 }
53
54 #[doc(alias = "gsk_renderer_realize")]
55 fn realize(&self, surface: Option<&gdk::Surface>) -> Result<(), glib::Error> {
56 unsafe {
57 let mut error = std::ptr::null_mut();
58 let is_ok = ffi::gsk_renderer_realize(
59 self.as_ref().to_glib_none().0,
60 surface.to_glib_none().0,
61 &mut error,
62 );
63 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
64 if error.is_null() {
65 Ok(())
66 } else {
67 Err(from_glib_full(error))
68 }
69 }
70 }
71
72 #[cfg(feature = "v4_14")]
73 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
74 #[doc(alias = "gsk_renderer_realize_for_display")]
75 fn realize_for_display(&self, display: &gdk::Display) -> Result<(), glib::Error> {
76 unsafe {
77 let mut error = std::ptr::null_mut();
78 let is_ok = ffi::gsk_renderer_realize_for_display(
79 self.as_ref().to_glib_none().0,
80 display.to_glib_none().0,
81 &mut error,
82 );
83 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
84 if error.is_null() {
85 Ok(())
86 } else {
87 Err(from_glib_full(error))
88 }
89 }
90 }
91
92 #[doc(alias = "gsk_renderer_render")]
93 fn render(&self, root: impl AsRef<RenderNode>, region: Option<&cairo::Region>) {
94 unsafe {
95 ffi::gsk_renderer_render(
96 self.as_ref().to_glib_none().0,
97 root.as_ref().to_glib_none().0,
98 region.to_glib_none().0,
99 );
100 }
101 }
102
103 #[doc(alias = "gsk_renderer_render_texture")]
104 fn render_texture(
105 &self,
106 root: impl AsRef<RenderNode>,
107 viewport: Option<&graphene::Rect>,
108 ) -> gdk::Texture {
109 unsafe {
110 from_glib_full(ffi::gsk_renderer_render_texture(
111 self.as_ref().to_glib_none().0,
112 root.as_ref().to_glib_none().0,
113 viewport.to_glib_none().0,
114 ))
115 }
116 }
117
118 #[doc(alias = "gsk_renderer_unrealize")]
119 fn unrealize(&self) {
120 unsafe {
121 ffi::gsk_renderer_unrealize(self.as_ref().to_glib_none().0);
122 }
123 }
124
125 #[doc(alias = "realized")]
126 fn connect_realized_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
127 unsafe extern "C" fn notify_realized_trampoline<P: IsA<Renderer>, F: Fn(&P) + 'static>(
128 this: *mut ffi::GskRenderer,
129 _param_spec: glib::ffi::gpointer,
130 f: glib::ffi::gpointer,
131 ) {
132 let f: &F = &*(f as *const F);
133 f(Renderer::from_glib_borrow(this).unsafe_cast_ref())
134 }
135 unsafe {
136 let f: Box_<F> = Box_::new(f);
137 connect_raw(
138 self.as_ptr() as *mut _,
139 c"notify::realized".as_ptr() as *const _,
140 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
141 notify_realized_trampoline::<Self, F> as *const (),
142 )),
143 Box_::into_raw(f),
144 )
145 }
146 }
147
148 #[doc(alias = "surface")]
149 fn connect_surface_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
150 unsafe extern "C" fn notify_surface_trampoline<P: IsA<Renderer>, F: Fn(&P) + 'static>(
151 this: *mut ffi::GskRenderer,
152 _param_spec: glib::ffi::gpointer,
153 f: glib::ffi::gpointer,
154 ) {
155 let f: &F = &*(f as *const F);
156 f(Renderer::from_glib_borrow(this).unsafe_cast_ref())
157 }
158 unsafe {
159 let f: Box_<F> = Box_::new(f);
160 connect_raw(
161 self.as_ptr() as *mut _,
162 c"notify::surface".as_ptr() as *const _,
163 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
164 notify_surface_trampoline::<Self, F> as *const (),
165 )),
166 Box_::into_raw(f),
167 )
168 }
169 }
170}
171
172impl<O: IsA<Renderer>> GskRendererExt for O {}