1use crate::{GLContext, GLDisplay, ffi};
7use glib::{
8 object::ObjectType as _,
9 prelude::*,
10 signal::{SignalHandlerId, connect_raw},
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 unsafe {
244 let f: &F = &*(f as *const F);
245 f(
246 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
247 &glib::GString::from_glib_borrow(id),
248 &glib::GString::from_glib_borrow(key),
249 )
250 }
251 }
252 unsafe {
253 let f: Box_<F> = Box_::new(f);
254 connect_raw(
255 self.as_ptr() as *mut _,
256 c"key-event".as_ptr(),
257 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
258 key_event_trampoline::<Self, F> as *const (),
259 )),
260 Box_::into_raw(f),
261 )
262 }
263 }
264
265 #[doc(alias = "mouse-event")]
266 fn connect_mouse_event<F: Fn(&Self, &str, i32, f64, f64) + Send + Sync + 'static>(
267 &self,
268 f: F,
269 ) -> SignalHandlerId {
270 unsafe extern "C" fn mouse_event_trampoline<
271 P: IsA<GLWindow>,
272 F: Fn(&P, &str, i32, f64, f64) + Send + Sync + 'static,
273 >(
274 this: *mut ffi::GstGLWindow,
275 id: *mut std::ffi::c_char,
276 button: std::ffi::c_int,
277 x: std::ffi::c_double,
278 y: std::ffi::c_double,
279 f: glib::ffi::gpointer,
280 ) {
281 unsafe {
282 let f: &F = &*(f as *const F);
283 f(
284 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
285 &glib::GString::from_glib_borrow(id),
286 button,
287 x,
288 y,
289 )
290 }
291 }
292 unsafe {
293 let f: Box_<F> = Box_::new(f);
294 connect_raw(
295 self.as_ptr() as *mut _,
296 c"mouse-event".as_ptr(),
297 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
298 mouse_event_trampoline::<Self, F> as *const (),
299 )),
300 Box_::into_raw(f),
301 )
302 }
303 }
304
305 #[cfg(feature = "v1_18")]
306 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
307 #[doc(alias = "scroll-event")]
308 fn connect_scroll_event<F: Fn(&Self, f64, f64, f64, f64) + Send + Sync + 'static>(
309 &self,
310 f: F,
311 ) -> SignalHandlerId {
312 unsafe extern "C" fn scroll_event_trampoline<
313 P: IsA<GLWindow>,
314 F: Fn(&P, f64, f64, f64, f64) + Send + Sync + 'static,
315 >(
316 this: *mut ffi::GstGLWindow,
317 x: std::ffi::c_double,
318 y: std::ffi::c_double,
319 delta_x: std::ffi::c_double,
320 delta_y: std::ffi::c_double,
321 f: glib::ffi::gpointer,
322 ) {
323 unsafe {
324 let f: &F = &*(f as *const F);
325 f(
326 GLWindow::from_glib_borrow(this).unsafe_cast_ref(),
327 x,
328 y,
329 delta_x,
330 delta_y,
331 )
332 }
333 }
334 unsafe {
335 let f: Box_<F> = Box_::new(f);
336 connect_raw(
337 self.as_ptr() as *mut _,
338 c"scroll-event".as_ptr(),
339 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
340 scroll_event_trampoline::<Self, F> as *const (),
341 )),
342 Box_::into_raw(f),
343 )
344 }
345 }
346
347 #[cfg(feature = "v1_20")]
348 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
349 #[doc(alias = "window-handle-changed")]
350 fn connect_window_handle_changed<F: Fn(&Self) + Send + Sync + 'static>(
351 &self,
352 f: F,
353 ) -> SignalHandlerId {
354 unsafe extern "C" fn window_handle_changed_trampoline<
355 P: IsA<GLWindow>,
356 F: Fn(&P) + Send + Sync + 'static,
357 >(
358 this: *mut ffi::GstGLWindow,
359 f: glib::ffi::gpointer,
360 ) {
361 unsafe {
362 let f: &F = &*(f as *const F);
363 f(GLWindow::from_glib_borrow(this).unsafe_cast_ref())
364 }
365 }
366 unsafe {
367 let f: Box_<F> = Box_::new(f);
368 connect_raw(
369 self.as_ptr() as *mut _,
370 c"window-handle-changed".as_ptr(),
371 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
372 window_handle_changed_trampoline::<Self, F> as *const (),
373 )),
374 Box_::into_raw(f),
375 )
376 }
377 }
378}
379
380impl<O: IsA<GLWindow>> GLWindowExt for O {}