1 use crate::sys;
2 use std::ptr::null_mut;
3 use std::ffi::{CStr, CString};
4 
5 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
6 pub enum Category {
7     Application,
8     Error,
9     Assert,
10     System,
11     Audio,
12     Video,
13     Render,
14     Input,
15     Test,
16     Custom,
17     Unknown,
18 }
19 
20 impl Category {
21     #[allow(dead_code)]
from_ll(value: u32) -> Category22     fn from_ll(value: u32) -> Category {
23         if value == sys::SDL_LOG_CATEGORY_APPLICATION as u32 {
24             Category::Application
25         } else if value == sys::SDL_LOG_CATEGORY_ERROR as u32 {
26             Category::Error
27         } else if value == sys::SDL_LOG_CATEGORY_ASSERT as u32 {
28             Category::Assert
29         } else if value == sys::SDL_LOG_CATEGORY_SYSTEM as u32 {
30             Category::System
31         } else if value == sys::SDL_LOG_CATEGORY_AUDIO as u32 {
32             Category::Audio
33         } else if value == sys::SDL_LOG_CATEGORY_VIDEO as u32 {
34             Category::Video
35         } else if value == sys::SDL_LOG_CATEGORY_RENDER as u32 {
36             Category::Render
37         } else if value == sys::SDL_LOG_CATEGORY_INPUT as u32 {
38             Category::Input
39         } else if value == sys::SDL_LOG_CATEGORY_TEST as u32 {
40             Category::Test
41         } else {
42             Category::Custom
43         }
44     }
45 }
46 
47 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
48 pub enum Priority {
49     Verbose,
50     Debug,
51     Info,
52     Warn,
53     Error,
54     Critical,
55 }
56 
57 impl Priority {
from_ll(value: sys::SDL_LogPriority) -> Priority58     fn from_ll(value: sys::SDL_LogPriority) -> Priority {
59         use crate::sys::SDL_LogPriority::*;
60         match value {
61             SDL_LOG_PRIORITY_VERBOSE => Priority::Verbose,
62             SDL_LOG_PRIORITY_DEBUG => Priority::Debug,
63             SDL_LOG_PRIORITY_INFO => Priority::Info,
64             SDL_LOG_PRIORITY_WARN => Priority::Warn,
65             SDL_LOG_PRIORITY_ERROR => Priority::Error,
66             SDL_LOG_PRIORITY_CRITICAL | _ => Priority::Critical,
67         }
68     }
69 }
70 
dummy(_priority: Priority, _category: Category, _message: &str)71 fn dummy(_priority: Priority, _category: Category, _message: &str) {
72 }
73 
74 #[allow(non_upper_case_globals)]
75 // NEVER make this public
76 static mut custom_log_fn : fn(Priority, Category, &str) = dummy;
77 
rust_sdl2_log_fn(_userdata: *mut libc::c_void, category: libc::c_int, priority: sys::SDL_LogPriority, message: *const libc::c_char)78 unsafe extern "C" fn rust_sdl2_log_fn(_userdata: *mut libc::c_void,
79                                    category: libc::c_int,
80                                    priority: sys::SDL_LogPriority,
81                                    message: *const libc::c_char) {
82     let category = Category::from_ll(category as u32);
83     let priority = Priority::from_ll(priority);
84     let message = CStr::from_ptr(message).to_string_lossy();
85     custom_log_fn(priority, category, &*message);
86 }
87 
set_output_function(callback : fn(Priority, Category, &str))88 pub fn set_output_function(callback : fn(Priority, Category, &str)) {
89     unsafe {
90         custom_log_fn = callback;
91         sys::SDL_LogSetOutputFunction(Some(rust_sdl2_log_fn), null_mut());
92     };
93 }
94 
95 /// Standard log function which takes as priority INFO and
96 /// as category APPLICATION
log(message: &str)97 pub fn log(message: &str) {
98     let message = message.replace('%', "%%");
99     let message = CString::new(message).unwrap();
100     unsafe {
101         crate::sys::SDL_Log(message.into_raw());
102     }
103 }
104