ddcutil_sys/
lib.rs

1#![doc(html_root_url = "http://arcnmx.github.io/ddcutil-rs/")]
2#![allow(non_camel_case_types, non_snake_case)]
3
4extern crate libc;
5
6use std::fmt;
7use std::slice::from_raw_parts;
8use libc::{c_char, c_int, c_void};
9
10#[link(name = "ddcutil")]
11extern {
12    pub fn ddca_ddcutil_version() -> DDCA_Ddcutil_Version_Spec;
13    pub fn ddca_ddcutil_version_string() -> *const c_char;
14
15    pub fn ddca_rc_name(status_code: DDCA_Status) -> *mut c_char;
16    pub fn ddca_rc_desc(status_code: DDCA_Status) -> *mut c_char;
17
18    pub fn ddca_mccs_version_id_name(version_id: DDCA_MCCS_Version_Id) -> *mut c_char;
19    pub fn ddca_mccs_version_id_desc(version_id: DDCA_MCCS_Version_Id) -> *mut c_char;
20
21    pub fn ddca_max_max_tries() -> c_int;
22    pub fn ddca_get_max_tries(retry_type: DDCA_Retry_Type) -> c_int;
23    pub fn ddca_set_max_tries(retry_type: DDCA_Retry_Type, max_tries: c_int) -> DDCA_Status;
24
25    pub fn ddca_enable_verify(onoff: bool);
26    pub fn ddca_is_verify_enabled() -> bool;
27
28    pub fn ddca_get_output_level() -> DDCA_Output_Level;
29    pub fn ddca_set_output_level(newval: DDCA_Output_Level);
30    pub fn ddca_enable_report_ddc_errors(onoff: bool);
31    pub fn ddca_is_report_ddc_errors_enabled() -> bool;
32
33    pub fn ddca_get_display_info_list() -> *mut DDCA_Display_Info_List;
34    pub fn ddca_free_display_info_list(dlist: *mut DDCA_Display_Info_List);
35    pub fn ddca_report_display_info(dinfo: *mut DDCA_Display_Info, depth: c_int);
36    pub fn ddca_report_display_info_list(dlist: *mut DDCA_Display_Info_List, depth: c_int);
37    pub fn ddca_report_active_displays(depth: c_int) -> c_int;
38
39    pub fn ddca_open_display(
40        ddca_dref: DDCA_Display_Ref,
41        p_ddca_dh: *mut DDCA_Display_Handle,
42    ) -> DDCA_Status;
43    pub fn ddca_close_display(ddca_dh: DDCA_Display_Handle) -> DDCA_Status;
44
45    pub fn ddca_get_capabilities_string(
46        ddca_dh: DDCA_Display_Handle,
47        p_caps: *mut *mut c_char,
48    ) -> DDCA_Status;
49
50    pub fn ddca_parse_capabilities_string(
51        capabilities_string: *mut c_char,
52        p_parsed_capabilities: *mut *mut DDCA_Capabilities,
53    ) -> DDCA_Status;
54
55    pub fn ddca_free_parsed_capabilities(
56        pcaps: *mut DDCA_Capabilities,
57    );
58
59    pub fn ddca_report_parsed_capabilities(
60        pcaps: *mut DDCA_Capabilities,
61        depth: c_int,
62    );
63
64    pub fn ddca_get_feature_info_by_vcp_version(
65        feature_code: DDCA_Vcp_Feature_Code,
66        mccs_version_id: DDCA_MCCS_Version_Id,
67        p_info: *mut *mut DDCA_Version_Feature_Info,
68    ) -> DDCA_Status;
69
70    pub fn ddca_get_feature_name(feature_code: DDCA_Vcp_Feature_Code) -> *mut c_char;
71
72    pub fn ddca_get_simple_sl_value_table(
73        feature_code: DDCA_Vcp_Feature_Code,
74        mccs_version_id: DDCA_MCCS_Version_Id,
75        p_value_table: *mut DDCA_Feature_Value_Table,
76    ) -> DDCA_Status;
77
78    pub fn ddca_get_simple_nc_feature_value_name(
79        ddca_dh: DDCA_Display_Handle,
80        feature_code: DDCA_Vcp_Feature_Code,
81        feature_value: u8,
82        p_feature_name: *mut *mut c_char,
83    ) -> DDCA_Status;
84
85    pub fn ddca_free_feature_info(info: *mut DDCA_Version_Feature_Info) -> DDCA_Status;
86
87    pub fn ddca_get_mccs_version(
88        ddca_dh: DDCA_Display_Handle,
89        pspec: *mut DDCA_MCCS_Version_Spec,
90    ) -> DDCA_Status;
91
92    pub fn ddca_get_mccs_version_id(
93        ddca_dh: DDCA_Display_Handle,
94        p_id: *mut DDCA_MCCS_Version_Id,
95    ) -> DDCA_Status;
96
97    /// do not free
98    pub fn ddca_get_edid_by_display_ref(
99        ddca_dref: DDCA_Display_Ref,
100        pbytes: *mut *mut u8,
101    ) -> DDCA_Status;
102
103    pub fn ddca_free_table_value_response(
104        table_value_response: *mut DDCA_Table_Value,
105    );
106
107    pub fn ddca_get_any_vcp_value(
108        ddca_dh: DDCA_Display_Handle,
109        feature_code: DDCA_Vcp_Feature_Code,
110        value_type: DDCA_Vcp_Value_Type_Parm,
111        pvalrec: *mut *mut DDCA_Any_Vcp_Value,
112    ) -> DDCA_Status;
113
114    pub fn ddca_set_continuous_vcp_value(
115        ddca_dh: DDCA_Display_Handle,
116        feature_code: DDCA_Vcp_Feature_Code,
117        new_value: c_int,
118    ) -> DDCA_Status;
119
120    pub fn ddca_set_simple_nc_vcp_value(
121        ddca_dh: DDCA_Display_Handle,
122        feature_code: DDCA_Vcp_Feature_Code,
123        new_value: u8,
124    ) -> DDCA_Status;
125
126    pub fn ddca_set_raw_vcp_value(
127        ddca_dh: DDCA_Display_Handle,
128        feature_code: DDCA_Vcp_Feature_Code,
129        hi_byte: u8,
130        lo_byte: u8,
131    ) -> DDCA_Status;
132}
133
134pub type DDCA_Status = c_int;
135
136pub type DDCA_Retry_Type = c_int;
137pub const DDCA_WRITE_ONLY_TRIES: DDCA_Retry_Type = 0;
138pub const DDCA_WRITE_READ_TRIES: DDCA_Retry_Type = 1;
139pub const DDCA_MULTI_PART_TRIES: DDCA_Retry_Type = 2;
140
141pub type DDCA_Output_Level = c_int;
142pub const DDCA_OL_TERSE: DDCA_Output_Level = 0x04;
143pub const DDCA_OL_NORMAL: DDCA_Output_Level = 0x08;
144pub const DDCA_OL_VERBOSE: DDCA_Output_Level = 0x10;
145
146#[repr(C)]
147#[derive(Copy, Clone, Debug)]
148pub struct DDCA_Ddcutil_Version_Spec {
149    pub major: u8,
150    pub minor: u8,
151    pub micro: u8,
152}
153
154pub type DDCA_Display_Identifier = *mut c_void;
155
156pub type DDCA_Display_Ref = *mut c_void;
157
158pub type DDCA_Display_Handle = *mut c_void;
159
160#[repr(C)]
161#[derive(Copy, Clone, Debug)]
162pub struct DDCA_Adlno {
163    pub iAdapterIndex: c_int,
164    pub iDisplayIndex: c_int,
165}
166
167pub type DDCA_IO_Mode = c_int;
168pub const DDCA_IO_DEVI2C: DDCA_IO_Mode = 0;
169pub const DDCA_IO_ADL: DDCA_IO_Mode = 1;
170pub const DDCA_IO_USB: DDCA_IO_Mode = 2;
171
172#[repr(C)]
173#[derive(Copy, Clone, Debug)]
174pub struct DDCA_IO_Path {
175    pub io_mode: DDCA_IO_Mode,
176    // union { i2c_busno: c_int, adlno: DDCA_Adlno: adlno, hiddev_devno: c_int }
177    pub _union: DDCA_Adlno,
178}
179
180impl DDCA_IO_Path {
181    pub fn i2c_busno(&self) -> c_int {
182        self._union.iAdapterIndex
183    }
184
185    pub fn hiddev_devno(&self) -> c_int {
186        self._union.iAdapterIndex
187    }
188
189    pub fn adlno(&self) -> &DDCA_Adlno {
190        &self._union
191    }
192}
193
194#[repr(C)]
195#[derive(Debug, Copy, Clone)]
196pub struct DDCA_Display_Info {
197    pub marker: [c_char; 4],
198    pub dispno: c_int,
199    pub path: DDCA_IO_Path,
200    pub usb_bus: c_int,
201    pub usb_device: c_int,
202    pub mfg_id: *const c_char,
203    pub model_name: *const c_char,
204    pub sn: *const c_char,
205    pub edid_bytes: *const u8,
206    pub dref: DDCA_Display_Ref,
207}
208
209impl DDCA_Display_Info {
210    pub fn edid_bytes(&self) -> &[u8] {
211        unsafe {
212            from_raw_parts(self.edid_bytes, 0x80)
213        }
214    }
215}
216
217#[repr(C)]
218pub struct DDCA_Display_Info_List {
219    pub ct: c_int,
220    pub info: [DDCA_Display_Info; 0],
221}
222
223impl DDCA_Display_Info_List {
224    pub fn info(&self) -> &[DDCA_Display_Info] {
225        unsafe {
226            from_raw_parts(self.info.as_ptr(), self.ct as usize)
227        }
228    }
229}
230
231impl fmt::Debug for DDCA_Display_Info_List {
232    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233        fmt::Debug::fmt(self.info(), f)
234    }
235}
236
237#[repr(C)]
238#[derive(Copy, Clone, Debug)]
239pub struct DDCA_MCCS_Version_Spec {
240    pub major: u8,
241    pub minor: u8,
242}
243
244pub type DDCA_MCCS_Version_Id = c_int;
245pub const DDCA_VNONE: DDCA_MCCS_Version_Id = 0;
246pub const DDCA_V10: DDCA_MCCS_Version_Id = 1;
247pub const DDCA_V20: DDCA_MCCS_Version_Id = 2;
248pub const DDCA_V21: DDCA_MCCS_Version_Id = 4;
249pub const DDCA_V30: DDCA_MCCS_Version_Id = 8;
250pub const DDCA_V22: DDCA_MCCS_Version_Id = 16;
251pub const DDCA_VANY: DDCA_MCCS_Version_Id = DDCA_VNONE;
252pub const DDCA_VUNK: DDCA_MCCS_Version_Id = DDCA_VNONE;
253
254pub type DDCA_Vcp_Feature_Code = u8;
255
256#[repr(C)]
257#[derive(Copy, Clone, Debug)]
258/// an entry of {0, NULL} terminates the list
259pub struct DDCA_Feature_Value_Entry {
260    pub value_code: u8,
261    pub value_name: *mut c_char,
262}
263
264pub type DDCA_Feature_Value_Table = *mut DDCA_Feature_Value_Entry;
265
266pub type DDCA_Version_Feature_Flags = u16;
267pub const DDCA_RO: DDCA_Version_Feature_Flags = 0x0400;
268pub const DDCA_WO: DDCA_Version_Feature_Flags = 0x0200;
269pub const DDCA_RW: DDCA_Version_Feature_Flags = 0x0100;
270pub const DDCA_READABLE: DDCA_Version_Feature_Flags = DDCA_RO | DDCA_RW;
271pub const DDCA_WRITABLE: DDCA_Version_Feature_Flags = DDCA_WO | DDCA_RW;
272pub const DDCA_STD_CONT: DDCA_Version_Feature_Flags = 0x0080;
273pub const DDCA_COMPLEX_CONT: DDCA_Version_Feature_Flags = 0x0040;
274pub const DDCA_SIMPLE_NC: DDCA_Version_Feature_Flags = 0x0020;
275pub const DDCA_COMPLEX_NC: DDCA_Version_Feature_Flags = 0x0010;
276pub const DDCA_WO_NC: DDCA_Version_Feature_Flags = 0x0008;
277pub const DDCA_NORMAL_TABLE: DDCA_Version_Feature_Flags = 0x0004;
278pub const DDCA_WO_TABLE: DDCA_Version_Feature_Flags = 0x0002;
279pub const DDCA_CONT: DDCA_Version_Feature_Flags = DDCA_STD_CONT|DDCA_COMPLEX_CONT;
280pub const DDCA_NC: DDCA_Version_Feature_Flags = DDCA_SIMPLE_NC|DDCA_COMPLEX_NC|DDCA_WO_NC;
281pub const DDCA_NON_TABLE: DDCA_Version_Feature_Flags = DDCA_CONT | DDCA_NC;
282pub const DDCA_TABLE: DDCA_Version_Feature_Flags = DDCA_NORMAL_TABLE | DDCA_WO_TABLE;
283pub const DDCA_KNOWN: DDCA_Version_Feature_Flags = DDCA_CONT | DDCA_NC | DDCA_TABLE;
284pub const DDCA_DEPRECATED: DDCA_Version_Feature_Flags = 0x0001;
285
286pub type DDCA_Global_Feature_Flags = u16;
287pub const DDCA_SYNTHETIC: DDCA_Global_Feature_Flags = 0x8000;
288
289/// union (DDCA_Version_Feature_Flags, DDCA_Global_Feature_Flags)
290pub type DDCA_Feature_Flags = u16;
291
292#[repr(C)]
293#[derive(Copy, Clone, Debug)]
294pub struct DDCA_Version_Feature_Info {
295    pub marker: [c_char; 4],
296    pub feature_code: DDCA_Vcp_Feature_Code,
297    pub vspec: DDCA_MCCS_Version_Spec,
298    pub version_id: DDCA_MCCS_Version_Id,
299    pub desc: *mut c_char,
300    /// valid when DDCA_SIMPLE_NC set
301    pub sl_values: DDCA_Feature_Value_Table,
302    pub feature_name: *mut c_char,
303    pub feature_flags: DDCA_Feature_Flags,
304}
305
306impl DDCA_Version_Feature_Info {
307    pub fn sl_values_len(&self) -> usize {
308        if self.feature_flags & DDCA_SIMPLE_NC != 0 {
309            let mut ptr = self.sl_values;
310            let mut len = 0;
311            unsafe {
312                while (*ptr).value_code != 0 || !(*ptr).value_name.is_null() {
313                    ptr = ptr.offset(1);
314                    len += 1;
315                }
316            }
317
318            len
319        } else {
320            0
321        }
322    }
323
324    pub fn sl_values(&self) -> &[DDCA_Feature_Value_Entry] {
325        let len = self.sl_values_len();
326        if len == 0 {
327            &[]
328        } else {
329            unsafe {
330                from_raw_parts(self.sl_values as *const _, len)
331            }
332        }
333    }
334}
335
336#[repr(C)]
337#[derive(Copy, Clone, Debug)]
338pub struct DDCA_Cap_Vcp {
339    pub marker: [c_char; 4],
340    pub feature_code: DDCA_Vcp_Feature_Code,
341    pub value_ct: c_int,
342    pub values: *mut u8,
343}
344
345impl DDCA_Cap_Vcp {
346    pub fn values(&self) -> &[u8] {
347        unsafe {
348            from_raw_parts(self.values as *const _, self.value_ct as usize)
349        }
350    }
351}
352
353#[repr(C)]
354#[derive(Copy, Clone, Debug)]
355pub struct DDCA_Capabilities {
356    pub marker: [c_char; 4],
357    pub unparsed_string: *mut c_char,
358    pub version_spec: DDCA_MCCS_Version_Spec,
359    pub vcp_code_ct: c_int,
360    pub vcp_codes: *mut DDCA_Cap_Vcp,
361}
362
363impl DDCA_Capabilities {
364    pub fn vcp_codes(&self) -> &[DDCA_Cap_Vcp] {
365        unsafe {
366            from_raw_parts(self.vcp_codes as *const _, self.vcp_code_ct as usize)
367        }
368    }
369}
370
371pub type DDCA_Vcp_Value_Type = c_int;
372pub const DDCA_NON_TABLE_VCP_VALUE: DDCA_Vcp_Value_Type = 1;
373pub const DDCA_TABLE_VCP_VALUE: DDCA_Vcp_Value_Type = 2;
374
375pub type DDCA_Vcp_Value_Type_Parm = c_int;
376pub const DDCA_UNSET_VCP_VALUE_TYPE_PARM: DDCA_Vcp_Value_Type_Parm = 0;
377pub const DDCA_NON_TABLE_VCP_VALUE_PARM: DDCA_Vcp_Value_Type_Parm = 1;
378pub const DDCA_TABLE_VCP_VALUE_PARM: DDCA_Vcp_Value_Type_Parm = 2;
379
380#[repr(C)]
381#[derive(Copy, Clone, Debug)]
382pub struct DDCA_Non_Table_Value {
383    pub mh: u8,
384    pub ml: u8,
385    pub sh: u8,
386    pub sl: u8,
387}
388
389impl DDCA_Non_Table_Value {
390    pub fn value(&self) -> u16 {
391        ((self.sh as u16) << 8) | self.sl as u16
392    }
393
394    pub fn maximum(&self) -> u16 {
395        ((self.mh as u16) << 8) | self.ml as u16
396    }
397}
398
399#[repr(C)]
400pub struct DDCA_Table_Value {
401    pub bytect: u16,
402    pub bytes: [u8; 0],
403}
404
405#[repr(C)]
406#[derive(Copy, Clone)]
407pub struct _DDCA_Table_Value {
408    pub bytes: *mut u8,
409    pub bytect: u16,
410}
411
412impl _DDCA_Table_Value {
413    pub fn bytes(&self) -> &[u8] {
414        unsafe {
415            from_raw_parts(self.bytes as *const _, self.bytect as usize)
416        }
417    }
418}
419
420impl fmt::Debug for _DDCA_Table_Value {
421    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
422        fmt::Debug::fmt(self.bytes(), f)
423    }
424}
425
426#[repr(C)]
427#[derive(Copy, Clone, Debug)]
428pub struct DDCA_Any_Vcp_Value {
429    pub opcode: DDCA_Vcp_Feature_Code,
430    pub value_type: DDCA_Vcp_Value_Type,
431    // union { _DDCA_Table_Value, DDCA_Non_Table_Value }
432    pub _val_union: _DDCA_Table_Value,
433}
434
435impl DDCA_Any_Vcp_Value {
436    pub unsafe fn c_nc(&self) -> &DDCA_Non_Table_Value {
437        ::std::mem::transmute(self.t())
438    }
439
440    pub unsafe fn t(&self) -> &_DDCA_Table_Value {
441        &self._val_union
442    }
443}