1use crate::{ffi, GLContext, GLDisplay};
7use glib::{
8 object::ObjectType as _,
9 prelude::*,
10 signal::{connect_raw, SignalHandlerId},
11 translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16 #[doc(alias = "GstGLWindow")]
17 pub struct GLWindow(Object<ffi::GstGLWindow, ffi::GstGLWindowClass>) @extends gst::Object;
18
19 match fn {
20 type_ => || ffi::gst_gl_window_get_type(),
21 }
22}
23
24impl GLWindow {
25 pub const NONE: Option<&'static GLWindow> = None;
26
27 #[doc(alias = "gst_gl_window_new")]
28 pub fn new(display: &impl IsA<GLDisplay>) -> GLWindow {
29 skip_assert_initialized!();
30 unsafe { from_glib_full(ffi::gst_gl_window_new(display.as_ref().to_glib_none().0)) }
31 }
32}
33
34unsafe impl Send for GLWindow {}
35unsafe impl Sync for GLWindow {}
36
37pub trait GLWindowExt: IsA<GLWindow> + 'static {
38 #[cfg(feature = "v1_16")]
39 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
40 #[doc(alias = "gst_gl_window_controls_viewport")]
41 fn controls_viewport(&self) -> bool {
42 unsafe {
43 from_glib(ffi::gst_gl_window_controls_viewport(
44 self.as_ref().to_glib_none().0,
45 ))
46 }
47 }
48
49 #[doc(alias = "gst_gl_window_draw")]
50 fn draw(&self) {
51 unsafe {
52 ffi::gst_gl_window_draw(self.as_ref().to_glib_none().0);
53 }
54 }
55
56 #[doc(alias = "gst_gl_window_get_context")]
57 #[doc(alias = "get_context")]
58 fn context(&self) -> GLContext {
59 unsafe {
60 from_glib_full(ffi::gst_gl_window_get_context(
61 self.as_ref().to_glib_none().0,
62 ))
63 }
64 }
65
66 #[cfg(feature = "v1_28")]
67 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
68 #[doc(alias = "gst_gl_window_get_request_output_surface")]
69 #[doc(alias = "get_request_output_surface")]
70 fn is_request_output_surface(&self) -> bool {
71 unsafe {
72 from_glib(ffi::gst_gl_window_get_request_output_surface(
73 self.as_ref().to_glib_none().0,
74 ))
75 }
76 }
77
78 #[doc(alias = "gst_gl_window_get_surface_dimensions")]
79 #[doc(alias = "get_surface_dimensions")]
80 fn surface_dimensions(&self) -> (u32, u32) {
81 unsafe {
82 let mut width = std::mem::MaybeUninit::uninit();
83 let mut height = std::mem::MaybeUninit::uninit();
84 ffi::gst_gl_window_get_surface_dimensions(
85 self.as_ref().to_glib_none().0,
86 width.as_mut_ptr(),
87 height.as_mut_ptr(),
88 );
89 (width.assume_init(), height.assume_init())
90 }
91 }
92
93 #[doc(alias = "gst_gl_window_handle_events")]
94 fn handle_events(&self, handle_events: bool) {
95 unsafe {
96 ffi::gst_gl_window_handle_events(
97 self.as_ref().to_glib_none().0,
98 handle_events.into_glib(),
99 );
100 }
101 }
102
103 #[cfg(feature = "v1_18")]
104 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
105 #[doc(alias = "gst_gl_window_has_output_surface")]
106 fn has_output_surface(&self) -> bool {
107 unsafe {
108 from_glib(ffi::gst_gl_window_has_output_surface(
109 self.as_ref().to_glib_none().0,
110 ))
111 }
112 }
113
114 #[doc(alias = "gst_gl_window_queue_resize")]
115 fn queue_resize(&self) {
116 unsafe {
117 ffi::gst_gl_window_queue_resize(self.as_ref().to_glib_none().0);
118 }
119 }
120
121 #[doc(alias = "gst_gl_window_quit")]
122 fn quit(&self) {
123 unsafe {
124 ffi::gst_gl_window_quit(self.as_ref().to_glib_none().0);
125 }
126 }
127
128 #[doc(alias = "gst_gl_window_resize")]
129 fn resize(&self, width: u32, height: u32) {
130 unsafe {
131 ffi::gst_gl_window_resize(self.as_ref().to_glib_none().0, width, height);
132 }
133 }
134
135 #[doc(alias = "gst_gl_window_run")]
136 fn run(&self) {
137 unsafe {
138 ffi::gst_gl_window_run(self.as_ref().to_glib_none().0);
139 }
140 }
141
142 #[doc(alias = "gst_gl_window_send_key_event")]
143 fn send_key_event(&self, event_type: &str, key_str: &str) {
144 unsafe {
145 ffi::gst_gl_window_send_key_event(
146 self.as_ref().to_glib_none().0,
147 event_type.to_glib_none().0,
148 key_str.to_glib_none().0,
149 );
150 }
151 }
152
153 #[doc(alias = "gst_gl_window_send_mouse_event")]
154 fn send_mouse_event(&self, event_type: &str, button: i32, posx: f64, posy: f64) {
155 unsafe {
156 ffi::gst_gl_window_send_mouse_event(
157 self.as_ref().to_glib_none().0,
158 event_type.to_glib_none().0,
159 button,
160 posx,
161 posy,
162 );
163 }
164 }
165
166 #[cfg(feature = "v1_18")]
167 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
168 #[doc(alias = "gst_gl_window_send_scroll_event")]
169 fn send_scroll_event(&self, posx: f64, posy: f64, delta_x: f64, delta_y: f64) {
170 unsafe {
171 ffi::gst_gl_window_send_scroll_event(
172 self.as_ref().to_glib_none().0,
173 posx,
174 posy,
175 delta_x,
176 delta_y,
177 );
178 }
179 }
180
181 #[doc(alias = "gst_gl_window_set_preferred_size")]
182 fn set_preferred_size(&self, width: i32, height: i32) {
183 unsafe {
184 ffi::gst_gl_window_set_preferred_size(self.as_ref().to_glib_none().0, width, height);
185 }
186 }
187
188 #[doc(alias = "gst_gl_window_set_render_rectangle")]
189 fn set_render_rectangle(
190 &self,
191 x: i32,
192 y: i32,
193 width: i32,
194 height: i32,
195 ) -> Result<(), glib::error::BoolError> {
196 unsafe {
197 glib::result_from_gboolean!(
198 ffi::gst_gl_window_set_render_rectangle(
199 self.as_ref().to_glib_none().0,
200 x,
201 y,
202 width,
203 height
204 ),
205 "Failed to set the specified region"
206 )
207 }
208 }
209
210 #[cfg(feature = "v1_28")]
211 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
212 #[doc(alias = "gst_gl_window_set_request_output_surface")]
213 fn set_request_output_surface(&self, output_surface: bool) {
214 unsafe {
215 ffi::gst_gl_window_set_request_output_surface(
216 self.as_ref().to_glib_none().0,
217 output_surface.into_glib(),
218 );
219 }
220 }
221
222 #[doc(alias = "gst_gl_window_show")]
223 fn show(&self) {
224 unsafe {
225 ffi::gst_gl_window_show(self.as_ref().to_glib_none().0);
226 }
227 }
228
229 #[doc(alias = "key-event")]
230 fn connect_key_event<F: Fn(&Self, &str, &str) + Send + Sync + 'static>(
231 &self,
232 f: F,
233 ) -> SignalHandlerId {
234 unsafe extern "C" fn key_event_trampoline<
235 P: IsA<GLWindow>,
236 F: Fn(&P, &str, &str) + Send + Sync + 'static,
237 >(
238 this: *mut ffi::GstGLWindow,
239 id: *mut std::ffi::c_char,
240 key: *mut std::ffi::c_char,
241 f: glib::ffi::gpointer,
242 ) {
243 let f: &F = &*(f as *const F);
244 f(
245 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
246 &glib::GString::from_glib_borrow(id),
247 &glib::GString::from_glib_borrow(key),
248 )
249 }
250 unsafe {
251 let f: Box_<F> = Box_::new(f);
252 connect_raw(
253 self.as_ptr() as *mut _,
254 c"key-event".as_ptr() as *const _,
255 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
256 key_event_trampoline::<Self, F> as *const (),
257 )),
258 Box_::into_raw(f),
259 )
260 }
261 }
262
263 #[doc(alias = "mouse-event")]
264 fn connect_mouse_event<F: Fn(&Self, &str, i32, f64, f64) + Send + Sync + 'static>(
265 &self,
266 f: F,
267 ) -> SignalHandlerId {
268 unsafe extern "C" fn mouse_event_trampoline<
269 P: IsA<GLWindow>,
270 F: Fn(&P, &str, i32, f64, f64) + Send + Sync + 'static,
271 >(
272 this: *mut ffi::GstGLWindow,
273 id: *mut std::ffi::c_char,
274 button: std::ffi::c_int,
275 x: std::ffi::c_double,
276 y: std::ffi::c_double,
277 f: glib::ffi::gpointer,
278 ) {
279 let f: &F = &*(f as *const F);
280 f(
281 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
282 &glib::GString::from_glib_borrow(id),
283 button,
284 x,
285 y,
286 )
287 }
288 unsafe {
289 let f: Box_<F> = Box_::new(f);
290 connect_raw(
291 self.as_ptr() as *mut _,
292 c"mouse-event".as_ptr() as *const _,
293 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
294 mouse_event_trampoline::<Self, F> as *const (),
295 )),
296 Box_::into_raw(f),
297 )
298 }
299 }
300
301 #[cfg(feature = "v1_18")]
302 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
303 #[doc(alias = "scroll-event")]
304 fn connect_scroll_event<F: Fn(&Self, f64, f64, f64, f64) + Send + Sync + 'static>(
305 &self,
306 f: F,
307 ) -> SignalHandlerId {
308 unsafe extern "C" fn scroll_event_trampoline<
309 P: IsA<GLWindow>,
310 F: Fn(&P, f64, f64, f64, f64) + Send + Sync + 'static,
311 >(
312 this: *mut ffi::GstGLWindow,
313 x: std::ffi::c_double,
314 y: std::ffi::c_double,
315 delta_x: std::ffi::c_double,
316 delta_y: std::ffi::c_double,
317 f: glib::ffi::gpointer,
318 ) {
319 let f: &F = &*(f as *const F);
320 f(
321 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
322 x,
323 y,
324 delta_x,
325 delta_y,
326 )
327 }
328 unsafe {
329 let f: Box_<F> = Box_::new(f);
330 connect_raw(
331 self.as_ptr() as *mut _,
332 c"scroll-event".as_ptr() as *const _,
333 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
334 scroll_event_trampoline::<Self, F> as *const (),
335 )),
336 Box_::into_raw(f),
337 )
338 }
339 }
340
341 #[cfg(feature = "v1_20")]
342 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
343 #[doc(alias = "window-handle-changed")]
344 fn connect_window_handle_changed<F: Fn(&Self) + Send + Sync + 'static>(
345 &self,
346 f: F,
347 ) -> SignalHandlerId {
348 unsafe extern "C" fn window_handle_changed_trampoline<
349 P: IsA<GLWindow>,
350 F: Fn(&P) + Send + Sync + 'static,
351 >(
352 this: *mut ffi::GstGLWindow,
353 f: glib::ffi::gpointer,
354 ) {
355 let f: &F = &*(f as *const F);
356 f(GLWindow::from_glib_borrow(this).unsafe_cast_ref())
357 }
358 unsafe {
359 let f: Box_<F> = Box_::new(f);
360 connect_raw(
361 self.as_ptr() as *mut _,
362 c"window-handle-changed".as_ptr() as *const _,
363 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
364 window_handle_changed_trampoline::<Self, F> as *const (),
365 )),
366 Box_::into_raw(f),
367 )
368 }
369 }
370}
371
372impl<O: IsA<GLWindow>> GLWindowExt for O {}