use crate::app::{init::init_all, init::is_initialized, widget::windows};
use crate::prelude::*;
use fltk_sys::fl;
use std::{mem, os::raw, panic, thread, time};
pub fn run() -> Result<(), FltkError> {
unsafe {
if !is_initialized() {
init_all();
}
if !crate::app::is_ui_thread() {
return Err(FltkError::Internal(FltkErrorKind::FailedToRun));
}
match fl::Fl_run() {
0 => Ok(()),
_ => Err(FltkError::Internal(FltkErrorKind::FailedToRun)),
}
}
}
pub fn enable_locks() -> Result<(), FltkError> {
lock()?;
Ok(())
}
pub fn lock() -> Result<(), FltkError> {
unsafe {
match fl::Fl_lock() {
0 => Ok(()),
_ => Err(FltkError::Internal(FltkErrorKind::FailedToLock)),
}
}
}
pub fn unlock() {
unsafe {
fl::Fl_unlock();
}
}
pub fn awake() {
unsafe { fl::Fl_awake() }
}
pub fn awake_callback<F: FnMut() + 'static>(cb: F) {
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let mut a: Box<Box<dyn FnMut()>> = Box::from_raw(data as *mut Box<dyn FnMut()>);
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: fl::Fl_Awake_Handler = Some(shim);
fl::Fl_awake_callback(callback, data);
}
}
pub fn wait() -> bool {
unsafe {
if !is_initialized() {
init_all();
}
assert!(crate::app::is_ui_thread());
fl::Fl_wait() != 0
}
}
pub fn sleep(dur: f64) {
let dur = dur * 1000.;
thread::sleep(time::Duration::from_millis(dur as u64));
}
pub fn wait_for(dur: f64) -> Result<bool, FltkError> {
unsafe {
if !is_initialized() {
init_all();
}
if !crate::app::is_ui_thread() {
return Err(FltkError::Internal(FltkErrorKind::FailedToRun));
}
match fl::Fl_wait_for(dur) as i32 {
0 => Ok(false),
1 => Ok(true),
_ => Err(FltkError::Unknown(String::from(
"The event loop was probably interrupted by an OS signal!",
))),
}
}
}
pub fn should_program_quit() -> bool {
unsafe { fl::Fl_should_program_quit() != 0 }
}
pub fn program_should_quit(flag: bool) {
unsafe { fl::Fl_program_should_quit(flag as i32) }
}
pub fn check() -> bool {
unsafe {
if !is_initialized() {
init_all();
}
assert!(crate::app::is_ui_thread());
fl::Fl_check() != 0
}
}
pub fn ready() -> bool {
unsafe {
if !is_initialized() {
init_all();
}
assert!(crate::app::is_ui_thread());
fl::Fl_ready() != 0
}
}
pub fn quit() {
if let Some(wins) = windows() {
for mut i in wins {
if i.shown() {
i.hide();
}
}
}
}
#[deprecated(since = "1.2.26", note = "please use `add_idle3` instead")]
pub fn add_idle<F: FnMut() + 'static>(cb: F) {
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut()> = data as *mut Box<dyn FnMut()>;
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_add_idle(callback, data);
}
}
#[deprecated(since = "1.2.26", note = "please use `remove_idle3` instead")]
pub fn remove_idle<F: FnMut() + 'static>(cb: F) {
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut()> = data as *mut Box<dyn FnMut()>;
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_remove_idle(callback, data);
}
}
#[deprecated(since = "1.2.26", note = "please use `has_idle3` instead")]
pub fn has_idle<F: FnMut() + 'static>(cb: F) -> bool {
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut()> = data as *mut Box<dyn FnMut()>;
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_has_idle(callback, data) != 0
}
}
pub fn add_idle2(cb: fn()) {
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_add_idle(callback, data);
}
}
pub fn remove_idle2(cb: fn()) {
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_remove_idle(callback, data);
}
}
pub fn has_idle2(cb: fn()) -> bool {
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_has_idle(callback, data) != 0
}
}
pub type IdleHandle = *mut ();
unsafe extern "C" fn idle_shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut(IdleHandle)> = data as *mut Box<dyn FnMut(IdleHandle)>;
let f: &mut dyn FnMut(IdleHandle) = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| (*f)(data as _)));
}
pub fn add_idle3<F: FnMut(IdleHandle) + 'static>(cb: F) -> IdleHandle {
unsafe {
let a: *mut Box<dyn FnMut(IdleHandle)> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(idle_shim);
fl::Fl_add_idle(callback, data);
data as _
}
}
pub fn remove_idle3(handle: IdleHandle) {
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(idle_shim);
fl::Fl_remove_idle(callback, data);
}
}
pub fn has_idle3(handle: IdleHandle) -> bool {
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(idle_shim);
fl::Fl_has_idle(callback, data) != 0
}
}
pub type CheckHandle = *mut ();
pub fn add_check<F: FnMut(CheckHandle) + 'static>(cb: F) -> CheckHandle {
unsafe {
let a: *mut Box<dyn FnMut(CheckHandle)> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(idle_shim);
fl::Fl_add_check(callback, data);
data as _
}
}
pub fn remove_check(handle: CheckHandle) {
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(idle_shim);
fl::Fl_remove_check(callback, data);
}
}
pub fn has_check(handle: CheckHandle) -> bool {
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(idle_shim);
fl::Fl_has_check(callback, data) != 0
}
}
pub fn add_clipboard_notify(cb: fn(source: i32)) {
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(source: i32, arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_add_clipboard_notify(callback, data);
}
}
pub fn remove_clipboard_notify(cb: fn(source: i32)) {
unsafe {
let callback: Option<unsafe extern "C" fn(source: i32, arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_remove_clipboard_notify(callback);
}
}
#[deprecated(since = "1.2.26", note = "please use `add_clipboard_notify3` instead")]
pub fn add_clipboard_notify2<F: FnMut(i32) + 'static>(cb: F) {
unsafe {
unsafe extern "C" fn shim(source: i32, data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut(i32)> = data as *mut Box<dyn FnMut(i32)>;
let f: &mut dyn FnMut(i32) = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| f(source)));
}
let a: *mut Box<dyn FnMut(i32)> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(source: i32, arg1: *mut raw::c_void)> =
Some(shim);
fl::Fl_add_clipboard_notify(callback, data);
}
}
unsafe extern "C" fn clipboard_notify_shim(source: i32, data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut(i32)> = data as *mut Box<dyn FnMut(i32)>;
let f: &mut dyn FnMut(i32) = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| (*f)(source)));
}
pub fn add_clipboard_notify3<F: FnMut(i32) + 'static>(cb: F) {
unsafe {
let a: *mut Box<dyn FnMut(i32)> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(source: i32, arg1: *mut raw::c_void)> =
Some(clipboard_notify_shim);
fl::Fl_add_clipboard_notify(callback, data);
}
}
pub fn remove_clipboard_notify3() {
unsafe {
let callback: Option<unsafe extern "C" fn(source: i32, arg1: *mut raw::c_void)> =
Some(clipboard_notify_shim);
fl::Fl_remove_clipboard_notify(callback);
}
}
#[deprecated(since = "1.2.26", note = "please use `add_timeout3` instead")]
pub fn add_timeout<F: FnMut() + 'static>(tm: f64, cb: F) {
unsafe {
assert!(crate::app::is_ui_thread());
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let mut a: Box<Box<dyn FnMut()>> = Box::from_raw(data as *mut Box<dyn FnMut()>);
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_add_timeout(tm, callback, data);
}
}
#[deprecated(since = "1.2.26", note = "please use `repeat_timeout3` instead")]
pub fn repeat_timeout<F: FnMut() + 'static>(tm: f64, cb: F) {
assert!(crate::app::is_ui_thread());
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut()> = data as *mut Box<dyn FnMut()>;
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_repeat_timeout(tm, callback, data);
}
}
#[deprecated(since = "1.2.26", note = "please use `remove_timeout3` instead")]
pub fn remove_timeout<F: FnMut() + 'static>(cb: F) {
assert!(crate::app::is_ui_thread());
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut()> = data as *mut Box<dyn FnMut()>;
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_remove_timeout(callback, data);
}
}
#[deprecated(since = "1.2.26", note = "please use `has_timeout3` instead")]
pub fn has_timeout<F: FnMut() + 'static>(cb: F) -> bool {
unsafe {
unsafe extern "C" fn shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut()> = data as *mut Box<dyn FnMut()>;
let f: &mut dyn FnMut() = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(f));
}
let a: *mut Box<dyn FnMut()> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(shim);
fl::Fl_has_timeout(callback, data) != 0
}
}
pub fn add_timeout2(tm: f64, cb: fn()) {
assert!(crate::app::is_ui_thread());
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_add_timeout(tm, callback, data);
}
}
pub fn repeat_timeout2(tm: f64, cb: fn()) {
assert!(crate::app::is_ui_thread());
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_repeat_timeout(tm, callback, data);
}
}
pub fn remove_timeout2(cb: fn()) {
assert!(crate::app::is_ui_thread());
if has_timeout2(cb) {
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_remove_timeout(callback, data);
}
}
}
pub fn has_timeout2(cb: fn()) -> bool {
unsafe {
let data: *mut raw::c_void = std::ptr::null_mut();
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
fl::Fl_has_timeout(callback, data) != 0
}
}
pub type TimeoutHandle = *mut ();
unsafe extern "C" fn timeout_shim(data: *mut raw::c_void) {
let a: *mut Box<dyn FnMut(TimeoutHandle)> = data as *mut Box<dyn FnMut(TimeoutHandle)>;
let f: &mut dyn FnMut(TimeoutHandle) = &mut **a;
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| (*f)(data as _)));
}
pub fn add_timeout3<F: FnMut(TimeoutHandle) + 'static>(tm: f64, cb: F) -> TimeoutHandle {
assert!(crate::app::is_ui_thread());
unsafe {
let a: *mut Box<dyn FnMut(TimeoutHandle)> = Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(timeout_shim);
fl::Fl_add_timeout(tm, callback, data);
data as _
}
}
pub fn repeat_timeout3(tm: f64, handle: TimeoutHandle) {
assert!(crate::app::is_ui_thread());
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(timeout_shim);
fl::Fl_repeat_timeout(tm, callback, data);
}
}
pub fn remove_timeout3(handle: TimeoutHandle) {
assert!(crate::app::is_ui_thread());
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(timeout_shim);
fl::Fl_remove_timeout(callback, data);
}
}
pub fn has_timeout3(handle: TimeoutHandle) -> bool {
assert!(crate::app::is_ui_thread());
unsafe {
let data: *mut raw::c_void = handle as *mut raw::c_void;
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> = Some(timeout_shim);
fl::Fl_has_timeout(callback, data) != 0
}
}
#[doc(hidden)]
pub fn add_raw_timeout<T>(tm: f64, cb: fn(*mut T), data: *mut T) {
unsafe {
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
let data: *mut raw::c_void = data as *mut raw::c_void;
fl::Fl_add_timeout(tm, callback, data);
}
}
#[doc(hidden)]
pub fn repeat_raw_timeout<T>(tm: f64, cb: fn(*mut T), data: *mut T) {
unsafe {
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
let data: *mut raw::c_void = data as *mut raw::c_void;
fl::Fl_repeat_timeout(tm, callback, data);
}
}
#[doc(hidden)]
pub fn remove_raw_timeout<T>(cb: fn(*mut T), data: *mut T) {
unsafe {
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
let data: *mut raw::c_void = data as *mut raw::c_void;
fl::Fl_remove_timeout(callback, data);
}
}
#[doc(hidden)]
pub fn has_raw_timeout<T>(cb: fn(*mut T), data: *mut T) -> bool {
unsafe {
let callback: Option<unsafe extern "C" fn(arg1: *mut raw::c_void)> =
Some(mem::transmute(cb));
let data: *mut raw::c_void = data as *mut raw::c_void;
fl::Fl_has_timeout(callback, data) != 0
}
}
pub unsafe fn add_system_handler(
cb: Option<unsafe extern "C" fn(*mut raw::c_void, *mut raw::c_void) -> i32>,
data: *mut raw::c_void,
) {
assert!(crate::app::is_ui_thread());
fl::Fl_add_system_handler(cb, data);
}
pub unsafe fn remove_system_handler(
cb: Option<unsafe extern "C" fn(*mut raw::c_void, *mut raw::c_void) -> i32>,
) {
assert!(crate::app::is_ui_thread());
fl::Fl_remove_system_handler(cb);
}