ove/
bindings_stub.rs

1// Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4//
5// This file is part of oveRTOS.
6
7//! Stub FFI bindings for docs.rs builds.
8//!
9//! This file is used in place of the bindgen-generated `ove_bindings.rs`
10//! when building documentation on docs.rs (detected via `DOCS_RS` env var
11//! and the `docsrs` cfg flag). It declares all types, constants, and
12//! `extern "C"` function signatures used by the Rust wrappers so that
13//! `cargo doc` succeeds without a real C toolchain or LVGL headers.
14
15#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, dead_code)]
16
17use core::ffi::c_void;
18
19// ---------------------------------------------------------------------------
20// Primitive aliases
21// ---------------------------------------------------------------------------
22
23pub type c_int   = i32;
24pub type c_uint  = u32;
25pub type c_ulong = u64;
26
27// ---------------------------------------------------------------------------
28// Error codes
29// ---------------------------------------------------------------------------
30
31pub const OVE_OK:                i32 = 0;
32pub const OVE_ERR_NOT_REGISTERED: i32 = -1;
33pub const OVE_ERR_INVALID_PARAM: i32 = -2;
34pub const OVE_ERR_NO_MEMORY:     i32 = -3;
35pub const OVE_ERR_TIMEOUT:       i32 = -4;
36pub const OVE_ERR_NOT_SUPPORTED: i32 = -5;
37pub const OVE_ERR_QUEUE_FULL:    i32 = -6;
38pub const OVE_ERR_ML_FAILED:    i32 = -7;
39pub const OVE_ERR_NET_REFUSED:  i32 = -8;
40pub const OVE_ERR_NET_UNREACHABLE: i32 = -9;
41pub const OVE_ERR_NET_ADDR_IN_USE: i32 = -10;
42pub const OVE_ERR_NET_RESET:    i32 = -11;
43pub const OVE_ERR_NET_DNS_FAIL: i32 = -12;
44pub const OVE_ERR_NET_CLOSED:   i32 = -13;
45pub const OVE_ERR_BUS_NACK:     i32 = -14;
46pub const OVE_ERR_BUS_BUSY:     i32 = -15;
47pub const OVE_ERR_BUS_ERROR:    i32 = -16;
48
49pub const OVE_WAIT_FOREVER: u32 = u32::MAX;
50
51// ---------------------------------------------------------------------------
52// Thread state constants
53// ---------------------------------------------------------------------------
54
55pub const OVE_THREAD_STATE_RUNNING:    u32 = 0;
56pub const OVE_THREAD_STATE_READY:      u32 = 1;
57pub const OVE_THREAD_STATE_BLOCKED:    u32 = 2;
58pub const OVE_THREAD_STATE_SUSPENDED:  u32 = 3;
59pub const OVE_THREAD_STATE_TERMINATED: u32 = 4;
60pub const OVE_THREAD_STATE_UNKNOWN:    u32 = 5;
61
62// ---------------------------------------------------------------------------
63// Thread priority constants
64// ---------------------------------------------------------------------------
65
66pub const OVE_PRIO_IDLE:         u32 = 0;
67pub const OVE_PRIO_LOW:          u32 = 1;
68pub const OVE_PRIO_BELOW_NORMAL: u32 = 2;
69pub const OVE_PRIO_NORMAL:       u32 = 3;
70pub const OVE_PRIO_ABOVE_NORMAL: u32 = 4;
71pub const OVE_PRIO_HIGH:         u32 = 5;
72pub const OVE_PRIO_REALTIME:     u32 = 6;
73pub const OVE_PRIO_CRITICAL:     u32 = 7;
74
75// ---------------------------------------------------------------------------
76// Filesystem flags
77// ---------------------------------------------------------------------------
78
79pub const OVE_FS_O_READ:   u32 = 0x01;
80pub const OVE_FS_O_WRITE:  u32 = 0x02;
81pub const OVE_FS_O_CREATE: u32 = 0x04;
82pub const OVE_FS_O_APPEND: u32 = 0x08;
83
84pub const OVE_FS_SEEK_SET: u32 = 0;
85pub const OVE_FS_SEEK_CUR: u32 = 1;
86pub const OVE_FS_SEEK_END: u32 = 2;
87
88// ---------------------------------------------------------------------------
89// Event group flags
90// ---------------------------------------------------------------------------
91
92pub const OVE_EG_WAIT_ALL:      u32 = 0x01;
93pub const OVE_EG_CLEAR_ON_EXIT: u32 = 0x02;
94
95// ---------------------------------------------------------------------------
96// Opaque handle types
97// ---------------------------------------------------------------------------
98
99pub type ove_thread_t     = *mut c_void;
100pub type ove_mutex_t      = *mut c_void;
101pub type ove_sem_t        = *mut c_void;
102pub type ove_event_t      = *mut c_void;
103pub type ove_condvar_t    = *mut c_void;
104pub type ove_eventgroup_t = *mut c_void;
105pub type ove_workqueue_t  = *mut c_void;
106pub type ove_work_t       = *mut c_void;
107pub type ove_stream_t     = *mut c_void;
108pub type ove_watchdog_t   = *mut c_void;
109pub type ove_file_t       = *mut c_void;
110pub type ove_dir_t        = *mut c_void;
111pub type ove_queue_t      = *mut c_void;
112pub type ove_timer_t      = *mut c_void;
113pub type ove_model_t      = *mut c_void;
114pub type ove_netif_t      = *mut c_void;
115pub type ove_socket_t     = *mut c_void;
116pub type ove_http_client_t = *mut c_void;
117pub type ove_mqtt_client_t = *mut c_void;
118pub type ove_tls_t        = *mut c_void;
119pub type ove_uart_t       = *mut c_void;
120pub type ove_spi_t        = *mut c_void;
121pub type ove_i2c_t        = *mut c_void;
122pub type ove_i2s_t        = *mut c_void;
123
124pub type ove_eventbits_t = u32;
125
126// ---------------------------------------------------------------------------
127// Storage types — opaque blobs large enough for any backend
128// ---------------------------------------------------------------------------
129
130#[repr(C)]
131pub struct ove_mutex_storage_t      { _opaque: [u8; 256] }
132#[repr(C)]
133pub struct ove_sem_storage_t        { _opaque: [u8; 256] }
134#[repr(C)]
135pub struct ove_event_storage_t      { _opaque: [u8; 256] }
136#[repr(C)]
137pub struct ove_condvar_storage_t    { _opaque: [u8; 256] }
138#[repr(C)]
139pub struct ove_thread_storage_t     { _opaque: [u8; 256] }
140#[repr(C)]
141pub struct ove_queue_storage_t      { _opaque: [u8; 256] }
142#[repr(C)]
143pub struct ove_timer_storage_t      { _opaque: [u8; 256] }
144#[repr(C)]
145pub struct ove_eventgroup_storage_t { _opaque: [u8; 256] }
146#[repr(C)]
147pub struct ove_workqueue_storage_t  { _opaque: [u8; 256] }
148#[repr(C)]
149pub struct ove_work_storage_t       { _opaque: [u8; 256] }
150#[repr(C)]
151pub struct ove_stream_storage_t     { _opaque: [u8; 256] }
152#[repr(C)]
153pub struct ove_watchdog_storage_t   { _opaque: [u8; 256] }
154#[repr(C)]
155pub struct ove_file_storage_t       { _opaque: [u8; 256] }
156#[repr(C)]
157pub struct ove_dir_storage_t        { _opaque: [u8; 256] }
158#[repr(C)]
159pub struct ove_model_storage_t      { _opaque: [u8; 256] }
160#[repr(C)]
161pub struct ove_netif_storage_t      { _opaque: [u8; 256] }
162#[repr(C)]
163pub struct ove_socket_storage_t     { _opaque: [u8; 256] }
164#[repr(C)]
165pub struct ove_http_client_storage_t { _opaque: [u8; 256] }
166#[repr(C)]
167pub struct ove_mqtt_client_storage_t { _opaque: [u8; 256] }
168#[repr(C)]
169pub struct ove_tls_storage_t        { _opaque: [u8; 256] }
170
171// ---------------------------------------------------------------------------
172// Networking types
173// ---------------------------------------------------------------------------
174
175#[repr(C)]
176#[derive(Clone, Copy)]
177pub struct ove_sockaddr_t {
178    pub family: u8,
179    pub port: u16,
180    pub addr: [u8; 16],
181}
182
183#[repr(C)]
184pub struct ove_netif_config_t {
185    pub use_dhcp: core::ffi::c_int,
186    pub static_ip: ove_sockaddr_t,
187    pub gateway: ove_sockaddr_t,
188    pub netmask: ove_sockaddr_t,
189    pub dns: ove_sockaddr_t,
190}
191
192pub type ove_http_method_t = u32;
193pub const OVE_HTTP_GET: ove_http_method_t = 0;
194pub const OVE_HTTP_POST: ove_http_method_t = 1;
195pub const OVE_HTTP_PUT: ove_http_method_t = 2;
196pub const OVE_HTTP_DELETE: ove_http_method_t = 3;
197pub const OVE_HTTP_PATCH: ove_http_method_t = 4;
198
199#[repr(C)]
200pub struct ove_http_response_t {
201    pub status: i32,
202    pub body: *mut core::ffi::c_char,
203    pub body_len: usize,
204    pub headers: *mut core::ffi::c_char,
205    pub headers_len: usize,
206}
207
208#[repr(C)]
209pub struct ove_http_header_t {
210    pub name: *const core::ffi::c_char,
211    pub value: *const core::ffi::c_char,
212}
213
214pub type ove_mqtt_qos_t = u32;
215pub const OVE_MQTT_QOS0: ove_mqtt_qos_t = 0;
216pub const OVE_MQTT_QOS1: ove_mqtt_qos_t = 1;
217
218#[repr(C)]
219pub struct ove_mqtt_config_t {
220    pub host: *const core::ffi::c_char,
221    pub port: u16,
222    pub client_id: *const core::ffi::c_char,
223    pub username: *const core::ffi::c_char,
224    pub password: *const core::ffi::c_char,
225    pub keep_alive_s: u16,
226    pub use_tls: core::ffi::c_int,
227    pub on_message: Option<unsafe extern "C" fn(*const core::ffi::c_char, usize, *const c_void, usize, *mut c_void)>,
228    pub user_data: *mut c_void,
229}
230
231pub type ove_httpd_handler_t = Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> core::ffi::c_int>;
232pub type ove_httpd_req_t = c_void;
233pub type ove_httpd_resp_t = c_void;
234pub type ove_httpd_ws_handler_t = Option<unsafe extern "C" fn(*mut c_void, *const c_void, usize) -> core::ffi::c_int>;
235pub type ove_httpd_ws_close_handler_t = Option<unsafe extern "C" fn(*mut c_void)>;
236pub type ove_httpd_ws_conn_t = c_void;
237
238#[repr(C)]
239pub struct ove_tls_config_t {
240    pub ca_cert: *const u8,
241    pub ca_cert_len: usize,
242    pub hostname: *const core::ffi::c_char,
243}
244
245#[repr(C)]
246pub struct ove_model_config {
247    pub model_data: *const u8,
248    pub model_size: usize,
249    pub arena_size: usize,
250}
251
252// ---------------------------------------------------------------------------
253// GPIO IRQ mode
254// ---------------------------------------------------------------------------
255
256pub type ove_gpio_irq_mode_t = u32;
257
258// ---------------------------------------------------------------------------
259// PM types
260// ---------------------------------------------------------------------------
261
262pub type ove_pm_state_t = u32;
263pub type ove_pm_wake_type_t = u32;
264pub type ove_pm_domain_t = u32;
265pub type ove_pm_event_t = u32;
266
267pub type ove_pm_policy_fn = Option<unsafe extern "C" fn(ove_pm_state_t, u32, *mut c_void) -> ove_pm_state_t>;
268pub type ove_pm_notify_fn = Option<unsafe extern "C" fn(ove_pm_event_t, ove_pm_state_t, ove_pm_state_t, *mut c_void)>;
269
270#[repr(C)]
271pub struct ove_pm_cfg {
272    pub idle_threshold_ms: u32,
273    pub standby_threshold_ms: u32,
274    pub deep_sleep_threshold_ms: u32,
275}
276
277#[repr(C)]
278pub struct ove_pm_wake_src {
279    pub type_: ove_pm_wake_type_t,
280    pub __bindgen_anon_1: ove_pm_wake_src__anon,
281}
282
283#[repr(C)]
284pub union ove_pm_wake_src__anon {
285    pub gpio: ove_pm_wake_src__gpio,
286    pub timer: ove_pm_wake_src__timer,
287    pub uart: ove_pm_wake_src__uart,
288    pub rtc: ove_pm_wake_src__rtc,
289}
290
291#[repr(C)]
292#[derive(Clone, Copy)]
293pub struct ove_pm_wake_src__gpio {
294    pub port: u32,
295    pub pin: u32,
296    pub edge: ove_gpio_irq_mode_t,
297}
298
299#[repr(C)]
300#[derive(Clone, Copy)]
301pub struct ove_pm_wake_src__timer {
302    pub timeout_ms: u32,
303}
304
305#[repr(C)]
306#[derive(Clone, Copy)]
307pub struct ove_pm_wake_src__uart {
308    pub instance: u32,
309}
310
311#[repr(C)]
312#[derive(Clone, Copy)]
313pub struct ove_pm_wake_src__rtc {
314    pub alarm_ms: u32,
315}
316
317#[repr(C)]
318pub struct ove_pm_stats {
319    pub current_state: ove_pm_state_t,
320    pub time_in_state_ms: [u64; 4],
321    pub transition_count: [u32; 4],
322    pub total_runtime_ms: u64,
323}
324
325// ---------------------------------------------------------------------------
326// Bus driver types
327// ---------------------------------------------------------------------------
328
329#[repr(C)]
330pub struct ove_spi_cs {
331    pub port: u32,
332    pub pin: u32,
333    pub active_low: i32,
334}
335
336#[repr(C)]
337pub struct ove_spi_xfer {
338    pub tx:  *const c_void,
339    pub rx:  *mut c_void,
340    pub len: usize,
341}
342
343// ---------------------------------------------------------------------------
344// Struct types
345// ---------------------------------------------------------------------------
346
347#[repr(C)]
348pub struct ove_thread_stats {
349    pub runtime_us:       u64,
350    pub cpu_percent_x100: u32,
351}
352
353#[repr(C)]
354pub struct ove_thread_desc {
355    pub name:       *const core::ffi::c_char,
356    pub entry:      Option<unsafe extern "C" fn(*mut c_void)>,
357    pub arg:        *mut c_void,
358    pub priority:   u32,
359    pub stack_size: usize,
360    pub stack:      *mut c_void,
361}
362
363#[repr(C)]
364pub struct ove_dirent {
365    pub name:   [core::ffi::c_char; 256],
366    pub size:   u32,
367    pub is_dir: i32,
368}
369
370#[repr(C)]
371pub struct ove_audio_fmt {
372    pub sample_rate: u32,
373    pub channels:    u32,
374    pub sample_fmt:  u32,
375}
376
377#[repr(C)]
378pub struct ove_audio_buf {
379    pub data:   *mut c_void,
380    pub frames: u32,
381    pub fmt:    *const ove_audio_fmt,
382}
383
384#[repr(C)]
385#[derive(Debug, Clone, Copy, PartialEq, Eq)]
386pub enum ove_audio_node_type {
387    OVE_AUDIO_NODE_SOURCE    = 0,
388    OVE_AUDIO_NODE_PROCESSOR = 1,
389    OVE_AUDIO_NODE_SINK      = 2,
390}
391
392#[repr(C)]
393pub struct ove_audio_node_ops {
394    pub configure: Option<unsafe extern "C" fn(*mut c_void, *const ove_audio_fmt, *mut ove_audio_fmt) -> i32>,
395    pub start:     Option<unsafe extern "C" fn(*mut c_void) -> i32>,
396    pub stop:      Option<unsafe extern "C" fn(*mut c_void) -> i32>,
397    pub process:   Option<unsafe extern "C" fn(*mut c_void, *const ove_audio_buf, *mut ove_audio_buf) -> i32>,
398    pub destroy:   Option<unsafe extern "C" fn(*mut c_void)>,
399}
400
401#[repr(C)]
402pub struct ove_audio_node {
403    pub name:    *const core::ffi::c_char,
404    pub type_:   ove_audio_node_type,
405    pub ops:     *const ove_audio_node_ops,
406    pub ctx:     *mut c_void,
407    pub out_fmt: ove_audio_fmt,
408}
409
410#[repr(C)]
411pub struct ove_audio_edge {
412    pub from: u32,
413    pub to:   u32,
414}
415
416#[repr(C)]
417pub struct ove_audio_graph_stats {
418    pub cycles:         u32,
419    pub underruns:      u32,
420    pub overruns:       u32,
421    pub node_errors:    u32,
422    pub max_process_us: u32,
423    pub avg_process_us: u32,
424}
425
426#[repr(C)]
427pub struct ove_audio_graph {
428    pub nodes:            [ove_audio_node; 16],
429    pub node_count:       u32,
430    pub edges:            [ove_audio_edge; 16],
431    pub edge_count:       u32,
432    pub exec_order:       [u32; 16],
433    pub exec_count:       u32,
434    pub buffers:          [ove_audio_buf; 16],
435    pub buf_storage:      *mut c_void,
436    pub frames_per_period: u32,
437    pub state:            u32,
438    pub stats:            ove_audio_graph_stats,
439}
440
441#[repr(C)]
442pub struct ove_audio_device_cfg {
443    pub transport:        u32,
444    pub fmt:              ove_audio_fmt,
445    pub num_buffers:      u32,
446    pub thread_priority:  u32,
447    pub thread_stack_size: u32,
448    pub transport_cfg:    [u8; 16], /* union: i2s/pdm */
449}
450
451#[repr(C)]
452pub struct ove_shell_cmd {
453    pub name:    *const core::ffi::c_char,
454    pub help:    *const core::ffi::c_char,
455    pub handler: Option<unsafe extern "C" fn(i32, *const *const core::ffi::c_char)>,
456}
457
458// ---------------------------------------------------------------------------
459// Function pointer types
460// ---------------------------------------------------------------------------
461
462pub type ove_thread_fn      = Option<unsafe extern "C" fn(*mut c_void)>;
463pub type ove_timer_fn       = Option<unsafe extern "C" fn(ove_timer_t, *mut c_void)>;
464pub type ove_work_fn        = Option<unsafe extern "C" fn(ove_work_t)>;
465pub type ove_shell_output_hook_t = Option<unsafe extern "C" fn(*const core::ffi::c_char)>;
466pub type ove_thread_state_t = u32;
467/* ove_audio_process_fn removed — replaced by graph node vtable */
468pub type ove_gpio_irq_cb    = Option<unsafe extern "C" fn(u32, u32, *mut c_void)>;
469pub type ove_shell_cmd_fn   = Option<unsafe extern "C" fn(i32, *const *const core::ffi::c_char)>;
470
471// ---------------------------------------------------------------------------
472// extern "C" — oveRTOS API
473// ---------------------------------------------------------------------------
474
475unsafe extern "C" {
476
477    // --- app / scheduler ---
478    pub fn ove_run();
479    pub fn ove_app_run() -> i32;
480
481    // --- thread ---
482    pub fn ove_thread_init(
483        handle:  *mut ove_thread_t,
484        storage: *mut ove_thread_storage_t,
485        desc:    *const ove_thread_desc,
486    ) -> i32;
487    pub fn ove_thread_deinit(handle: ove_thread_t) -> i32;
488    pub fn ove_thread_create_(
489        handle: *mut ove_thread_t,
490        desc:   *const ove_thread_desc,
491    ) -> i32;
492    pub fn ove_thread_destroy(handle: ove_thread_t) -> i32;
493    pub fn ove_thread_get_self() -> ove_thread_t;
494    pub fn ove_thread_set_priority(handle: ove_thread_t, prio: u32);
495    pub fn ove_thread_sleep_ms(ms: u32);
496    pub fn ove_thread_yield();
497    pub fn ove_thread_suspend(handle: ove_thread_t);
498    pub fn ove_thread_resume(handle: ove_thread_t);
499    pub fn ove_thread_get_stack_usage(handle: ove_thread_t) -> usize;
500    pub fn ove_thread_get_state(handle: ove_thread_t) -> u32;
501    pub fn ove_thread_get_runtime_stats(
502        handle: ove_thread_t,
503        stats:  *mut ove_thread_stats,
504    ) -> i32;
505
506    // --- mutex ---
507    pub fn ove_mutex_init(mtx: *mut ove_mutex_t, storage: *mut ove_mutex_storage_t) -> i32;
508    pub fn ove_mutex_deinit(mtx: ove_mutex_t);
509    pub fn ove_mutex_create(mtx: *mut ove_mutex_t) -> i32;
510    pub fn ove_mutex_destroy(mtx: ove_mutex_t);
511    pub fn ove_mutex_lock(mtx: ove_mutex_t, timeout_ms: u32) -> i32;
512    pub fn ove_mutex_unlock(mtx: ove_mutex_t);
513
514    // --- recursive mutex ---
515    pub fn ove_recursive_mutex_init(
516        mtx:     *mut ove_mutex_t,
517        storage: *mut ove_mutex_storage_t,
518    ) -> i32;
519    pub fn ove_recursive_mutex_create(mtx: *mut ove_mutex_t) -> i32;
520    pub fn ove_recursive_mutex_destroy(mtx: ove_mutex_t);
521    pub fn ove_recursive_mutex_lock(mtx: ove_mutex_t, timeout_ms: u32) -> i32;
522    pub fn ove_recursive_mutex_unlock(mtx: ove_mutex_t);
523
524    // --- semaphore ---
525    pub fn ove_sem_init(
526        sem:     *mut ove_sem_t,
527        storage: *mut ove_sem_storage_t,
528        initial: u32,
529        max:     u32,
530    ) -> i32;
531    pub fn ove_sem_deinit(sem: ove_sem_t);
532    pub fn ove_sem_create(sem: *mut ove_sem_t, initial: u32, max: u32) -> i32;
533    pub fn ove_sem_destroy(sem: ove_sem_t);
534    pub fn ove_sem_take(sem: ove_sem_t, timeout_ms: u32) -> i32;
535    pub fn ove_sem_give(sem: ove_sem_t);
536
537    // --- event ---
538    pub fn ove_event_init(
539        evt:     *mut ove_event_t,
540        storage: *mut ove_event_storage_t,
541    ) -> i32;
542    pub fn ove_event_deinit(evt: ove_event_t);
543    pub fn ove_event_create(evt: *mut ove_event_t) -> i32;
544    pub fn ove_event_destroy(evt: ove_event_t);
545    pub fn ove_event_wait(evt: ove_event_t, timeout_ms: u32) -> i32;
546    pub fn ove_event_signal(evt: ove_event_t);
547    pub fn ove_event_signal_from_isr(evt: ove_event_t);
548
549    // --- condvar ---
550    pub fn ove_condvar_init(
551        cv:      *mut ove_condvar_t,
552        storage: *mut ove_condvar_storage_t,
553    ) -> i32;
554    pub fn ove_condvar_deinit(cv: ove_condvar_t);
555    pub fn ove_condvar_create(cv: *mut ove_condvar_t) -> i32;
556    pub fn ove_condvar_destroy(cv: ove_condvar_t);
557    pub fn ove_condvar_wait(cv: ove_condvar_t, mtx: ove_mutex_t, timeout_ms: u32) -> i32;
558    pub fn ove_condvar_signal(cv: ove_condvar_t);
559    pub fn ove_condvar_broadcast(cv: ove_condvar_t);
560
561    // --- queue ---
562    pub fn ove_queue_init(
563        q:         *mut ove_queue_t,
564        storage:   *mut ove_queue_storage_t,
565        buffer:    *mut c_void,
566        item_size: usize,
567        max_items: u32,
568    ) -> i32;
569    pub fn ove_queue_deinit(q: ove_queue_t);
570    pub fn ove_queue_create(q: *mut ove_queue_t, item_size: usize, max_items: u32) -> i32;
571    pub fn ove_queue_destroy(q: ove_queue_t);
572    pub fn ove_queue_send(q: ove_queue_t, data: *const c_void, timeout_ms: u32) -> i32;
573    pub fn ove_queue_receive(q: ove_queue_t, buf: *mut c_void, timeout_ms: u32) -> i32;
574    pub fn ove_queue_send_from_isr(q: ove_queue_t, data: *const c_void) -> i32;
575    pub fn ove_queue_receive_from_isr(q: ove_queue_t, buf: *mut c_void) -> i32;
576
577    // --- timer ---
578    pub fn ove_timer_init(
579        timer:     *mut ove_timer_t,
580        storage:   *mut ove_timer_storage_t,
581        callback:  ove_timer_fn,
582        user_data: *mut c_void,
583        period_ms: u32,
584        one_shot:  i32,
585    ) -> i32;
586    pub fn ove_timer_deinit(timer: ove_timer_t);
587    pub fn ove_timer_create(
588        timer:     *mut ove_timer_t,
589        callback:  ove_timer_fn,
590        user_data: *mut c_void,
591        period_ms: u32,
592        one_shot:  i32,
593    ) -> i32;
594    pub fn ove_timer_destroy(timer: ove_timer_t);
595    pub fn ove_timer_start(timer: ove_timer_t) -> i32;
596    pub fn ove_timer_stop(timer: ove_timer_t) -> i32;
597    pub fn ove_timer_reset(timer: ove_timer_t) -> i32;
598
599    // --- event group ---
600    pub fn ove_eventgroup_init(
601        eg:      *mut ove_eventgroup_t,
602        storage: *mut ove_eventgroup_storage_t,
603    ) -> i32;
604    pub fn ove_eventgroup_deinit(eg: ove_eventgroup_t);
605    pub fn ove_eventgroup_create(eg: *mut ove_eventgroup_t) -> i32;
606    pub fn ove_eventgroup_destroy(eg: ove_eventgroup_t);
607    pub fn ove_eventgroup_set_bits(eg: ove_eventgroup_t, bits: ove_eventbits_t) -> ove_eventbits_t;
608    pub fn ove_eventgroup_clear_bits(eg: ove_eventgroup_t, bits: ove_eventbits_t) -> ove_eventbits_t;
609    pub fn ove_eventgroup_wait_bits(
610        eg:         ove_eventgroup_t,
611        bits:       ove_eventbits_t,
612        flags:      u32,
613        timeout_ms: u32,
614        result:     *mut ove_eventbits_t,
615    ) -> i32;
616    pub fn ove_eventgroup_set_bits_from_isr(
617        eg:   ove_eventgroup_t,
618        bits: ove_eventbits_t,
619    ) -> ove_eventbits_t;
620    pub fn ove_eventgroup_get_bits(eg: ove_eventgroup_t) -> ove_eventbits_t;
621
622    // --- workqueue ---
623    pub fn ove_workqueue_init(
624        wq:        *mut ove_workqueue_t,
625        storage:   *mut ove_workqueue_storage_t,
626        name:      *const core::ffi::c_char,
627        priority:  u32,
628        stack_size: usize,
629        stack:     *mut c_void,
630    ) -> i32;
631    pub fn ove_workqueue_deinit(wq: ove_workqueue_t);
632    pub fn ove_workqueue_create(
633        wq:         *mut ove_workqueue_t,
634        name:       *const core::ffi::c_char,
635        priority:   u32,
636        stack_size: usize,
637    ) -> i32;
638    pub fn ove_workqueue_destroy(wq: ove_workqueue_t);
639    pub fn ove_work_init_static(
640        work:    *mut ove_work_t,
641        storage: *mut ove_work_storage_t,
642        handler: ove_work_fn,
643    ) -> i32;
644    pub fn ove_work_init(work: *mut ove_work_t, handler: ove_work_fn) -> i32;
645    pub fn ove_work_free(work: ove_work_t);
646    pub fn ove_work_submit(wq: ove_workqueue_t, work: ove_work_t) -> i32;
647    pub fn ove_work_submit_delayed(wq: ove_workqueue_t, work: ove_work_t, delay_ms: u32) -> i32;
648    pub fn ove_work_cancel(work: ove_work_t) -> i32;
649
650    // --- stream ---
651    pub fn ove_stream_init(
652        stream:  *mut ove_stream_t,
653        storage: *mut ove_stream_storage_t,
654        buffer:  *mut c_void,
655        size:    usize,
656        trigger: usize,
657    ) -> i32;
658    pub fn ove_stream_deinit(stream: ove_stream_t);
659    pub fn ove_stream_create(stream: *mut ove_stream_t, size: usize, trigger: usize) -> i32;
660    pub fn ove_stream_destroy(stream: ove_stream_t);
661    pub fn ove_stream_send(
662        stream:     ove_stream_t,
663        data:       *const c_void,
664        len:        usize,
665        timeout_ms: u32,
666        bytes_sent: *mut usize,
667    ) -> i32;
668    pub fn ove_stream_receive(
669        stream:         ove_stream_t,
670        buf:            *mut c_void,
671        len:            usize,
672        timeout_ms:     u32,
673        bytes_received: *mut usize,
674    ) -> i32;
675    pub fn ove_stream_send_from_isr(
676        stream:     ove_stream_t,
677        data:       *const c_void,
678        len:        usize,
679        bytes_sent: *mut usize,
680    ) -> i32;
681    pub fn ove_stream_receive_from_isr(
682        stream:         ove_stream_t,
683        buf:            *mut c_void,
684        len:            usize,
685        bytes_received: *mut usize,
686    ) -> i32;
687    pub fn ove_stream_reset(stream: ove_stream_t) -> i32;
688    pub fn ove_stream_bytes_available(stream: ove_stream_t) -> usize;
689
690    // --- watchdog ---
691    pub fn ove_watchdog_init(
692        wdt:        *mut ove_watchdog_t,
693        storage:    *mut ove_watchdog_storage_t,
694        timeout_ms: u32,
695    ) -> i32;
696    pub fn ove_watchdog_deinit(wdt: ove_watchdog_t);
697    pub fn ove_watchdog_create(wdt: *mut ove_watchdog_t, timeout_ms: u32) -> i32;
698    pub fn ove_watchdog_destroy(wdt: ove_watchdog_t);
699    pub fn ove_watchdog_start(wdt: ove_watchdog_t) -> i32;
700    pub fn ove_watchdog_feed(wdt: ove_watchdog_t) -> i32;
701
702    // --- filesystem ---
703    pub fn ove_fs_mount(dev_path: *const core::ffi::c_char, mount_point: *const core::ffi::c_char) -> i32;
704    pub fn ove_fs_open(file: *mut ove_file_t, path: *const core::ffi::c_char, flags: i32) -> i32;
705    pub fn ove_fs_close(file: ove_file_t) -> i32;
706    pub fn ove_fs_read(
707        file:       ove_file_t,
708        buf:        *mut c_void,
709        count:      usize,
710        bytes_read: *mut usize,
711    ) -> i32;
712    pub fn ove_fs_write(
713        file:          ove_file_t,
714        buf:           *const c_void,
715        count:         usize,
716        bytes_written: *mut usize,
717    ) -> i32;
718    pub fn ove_fs_opendir(dir: *mut ove_dir_t, path: *const core::ffi::c_char) -> i32;
719    pub fn ove_fs_closedir(dir: ove_dir_t) -> i32;
720    pub fn ove_fs_readdir(dir: ove_dir_t, entry: *mut ove_dirent) -> i32;
721
722    // --- audio graph ---
723    pub fn ove_audio_graph_init(g: *mut ove_audio_graph, frames_per_period: u32) -> i32;
724    pub fn ove_audio_graph_deinit(g: *mut ove_audio_graph);
725    pub fn ove_audio_graph_add_node(g: *mut ove_audio_graph, ops: *const ove_audio_node_ops, ctx: *mut c_void, name: *const core::ffi::c_char, node_type: ove_audio_node_type) -> i32;
726    pub fn ove_audio_graph_connect(g: *mut ove_audio_graph, from: u32, to: u32) -> i32;
727    pub fn ove_audio_graph_build(g: *mut ove_audio_graph) -> i32;
728    pub fn ove_audio_graph_start(g: *mut ove_audio_graph) -> i32;
729    pub fn ove_audio_graph_stop(g: *mut ove_audio_graph) -> i32;
730    pub fn ove_audio_graph_process(g: *mut ove_audio_graph) -> i32;
731    pub fn ove_audio_graph_get_stats(g: *const ove_audio_graph, stats: *mut ove_audio_graph_stats) -> i32;
732    pub fn ove_audio_device_source(g: *mut ove_audio_graph, cfg: *const ove_audio_device_cfg, name: *const core::ffi::c_char) -> i32;
733    pub fn ove_audio_device_sink(g: *mut ove_audio_graph, cfg: *const ove_audio_device_cfg, name: *const core::ffi::c_char) -> i32;
734
735    // --- NVS ---
736    pub fn ove_nvs_init() -> i32;
737    pub fn ove_nvs_read(
738        key:     *const core::ffi::c_char,
739        buf:     *mut c_void,
740        buf_len: usize,
741        out_len: *mut usize,
742    ) -> i32;
743    pub fn ove_nvs_write(key: *const core::ffi::c_char, data: *const c_void, len: usize) -> i32;
744    pub fn ove_nvs_erase(key: *const core::ffi::c_char) -> i32;
745
746    // --- shell ---
747    pub fn ove_shell_init() -> i32;
748    pub fn ove_shell_register_cmd(cmd: *const ove_shell_cmd) -> i32;
749    pub fn ove_shell_process_char(c: i32);
750
751    // --- console ---
752    pub fn ove_console_getchar() -> i32;
753    pub fn ove_console_putchar(c: i32);
754    pub fn ove_console_write(buf: *const core::ffi::c_char, len: u32);
755
756    // --- GPIO ---
757    pub fn ove_gpio_configure(port: u32, pin: u32, mode: u32) -> i32;
758    pub fn ove_gpio_set(port: u32, pin: u32, value: i32) -> i32;
759    pub fn ove_gpio_get(port: u32, pin: u32) -> i32;
760    pub fn ove_gpio_irq_register(
761        port:      u32,
762        pin:       u32,
763        mode:      u32,
764        callback:  ove_gpio_irq_cb,
765        user_data: *mut c_void,
766    ) -> i32;
767    pub fn ove_gpio_irq_enable(port: u32, pin: u32) -> i32;
768    pub fn ove_gpio_irq_disable(port: u32, pin: u32) -> i32;
769
770    // --- LED ---
771    pub fn ove_led_set(led: u32, on: i32);
772    pub fn ove_led_toggle(led: u32);
773    pub fn ove_led_count() -> u32;
774
775    // --- board ---
776    pub fn ove_board_init() -> i32;
777    pub fn ove_board_name() -> *const core::ffi::c_char;
778
779    // --- time ---
780    pub fn ove_time_get_us(out: *mut u64) -> i32;
781    pub fn ove_time_delay_ms(ms: u32);
782    pub fn ove_time_delay_us(us: u32);
783
784    // --- LVGL integration ---
785    pub fn ove_lvgl_init() -> i32;
786    pub fn ove_lvgl_lock();
787    pub fn ove_lvgl_unlock();
788    pub fn ove_lvgl_tick(ms: u32);
789    pub fn ove_lvgl_handler();
790
791    // --- infer (ML model) ---
792    pub fn ove_model_create(m: *mut ove_model_t, cfg: *const ove_model_config) -> i32;
793    pub fn ove_model_destroy(m: ove_model_t);
794    pub fn ove_model_init(m: *mut ove_model_t, storage: *mut ove_model_storage_t, arena: *mut u8, cfg: *const ove_model_config) -> i32;
795    pub fn ove_model_deinit(m: ove_model_t);
796    pub fn ove_model_invoke(m: ove_model_t) -> i32;
797    pub fn ove_model_last_inference_us(m: ove_model_t) -> u64;
798
799    // --- networking ---
800    pub fn ove_sockaddr_ipv4(addr: *mut ove_sockaddr_t, a: u8, b: u8, c: u8, d: u8, port: u16);
801    pub fn ove_dns_resolve(hostname: *const core::ffi::c_char, addr: *mut ove_sockaddr_t, timeout_ms: u32) -> i32;
802    pub fn ove_netif_init(netif: *mut ove_netif_t, storage: *mut ove_netif_storage_t) -> i32;
803    pub fn ove_netif_deinit(netif: ove_netif_t);
804    pub fn ove_netif_create(netif: *mut ove_netif_t) -> i32;
805    pub fn ove_netif_destroy(netif: ove_netif_t);
806    pub fn ove_netif_up(netif: ove_netif_t, cfg: *const ove_netif_config_t) -> i32;
807    pub fn ove_netif_down(netif: ove_netif_t);
808    pub fn ove_netif_get_addr(netif: ove_netif_t, ip: *mut ove_sockaddr_t, gw: *mut ove_sockaddr_t, nm: *mut ove_sockaddr_t) -> i32;
809    pub fn ove_socket_open(sock: *mut ove_socket_t, storage: *mut ove_socket_storage_t, af: u8, sock_type: u8) -> i32;
810    pub fn ove_socket_close(sock: ove_socket_t);
811    pub fn ove_socket_create(sock: *mut ove_socket_t, af: u8, sock_type: u8) -> i32;
812    pub fn ove_socket_destroy(sock: ove_socket_t);
813    pub fn ove_socket_connect(sock: ove_socket_t, addr: *const ove_sockaddr_t, timeout_ms: u32) -> i32;
814    pub fn ove_socket_bind(sock: ove_socket_t, addr: *const ove_sockaddr_t) -> i32;
815    pub fn ove_socket_listen(sock: ove_socket_t, backlog: i32) -> i32;
816    pub fn ove_socket_accept(sock: ove_socket_t, client: *mut ove_socket_t, client_storage: *mut ove_socket_storage_t, timeout_ms: u32) -> i32;
817    pub fn ove_socket_send(sock: ove_socket_t, data: *const c_void, len: usize, sent: *mut usize) -> i32;
818    pub fn ove_socket_recv(sock: ove_socket_t, buf: *mut c_void, len: usize, received: *mut usize, timeout_ms: u32) -> i32;
819    pub fn ove_socket_sendto(sock: ove_socket_t, data: *const c_void, len: usize, sent: *mut usize, dest: *const ove_sockaddr_t) -> i32;
820    pub fn ove_socket_recvfrom(sock: ove_socket_t, buf: *mut c_void, len: usize, received: *mut usize, src: *mut ove_sockaddr_t, timeout_ms: u32) -> i32;
821    pub fn ove_http_client_init(client: *mut ove_http_client_t, storage: *mut ove_http_client_storage_t) -> i32;
822    pub fn ove_http_client_deinit(client: ove_http_client_t);
823    pub fn ove_http_client_create(client: *mut ove_http_client_t) -> i32;
824    pub fn ove_http_client_destroy(client: ove_http_client_t);
825    pub fn ove_http_get(client: ove_http_client_t, url: *const core::ffi::c_char, resp: *mut ove_http_response_t) -> i32;
826    pub fn ove_http_post(client: ove_http_client_t, url: *const core::ffi::c_char, ct: *const core::ffi::c_char, body: *const c_void, body_len: usize, resp: *mut ove_http_response_t) -> i32;
827    pub fn ove_http_request_ex(client: ove_http_client_t, method: ove_http_method_t, url: *const core::ffi::c_char, ct: *const core::ffi::c_char, body: *const c_void, body_len: usize, headers: *const ove_http_header_t, header_count: usize, resp: *mut ove_http_response_t) -> i32;
828    pub fn ove_http_response_free(resp: *mut ove_http_response_t);
829    pub fn ove_mqtt_client_init(client: *mut ove_mqtt_client_t, storage: *mut ove_mqtt_client_storage_t) -> i32;
830    pub fn ove_mqtt_client_deinit(client: ove_mqtt_client_t);
831    pub fn ove_mqtt_client_create(client: *mut ove_mqtt_client_t) -> i32;
832    pub fn ove_mqtt_client_destroy(client: ove_mqtt_client_t);
833    pub fn ove_mqtt_connect(client: ove_mqtt_client_t, cfg: *const ove_mqtt_config_t) -> i32;
834    pub fn ove_mqtt_disconnect(client: ove_mqtt_client_t);
835    pub fn ove_mqtt_publish(client: ove_mqtt_client_t, topic: *const core::ffi::c_char, payload: *const c_void, payload_len: usize, qos: ove_mqtt_qos_t) -> i32;
836    pub fn ove_mqtt_subscribe(client: ove_mqtt_client_t, topic: *const core::ffi::c_char, qos: ove_mqtt_qos_t) -> i32;
837    pub fn ove_mqtt_unsubscribe(client: ove_mqtt_client_t, topic: *const core::ffi::c_char) -> i32;
838    pub fn ove_mqtt_loop(client: ove_mqtt_client_t, timeout_ms: u32) -> i32;
839    pub fn ove_httpd_start(cfg: *const c_void) -> i32;
840    pub fn ove_httpd_stop();
841    pub fn ove_httpd_route(method: *const core::ffi::c_char, path: *const core::ffi::c_char, handler: ove_httpd_handler_t) -> i32;
842    pub fn ove_httpd_register_builtin_routes();
843    pub fn ove_httpd_req_method(req: *mut c_void) -> *const core::ffi::c_char;
844    pub fn ove_httpd_req_path(req: *mut c_void) -> *const core::ffi::c_char;
845    pub fn ove_httpd_req_query(req: *mut c_void) -> *const core::ffi::c_char;
846    pub fn ove_httpd_req_body(req: *mut c_void) -> *const core::ffi::c_char;
847    pub fn ove_httpd_req_body_len(req: *mut c_void) -> usize;
848    pub fn ove_httpd_req_segment(req: *mut c_void, idx: i32) -> *const core::ffi::c_char;
849    pub fn ove_httpd_resp_json(resp: *mut c_void, status: i32, json: *const core::ffi::c_char) -> i32;
850    pub fn ove_httpd_resp_html(resp: *mut c_void, status: i32, html: *const core::ffi::c_char, len: usize) -> i32;
851    pub fn ove_httpd_resp_send(resp: *mut c_void, status: i32, ct: *const core::ffi::c_char, body: *const c_void, len: usize) -> i32;
852    pub fn ove_httpd_resp_send_gz(resp: *mut c_void, status: i32, ct: *const core::ffi::c_char, body: *const c_void, len: usize) -> i32;
853    pub fn ove_httpd_resp_error(resp: *mut c_void, status: i32, msg: *const core::ffi::c_char) -> i32;
854    pub fn ove_httpd_log_append(line: *const core::ffi::c_char);
855    pub fn ove_httpd_set_netif(netif: ove_netif_t);
856    pub fn ove_httpd_ws_route(path: *const core::ffi::c_char, on_msg: ove_httpd_ws_handler_t, on_close: ove_httpd_ws_close_handler_t) -> i32;
857    pub fn ove_httpd_ws_send(conn: *mut ove_httpd_ws_conn_t, data: *const c_void, len: usize) -> i32;
858    pub fn ove_httpd_ws_broadcast(path: *const core::ffi::c_char, data: *const c_void, len: usize) -> i32;
859    pub fn ove_httpd_ws_active_count() -> i32;
860    pub fn ove_tls_init(tls: *mut ove_tls_t, storage: *mut ove_tls_storage_t) -> i32;
861    pub fn ove_tls_deinit(tls: ove_tls_t);
862    pub fn ove_tls_create(tls: *mut ove_tls_t) -> i32;
863    pub fn ove_tls_destroy(tls: ove_tls_t);
864    pub fn ove_tls_handshake(tls: ove_tls_t, sock: ove_socket_t, cfg: *const ove_tls_config_t) -> i32;
865    pub fn ove_tls_send(tls: ove_tls_t, data: *const c_void, len: usize, sent: *mut usize) -> i32;
866    pub fn ove_tls_recv(tls: ove_tls_t, buf: *mut c_void, len: usize, received: *mut usize) -> i32;
867    pub fn ove_tls_close(tls: ove_tls_t);
868    pub fn ove_shell_set_output_hook(hook: ove_shell_output_hook_t);
869    pub fn ove_sntp_sync(cfg: *const c_void) -> i32;
870    pub fn ove_sntp_get_offset_us(offset_us: *mut i64) -> i32;
871    pub fn ove_sntp_get_utc(utc_s: *mut u32) -> i32;
872
873    // --- PM ---
874    pub fn ove_pm_init(cfg: *const ove_pm_cfg) -> i32;
875    pub fn ove_pm_deinit();
876    pub fn ove_pm_set_state(state: ove_pm_state_t) -> i32;
877    pub fn ove_pm_get_state() -> ove_pm_state_t;
878    pub fn ove_pm_activity();
879    pub fn ove_pm_wake_register(src: *const ove_pm_wake_src) -> i32;
880    pub fn ove_pm_wake_unregister(src: *const ove_pm_wake_src) -> i32;
881    pub fn ove_pm_domain_request(domain: ove_pm_domain_t) -> i32;
882    pub fn ove_pm_domain_release(domain: ove_pm_domain_t) -> i32;
883    pub fn ove_pm_domain_get_refcount(domain: ove_pm_domain_t) -> i32;
884    pub fn ove_pm_set_policy(policy: ove_pm_policy_fn, user_data: *mut c_void) -> i32;
885    pub fn ove_pm_notify_register(cb: ove_pm_notify_fn, user_data: *mut c_void) -> i32;
886    pub fn ove_pm_notify_unregister(cb: ove_pm_notify_fn, user_data: *mut c_void) -> i32;
887    pub fn ove_pm_get_stats(stats: *mut ove_pm_stats) -> i32;
888    pub fn ove_pm_reset_stats() -> i32;
889    pub fn ove_pm_set_budget(target: u32) -> i32;
890    pub fn ove_pm_get_budget_status(actual: *mut u32) -> i32;
891
892    // --- UART ---
893    pub fn ove_uart_write(uart: ove_uart_t, data: *const c_void, len: usize, sent: *mut usize) -> i32;
894    pub fn ove_uart_read(uart: ove_uart_t, buf: *mut c_void, len: usize, received: *mut usize, timeout_ms: u32) -> i32;
895    pub fn ove_uart_flush(uart: ove_uart_t) -> i32;
896    pub fn ove_uart_bytes_available(uart: ove_uart_t) -> usize;
897
898    // --- SPI ---
899    pub fn ove_spi_transfer(spi: ove_spi_t, cs: *const ove_spi_cs, tx: *const c_void, rx: *mut c_void, len: usize, timeout_ms: u32) -> i32;
900    pub fn ove_spi_write(spi: ove_spi_t, cs: *const ove_spi_cs, data: *const c_void, len: usize, timeout_ms: u32) -> i32;
901    pub fn ove_spi_read(spi: ove_spi_t, cs: *const ove_spi_cs, buf: *mut c_void, len: usize, timeout_ms: u32) -> i32;
902    pub fn ove_spi_transfer_seq(spi: ove_spi_t, cs: *const ove_spi_cs, xfers: *const ove_spi_xfer, num_xfers: u32, timeout_ms: u32) -> i32;
903
904    // --- I2C ---
905    pub fn ove_i2c_write(i2c: ove_i2c_t, addr: u16, data: *const c_void, len: usize, timeout_ms: u32) -> i32;
906    pub fn ove_i2c_read(i2c: ove_i2c_t, addr: u16, buf: *mut c_void, len: usize, timeout_ms: u32) -> i32;
907    pub fn ove_i2c_write_read(i2c: ove_i2c_t, addr: u16, tx: *const c_void, tx_len: usize, rx: *mut c_void, rx_len: usize, timeout_ms: u32) -> i32;
908    pub fn ove_i2c_probe(i2c: ove_i2c_t, addr: u16, timeout_ms: u32) -> i32;
909    pub fn ove_i2c_reg_write(i2c: ove_i2c_t, addr: u16, reg: u8, data: *const c_void, len: usize, timeout_ms: u32) -> i32;
910    pub fn ove_i2c_reg_read(i2c: ove_i2c_t, addr: u16, reg: u8, buf: *mut c_void, len: usize, timeout_ms: u32) -> i32;
911
912} // extern "C" oveRTOS
913
914// ---------------------------------------------------------------------------
915// LVGL types — opaque stubs
916// ---------------------------------------------------------------------------
917
918/// Opaque LVGL object. All access goes through `lv_obj_*` functions.
919#[repr(C)]
920pub struct lv_obj_t {
921    _opaque: [u8; 256],
922}
923
924/// LVGL color (BGR888 layout to match LVGL v9 `lv_color_t`).
925#[repr(C)]
926#[derive(Clone, Copy)]
927pub struct lv_color_t {
928    pub blue:  u8,
929    pub green: u8,
930    pub red:   u8,
931}
932
933/// Opaque LVGL font descriptor.
934#[repr(C)]
935pub struct lv_font_t {
936    _opaque: [u8; 64],
937}
938
939/// Opaque LVGL style.
940#[repr(C)]
941pub struct lv_style_t {
942    _opaque: [u8; 128],
943}
944
945/// LVGL event callback function pointer type.
946pub type lv_event_cb_t = Option<unsafe extern "C" fn(*mut c_void)>;
947/// LVGL event code type.
948pub type lv_event_code_t = u32;
949
950// ---------------------------------------------------------------------------
951// LVGL constants
952// ---------------------------------------------------------------------------
953
954pub const LV_OBJ_FLAG_HIDDEN:     u32 = 1 << 0;
955pub const LV_OBJ_FLAG_CLICKABLE:  u32 = 1 << 1;
956pub const LV_OBJ_FLAG_SCROLLABLE: u32 = 1 << 2;
957
958pub const LV_EVENT_CLICKED:       u32 = 7;
959pub const LV_EVENT_VALUE_CHANGED: u32 = 28;
960
961pub const LV_FLEX_FLOW_ROW:    u32 = 0;
962pub const LV_FLEX_FLOW_COLUMN: u32 = 1;
963
964// ---------------------------------------------------------------------------
965// LVGL font statics
966// ---------------------------------------------------------------------------
967
968unsafe extern "C" {
969    pub static lv_font_montserrat_14: lv_font_t;
970    pub static lv_font_montserrat_32: lv_font_t;
971}
972
973// ---------------------------------------------------------------------------
974// extern "C" — LVGL functions
975// ---------------------------------------------------------------------------
976
977unsafe extern "C" {
978
979    // core object
980    pub fn lv_obj_create(parent: *mut lv_obj_t) -> *mut lv_obj_t;
981    pub fn lv_obj_delete(obj: *mut lv_obj_t);
982    pub fn lv_obj_clean(obj: *mut lv_obj_t);
983    pub fn lv_obj_get_parent(obj: *mut lv_obj_t) -> *mut lv_obj_t;
984    pub fn lv_obj_get_child_count(obj: *mut lv_obj_t) -> u32;
985    pub fn lv_obj_get_width(obj: *mut lv_obj_t) -> i32;
986    pub fn lv_obj_get_height(obj: *mut lv_obj_t) -> i32;
987    pub fn lv_obj_set_size(obj: *mut lv_obj_t, w: i32, h: i32);
988    pub fn lv_obj_set_width(obj: *mut lv_obj_t, w: i32);
989    pub fn lv_obj_set_height(obj: *mut lv_obj_t, h: i32);
990    pub fn lv_obj_set_pos(obj: *mut lv_obj_t, x: i32, y: i32);
991    pub fn lv_obj_center(obj: *mut lv_obj_t);
992    pub fn lv_obj_align(obj: *mut lv_obj_t, align: u8, x_ofs: i32, y_ofs: i32);
993    pub fn lv_obj_set_user_data(obj: *mut lv_obj_t, data: *mut c_void);
994    pub fn lv_obj_get_user_data(obj: *mut lv_obj_t) -> *mut c_void;
995    pub fn lv_obj_add_flag(obj: *mut lv_obj_t, f: u32);
996    pub fn lv_obj_remove_flag(obj: *mut lv_obj_t, f: u32);
997    pub fn lv_obj_add_state(obj: *mut lv_obj_t, state: u16);
998    pub fn lv_obj_remove_state(obj: *mut lv_obj_t, state: u16);
999    pub fn lv_obj_add_event_cb(
1000        obj:       *mut lv_obj_t,
1001        event_cb:  lv_event_cb_t,
1002        filter:    u32,
1003        user_data: *mut c_void,
1004    );
1005    pub fn lv_obj_add_style(obj: *mut lv_obj_t, style: *mut lv_style_t, selector: u32);
1006    pub fn lv_obj_set_flex_flow(obj: *mut lv_obj_t, flow: u32);
1007
1008    // inline styles
1009    pub fn lv_obj_set_style_bg_color(obj: *mut lv_obj_t, color: lv_color_t, selector: u32);
1010    pub fn lv_obj_set_style_bg_opa(obj: *mut lv_obj_t, opa: u8, selector: u32);
1011    pub fn lv_obj_set_style_border_color(obj: *mut lv_obj_t, color: lv_color_t, selector: u32);
1012    pub fn lv_obj_set_style_border_width(obj: *mut lv_obj_t, w: i32, selector: u32);
1013    pub fn lv_obj_set_style_radius(obj: *mut lv_obj_t, r: i32, selector: u32);
1014    pub fn lv_obj_set_style_pad_top(obj: *mut lv_obj_t, p: i32, selector: u32);
1015    pub fn lv_obj_set_style_pad_bottom(obj: *mut lv_obj_t, p: i32, selector: u32);
1016    pub fn lv_obj_set_style_pad_left(obj: *mut lv_obj_t, p: i32, selector: u32);
1017    pub fn lv_obj_set_style_pad_right(obj: *mut lv_obj_t, p: i32, selector: u32);
1018    pub fn lv_obj_set_style_pad_row(obj: *mut lv_obj_t, g: i32, selector: u32);
1019    pub fn lv_obj_set_style_pad_column(obj: *mut lv_obj_t, g: i32, selector: u32);
1020    pub fn lv_obj_set_style_text_color(obj: *mut lv_obj_t, color: lv_color_t, selector: u32);
1021    pub fn lv_obj_set_style_text_font(
1022        obj:      *mut lv_obj_t,
1023        font:     *const lv_font_t,
1024        selector: u32,
1025    );
1026
1027    // style objects
1028    pub fn lv_style_init(style: *mut lv_style_t);
1029    pub fn lv_style_reset(style: *mut lv_style_t);
1030    pub fn lv_style_set_bg_color(style: *mut lv_style_t, color: lv_color_t);
1031    pub fn lv_style_set_bg_opa(style: *mut lv_style_t, opa: u8);
1032    pub fn lv_style_set_radius(style: *mut lv_style_t, r: i32);
1033    pub fn lv_style_set_border_color(style: *mut lv_style_t, color: lv_color_t);
1034    pub fn lv_style_set_border_width(style: *mut lv_style_t, w: i32);
1035    pub fn lv_style_set_pad_top(style: *mut lv_style_t, p: i32);
1036    pub fn lv_style_set_pad_bottom(style: *mut lv_style_t, p: i32);
1037    pub fn lv_style_set_pad_left(style: *mut lv_style_t, p: i32);
1038    pub fn lv_style_set_pad_right(style: *mut lv_style_t, p: i32);
1039    pub fn lv_style_set_text_color(style: *mut lv_style_t, color: lv_color_t);
1040    pub fn lv_style_set_text_font(style: *mut lv_style_t, font: *const lv_font_t);
1041
1042    // color helpers
1043    pub fn lv_palette_main(palette: u32) -> lv_color_t;
1044
1045    // screen
1046    pub fn lv_screen_active() -> *mut lv_obj_t;
1047
1048    // label widget
1049    pub fn lv_label_create(parent: *mut lv_obj_t) -> *mut lv_obj_t;
1050    pub fn lv_label_set_text(label: *mut lv_obj_t, text: *const core::ffi::c_char);
1051    pub fn lv_label_set_text_static(label: *mut lv_obj_t, text: *const core::ffi::c_char);
1052
1053    // bar widget
1054    pub fn lv_bar_create(parent: *mut lv_obj_t) -> *mut lv_obj_t;
1055    pub fn lv_bar_set_value(bar: *mut lv_obj_t, value: i32, anim: i32);
1056    pub fn lv_bar_set_range(bar: *mut lv_obj_t, min: i32, max: i32);
1057
1058} // extern "C" LVGL