gdk4/auto/
gl_context.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4#![allow(deprecated)]
5
6#[cfg(feature = "v4_6")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
8use crate::GLAPI;
9use crate::{ffi, Display, DrawContext, Surface};
10#[cfg(feature = "v4_6")]
11#[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
12use glib::signal::{connect_raw, SignalHandlerId};
13use glib::{prelude::*, translate::*};
14#[cfg(feature = "v4_6")]
15#[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
16use std::boxed::Box as Box_;
17
18glib::wrapper! {
19    /// [`GLContext`][crate::GLContext] is an object representing a platform-specific
20    /// OpenGL draw context.
21    ///
22    /// [`GLContext`][crate::GLContext]s are created for a surface using
23    /// [`SurfaceExt::create_gl_context()`][crate::prelude::SurfaceExt::create_gl_context()], and the context will match
24    /// the characteristics of the surface.
25    ///
26    /// A [`GLContext`][crate::GLContext] is not tied to any particular normal framebuffer.
27    /// For instance, it cannot draw to the surface back buffer. The GDK
28    /// repaint system is in full control of the painting to that. Instead,
29    /// you can create render buffers or textures and use [`draw_from_gl()`][crate::draw_from_gl()]
30    /// in the draw function of your widget to draw them. Then GDK will handle
31    /// the integration of your rendering with that of other widgets.
32    ///
33    /// Support for [`GLContext`][crate::GLContext] is platform-specific and context creation
34    /// can fail, returning [`None`] context.
35    ///
36    /// A [`GLContext`][crate::GLContext] has to be made "current" in order to start using
37    /// it, otherwise any OpenGL call will be ignored.
38    ///
39    /// ## Creating a new OpenGL context
40    ///
41    /// In order to create a new [`GLContext`][crate::GLContext] instance you need a [`Surface`][crate::Surface],
42    /// which you typically get during the realize call of a widget.
43    ///
44    /// A [`GLContext`][crate::GLContext] is not realized until either [`GLContextExt::make_current()`][crate::prelude::GLContextExt::make_current()]
45    /// or [`GLContextExt::realize()`][crate::prelude::GLContextExt::realize()] is called. It is possible to specify
46    /// details of the GL context like the OpenGL version to be used, or whether
47    /// the GL context should have extra state validation enabled after calling
48    /// [`SurfaceExt::create_gl_context()`][crate::prelude::SurfaceExt::create_gl_context()] by calling [`GLContextExt::realize()`][crate::prelude::GLContextExt::realize()].
49    /// If the realization fails you have the option to change the settings of
50    /// the [`GLContext`][crate::GLContext] and try again.
51    ///
52    /// ## Using a GdkGLContext
53    ///
54    /// You will need to make the [`GLContext`][crate::GLContext] the current context before issuing
55    /// OpenGL calls; the system sends OpenGL commands to whichever context is current.
56    /// It is possible to have multiple contexts, so you always need to ensure that
57    /// the one which you want to draw with is the current one before issuing commands:
58    ///
59    /// **⚠️ The following code is in c ⚠️**
60    ///
61    /// ```c
62    /// gdk_gl_context_make_current (context);
63    /// ```
64    ///
65    /// You can now perform your drawing using OpenGL commands.
66    ///
67    /// You can check which [`GLContext`][crate::GLContext] is the current one by using
68    /// [`current()`][Self::current()]; you can also unset any [`GLContext`][crate::GLContext]
69    /// that is currently set by calling [`clear_current()`][Self::clear_current()].
70    ///
71    /// This is an Abstract Base Class, you cannot instantiate it.
72    ///
73    /// ## Properties
74    ///
75    ///
76    /// #### `allowed-apis`
77    ///  The allowed APIs.
78    ///
79    /// Readable | Writeable
80    ///
81    ///
82    /// #### `api`
83    ///  The API currently in use.
84    ///
85    /// Readable
86    ///
87    ///
88    /// #### `shared-context`
89    ///  Always [`None`]
90    ///
91    /// As many contexts can share data now and no single shared context exists
92    /// anymore, this function has been deprecated and now always returns [`None`].
93    ///
94    /// Readable | Writeable | Construct Only
95    /// <details><summary><h4>DrawContext</h4></summary>
96    ///
97    ///
98    /// #### `display`
99    ///  The [`Display`][crate::Display] used to create the [`DrawContext`][crate::DrawContext].
100    ///
101    /// Readable | Writeable | Construct Only
102    ///
103    ///
104    /// #### `surface`
105    ///  The [`Surface`][crate::Surface] the context is bound to.
106    ///
107    /// Readable | Writeable | Construct Only
108    /// </details>
109    ///
110    /// # Implements
111    ///
112    /// [`GLContextExt`][trait@crate::prelude::GLContextExt], [`DrawContextExt`][trait@crate::prelude::DrawContextExt], [`DrawContextExtManual`][trait@crate::prelude::DrawContextExtManual]
113    #[doc(alias = "GdkGLContext")]
114    pub struct GLContext(Object<ffi::GdkGLContext>) @extends DrawContext;
115
116    match fn {
117        type_ => || ffi::gdk_gl_context_get_type(),
118    }
119}
120
121impl GLContext {
122    pub const NONE: Option<&'static GLContext> = None;
123
124    /// Clears the current [`GLContext`][crate::GLContext].
125    ///
126    /// Any OpenGL call after this function returns will be ignored
127    /// until [`GLContextExt::make_current()`][crate::prelude::GLContextExt::make_current()] is called.
128    #[doc(alias = "gdk_gl_context_clear_current")]
129    pub fn clear_current() {
130        assert_initialized_main_thread!();
131        unsafe {
132            ffi::gdk_gl_context_clear_current();
133        }
134    }
135
136    /// Retrieves the current [`GLContext`][crate::GLContext].
137    ///
138    /// # Returns
139    ///
140    /// the current [`GLContext`][crate::GLContext]
141    #[doc(alias = "gdk_gl_context_get_current")]
142    #[doc(alias = "get_current")]
143    pub fn current() -> Option<GLContext> {
144        assert_initialized_main_thread!();
145        unsafe { from_glib_none(ffi::gdk_gl_context_get_current()) }
146    }
147}
148
149mod sealed {
150    pub trait Sealed {}
151    impl<T: super::IsA<super::GLContext>> Sealed for T {}
152}
153
154/// Trait containing all [`struct@GLContext`] methods.
155///
156/// # Implementors
157///
158/// [`GLContext`][struct@crate::GLContext]
159pub trait GLContextExt: IsA<GLContext> + sealed::Sealed + 'static {
160    /// Gets the allowed APIs set via gdk_gl_context_set_allowed_apis().
161    ///
162    /// # Returns
163    ///
164    /// the allowed APIs
165    #[cfg(feature = "v4_6")]
166    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
167    #[doc(alias = "gdk_gl_context_get_allowed_apis")]
168    #[doc(alias = "get_allowed_apis")]
169    #[doc(alias = "allowed-apis")]
170    fn allowed_apis(&self) -> GLAPI {
171        unsafe {
172            from_glib(ffi::gdk_gl_context_get_allowed_apis(
173                self.as_ref().to_glib_none().0,
174            ))
175        }
176    }
177
178    /// Gets the API currently in use.
179    ///
180    /// If the renderer has not been realized yet, 0 is returned.
181    ///
182    /// # Returns
183    ///
184    /// the currently used API
185    #[cfg(feature = "v4_6")]
186    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
187    #[doc(alias = "gdk_gl_context_get_api")]
188    #[doc(alias = "get_api")]
189    fn api(&self) -> GLAPI {
190        unsafe { from_glib(ffi::gdk_gl_context_get_api(self.as_ref().to_glib_none().0)) }
191    }
192
193    /// Retrieves whether the context is doing extra validations and runtime checking.
194    ///
195    /// See [`set_debug_enabled()`][Self::set_debug_enabled()].
196    ///
197    /// # Returns
198    ///
199    /// [`true`] if debugging is enabled
200    #[doc(alias = "gdk_gl_context_get_debug_enabled")]
201    #[doc(alias = "get_debug_enabled")]
202    fn is_debug_enabled(&self) -> bool {
203        unsafe {
204            from_glib(ffi::gdk_gl_context_get_debug_enabled(
205                self.as_ref().to_glib_none().0,
206            ))
207        }
208    }
209
210    /// Retrieves the display the @self is created for
211    ///
212    /// # Returns
213    ///
214    /// a [`Display`][crate::Display]
215    #[doc(alias = "gdk_gl_context_get_display")]
216    #[doc(alias = "get_display")]
217    fn display(&self) -> Option<Display> {
218        unsafe {
219            from_glib_none(ffi::gdk_gl_context_get_display(
220                self.as_ref().to_glib_none().0,
221            ))
222        }
223    }
224
225    /// Retrieves whether the context is forward-compatible.
226    ///
227    /// See [`set_forward_compatible()`][Self::set_forward_compatible()].
228    ///
229    /// # Returns
230    ///
231    /// [`true`] if the context should be forward-compatible
232    #[doc(alias = "gdk_gl_context_get_forward_compatible")]
233    #[doc(alias = "get_forward_compatible")]
234    fn is_forward_compatible(&self) -> bool {
235        unsafe {
236            from_glib(ffi::gdk_gl_context_get_forward_compatible(
237                self.as_ref().to_glib_none().0,
238            ))
239        }
240    }
241
242    /// Retrieves required OpenGL version set as a requirement for the @self
243    /// realization. It will not change even if a greater OpenGL version is supported
244    /// and used after the @self is realized. See
245    /// [`version()`][Self::version()] for the real version in use.
246    ///
247    /// See [`set_required_version()`][Self::set_required_version()].
248    ///
249    /// # Returns
250    ///
251    ///
252    /// ## `major`
253    /// return location for the major version to request
254    ///
255    /// ## `minor`
256    /// return location for the minor version to request
257    #[doc(alias = "gdk_gl_context_get_required_version")]
258    #[doc(alias = "get_required_version")]
259    fn required_version(&self) -> (i32, i32) {
260        unsafe {
261            let mut major = std::mem::MaybeUninit::uninit();
262            let mut minor = std::mem::MaybeUninit::uninit();
263            ffi::gdk_gl_context_get_required_version(
264                self.as_ref().to_glib_none().0,
265                major.as_mut_ptr(),
266                minor.as_mut_ptr(),
267            );
268            (major.assume_init(), minor.assume_init())
269        }
270    }
271
272    /// Used to retrieves the [`GLContext`][crate::GLContext] that this @self share data with.
273    ///
274    /// As many contexts can share data now and no single shared context exists
275    /// anymore, this function has been deprecated and now always returns [`None`].
276    ///
277    /// # Deprecated since 4.4
278    ///
279    /// Use [`is_shared()`][Self::is_shared()] to check if contexts
280    ///   can be shared.
281    ///
282    /// # Returns
283    ///
284    /// [`None`]
285    #[cfg_attr(feature = "v4_4", deprecated = "Since 4.4")]
286    #[allow(deprecated)]
287    #[doc(alias = "gdk_gl_context_get_shared_context")]
288    #[doc(alias = "get_shared_context")]
289    #[doc(alias = "shared-context")]
290    #[must_use]
291    fn shared_context(&self) -> Option<GLContext> {
292        unsafe {
293            from_glib_none(ffi::gdk_gl_context_get_shared_context(
294                self.as_ref().to_glib_none().0,
295            ))
296        }
297    }
298
299    /// Retrieves the surface used by the @self.
300    ///
301    /// # Returns
302    ///
303    /// a [`Surface`][crate::Surface]
304    #[doc(alias = "gdk_gl_context_get_surface")]
305    #[doc(alias = "get_surface")]
306    fn surface(&self) -> Option<Surface> {
307        unsafe {
308            from_glib_none(ffi::gdk_gl_context_get_surface(
309                self.as_ref().to_glib_none().0,
310            ))
311        }
312    }
313
314    /// Checks whether the @self is using an OpenGL or OpenGL ES profile.
315    ///
316    /// # Returns
317    ///
318    /// [`true`] if the [`GLContext`][crate::GLContext] is using an OpenGL ES profile;
319    /// [`false`] if other profile is in use of if the @self has not yet
320    /// been realized.
321    #[doc(alias = "gdk_gl_context_get_use_es")]
322    #[doc(alias = "get_use_es")]
323    fn uses_es(&self) -> bool {
324        unsafe {
325            from_glib(ffi::gdk_gl_context_get_use_es(
326                self.as_ref().to_glib_none().0,
327            ))
328        }
329    }
330
331    /// Retrieves the OpenGL version of the @self.
332    ///
333    /// The @self must be realized prior to calling this function.
334    ///
335    /// # Returns
336    ///
337    ///
338    /// ## `major`
339    /// return location for the major version
340    ///
341    /// ## `minor`
342    /// return location for the minor version
343    #[doc(alias = "gdk_gl_context_get_version")]
344    #[doc(alias = "get_version")]
345    fn version(&self) -> (i32, i32) {
346        unsafe {
347            let mut major = std::mem::MaybeUninit::uninit();
348            let mut minor = std::mem::MaybeUninit::uninit();
349            ffi::gdk_gl_context_get_version(
350                self.as_ref().to_glib_none().0,
351                major.as_mut_ptr(),
352                minor.as_mut_ptr(),
353            );
354            (major.assume_init(), minor.assume_init())
355        }
356    }
357
358    /// Whether the [`GLContext`][crate::GLContext] is in legacy mode or not.
359    ///
360    /// The [`GLContext`][crate::GLContext] must be realized before calling this function.
361    ///
362    /// When realizing a GL context, GDK will try to use the OpenGL 3.2 core
363    /// profile; this profile removes all the OpenGL API that was deprecated
364    /// prior to the 3.2 version of the specification. If the realization is
365    /// successful, this function will return [`false`].
366    ///
367    /// If the underlying OpenGL implementation does not support core profiles,
368    /// GDK will fall back to a pre-3.2 compatibility profile, and this function
369    /// will return [`true`].
370    ///
371    /// You can use the value returned by this function to decide which kind
372    /// of OpenGL API to use, or whether to do extension discovery, or what
373    /// kind of shader programs to load.
374    ///
375    /// # Returns
376    ///
377    /// [`true`] if the GL context is in legacy mode
378    #[doc(alias = "gdk_gl_context_is_legacy")]
379    fn is_legacy(&self) -> bool {
380        unsafe {
381            from_glib(ffi::gdk_gl_context_is_legacy(
382                self.as_ref().to_glib_none().0,
383            ))
384        }
385    }
386
387    /// Checks if the two GL contexts can share resources.
388    ///
389    /// When they can, the texture IDs from @other can be used in @self. This
390    /// is particularly useful when passing [`GLTexture`][crate::GLTexture] objects between
391    /// different contexts.
392    ///
393    /// Contexts created for the same display with the same properties will
394    /// always be compatible, even if they are created for different surfaces.
395    /// For other contexts it depends on the GL backend.
396    ///
397    /// Both contexts must be realized for this check to succeed. If either one
398    /// is not, this function will return [`false`].
399    /// ## `other`
400    /// the [`GLContext`][crate::GLContext] that should be compatible with @self
401    ///
402    /// # Returns
403    ///
404    /// [`true`] if the two GL contexts are compatible.
405    #[cfg(feature = "v4_4")]
406    #[cfg_attr(docsrs, doc(cfg(feature = "v4_4")))]
407    #[doc(alias = "gdk_gl_context_is_shared")]
408    fn is_shared(&self, other: &impl IsA<GLContext>) -> bool {
409        unsafe {
410            from_glib(ffi::gdk_gl_context_is_shared(
411                self.as_ref().to_glib_none().0,
412                other.as_ref().to_glib_none().0,
413            ))
414        }
415    }
416
417    /// Makes the @self the current one.
418    #[doc(alias = "gdk_gl_context_make_current")]
419    fn make_current(&self) {
420        unsafe {
421            ffi::gdk_gl_context_make_current(self.as_ref().to_glib_none().0);
422        }
423    }
424
425    /// Realizes the given [`GLContext`][crate::GLContext].
426    ///
427    /// It is safe to call this function on a realized [`GLContext`][crate::GLContext].
428    ///
429    /// # Returns
430    ///
431    /// [`true`] if the context is realized
432    #[doc(alias = "gdk_gl_context_realize")]
433    fn realize(&self) -> Result<(), glib::Error> {
434        unsafe {
435            let mut error = std::ptr::null_mut();
436            let is_ok = ffi::gdk_gl_context_realize(self.as_ref().to_glib_none().0, &mut error);
437            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
438            if error.is_null() {
439                Ok(())
440            } else {
441                Err(from_glib_full(error))
442            }
443        }
444    }
445
446    /// Sets the allowed APIs. When gdk_gl_context_realize() is called, only the
447    /// allowed APIs will be tried. If you set this to 0, realizing will always fail.
448    ///
449    /// If you set it on a realized context, the property will not have any effect.
450    /// It is only relevant during gdk_gl_context_realize().
451    ///
452    /// By default, all APIs are allowed.
453    /// ## `apis`
454    /// the allowed APIs
455    #[cfg(feature = "v4_6")]
456    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
457    #[doc(alias = "gdk_gl_context_set_allowed_apis")]
458    #[doc(alias = "allowed-apis")]
459    fn set_allowed_apis(&self, apis: GLAPI) {
460        unsafe {
461            ffi::gdk_gl_context_set_allowed_apis(self.as_ref().to_glib_none().0, apis.into_glib());
462        }
463    }
464
465    /// Sets whether the [`GLContext`][crate::GLContext] should perform extra validations and
466    /// runtime checking.
467    ///
468    /// This is useful during development, but has additional overhead.
469    ///
470    /// The [`GLContext`][crate::GLContext] must not be realized or made current prior to
471    /// calling this function.
472    /// ## `enabled`
473    /// whether to enable debugging in the context
474    #[doc(alias = "gdk_gl_context_set_debug_enabled")]
475    fn set_debug_enabled(&self, enabled: bool) {
476        unsafe {
477            ffi::gdk_gl_context_set_debug_enabled(
478                self.as_ref().to_glib_none().0,
479                enabled.into_glib(),
480            );
481        }
482    }
483
484    /// Sets whether the [`GLContext`][crate::GLContext] should be forward-compatible.
485    ///
486    /// Forward-compatible contexts must not support OpenGL functionality that
487    /// has been marked as deprecated in the requested version; non-forward
488    /// compatible contexts, on the other hand, must support both deprecated and
489    /// non deprecated functionality.
490    ///
491    /// The [`GLContext`][crate::GLContext] must not be realized or made current prior to calling
492    /// this function.
493    /// ## `compatible`
494    /// whether the context should be forward-compatible
495    #[doc(alias = "gdk_gl_context_set_forward_compatible")]
496    fn set_forward_compatible(&self, compatible: bool) {
497        unsafe {
498            ffi::gdk_gl_context_set_forward_compatible(
499                self.as_ref().to_glib_none().0,
500                compatible.into_glib(),
501            );
502        }
503    }
504
505    /// Sets the major and minor version of OpenGL to request.
506    ///
507    /// Setting @major and @minor to zero will use the default values.
508    ///
509    /// Setting @major and @minor lower than the minimum versions required
510    /// by GTK will result in the context choosing the minimum version.
511    ///
512    /// The @self must not be realized or made current prior to calling
513    /// this function.
514    /// ## `major`
515    /// the major version to request
516    /// ## `minor`
517    /// the minor version to request
518    #[doc(alias = "gdk_gl_context_set_required_version")]
519    fn set_required_version(&self, major: i32, minor: i32) {
520        unsafe {
521            ffi::gdk_gl_context_set_required_version(self.as_ref().to_glib_none().0, major, minor);
522        }
523    }
524
525    /// Requests that GDK create an OpenGL ES context instead of an OpenGL one.
526    ///
527    /// Not all platforms support OpenGL ES.
528    ///
529    /// The @self must not have been realized.
530    ///
531    /// By default, GDK will attempt to automatically detect whether the
532    /// underlying GL implementation is OpenGL or OpenGL ES once the @self
533    /// is realized.
534    ///
535    /// You should check the return value of [`uses_es()`][Self::uses_es()]
536    /// after calling [`realize()`][Self::realize()] to decide whether to use
537    /// the OpenGL or OpenGL ES API, extensions, or shaders.
538    /// ## `use_es`
539    /// whether the context should use OpenGL ES instead of OpenGL,
540    ///   or -1 to allow auto-detection
541    #[doc(alias = "gdk_gl_context_set_use_es")]
542    fn set_use_es(&self, use_es: i32) {
543        unsafe {
544            ffi::gdk_gl_context_set_use_es(self.as_ref().to_glib_none().0, use_es);
545        }
546    }
547
548    #[cfg(feature = "v4_6")]
549    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
550    #[doc(alias = "allowed-apis")]
551    fn connect_allowed_apis_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
552        unsafe extern "C" fn notify_allowed_apis_trampoline<
553            P: IsA<GLContext>,
554            F: Fn(&P) + 'static,
555        >(
556            this: *mut ffi::GdkGLContext,
557            _param_spec: glib::ffi::gpointer,
558            f: glib::ffi::gpointer,
559        ) {
560            let f: &F = &*(f as *const F);
561            f(GLContext::from_glib_borrow(this).unsafe_cast_ref())
562        }
563        unsafe {
564            let f: Box_<F> = Box_::new(f);
565            connect_raw(
566                self.as_ptr() as *mut _,
567                b"notify::allowed-apis\0".as_ptr() as *const _,
568                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
569                    notify_allowed_apis_trampoline::<Self, F> as *const (),
570                )),
571                Box_::into_raw(f),
572            )
573        }
574    }
575
576    #[cfg(feature = "v4_6")]
577    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
578    #[doc(alias = "api")]
579    fn connect_api_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
580        unsafe extern "C" fn notify_api_trampoline<P: IsA<GLContext>, F: Fn(&P) + 'static>(
581            this: *mut ffi::GdkGLContext,
582            _param_spec: glib::ffi::gpointer,
583            f: glib::ffi::gpointer,
584        ) {
585            let f: &F = &*(f as *const F);
586            f(GLContext::from_glib_borrow(this).unsafe_cast_ref())
587        }
588        unsafe {
589            let f: Box_<F> = Box_::new(f);
590            connect_raw(
591                self.as_ptr() as *mut _,
592                b"notify::api\0".as_ptr() as *const _,
593                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
594                    notify_api_trampoline::<Self, F> as *const (),
595                )),
596                Box_::into_raw(f),
597            )
598        }
599    }
600}
601
602impl<O: IsA<GLContext>> GLContextExt for O {}