1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
//! EGL utilities
//!
//! This module contains bindings to the `libwayland-egl.so` library.
//!
//! This library is used to interface with the OpenGL stack, and creating
//! EGL surfaces from a wayland surface.
//!
//! See WlEglSurface documentation for details.
use std::os::raw::c_void;
use wayland_client::protocol::wl_surface::WlSurface;
use wayland_sys::{client::wl_proxy, egl::*, ffi_dispatch};
/// Checks if the wayland-egl lib is available and can be used
///
/// Trying to create an `WlEglSurface` while this function returns
/// `false` will result in a panic.
pub fn is_available() -> bool {
is_lib_available()
}
unsafe impl Send for WlEglSurface {}
unsafe impl Sync for WlEglSurface {}
/// EGL surface
///
/// This object is a simple wrapper around a `WlSurface` to add the EGL
/// capabilities. Just use the `ptr` method once this object is created
/// to get the window pointer your OpenGL library is needing to initialize the
/// EGL context (you'll most likely need the display ptr as well, that you can
/// get via the `ptr` method of the `Proxy` trait on the `WlDisplay` object).
pub struct WlEglSurface {
ptr: *mut wl_egl_window,
}
impl WlEglSurface {
/// Create an EGL surface from a wayland surface
pub fn new(surface: &WlSurface, width: i32, height: i32) -> WlEglSurface {
unsafe { WlEglSurface::new_from_raw(surface.as_ref().c_ptr(), width, height) }
}
/// Create an EGL surface from a raw pointer to a wayland surface
///
/// # Safety
///
/// The provided pointer must be a valid `wl_surface` pointer from `libwayland-client`.
pub unsafe fn new_from_raw(surface: *mut wl_proxy, width: i32, height: i32) -> WlEglSurface {
let ptr = ffi_dispatch!(WAYLAND_EGL_HANDLE, wl_egl_window_create, surface, width, height);
WlEglSurface { ptr }
}
/// Fetch current size of the EGL surface
pub fn get_size(&self) -> (i32, i32) {
let mut w = 0i32;
let mut h = 0i32;
unsafe {
ffi_dispatch!(
WAYLAND_EGL_HANDLE,
wl_egl_window_get_attached_size,
self.ptr,
&mut w as *mut i32,
&mut h as *mut i32
);
}
(w, h)
}
/// Resize the EGL surface
///
/// The two first arguments `(width, height)` are the new size of
/// the surface, the two others `(dx, dy)` represent the displacement
/// of the top-left corner of the surface. It allows you to control the
/// direction of the resizing if necessary.
pub fn resize(&self, width: i32, height: i32, dx: i32, dy: i32) {
unsafe {
ffi_dispatch!(WAYLAND_EGL_HANDLE, wl_egl_window_resize, self.ptr, width, height, dx, dy)
}
}
/// Raw pointer to the EGL surface
///
/// You'll need this pointer to initialize the EGL context in your
/// favourite OpenGL lib.
pub fn ptr(&self) -> *const c_void {
self.ptr as *const c_void
}
}
impl Drop for WlEglSurface {
fn drop(&mut self) {
unsafe {
ffi_dispatch!(WAYLAND_EGL_HANDLE, wl_egl_window_destroy, self.ptr);
}
}
}