1use std::mem::MaybeUninit;
3
4use libdisplay_info_derive::FFIFrom;
5
6use crate::ffi;
7
8pub const DEFAULT_M: f64 = 600.0;
9pub const DEFAULT_C: f64 = 40.0;
10pub const DEFAULT_K: f64 = 128.0;
11pub const DEFAULT_J: f64 = 20.0;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
15#[ffi(ffi::gtf::di_gtf_ip_param)]
16#[repr(u32)]
17pub enum IpParam {
18 VFrameRate = ffi::gtf::di_gtf_ip_param_DI_GTF_IP_PARAM_V_FRAME_RATE,
20 HFreq = ffi::gtf::di_gtf_ip_param_DI_GTF_IP_PARAM_H_FREQ,
22 HPixels = ffi::gtf::di_gtf_ip_param_DI_GTF_IP_PARAM_H_PIXELS,
24}
25
26#[derive(Debug, Copy, Clone, FFIFrom)]
28#[ffi(ffi::gtf::di_gtf_options)]
29pub struct Options {
30 pub h_pixels: i32,
32 pub v_lines: i32,
34 pub margins_rqd: bool,
36 pub ip_param: IpParam,
38 pub ip_freq_rqd: f64,
40 pub int_rqd: bool,
42 pub m: f64,
44 pub c: f64,
46 pub k: f64,
48 pub j: f64,
50}
51
52#[derive(Debug, Copy, Clone, FFIFrom)]
54#[ffi(ffi::gtf::di_gtf_timing)]
55pub struct Timing {
56 pub h_pixels: i32,
57 pub v_lines: i32,
58 pub h_sync: i32,
59 pub v_sync: i32,
60 pub h_front_porch: i32,
61 pub h_back_porch: i32,
62 pub v_front_porch: i32,
63 pub v_back_porch: i32,
64 pub h_border: i32,
65 pub v_border: i32,
66 pub pixel_freq_mhz: f64,
67}
68
69impl Timing {
70 pub fn compute(options: Options) -> Self {
72 let mut timing = MaybeUninit::<ffi::gtf::di_gtf_timing>::uninit();
73 let options = ffi::gtf::di_gtf_options {
74 h_pixels: options.h_pixels,
75 v_lines: options.v_lines,
76 margins_rqd: options.margins_rqd,
77 ip_param: options.ip_param as u32,
78 ip_freq_rqd: options.ip_freq_rqd,
79 int_rqd: options.int_rqd,
80 m: options.m,
81 c: options.c,
82 k: options.k,
83 j: options.j,
84 };
85 unsafe {
86 ffi::gtf::di_gtf_compute(timing.as_mut_ptr(), &options);
87 }
88 Timing::from(unsafe { timing.assume_init() })
89 }
90}