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")]
64 pub struct GLWindow(Object<ffi::GstGLWindow, ffi::GstGLWindowClass>) @extends gst::Object;
65
66 match fn {
67 type_ => || ffi::gst_gl_window_get_type(),
68 }
69}
70
71impl GLWindow {
72 pub const NONE: Option<&'static GLWindow> = None;
73
74 #[doc(alias = "gst_gl_window_new")]
81 pub fn new(display: &impl IsA<GLDisplay>) -> GLWindow {
82 skip_assert_initialized!();
83 unsafe { from_glib_full(ffi::gst_gl_window_new(display.as_ref().to_glib_none().0)) }
84 }
85}
86
87unsafe impl Send for GLWindow {}
88unsafe impl Sync for GLWindow {}
89
90mod sealed {
91 pub trait Sealed {}
92 impl<T: super::IsA<super::GLWindow>> Sealed for T {}
93}
94
95pub trait GLWindowExt: IsA<GLWindow> + sealed::Sealed + 'static {
101 #[cfg(feature = "v1_16")]
107 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
108 #[doc(alias = "gst_gl_window_controls_viewport")]
109 fn controls_viewport(&self) -> bool {
110 unsafe {
111 from_glib(ffi::gst_gl_window_controls_viewport(
112 self.as_ref().to_glib_none().0,
113 ))
114 }
115 }
116
117 #[doc(alias = "gst_gl_window_draw")]
119 fn draw(&self) {
120 unsafe {
121 ffi::gst_gl_window_draw(self.as_ref().to_glib_none().0);
122 }
123 }
124
125 #[doc(alias = "gst_gl_window_get_context")]
130 #[doc(alias = "get_context")]
131 fn context(&self) -> GLContext {
132 unsafe {
133 from_glib_full(ffi::gst_gl_window_get_context(
134 self.as_ref().to_glib_none().0,
135 ))
136 }
137 }
138
139 #[doc(alias = "gst_gl_window_get_surface_dimensions")]
149 #[doc(alias = "get_surface_dimensions")]
150 fn surface_dimensions(&self) -> (u32, u32) {
151 unsafe {
152 let mut width = std::mem::MaybeUninit::uninit();
153 let mut height = std::mem::MaybeUninit::uninit();
154 ffi::gst_gl_window_get_surface_dimensions(
155 self.as_ref().to_glib_none().0,
156 width.as_mut_ptr(),
157 height.as_mut_ptr(),
158 );
159 (width.assume_init(), height.assume_init())
160 }
161 }
162
163 #[doc(alias = "gst_gl_window_handle_events")]
171 fn handle_events(&self, handle_events: bool) {
172 unsafe {
173 ffi::gst_gl_window_handle_events(
174 self.as_ref().to_glib_none().0,
175 handle_events.into_glib(),
176 );
177 }
178 }
179
180 #[cfg(feature = "v1_18")]
186 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
187 #[doc(alias = "gst_gl_window_has_output_surface")]
188 fn has_output_surface(&self) -> bool {
189 unsafe {
190 from_glib(ffi::gst_gl_window_has_output_surface(
191 self.as_ref().to_glib_none().0,
192 ))
193 }
194 }
195
196 #[doc(alias = "gst_gl_window_queue_resize")]
198 fn queue_resize(&self) {
199 unsafe {
200 ffi::gst_gl_window_queue_resize(self.as_ref().to_glib_none().0);
201 }
202 }
203
204 #[doc(alias = "gst_gl_window_quit")]
206 fn quit(&self) {
207 unsafe {
208 ffi::gst_gl_window_quit(self.as_ref().to_glib_none().0);
209 }
210 }
211
212 #[doc(alias = "gst_gl_window_resize")]
218 fn resize(&self, width: u32, height: u32) {
219 unsafe {
220 ffi::gst_gl_window_resize(self.as_ref().to_glib_none().0, width, height);
221 }
222 }
223
224 #[doc(alias = "gst_gl_window_run")]
226 fn run(&self) {
227 unsafe {
228 ffi::gst_gl_window_run(self.as_ref().to_glib_none().0);
229 }
230 }
231
232 #[doc(alias = "gst_gl_window_send_key_event")]
233 fn send_key_event(&self, event_type: &str, key_str: &str) {
234 unsafe {
235 ffi::gst_gl_window_send_key_event(
236 self.as_ref().to_glib_none().0,
237 event_type.to_glib_none().0,
238 key_str.to_glib_none().0,
239 );
240 }
241 }
242
243 #[doc(alias = "gst_gl_window_send_mouse_event")]
244 fn send_mouse_event(&self, event_type: &str, button: i32, posx: f64, posy: f64) {
245 unsafe {
246 ffi::gst_gl_window_send_mouse_event(
247 self.as_ref().to_glib_none().0,
248 event_type.to_glib_none().0,
249 button,
250 posx,
251 posy,
252 );
253 }
254 }
255
256 #[cfg(feature = "v1_18")]
267 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
268 #[doc(alias = "gst_gl_window_send_scroll_event")]
269 fn send_scroll_event(&self, posx: f64, posy: f64, delta_x: f64, delta_y: f64) {
270 unsafe {
271 ffi::gst_gl_window_send_scroll_event(
272 self.as_ref().to_glib_none().0,
273 posx,
274 posy,
275 delta_x,
276 delta_y,
277 );
278 }
279 }
280
281 #[doc(alias = "gst_gl_window_set_preferred_size")]
288 fn set_preferred_size(&self, width: i32, height: i32) {
289 unsafe {
290 ffi::gst_gl_window_set_preferred_size(self.as_ref().to_glib_none().0, width, height);
291 }
292 }
293
294 #[doc(alias = "gst_gl_window_set_render_rectangle")]
309 fn set_render_rectangle(
310 &self,
311 x: i32,
312 y: i32,
313 width: i32,
314 height: i32,
315 ) -> Result<(), glib::error::BoolError> {
316 unsafe {
317 glib::result_from_gboolean!(
318 ffi::gst_gl_window_set_render_rectangle(
319 self.as_ref().to_glib_none().0,
320 x,
321 y,
322 width,
323 height
324 ),
325 "Failed to set the specified region"
326 )
327 }
328 }
329
330 #[doc(alias = "gst_gl_window_show")]
332 fn show(&self) {
333 unsafe {
334 ffi::gst_gl_window_show(self.as_ref().to_glib_none().0);
335 }
336 }
337
338 #[doc(alias = "key-event")]
344 fn connect_key_event<F: Fn(&Self, &str, &str) + Send + Sync + 'static>(
345 &self,
346 f: F,
347 ) -> SignalHandlerId {
348 unsafe extern "C" fn key_event_trampoline<
349 P: IsA<GLWindow>,
350 F: Fn(&P, &str, &str) + Send + Sync + 'static,
351 >(
352 this: *mut ffi::GstGLWindow,
353 id: *mut std::ffi::c_char,
354 key: *mut std::ffi::c_char,
355 f: glib::ffi::gpointer,
356 ) {
357 let f: &F = &*(f as *const F);
358 f(
359 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
360 &glib::GString::from_glib_borrow(id),
361 &glib::GString::from_glib_borrow(key),
362 )
363 }
364 unsafe {
365 let f: Box_<F> = Box_::new(f);
366 connect_raw(
367 self.as_ptr() as *mut _,
368 b"key-event\0".as_ptr() as *const _,
369 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
370 key_event_trampoline::<Self, F> as *const (),
371 )),
372 Box_::into_raw(f),
373 )
374 }
375 }
376
377 #[doc(alias = "mouse-event")]
387 fn connect_mouse_event<F: Fn(&Self, &str, i32, f64, f64) + Send + Sync + 'static>(
388 &self,
389 f: F,
390 ) -> SignalHandlerId {
391 unsafe extern "C" fn mouse_event_trampoline<
392 P: IsA<GLWindow>,
393 F: Fn(&P, &str, i32, f64, f64) + Send + Sync + 'static,
394 >(
395 this: *mut ffi::GstGLWindow,
396 id: *mut std::ffi::c_char,
397 button: std::ffi::c_int,
398 x: std::ffi::c_double,
399 y: std::ffi::c_double,
400 f: glib::ffi::gpointer,
401 ) {
402 let f: &F = &*(f as *const F);
403 f(
404 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
405 &glib::GString::from_glib_borrow(id),
406 button,
407 x,
408 y,
409 )
410 }
411 unsafe {
412 let f: Box_<F> = Box_::new(f);
413 connect_raw(
414 self.as_ptr() as *mut _,
415 b"mouse-event\0".as_ptr() as *const _,
416 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
417 mouse_event_trampoline::<Self, F> as *const (),
418 )),
419 Box_::into_raw(f),
420 )
421 }
422 }
423
424 #[cfg(feature = "v1_18")]
434 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
435 #[doc(alias = "scroll-event")]
436 fn connect_scroll_event<F: Fn(&Self, f64, f64, f64, f64) + Send + Sync + 'static>(
437 &self,
438 f: F,
439 ) -> SignalHandlerId {
440 unsafe extern "C" fn scroll_event_trampoline<
441 P: IsA<GLWindow>,
442 F: Fn(&P, f64, f64, f64, f64) + Send + Sync + 'static,
443 >(
444 this: *mut ffi::GstGLWindow,
445 x: std::ffi::c_double,
446 y: std::ffi::c_double,
447 delta_x: std::ffi::c_double,
448 delta_y: std::ffi::c_double,
449 f: glib::ffi::gpointer,
450 ) {
451 let f: &F = &*(f as *const F);
452 f(
453 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
454 x,
455 y,
456 delta_x,
457 delta_y,
458 )
459 }
460 unsafe {
461 let f: Box_<F> = Box_::new(f);
462 connect_raw(
463 self.as_ptr() as *mut _,
464 b"scroll-event\0".as_ptr() as *const _,
465 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
466 scroll_event_trampoline::<Self, F> as *const (),
467 )),
468 Box_::into_raw(f),
469 )
470 }
471 }
472
473 #[cfg(feature = "v1_20")]
478 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
479 #[doc(alias = "window-handle-changed")]
480 fn connect_window_handle_changed<F: Fn(&Self) + Send + Sync + 'static>(
481 &self,
482 f: F,
483 ) -> SignalHandlerId {
484 unsafe extern "C" fn window_handle_changed_trampoline<
485 P: IsA<GLWindow>,
486 F: Fn(&P) + Send + Sync + 'static,
487 >(
488 this: *mut ffi::GstGLWindow,
489 f: glib::ffi::gpointer,
490 ) {
491 let f: &F = &*(f as *const F);
492 f(GLWindow::from_glib_borrow(this).unsafe_cast_ref())
493 }
494 unsafe {
495 let f: Box_<F> = Box_::new(f);
496 connect_raw(
497 self.as_ptr() as *mut _,
498 b"window-handle-changed\0".as_ptr() as *const _,
499 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
500 window_handle_changed_trampoline::<Self, F> as *const (),
501 )),
502 Box_::into_raw(f),
503 )
504 }
505 }
506}
507
508impl<O: IsA<GLWindow>> GLWindowExt for O {}