libdisplay_info/
cvt.rs

1//! Low-level API for VESA Coordinated Video Timings (CVT) version 2.0.
2use std::mem::MaybeUninit;
3
4use libdisplay_info_derive::FFIFrom;
5
6use crate::ffi;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
9#[ffi(ffi::cvt::di_cvt_reduced_blanking_version)]
10#[repr(u32)]
11pub enum ReducedBlankingVersion {
12    None = ffi::cvt::di_cvt_reduced_blanking_version_DI_CVT_REDUCED_BLANKING_NONE,
13    V1 = ffi::cvt::di_cvt_reduced_blanking_version_DI_CVT_REDUCED_BLANKING_V1,
14    V2 = ffi::cvt::di_cvt_reduced_blanking_version_DI_CVT_REDUCED_BLANKING_V2,
15    V3 = ffi::cvt::di_cvt_reduced_blanking_version_DI_CVT_REDUCED_BLANKING_V3,
16}
17
18/// Input parameters, defined in table 3-1.
19#[derive(Debug, Copy, Clone, FFIFrom)]
20#[ffi(ffi::cvt::di_cvt_options)]
21pub struct Options {
22    pub red_blank_ver: ReducedBlankingVersion,
23    pub h_pixels: i32,
24    pub v_lines: i32,
25    pub ip_freq_rqd: f64,
26    pub video_opt: bool,
27    pub vblank: f64,
28    pub additional_hblank: i32,
29    pub early_vsync_rqd: bool,
30    pub int_rqd: bool,
31    pub margins_rqd: bool,
32}
33
34/// Output parameters, defined in table 3-4.
35#[derive(Debug, Copy, Clone, FFIFrom)]
36#[ffi(ffi::cvt::di_cvt_timing)]
37pub struct Timing {
38    pub act_pixel_freq: f64,
39    pub total_active_pixels: f64,
40    pub v_lines_rnd: f64,
41    pub h_front_porch: f64,
42    pub h_sync: f64,
43    pub h_back_porch: f64,
44    pub v_front_porch: f64,
45    pub v_sync: f64,
46    pub v_back_porch: f64,
47    pub act_frame_rate: f64,
48}
49
50impl Timing {
51    /// Compute a timing via the CVT formula.
52    pub fn compute(options: Options) -> Self {
53        let mut timing = MaybeUninit::<ffi::cvt::di_cvt_timing>::uninit();
54        let options = ffi::cvt::di_cvt_options {
55            red_blank_ver: options.red_blank_ver as u32,
56            h_pixels: options.h_pixels,
57            v_lines: options.v_lines,
58            ip_freq_rqd: options.ip_freq_rqd,
59            video_opt: options.video_opt,
60            vblank: options.vblank,
61            additional_hblank: options.additional_hblank,
62            early_vsync_rqd: options.early_vsync_rqd,
63            int_rqd: options.int_rqd,
64            margins_rqd: options.margins_rqd,
65        };
66        unsafe { ffi::cvt::di_cvt_compute(timing.as_mut_ptr(), &options) };
67        Timing::from(unsafe { timing.assume_init() })
68    }
69}