1use std::io::Write;
2
3use bitflags::bitflags;
4use crossterm::{self, queue};
5use log::trace;
6
7#[cfg(not(feature = "docsrs"))]
8include!(concat!(env!("OUT_DIR"), "/colors.rs"));
9#[cfg(feature = "docsrs")]
10pub static COLORS: &str =
11 r##"[{"error": "Feature `docsrs` is enabled. COLORS json not available."}]"##;
12
13fn convert_string_to_c_char(string: String) -> *mut libc::c_char {
14 let c_string = match std::ffi::CString::new(string.as_bytes()) {
16 Ok(c_string) => c_string,
17 Err(_) => {
18 set_last_error(anyhow::anyhow!("Unable to convert {} to CString", &string));
19 return std::ptr::null_mut();
20 }
21 };
22
23 let string_len = c_string.as_bytes_with_nul().len();
25 let addr = unsafe {
26 let addr = libc::malloc(string_len) as *mut libc::c_char;
27 if addr.is_null() {
28 set_last_error(anyhow::anyhow!("Unable to malloc for {}", &string));
29 return std::ptr::null_mut();
30 }
31 addr
32 };
33
34 unsafe {
36 std::ptr::copy_nonoverlapping(c_string.as_ptr(), addr, string_len);
37 }
38 addr
39}
40
41pub trait CUnwrapper<T> {
43 fn c_unwrap(self) -> T;
44}
45
46impl<T> CUnwrapper<T> for anyhow::Result<T>
47where
48 T: Default,
49{
50 fn c_unwrap(self) -> T {
51 match self {
52 Ok(t) => {
53 RESULT.with(|r| {
54 *r.borrow_mut() = 0;
55 });
56 take_last_error();
57 t
58 }
59 Err(err) => {
60 RESULT.with(|r| {
61 *r.borrow_mut() = -1;
62 });
63 set_last_error(err);
64 T::default()
65 }
66 }
67 }
68}
69
70impl<T> CUnwrapper<T> for Result<T, std::io::Error>
71where
72 T: Default,
73{
74 fn c_unwrap(self) -> T {
75 match self {
76 Ok(t) => {
77 RESULT.with(|r| {
78 *r.borrow_mut() = 0;
79 });
80 take_last_error();
81 t
82 }
83 Err(err) => {
84 RESULT.with(|r| {
85 *r.borrow_mut() = -1;
86 });
87 set_last_error(err.into());
88 T::default()
89 }
90 }
91 }
92}
93
94thread_local! {
95 static LAST_ERROR: std::cell::RefCell<Option<anyhow::Error>> = std::cell::RefCell::new(None);
96 static RESULT: std::cell::RefCell<libc::c_int> = std::cell::RefCell::new(0);
97 static USE_STDOUT: std::cell::RefCell<bool> = std::cell::RefCell::new(std::env::var("LIBCROSSTERM_OUTPUT").unwrap_or_default() == "stdout");
98}
99
100macro_rules! r {
101 () => {
102 RESULT.with(|r| r.borrow().clone())
103 };
104}
105
106macro_rules! io {
107 () => {
108 if USE_STDOUT.with(|r| *r.borrow()) {
109 Box::new(std::io::stdout()) as Box<dyn Write>
110 } else {
111 Box::new(std::io::stderr()) as Box<dyn Write>
112 }
113 };
114}
115
116fn set_last_error(err: anyhow::Error) {
117 trace!("Set last error");
118 LAST_ERROR.with(|e| {
119 *e.borrow_mut() = Some(err);
120 });
121}
122
123pub fn take_last_error() -> Option<anyhow::Error> {
125 LAST_ERROR.with(|prev| prev.borrow_mut().take())
126}
127
128#[no_mangle]
130pub extern "C" fn crossterm_has_error() -> bool {
131 LAST_ERROR.with(|prev| prev.borrow().is_some())
132}
133
134#[no_mangle]
135pub extern "C" fn crossterm_clear_last_error() {
136 let _ = take_last_error();
137}
138
139pub fn error_message() -> Option<String> {
141 LAST_ERROR.with(|prev| prev.borrow().as_ref().map(|e| format!("{:#}", e)))
142}
143
144#[no_mangle]
148pub extern "C" fn crossterm_last_error_length() -> libc::c_int {
149 LAST_ERROR.with(|prev| match *prev.borrow() {
150 Some(ref err) => format!("{:#}", err).len() as libc::c_int + 1,
151 None => 0,
152 })
153}
154
155#[no_mangle]
161pub extern "C" fn crossterm_last_error_message() -> *const libc::c_char {
162 let last_error = take_last_error().unwrap_or(anyhow::anyhow!(
163 "No error message found. Check library documentation for more information."
164 ));
165 let string = format!("{:#}", last_error);
166 convert_string_to_c_char(string)
167}
168
169#[no_mangle]
173pub extern "C" fn crossterm_free_c_char(s: *mut libc::c_char) -> libc::c_int {
174 if !s.is_null() {
175 unsafe {
176 libc::free(s as *mut libc::c_void);
177 }
178 0
179 } else {
180 set_last_error(anyhow::anyhow!("Received null pointer to free"));
181 -1
182 }
183}
184
185#[repr(C)]
187pub enum MediaKeyCode {
188 Play,
190 Pause,
192 PlayPause,
194 Reverse,
196 Stop,
198 FastForward,
200 Rewind,
202 TrackNext,
204 TrackPrevious,
206 Record,
208 LowerVolume,
210 RaiseVolume,
212 MuteVolume,
214}
215
216#[repr(C)]
218pub enum ModifierKeyCode {
219 LeftShift,
221 LeftControl,
223 LeftAlt,
225 LeftSuper,
227 LeftHyper,
229 LeftMeta,
231 RightShift,
233 RightControl,
235 RightAlt,
237 RightSuper,
239 RightHyper,
241 RightMeta,
243 IsoLevel3Shift,
245 IsoLevel5Shift,
247}
248
249#[repr(C)]
251pub enum KeyCode {
252 Backspace,
254 Enter,
256 Left,
258 Right,
260 Up,
262 Down,
264 Home,
266 End,
268 PageUp,
270 PageDown,
272 Tab,
274 BackTab,
276 Delete,
278 Insert,
280 F(u8),
284 Char(char),
288 Null,
290 Esc,
292 CapsLock,
298 ScrollLock,
304 NumLock,
310 PrintScreen,
316 Pause,
322 Menu,
328 KeypadBegin,
334 Media(MediaKeyCode),
340 Modifier(ModifierKeyCode),
347}
348
349bitflags! {
350 #[repr(C)]
356 pub struct KeyModifiers: u8 {
357 const SHIFT = 0b0000_0001;
358 const CONTROL = 0b0000_0010;
359 const ALT = 0b0000_0100;
360 const SUPER = 0b0000_1000;
361 const HYPER = 0b0001_0000;
362 const META = 0b0010_0000;
363 const NONE = 0b0000_0000;
364 }
365}
366
367#[repr(C)]
369pub enum KeyEventKind {
370 Press,
371 Repeat,
372 Release,
373}
374
375bitflags! {
376 #[repr(C)]
382 pub struct KeyEventState: u8 {
383 const KEYPAD = 0b0000_0001;
385 const CAPS_LOCK = 0b0000_1000;
389 const NUM_LOCK = 0b0000_1000;
393 const NONE = 0b0000_0000;
394 }
395}
396
397#[repr(C)]
399pub struct KeyEvent {
400 pub code: KeyCode,
402 pub modifiers: KeyModifiers,
404 pub kind: KeyEventKind,
410 pub state: KeyEventState,
415}
416
417#[repr(C)]
427pub enum MouseEventKind {
428 Down(MouseButton),
430 Up(MouseButton),
432 Drag(MouseButton),
434 Moved,
436 ScrollDown,
438 ScrollUp,
440}
441
442#[repr(C)]
444pub enum MouseButton {
445 Left,
447 Right,
449 Middle,
451}
452
453#[repr(C)]
469pub struct MouseEvent {
470 pub kind: MouseEventKind,
472 pub col: u16,
474 pub row: u16,
476 pub modifiers: KeyModifiers,
478}
479
480#[repr(C)]
482pub enum Event {
483 FocusGained,
485 FocusLost,
487 Key(KeyEvent),
489 Mouse(MouseEvent),
491 Paste(*const libc::c_char),
494 Resize(u16, u16),
497}
498
499#[no_mangle]
511pub extern "C" fn crossterm_event_poll(secs: u64, nanos: u32) -> libc::c_int {
512 let r = crossterm::event::poll(std::time::Duration::new(secs, nanos)).c_unwrap();
513 if crossterm_has_error() {
514 r!()
515 } else {
516 r.into()
517 }
518}
519
520#[no_mangle]
529pub extern "C" fn crossterm_event_read() -> *const libc::c_char {
530 let json_value = match crossterm::event::read() {
531 Ok(evt) => serde_json::to_value(&evt).unwrap_or_else(|e| {
532 serde_json::json!({
533 "error": format!("Unable to convert event {:?} to JSON: {:?}", evt, e),
534 })
535 }),
536 Err(e) => serde_json::json!({
537 "error": format!("Something went wrong with crossterm_event_read(): {:?}", e),
538 }),
539 };
540
541 let json_string = serde_json::to_string(&json_value).unwrap_or_else(|e| {
542 serde_json::json!({
543 "error": format!("Unable to convert JSON value to string: {:?}", e),
544 })
545 .to_string()
546 });
547 convert_string_to_c_char(json_string)
548}
549
550#[no_mangle]
552pub extern "C" fn crossterm_use_stdout() {
553 USE_STDOUT.with(|io| {
554 *io.borrow_mut() = true;
555 });
556}
557
558#[no_mangle]
560pub extern "C" fn crossterm_use_stderr() {
561 USE_STDOUT.with(|io| {
562 *io.borrow_mut() = false;
563 });
564}
565
566#[no_mangle]
568pub extern "C" fn crossterm_sleep(seconds: f64) {
569 let duration = std::time::Duration::from_nanos((seconds * 1e9).round() as u64);
570 std::thread::sleep(duration);
571}
572
573#[no_mangle]
578pub extern "C" fn crossterm_cursor_position_set(col: u16, row: u16) -> libc::c_int {
579 queue!(io!(), crossterm::cursor::MoveTo(col, row)).c_unwrap();
580 r!()
581}
582
583#[no_mangle]
588pub extern "C" fn crossterm_cursor_position(col: &mut u16, row: &mut u16) -> libc::c_int {
589 let (c, r) = crossterm::cursor::position().c_unwrap();
590 *col = c;
591 *row = r;
592 r!()
593}
594
595#[no_mangle]
600pub extern "C" fn crossterm_cursor_move_to(col: u16, row: u16) -> libc::c_int {
601 queue!(io!(), crossterm::cursor::MoveTo(col, row)).c_unwrap();
602 r!()
603}
604
605#[no_mangle]
611pub extern "C" fn crossterm_cursor_move_to_next_line(n: u16) -> libc::c_int {
612 queue!(io!(), crossterm::cursor::MoveToNextLine(n)).c_unwrap();
613 r!()
614}
615
616#[no_mangle]
618pub extern "C" fn crossterm_cursor_move_to_previous_line(n: u16) -> libc::c_int {
619 queue!(io!(), crossterm::cursor::MoveToPreviousLine(n)).c_unwrap();
620 r!()
621}
622
623#[no_mangle]
625pub extern "C" fn crossterm_cursor_move_to_column(col: u16) -> libc::c_int {
626 queue!(io!(), crossterm::cursor::MoveToColumn(col)).c_unwrap();
627 r!()
628}
629
630#[no_mangle]
632pub extern "C" fn crossterm_cursor_move_to_row(row: u16) -> libc::c_int {
633 queue!(io!(), crossterm::cursor::MoveToRow(row)).c_unwrap();
634 r!()
635}
636
637#[no_mangle]
639pub extern "C" fn crossterm_cursor_move_up(rows: u16) -> libc::c_int {
640 queue!(io!(), crossterm::cursor::MoveUp(rows)).c_unwrap();
641 r!()
642}
643
644#[no_mangle]
646pub extern "C" fn crossterm_cursor_move_right(cols: u16) -> libc::c_int {
647 queue!(io!(), crossterm::cursor::MoveRight(cols)).c_unwrap();
648 r!()
649}
650
651#[no_mangle]
653pub extern "C" fn crossterm_cursor_move_down(rows: u16) -> libc::c_int {
654 queue!(io!(), crossterm::cursor::MoveDown(rows)).c_unwrap();
655 r!()
656}
657
658#[no_mangle]
660pub extern "C" fn crossterm_cursor_move_left(cols: u16) -> libc::c_int {
661 queue!(io!(), crossterm::cursor::MoveLeft(cols)).c_unwrap();
662 r!()
663}
664
665#[no_mangle]
667pub extern "C" fn crossterm_cursor_save_position() -> libc::c_int {
668 queue!(io!(), crossterm::cursor::SavePosition).c_unwrap();
669 r!()
670}
671
672#[no_mangle]
674pub extern "C" fn crossterm_cursor_restore_position() -> libc::c_int {
675 queue!(io!(), crossterm::cursor::RestorePosition).c_unwrap();
676 r!()
677}
678
679#[no_mangle]
681pub extern "C" fn crossterm_cursor_hide() -> libc::c_int {
682 queue!(io!(), crossterm::cursor::Hide).c_unwrap();
683 r!()
684}
685
686#[no_mangle]
688pub extern "C" fn crossterm_cursor_show() -> libc::c_int {
689 queue!(io!(), crossterm::cursor::Show).c_unwrap();
690 r!()
691}
692
693#[no_mangle]
695pub extern "C" fn crossterm_cursor_enable_blinking() -> libc::c_int {
696 queue!(io!(), crossterm::cursor::EnableBlinking).c_unwrap();
697 r!()
698}
699
700#[no_mangle]
702pub extern "C" fn crossterm_cursor_disable_blinking() -> libc::c_int {
703 queue!(io!(), crossterm::cursor::DisableBlinking).c_unwrap();
704 r!()
705}
706
707#[repr(C)]
710#[derive(Clone, Copy)]
711pub enum CursorStyle {
712 DefaultUserShape,
714 BlinkingBlock,
716 SteadyBlock,
718 BlinkingUnderScore,
720 SteadyUnderScore,
722 BlinkingBar,
724 SteadyBar,
726}
727
728#[no_mangle]
730pub extern "C" fn crossterm_cursor_style(cursor_style: CursorStyle) -> libc::c_int {
731 let cs = match cursor_style {
732 CursorStyle::DefaultUserShape => crossterm::cursor::SetCursorStyle::DefaultUserShape,
733 CursorStyle::BlinkingBlock => crossterm::cursor::SetCursorStyle::BlinkingBlock,
734 CursorStyle::SteadyBlock => crossterm::cursor::SetCursorStyle::SteadyBlock,
735 CursorStyle::BlinkingUnderScore => crossterm::cursor::SetCursorStyle::BlinkingUnderScore,
736 CursorStyle::SteadyUnderScore => crossterm::cursor::SetCursorStyle::SteadyUnderScore,
737 CursorStyle::BlinkingBar => crossterm::cursor::SetCursorStyle::BlinkingBar,
738 CursorStyle::SteadyBar => crossterm::cursor::SetCursorStyle::SteadyBar,
739 };
740 queue!(io!(), cs).c_unwrap();
741 r!()
742}
743
744#[no_mangle]
746pub extern "C" fn crossterm_cursor_style_default_user_shape() -> libc::c_int {
747 queue!(io!(), crossterm::cursor::SetCursorStyle::DefaultUserShape).c_unwrap();
748 r!()
749}
750
751#[no_mangle]
753pub extern "C" fn crossterm_cursor_style_blinking_block() -> libc::c_int {
754 queue!(io!(), crossterm::cursor::SetCursorStyle::BlinkingBlock).c_unwrap();
755 r!()
756}
757
758#[no_mangle]
760pub extern "C" fn crossterm_cursor_style_steady_block() -> libc::c_int {
761 queue!(io!(), crossterm::cursor::SetCursorStyle::SteadyBlock).c_unwrap();
762 r!()
763}
764
765#[no_mangle]
767pub extern "C" fn crossterm_cursor_style_blinking_underscore() -> libc::c_int {
768 queue!(io!(), crossterm::cursor::SetCursorStyle::BlinkingUnderScore).c_unwrap();
769 r!()
770}
771
772#[no_mangle]
774pub extern "C" fn crossterm_cursor_style_steady_underscore() -> libc::c_int {
775 queue!(io!(), crossterm::cursor::SetCursorStyle::SteadyUnderScore).c_unwrap();
776 r!()
777}
778
779#[no_mangle]
781pub extern "C" fn crossterm_cursor_style_blinking_bar() -> libc::c_int {
782 queue!(io!(), crossterm::cursor::SetCursorStyle::BlinkingBar).c_unwrap();
783 r!()
784}
785
786#[no_mangle]
788pub extern "C" fn crossterm_cursor_style_steady_bar() -> libc::c_int {
789 queue!(io!(), crossterm::cursor::SetCursorStyle::SteadyBar).c_unwrap();
790 r!()
791}
792
793#[no_mangle]
795pub extern "C" fn crossterm_event_enable_mouse_capture() -> libc::c_int {
796 queue!(io!(), crossterm::event::EnableMouseCapture).c_unwrap();
797 r!()
798}
799
800#[no_mangle]
802pub extern "C" fn crossterm_event_disable_mouse_capture() -> libc::c_int {
803 queue!(io!(), crossterm::event::DisableMouseCapture).c_unwrap();
804 r!()
805}
806
807#[repr(u8)]
813pub enum KeyboardEnhancementFlags {
814 DisambiguateEscapeCodes = 0b0000_0001,
817 ReportEventTypes = 0b0000_0010,
820 ReportAlternateKeys = 0b0000_0100,
824 ReportAllKeysAsEscapeCodes = 0b0000_1000,
827}
828
829#[no_mangle]
833pub extern "C" fn crossterm_event_push_keyboard_enhancement_flags(flags: u8) -> libc::c_int {
834 let flags = crossterm::event::KeyboardEnhancementFlags::from_bits(flags).unwrap();
835 queue!(io!(), crossterm::event::PushKeyboardEnhancementFlags(flags)).c_unwrap();
836 r!()
837}
838
839#[no_mangle]
841pub extern "C" fn crossterm_event_pop_keyboard_enhancement_flags() -> libc::c_int {
842 queue!(io!(), crossterm::event::PopKeyboardEnhancementFlags).c_unwrap();
843 r!()
844}
845
846#[no_mangle]
852pub extern "C" fn crossterm_event_enable_focus_change() -> libc::c_int {
853 queue!(io!(), crossterm::event::EnableFocusChange).c_unwrap();
854 r!()
855}
856
857#[no_mangle]
859pub extern "C" fn crossterm_event_disable_focus_change() -> libc::c_int {
860 queue!(io!(), crossterm::event::DisableFocusChange).c_unwrap();
861 r!()
862}
863
864#[no_mangle]
871pub extern "C" fn crossterm_event_enable_bracketed_paste() -> libc::c_int {
872 queue!(io!(), crossterm::event::EnableBracketedPaste).c_unwrap();
873 r!()
874}
875
876#[no_mangle]
878pub extern "C" fn crossterm_event_disable_bracketed_paste() -> libc::c_int {
879 queue!(io!(), crossterm::event::DisableBracketedPaste).c_unwrap();
880 r!()
881}
882
883#[repr(C)]
884pub enum Attribute {
885 Reset,
887 Bold,
889 Dim,
891 Italic,
893 Underlined,
895 DoubleUnderlined,
897 Undercurled,
899 Underdotted,
901 Underdashed,
903 SlowBlink,
905 RapidBlink,
907 Reverse,
909 Hidden,
911 CrossedOut,
913 Fraktur,
917 NoBold,
919 NormalIntensity,
921 NoItalic,
923 NoUnderline,
925 NoBlink,
927 NoReverse,
929 NoHidden,
931 NotCrossedOut,
933 Framed,
935 Encircled,
937 OverLined,
939 NotFramedOrEncircled,
941 NotOverLined,
943}
944
945impl From<Attribute> for crossterm::style::Attribute {
946 fn from(value: Attribute) -> Self {
947 match value {
948 Attribute::Reset => crossterm::style::Attribute::Reset,
949 Attribute::Bold => crossterm::style::Attribute::Bold,
950 Attribute::Dim => crossterm::style::Attribute::Dim,
951 Attribute::Italic => crossterm::style::Attribute::Italic,
952 Attribute::Underlined => crossterm::style::Attribute::Underlined,
953 Attribute::DoubleUnderlined => crossterm::style::Attribute::DoubleUnderlined,
954 Attribute::Undercurled => crossterm::style::Attribute::Undercurled,
955 Attribute::Underdotted => crossterm::style::Attribute::Underdotted,
956 Attribute::Underdashed => crossterm::style::Attribute::Underdashed,
957 Attribute::SlowBlink => crossterm::style::Attribute::SlowBlink,
958 Attribute::RapidBlink => crossterm::style::Attribute::RapidBlink,
959 Attribute::Reverse => crossterm::style::Attribute::Reverse,
960 Attribute::Hidden => crossterm::style::Attribute::Hidden,
961 Attribute::CrossedOut => crossterm::style::Attribute::CrossedOut,
962 Attribute::Fraktur => crossterm::style::Attribute::Fraktur,
963 Attribute::NoBold => crossterm::style::Attribute::NoBold,
964 Attribute::NormalIntensity => crossterm::style::Attribute::NormalIntensity,
965 Attribute::NoItalic => crossterm::style::Attribute::NoItalic,
966 Attribute::NoUnderline => crossterm::style::Attribute::NoUnderline,
967 Attribute::NoBlink => crossterm::style::Attribute::NoBlink,
968 Attribute::NoReverse => crossterm::style::Attribute::NoReverse,
969 Attribute::NoHidden => crossterm::style::Attribute::NoHidden,
970 Attribute::NotCrossedOut => crossterm::style::Attribute::NotCrossedOut,
971 Attribute::Framed => crossterm::style::Attribute::Framed,
972 Attribute::Encircled => crossterm::style::Attribute::Encircled,
973 Attribute::OverLined => crossterm::style::Attribute::OverLined,
974 Attribute::NotFramedOrEncircled => crossterm::style::Attribute::NotFramedOrEncircled,
975 Attribute::NotOverLined => crossterm::style::Attribute::NotOverLined,
976 }
977 }
978}
979
980#[repr(C)]
982#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
983pub struct Attributes(u32);
984
985#[no_mangle]
989pub extern "C" fn crossterm_style_attribute(attr: Attribute) -> libc::c_int {
990 queue!(io!(), crossterm::style::SetAttribute(attr.into())).c_unwrap();
991 r!()
992}
993
994#[no_mangle]
996pub extern "C" fn crossterm_style_attribute_reset() -> libc::c_int {
997 queue!(
998 io!(),
999 crossterm::style::SetAttribute(Attribute::Reset.into())
1000 )
1001 .c_unwrap();
1002 r!()
1003}
1004
1005#[no_mangle]
1007pub extern "C" fn crossterm_style_attribute_bold() -> libc::c_int {
1008 queue!(
1009 io!(),
1010 crossterm::style::SetAttribute(Attribute::Bold.into())
1011 )
1012 .c_unwrap();
1013 r!()
1014}
1015
1016#[no_mangle]
1018pub extern "C" fn crossterm_style_attribute_dim() -> libc::c_int {
1019 queue!(io!(), crossterm::style::SetAttribute(Attribute::Dim.into())).c_unwrap();
1020 r!()
1021}
1022
1023#[no_mangle]
1025pub extern "C" fn crossterm_style_attribute_italic() -> libc::c_int {
1026 queue!(
1027 io!(),
1028 crossterm::style::SetAttribute(Attribute::Italic.into())
1029 )
1030 .c_unwrap();
1031 r!()
1032}
1033
1034#[no_mangle]
1036pub extern "C" fn crossterm_style_attribute_underlined() -> libc::c_int {
1037 queue!(
1038 io!(),
1039 crossterm::style::SetAttribute(Attribute::Underlined.into())
1040 )
1041 .c_unwrap();
1042 r!()
1043}
1044
1045#[no_mangle]
1047pub extern "C" fn crossterm_style_attribute_double_underlined() -> libc::c_int {
1048 queue!(
1049 io!(),
1050 crossterm::style::SetAttribute(Attribute::DoubleUnderlined.into())
1051 )
1052 .c_unwrap();
1053 r!()
1054}
1055
1056#[no_mangle]
1058pub extern "C" fn crossterm_style_attribute_undercurled() -> libc::c_int {
1059 queue!(
1060 io!(),
1061 crossterm::style::SetAttribute(Attribute::Undercurled.into())
1062 )
1063 .c_unwrap();
1064 r!()
1065}
1066
1067#[no_mangle]
1069pub extern "C" fn crossterm_style_attribute_underdotted() -> libc::c_int {
1070 queue!(
1071 io!(),
1072 crossterm::style::SetAttribute(Attribute::Underdotted.into())
1073 )
1074 .c_unwrap();
1075 r!()
1076}
1077
1078#[no_mangle]
1080pub extern "C" fn crossterm_style_attribute_underdashed() -> libc::c_int {
1081 queue!(
1082 io!(),
1083 crossterm::style::SetAttribute(Attribute::Underdashed.into())
1084 )
1085 .c_unwrap();
1086 r!()
1087}
1088
1089#[no_mangle]
1091pub extern "C" fn crossterm_style_attribute_slow_blink() -> libc::c_int {
1092 queue!(
1093 io!(),
1094 crossterm::style::SetAttribute(Attribute::SlowBlink.into())
1095 )
1096 .c_unwrap();
1097 r!()
1098}
1099
1100#[no_mangle]
1102pub extern "C" fn crossterm_style_attribute_rapid_blink() -> libc::c_int {
1103 queue!(
1104 io!(),
1105 crossterm::style::SetAttribute(Attribute::RapidBlink.into())
1106 )
1107 .c_unwrap();
1108 r!()
1109}
1110
1111#[no_mangle]
1113pub extern "C" fn crossterm_style_attribute_reverse() -> libc::c_int {
1114 queue!(
1115 io!(),
1116 crossterm::style::SetAttribute(Attribute::Reverse.into())
1117 )
1118 .c_unwrap();
1119 r!()
1120}
1121
1122#[no_mangle]
1124pub extern "C" fn crossterm_style_attribute_hidden() -> libc::c_int {
1125 queue!(
1126 io!(),
1127 crossterm::style::SetAttribute(Attribute::Hidden.into())
1128 )
1129 .c_unwrap();
1130 r!()
1131}
1132
1133#[no_mangle]
1135pub extern "C" fn crossterm_style_attribute_crossed_out() -> libc::c_int {
1136 queue!(
1137 io!(),
1138 crossterm::style::SetAttribute(Attribute::CrossedOut.into())
1139 )
1140 .c_unwrap();
1141 r!()
1142}
1143
1144#[no_mangle]
1146pub extern "C" fn crossterm_style_attribute_fraktur() -> libc::c_int {
1147 queue!(
1148 io!(),
1149 crossterm::style::SetAttribute(Attribute::Fraktur.into())
1150 )
1151 .c_unwrap();
1152 r!()
1153}
1154
1155#[no_mangle]
1157pub extern "C" fn crossterm_style_attribute_no_bold() -> libc::c_int {
1158 queue!(
1159 io!(),
1160 crossterm::style::SetAttribute(Attribute::NoBold.into())
1161 )
1162 .c_unwrap();
1163 r!()
1164}
1165
1166#[no_mangle]
1168pub extern "C" fn crossterm_style_attribute_normal_intensity() -> libc::c_int {
1169 queue!(
1170 io!(),
1171 crossterm::style::SetAttribute(Attribute::NormalIntensity.into())
1172 )
1173 .c_unwrap();
1174 r!()
1175}
1176
1177#[no_mangle]
1179pub extern "C" fn crossterm_style_attribute_no_italic() -> libc::c_int {
1180 queue!(
1181 io!(),
1182 crossterm::style::SetAttribute(Attribute::NoItalic.into())
1183 )
1184 .c_unwrap();
1185 r!()
1186}
1187
1188#[no_mangle]
1190pub extern "C" fn crossterm_style_attribute_no_underline() -> libc::c_int {
1191 queue!(
1192 io!(),
1193 crossterm::style::SetAttribute(Attribute::NoUnderline.into())
1194 )
1195 .c_unwrap();
1196 r!()
1197}
1198
1199#[no_mangle]
1201pub extern "C" fn crossterm_style_attribute_no_blink() -> libc::c_int {
1202 queue!(
1203 io!(),
1204 crossterm::style::SetAttribute(Attribute::NoBlink.into())
1205 )
1206 .c_unwrap();
1207 r!()
1208}
1209
1210#[no_mangle]
1212pub extern "C" fn crossterm_style_attribute_no_reverse() -> libc::c_int {
1213 queue!(
1214 io!(),
1215 crossterm::style::SetAttribute(Attribute::NoReverse.into())
1216 )
1217 .c_unwrap();
1218 r!()
1219}
1220
1221#[no_mangle]
1223pub extern "C" fn crossterm_style_attribute_no_hidden() -> libc::c_int {
1224 queue!(
1225 io!(),
1226 crossterm::style::SetAttribute(Attribute::NoHidden.into())
1227 )
1228 .c_unwrap();
1229 r!()
1230}
1231
1232#[no_mangle]
1234pub extern "C" fn crossterm_style_attribute_not_crossed_out() -> libc::c_int {
1235 queue!(
1236 io!(),
1237 crossterm::style::SetAttribute(Attribute::NotCrossedOut.into())
1238 )
1239 .c_unwrap();
1240 r!()
1241}
1242
1243#[no_mangle]
1245pub extern "C" fn crossterm_style_print_char(c: u32) -> libc::c_int {
1246 if let Some(ch) = std::char::from_u32(c) {
1247 queue!(io!(), crossterm::style::Print(ch)).c_unwrap();
1248 r!()
1249 } else {
1250 set_last_error(anyhow::anyhow!("Unable to convert {} to valid char", c));
1251 -1
1252 }
1253}
1254
1255#[no_mangle]
1266pub unsafe extern "C" fn crossterm_style_print_string(s: *const libc::c_char) -> libc::c_int {
1267 if s.is_null() {
1268 RESULT.with(|r| {
1269 *r.borrow_mut() = -1;
1270 });
1271 set_last_error(anyhow::anyhow!("Received null pointer for print string"));
1272 return r!();
1273 };
1274 let c_str: &std::ffi::CStr = std::ffi::CStr::from_ptr(s);
1275 if let Ok(string) = c_str.to_str() {
1276 queue!(io!(), crossterm::style::Print(string)).c_unwrap();
1277 r!()
1278 } else {
1279 RESULT.with(|r| {
1280 *r.borrow_mut() = -1;
1281 });
1282 set_last_error(anyhow::anyhow!(
1283 "Received invalid UTF-8 string for print string"
1284 ));
1285 r!()
1286 }
1287}
1288
1289#[no_mangle]
1300pub unsafe extern "C" fn crossterm_style_print(s: *const libc::c_char) -> libc::c_int {
1301 crossterm_style_print_string(s)
1302}
1303
1304#[repr(C)]
1305#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
1306pub enum Color {
1307 Reset,
1309 Black,
1311 DarkGrey,
1313 Red,
1315 DarkRed,
1317 Green,
1319 DarkGreen,
1321 Yellow,
1323 DarkYellow,
1325 Blue,
1327 DarkBlue,
1329 Magenta,
1331 DarkMagenta,
1333 Cyan,
1335 DarkCyan,
1337 White,
1339 Grey,
1341 Rgb { r: u8, g: u8, b: u8 },
1345 AnsiValue(u8),
1349}
1350
1351impl From<Color> for crossterm::style::Color {
1352 fn from(color: Color) -> Self {
1353 match color {
1354 Color::Reset => crossterm::style::Color::Reset,
1355 Color::Black => crossterm::style::Color::Black,
1356 Color::DarkGrey => crossterm::style::Color::DarkGrey,
1357 Color::Red => crossterm::style::Color::Red,
1358 Color::DarkRed => crossterm::style::Color::DarkRed,
1359 Color::Green => crossterm::style::Color::Green,
1360 Color::DarkGreen => crossterm::style::Color::DarkGreen,
1361 Color::Yellow => crossterm::style::Color::Yellow,
1362 Color::DarkYellow => crossterm::style::Color::DarkYellow,
1363 Color::Blue => crossterm::style::Color::Blue,
1364 Color::DarkBlue => crossterm::style::Color::DarkBlue,
1365 Color::Magenta => crossterm::style::Color::Magenta,
1366 Color::DarkMagenta => crossterm::style::Color::DarkMagenta,
1367 Color::Cyan => crossterm::style::Color::Cyan,
1368 Color::DarkCyan => crossterm::style::Color::DarkCyan,
1369 Color::White => crossterm::style::Color::White,
1370 Color::Grey => crossterm::style::Color::Grey,
1371 Color::Rgb { r, g, b } => crossterm::style::Color::Rgb { r, g, b },
1372 Color::AnsiValue(v) => crossterm::style::Color::AnsiValue(v),
1373 }
1374 }
1375}
1376
1377#[no_mangle]
1381pub extern "C" fn crossterm_style_background_color(color: Color) -> libc::c_int {
1382 queue!(io!(), crossterm::style::SetBackgroundColor(color.into())).c_unwrap();
1383 r!()
1384}
1385
1386#[no_mangle]
1388pub extern "C" fn crossterm_style_background_color_rgb(r: u8, g: u8, b: u8) -> libc::c_int {
1389 crossterm_style_background_color(Color::Rgb { r, g, b })
1390}
1391
1392#[no_mangle]
1394pub extern "C" fn crossterm_style_background_color_ansi(value: u8) -> libc::c_int {
1395 crossterm_style_background_color(Color::AnsiValue(value))
1396}
1397
1398#[no_mangle]
1400pub extern "C" fn crossterm_style_background_color_reset() -> libc::c_int {
1401 crossterm_style_background_color(Color::Reset)
1402}
1403
1404#[no_mangle]
1406pub extern "C" fn crossterm_style_background_color_black() -> libc::c_int {
1407 crossterm_style_background_color(Color::Black)
1408}
1409
1410#[no_mangle]
1412pub extern "C" fn crossterm_style_background_color_dark_grey() -> libc::c_int {
1413 crossterm_style_background_color(Color::DarkGrey)
1414}
1415
1416#[no_mangle]
1418pub extern "C" fn crossterm_style_background_color_red() -> libc::c_int {
1419 crossterm_style_background_color(Color::Red)
1420}
1421
1422#[no_mangle]
1424pub extern "C" fn crossterm_style_background_color_dark_red() -> libc::c_int {
1425 crossterm_style_background_color(Color::DarkRed)
1426}
1427
1428#[no_mangle]
1430pub extern "C" fn crossterm_style_background_color_green() -> libc::c_int {
1431 crossterm_style_background_color(Color::Green)
1432}
1433
1434#[no_mangle]
1436pub extern "C" fn crossterm_style_background_color_dark_green() -> libc::c_int {
1437 crossterm_style_background_color(Color::DarkGreen)
1438}
1439
1440#[no_mangle]
1442pub extern "C" fn crossterm_style_background_color_yellow() -> libc::c_int {
1443 crossterm_style_background_color(Color::Yellow)
1444}
1445
1446#[no_mangle]
1448pub extern "C" fn crossterm_style_background_color_dark_yellow() -> libc::c_int {
1449 crossterm_style_background_color(Color::DarkYellow)
1450}
1451
1452#[no_mangle]
1454pub extern "C" fn crossterm_style_background_color_blue() -> libc::c_int {
1455 crossterm_style_background_color(Color::Blue)
1456}
1457
1458#[no_mangle]
1460pub extern "C" fn crossterm_style_background_color_dark_blue() -> libc::c_int {
1461 crossterm_style_background_color(Color::DarkBlue)
1462}
1463
1464#[no_mangle]
1466pub extern "C" fn crossterm_style_background_color_magenta() -> libc::c_int {
1467 crossterm_style_background_color(Color::Magenta)
1468}
1469
1470#[no_mangle]
1472pub extern "C" fn crossterm_style_background_color_dark_magenta() -> libc::c_int {
1473 crossterm_style_background_color(Color::DarkMagenta)
1474}
1475
1476#[no_mangle]
1478pub extern "C" fn crossterm_style_background_color_cyan() -> libc::c_int {
1479 crossterm_style_background_color(Color::Cyan)
1480}
1481
1482#[no_mangle]
1484pub extern "C" fn crossterm_style_background_color_dark_cyan() -> libc::c_int {
1485 crossterm_style_background_color(Color::DarkCyan)
1486}
1487
1488#[no_mangle]
1490pub extern "C" fn crossterm_style_background_color_white() -> libc::c_int {
1491 crossterm_style_background_color(Color::White)
1492}
1493
1494#[no_mangle]
1496pub extern "C" fn crossterm_style_background_color_grey() -> libc::c_int {
1497 crossterm_style_background_color(Color::Grey)
1498}
1499
1500#[no_mangle]
1504pub extern "C" fn crossterm_style_foreground_color(color: Color) -> libc::c_int {
1505 queue!(io!(), crossterm::style::SetForegroundColor(color.into())).c_unwrap();
1506 r!()
1507}
1508
1509#[no_mangle]
1511pub extern "C" fn crossterm_style_foreground_color_rgb(r: u8, g: u8, b: u8) -> libc::c_int {
1512 crossterm_style_foreground_color(Color::Rgb { r, g, b })
1513}
1514
1515#[no_mangle]
1517pub extern "C" fn crossterm_style_foreground_color_ansi(value: u8) -> libc::c_int {
1518 crossterm_style_foreground_color(Color::AnsiValue(value))
1519}
1520
1521#[no_mangle]
1523pub extern "C" fn crossterm_style_foreground_color_reset() -> libc::c_int {
1524 crossterm_style_foreground_color(Color::Reset)
1525}
1526
1527#[no_mangle]
1529pub extern "C" fn crossterm_style_foreground_color_black() -> libc::c_int {
1530 crossterm_style_foreground_color(Color::Black)
1531}
1532
1533#[no_mangle]
1535pub extern "C" fn crossterm_style_foreground_color_dark_grey() -> libc::c_int {
1536 crossterm_style_foreground_color(Color::DarkGrey)
1537}
1538
1539#[no_mangle]
1541pub extern "C" fn crossterm_style_foreground_color_red() -> libc::c_int {
1542 crossterm_style_foreground_color(Color::Red)
1543}
1544
1545#[no_mangle]
1547pub extern "C" fn crossterm_style_foreground_color_dark_red() -> libc::c_int {
1548 crossterm_style_foreground_color(Color::DarkRed)
1549}
1550
1551#[no_mangle]
1553pub extern "C" fn crossterm_style_foreground_color_green() -> libc::c_int {
1554 crossterm_style_foreground_color(Color::Green)
1555}
1556
1557#[no_mangle]
1559pub extern "C" fn crossterm_style_foreground_color_dark_green() -> libc::c_int {
1560 crossterm_style_foreground_color(Color::DarkGreen)
1561}
1562
1563#[no_mangle]
1565pub extern "C" fn crossterm_style_foreground_color_yellow() -> libc::c_int {
1566 crossterm_style_foreground_color(Color::Yellow)
1567}
1568
1569#[no_mangle]
1571pub extern "C" fn crossterm_style_foreground_color_dark_yellow() -> libc::c_int {
1572 crossterm_style_foreground_color(Color::DarkYellow)
1573}
1574
1575#[no_mangle]
1577pub extern "C" fn crossterm_style_foreground_color_blue() -> libc::c_int {
1578 crossterm_style_foreground_color(Color::Blue)
1579}
1580
1581#[no_mangle]
1583pub extern "C" fn crossterm_style_foreground_color_dark_blue() -> libc::c_int {
1584 crossterm_style_foreground_color(Color::DarkBlue)
1585}
1586
1587#[no_mangle]
1589pub extern "C" fn crossterm_style_foreground_color_magenta() -> libc::c_int {
1590 crossterm_style_foreground_color(Color::Magenta)
1591}
1592
1593#[no_mangle]
1595pub extern "C" fn crossterm_style_foreground_color_dark_magenta() -> libc::c_int {
1596 crossterm_style_foreground_color(Color::DarkMagenta)
1597}
1598
1599#[no_mangle]
1601pub extern "C" fn crossterm_style_foreground_color_cyan() -> libc::c_int {
1602 crossterm_style_foreground_color(Color::Cyan)
1603}
1604
1605#[no_mangle]
1607pub extern "C" fn crossterm_style_foreground_color_dark_cyan() -> libc::c_int {
1608 crossterm_style_foreground_color(Color::DarkCyan)
1609}
1610
1611#[no_mangle]
1613pub extern "C" fn crossterm_style_foreground_color_white() -> libc::c_int {
1614 crossterm_style_foreground_color(Color::White)
1615}
1616
1617#[no_mangle]
1619pub extern "C" fn crossterm_style_foreground_color_grey() -> libc::c_int {
1620 crossterm_style_foreground_color(Color::Grey)
1621}
1622
1623#[no_mangle]
1627pub extern "C" fn crossterm_style_underline_color(color: Color) -> libc::c_int {
1628 queue!(io!(), crossterm::style::SetUnderlineColor(color.into())).c_unwrap();
1629 r!()
1630}
1631
1632#[no_mangle]
1634pub extern "C" fn crossterm_style_underline_color_rgb(r: u8, g: u8, b: u8) -> libc::c_int {
1635 crossterm_style_underline_color(Color::Rgb { r, g, b })
1636}
1637
1638#[no_mangle]
1640pub extern "C" fn crossterm_style_underline_color_ansi(value: u8) -> libc::c_int {
1641 crossterm_style_underline_color(Color::AnsiValue(value))
1642}
1643
1644#[no_mangle]
1646pub extern "C" fn crossterm_style_underline_color_reset() -> libc::c_int {
1647 crossterm_style_underline_color(Color::Reset)
1648}
1649
1650#[no_mangle]
1652pub extern "C" fn crossterm_style_underline_color_black() -> libc::c_int {
1653 crossterm_style_underline_color(Color::Black)
1654}
1655
1656#[no_mangle]
1658pub extern "C" fn crossterm_style_underline_color_dark_grey() -> libc::c_int {
1659 crossterm_style_underline_color(Color::DarkGrey)
1660}
1661
1662#[no_mangle]
1664pub extern "C" fn crossterm_style_underline_color_red() -> libc::c_int {
1665 crossterm_style_underline_color(Color::Red)
1666}
1667
1668#[no_mangle]
1670pub extern "C" fn crossterm_style_underline_color_dark_red() -> libc::c_int {
1671 crossterm_style_underline_color(Color::DarkRed)
1672}
1673
1674#[no_mangle]
1676pub extern "C" fn crossterm_style_underline_color_green() -> libc::c_int {
1677 crossterm_style_underline_color(Color::Green)
1678}
1679
1680#[no_mangle]
1682pub extern "C" fn crossterm_style_underline_color_dark_green() -> libc::c_int {
1683 crossterm_style_underline_color(Color::DarkGreen)
1684}
1685
1686#[no_mangle]
1688pub extern "C" fn crossterm_style_underline_color_yellow() -> libc::c_int {
1689 crossterm_style_underline_color(Color::Yellow)
1690}
1691
1692#[no_mangle]
1694pub extern "C" fn crossterm_style_underline_color_dark_yellow() -> libc::c_int {
1695 crossterm_style_underline_color(Color::DarkYellow)
1696}
1697
1698#[no_mangle]
1700pub extern "C" fn crossterm_style_underline_color_blue() -> libc::c_int {
1701 crossterm_style_underline_color(Color::Blue)
1702}
1703
1704#[no_mangle]
1706pub extern "C" fn crossterm_style_underline_color_dark_blue() -> libc::c_int {
1707 crossterm_style_underline_color(Color::DarkBlue)
1708}
1709
1710#[no_mangle]
1712pub extern "C" fn crossterm_style_underline_color_magenta() -> libc::c_int {
1713 crossterm_style_underline_color(Color::Magenta)
1714}
1715
1716#[no_mangle]
1718pub extern "C" fn crossterm_style_underline_color_dark_magenta() -> libc::c_int {
1719 crossterm_style_underline_color(Color::DarkMagenta)
1720}
1721
1722#[no_mangle]
1724pub extern "C" fn crossterm_style_underline_color_cyan() -> libc::c_int {
1725 crossterm_style_underline_color(Color::Cyan)
1726}
1727
1728#[no_mangle]
1730pub extern "C" fn crossterm_style_underline_color_dark_cyan() -> libc::c_int {
1731 crossterm_style_underline_color(Color::DarkCyan)
1732}
1733
1734#[no_mangle]
1736pub extern "C" fn crossterm_style_underline_color_white() -> libc::c_int {
1737 crossterm_style_underline_color(Color::White)
1738}
1739
1740#[no_mangle]
1742pub extern "C" fn crossterm_style_underline_color_grey() -> libc::c_int {
1743 crossterm_style_underline_color(Color::Grey)
1744}
1745
1746#[no_mangle]
1748pub extern "C" fn crossterm_style_reset_color() -> libc::c_int {
1749 queue!(io!(), crossterm::style::ResetColor).c_unwrap();
1750 r!()
1751}
1752
1753#[no_mangle]
1759pub extern "C" fn crossterm_colors() -> *const libc::c_char {
1760 convert_string_to_c_char(COLORS.to_string())
1761}
1762
1763#[no_mangle]
1767pub fn crossterm_terminal_is_raw_mode_enabled() -> bool {
1768 crossterm::terminal::is_raw_mode_enabled().c_unwrap()
1769}
1770
1771#[no_mangle]
1773pub extern "C" fn crossterm_terminal_disable_raw_mode() -> libc::c_int {
1774 crossterm::terminal::disable_raw_mode().c_unwrap();
1775 r!()
1776}
1777
1778#[no_mangle]
1780pub extern "C" fn crossterm_terminal_enable_raw_mode() -> libc::c_int {
1781 crossterm::terminal::enable_raw_mode().c_unwrap();
1782 r!()
1783}
1784
1785#[no_mangle]
1787pub extern "C" fn crossterm_terminal_size(width: &mut u16, height: &mut u16) -> libc::c_int {
1788 let (w, h) = crossterm::terminal::size().c_unwrap();
1789 *width = w;
1790 *height = h;
1791 r!()
1792}
1793
1794#[no_mangle]
1796pub extern "C" fn crossterm_terminal_size_set(cols: u16, rows: u16) -> libc::c_int {
1797 queue!(io!(), crossterm::terminal::SetSize(cols, rows)).c_unwrap();
1798 r!()
1799}
1800
1801#[no_mangle]
1803pub extern "C" fn crossterm_terminal_disable_line_wrap() -> libc::c_int {
1804 queue!(io!(), crossterm::terminal::DisableLineWrap).c_unwrap();
1805 r!()
1806}
1807
1808#[no_mangle]
1810pub extern "C" fn crossterm_terminal_enable_line_wrap() -> libc::c_int {
1811 queue!(io!(), crossterm::terminal::EnableLineWrap).c_unwrap();
1812 r!()
1813}
1814
1815#[no_mangle]
1817pub extern "C" fn crossterm_terminal_enter_alternate_screen() -> libc::c_int {
1818 queue!(io!(), crossterm::terminal::EnterAlternateScreen).c_unwrap();
1819 r!()
1820}
1821
1822#[no_mangle]
1824pub extern "C" fn crossterm_terminal_leave_alternate_screen() -> libc::c_int {
1825 queue!(io!(), crossterm::terminal::LeaveAlternateScreen).c_unwrap();
1826 r!()
1827}
1828
1829#[repr(C)]
1831pub enum ClearType {
1832 All,
1834 Purge,
1836 FromCursorDown,
1838 FromCursorUp,
1840 CurrentLine,
1842 UntilNewLine,
1844}
1845
1846impl From<ClearType> for crossterm::terminal::ClearType {
1847 fn from(value: ClearType) -> Self {
1848 match value {
1849 ClearType::All => crossterm::terminal::ClearType::All,
1850 ClearType::Purge => crossterm::terminal::ClearType::Purge,
1851 ClearType::FromCursorDown => crossterm::terminal::ClearType::FromCursorDown,
1852 ClearType::FromCursorUp => crossterm::terminal::ClearType::FromCursorUp,
1853 ClearType::CurrentLine => crossterm::terminal::ClearType::CurrentLine,
1854 ClearType::UntilNewLine => crossterm::terminal::ClearType::UntilNewLine,
1855 }
1856 }
1857}
1858
1859#[no_mangle]
1861pub extern "C" fn crossterm_terminal_scroll_up(n: libc::c_ushort) -> libc::c_int {
1862 queue!(io!(), crossterm::terminal::ScrollUp(n)).c_unwrap();
1863 r!()
1864}
1865
1866#[no_mangle]
1868pub extern "C" fn crossterm_terminal_scroll_down(n: libc::c_ushort) -> libc::c_int {
1869 queue!(io!(), crossterm::terminal::ScrollDown(n)).c_unwrap();
1870 r!()
1871}
1872
1873#[no_mangle]
1875pub extern "C" fn crossterm_terminal_clear(ct: ClearType) -> libc::c_int {
1876 queue!(io!(), crossterm::terminal::Clear(ct.into())).c_unwrap();
1877 r!()
1878}
1879
1880#[no_mangle]
1891pub unsafe extern "C" fn crossterm_terminal_title(title: *const libc::c_char) -> libc::c_int {
1892 if title.is_null() {
1893 RESULT.with(|r| {
1894 *r.borrow_mut() = -1;
1895 });
1896 set_last_error(anyhow::anyhow!("Received null pointer for title string"));
1897 return r!();
1898 };
1899 let c_str: &std::ffi::CStr = std::ffi::CStr::from_ptr(title);
1900 if let Ok(string) = c_str.to_str() {
1901 queue!(io!(), crossterm::terminal::SetTitle(string)).c_unwrap();
1902 r!()
1903 } else {
1904 RESULT.with(|r| {
1905 *r.borrow_mut() = -1;
1906 });
1907 set_last_error(anyhow::anyhow!("Received invalid UTF-8 string for title"));
1908 r!()
1909 }
1910}
1911
1912#[no_mangle]
1929pub extern "C" fn crossterm_terminal_begin_synchronized_update() -> libc::c_int {
1930 queue!(io!(), crossterm::terminal::BeginSynchronizedUpdate).c_unwrap();
1931 r!()
1932}
1933
1934#[no_mangle]
1951pub extern "C" fn crossterm_terminal_end_synchronized_update() -> libc::c_int {
1952 queue!(io!(), crossterm::terminal::EndSynchronizedUpdate).c_unwrap();
1953 r!()
1954}
1955
1956#[no_mangle]
1958pub extern "C" fn crossterm_terminal_ring_bell() -> libc::c_int {
1959 queue!(io!(), crossterm::style::Print("\x07")).c_unwrap();
1960 r!()
1961}
1962
1963#[no_mangle]
1967pub extern "C" fn crossterm_flush() -> libc::c_int {
1968 if let Err(err) = io!().flush() {
1969 set_last_error(anyhow::anyhow!(err))
1970 }
1971 r!()
1972}