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 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 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)]
258pub 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
289pub 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 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 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}