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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use libc::{c_void, uint32_t, uintptr_t};
use std::mem;
use super::types::{Geometry};
pub const BITS_PER_PIXEL: u32 = 32;
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum wlc_pixel_format {
WLC_RGBA8888
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum wlc_renderer {
WLC_RENDERER_GLES2,
WLC_NO_RENDERER
}
#[allow(missing_docs)]
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum wlc_surface_format {
SURFACE_RGB,
SURFACE_RGBA,
SURFACE_EGL,
SURFACE_Y_UV,
SURFACE_Y_U_V,
SURFACE_Y_XUXV,
}
#[cfg_attr(feature = "static-wlc", link(name = "wlc", kind = "static"))]
#[cfg_attr(not(feature = "static-wlc"), link(name = "wlc"))]
extern "C" {
pub fn wlc_pixels_write(format: wlc_pixel_format, geometry: *const Geometry, data: *const c_void);
pub fn wlc_pixels_read(format: wlc_pixel_format,
geometry: *const Geometry,
out_geo: *mut Geometry,
data: *mut c_void);
pub fn wlc_surface_render(surface: uintptr_t, geometry: *const Geometry);
pub fn wlc_output_schedule_render(output: uintptr_t) -> wlc_renderer;
pub fn wlc_surface_flush_frame_callbacks(surface: uintptr_t);
pub fn wlc_output_get_renderer(output: uintptr_t) -> wlc_renderer;
pub fn wlc_surface_get_textures(surface: uintptr_t,
out_textures: *mut uint32_t,
out_format: *mut wlc_surface_format) -> bool;
pub fn wlc_output_set_gamma(output: uintptr_t,
size: u16,
red: *mut u16,
green: *mut u16,
blue: *mut u16);
pub fn wlc_output_get_gamma_size(output: uintptr_t) -> u16 ;
}
pub fn write_pixels(format: wlc_pixel_format, geometry: Geometry, data: &[u8]) {
unsafe {
let data = data as *const _ as *const c_void;
wlc_pixels_write(format, &geometry as *const Geometry, data);
}
}
pub fn read_pixels(format: wlc_pixel_format, mut geometry: Geometry) -> ([u8; 9], Vec<u8>) {
let data_size = (geometry.size.w * geometry.size.h * 4) as usize;
let header_size = 9;
let mut in_buf: Vec<u8> = Vec::with_capacity(header_size + data_size);
let in_buf_ptr = in_buf.as_mut_ptr();
mem::forget(in_buf);
let mut out_buf = unsafe {
let mut out_geo = Geometry::zero();
wlc_pixels_read(format,
&mut geometry as *mut _,
&mut out_geo as *mut _,
in_buf_ptr as *mut c_void);
let size = header_size +
out_geo.size.w as usize * out_geo.size.h as usize * 4;
Vec::from_raw_parts(in_buf_ptr, size, size)
};
let mut header_response = [0u8; 9];
let response: Vec<u8> = out_buf.drain(0..9).collect();
header_response.copy_from_slice(response.as_slice());
(header_response, out_buf)
}
pub fn calculate_stride(width: u32) -> u32 {
let stride_alignment = ::std::mem::size_of::<u32>() as u32;
((BITS_PER_PIXEL * width + 7 ) / 8 + (stride_alignment - 1)) & (stride_alignment.overflowing_neg().0)
}