Merge pull request #105 from mahkoh/jorth/unstable
all: remove extern_types feature
This commit is contained in:
commit
ecc45f01f4
26 changed files with 215 additions and 215 deletions
|
|
@ -8,5 +8,4 @@ tasks:
|
||||||
rustup toolchain install stable
|
rustup toolchain install stable
|
||||||
- build: |
|
- build: |
|
||||||
cd jay
|
cd jay
|
||||||
export RUSTC_BOOTSTRAP=1
|
|
||||||
cargo build
|
cargo build
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ tasks:
|
||||||
sudo chmod o+rw /dev/dri/card*
|
sudo chmod o+rw /dev/dri/card*
|
||||||
- build: |
|
- build: |
|
||||||
cd jay
|
cd jay
|
||||||
export RUSTC_BOOTSTRAP=1
|
|
||||||
cargo build --features it
|
cargo build --features it
|
||||||
- test: |
|
- test: |
|
||||||
cd jay
|
cd jay
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,4 @@ tasks:
|
||||||
rustup toolchain install stable
|
rustup toolchain install stable
|
||||||
- test: |
|
- test: |
|
||||||
cd jay
|
cd jay
|
||||||
export RUSTC_BOOTSTRAP=1
|
|
||||||
cargo test
|
cargo test
|
||||||
|
|
|
||||||
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -196,12 +196,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.83"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
|
@ -501,6 +498,7 @@ dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bstr",
|
"bstr",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"cc",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ repc = "0.1.1"
|
||||||
anyhow = "1.0.79"
|
anyhow = "1.0.79"
|
||||||
bstr = { version = "1.9.0", default-features = false, features = ["std"] }
|
bstr = { version = "1.9.0", default-features = false, features = ["std"] }
|
||||||
shaderc = "0.8.3"
|
shaderc = "0.8.3"
|
||||||
|
cc = "1.0.86"
|
||||||
|
|
||||||
#[profile.dev.build-override]
|
#[profile.dev.build-override]
|
||||||
#opt-level = 3
|
#opt-level = 3
|
||||||
|
|
|
||||||
|
|
@ -88,13 +88,13 @@ only the latest stable version is supported.
|
||||||
|
|
||||||
You can now build Jay using this command:
|
You can now build Jay using this command:
|
||||||
```sh
|
```sh
|
||||||
RUSTC_BOOTSTRAP=1 cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
The resulting binary will be located at `./target/release/jay`.
|
The resulting binary will be located at `./target/release/jay`.
|
||||||
|
|
||||||
Alternatively, cargo can also install the binary for you:
|
Alternatively, cargo can also install the binary for you:
|
||||||
```sh
|
```sh
|
||||||
RUSTC_BOOTSTRAP=1 cargo install --path .
|
cargo install --path .
|
||||||
```
|
```
|
||||||
This will install the binary at `$HOME/.cargo/bin/jay`. If you have not already
|
This will install the binary at `$HOME/.cargo/bin/jay`. If you have not already
|
||||||
done so, you can add `$HOME/.cargo/bin` to your path.
|
done so, you can add `$HOME/.cargo/bin` to your path.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ use std::{
|
||||||
|
|
||||||
mod egl;
|
mod egl;
|
||||||
mod enums;
|
mod enums;
|
||||||
|
mod logging;
|
||||||
mod tokens;
|
mod tokens;
|
||||||
mod vulkan;
|
mod vulkan;
|
||||||
mod wire;
|
mod wire;
|
||||||
|
|
@ -49,6 +50,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
enums::main()?;
|
enums::main()?;
|
||||||
egl::main()?;
|
egl::main()?;
|
||||||
vulkan::main()?;
|
vulkan::main()?;
|
||||||
|
logging::main()?;
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build/build.rs");
|
println!("cargo:rerun-if-changed=build/build.rs");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
5
build/logging.rs
Normal file
5
build/logging.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
pub fn main() -> anyhow::Result<()> {
|
||||||
|
println!("cargo:rerun-if-changed=src/bridge.c");
|
||||||
|
cc::Build::new().file("src/bridge.c").compile("bridge");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ impl Drop for Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
pub(crate) static CLIENT: std::cell::Cell<*const Client> = const { std::cell::Cell::new(ptr::null()) };
|
pub(crate) static CLIENT: Cell<*const Client> = const { Cell::new(ptr::null()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn with_client<T, F: FnOnce(&Client) -> T>(data: *const u8, f: F) -> T {
|
unsafe fn with_client<T, F: FnOnce(&Client) -> T>(data: *const u8, f: F) -> T {
|
||||||
|
|
|
||||||
49
src/bridge.c
Normal file
49
src/bridge.c
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static char *fmt(const char *format, va_list args) {
|
||||||
|
char *line;
|
||||||
|
int ret = vasprintf(&line, format, args);
|
||||||
|
if (ret < 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void jay_libinput_log_handler(
|
||||||
|
void *libinput,
|
||||||
|
int priority,
|
||||||
|
const char *line
|
||||||
|
);
|
||||||
|
|
||||||
|
void jay_libinput_log_handler_bridge(
|
||||||
|
void *libinput,
|
||||||
|
int priority,
|
||||||
|
const char *format,
|
||||||
|
va_list args
|
||||||
|
) {
|
||||||
|
char *line = fmt(format, args);
|
||||||
|
jay_libinput_log_handler(libinput, priority, line);
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void jay_xkbcommon_log_handler(
|
||||||
|
void *ctx,
|
||||||
|
int xkb_log_level,
|
||||||
|
const char *line
|
||||||
|
);
|
||||||
|
|
||||||
|
void jay_xkbcommon_log_handler_bridge(
|
||||||
|
void *ctx,
|
||||||
|
int xkb_log_level,
|
||||||
|
const char *format,
|
||||||
|
va_list args
|
||||||
|
) {
|
||||||
|
char *line = fmt(format, args);
|
||||||
|
jay_xkbcommon_log_handler(ctx, xkb_log_level, line);
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
|
@ -88,12 +88,12 @@ impl ClientMemOffset {
|
||||||
}
|
}
|
||||||
let mref = MemRef {
|
let mref = MemRef {
|
||||||
mem: &*self.mem,
|
mem: &*self.mem,
|
||||||
outer: MEM,
|
outer: MEM.get(),
|
||||||
};
|
};
|
||||||
MEM = &mref;
|
MEM.set(&mref);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
let res = f(&*self.data);
|
let res = f(&*self.data);
|
||||||
MEM = mref.outer;
|
MEM.set(mref.outer);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
match self.mem.failed.get() {
|
match self.mem.failed.get() {
|
||||||
true => Err(ClientMemError::Sigbus),
|
true => Err(ClientMemError::Sigbus),
|
||||||
|
|
@ -116,8 +116,9 @@ struct MemRef {
|
||||||
outer: *const MemRef,
|
outer: *const MemRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static mut MEM: *const MemRef = ptr::null();
|
static MEM: Cell<*const MemRef> = const { Cell::new(ptr::null()) };
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn kill() -> ! {
|
unsafe fn kill() -> ! {
|
||||||
c::signal(c::SIGBUS, c::SIG_DFL);
|
c::signal(c::SIGBUS, c::SIG_DFL);
|
||||||
|
|
@ -127,7 +128,7 @@ unsafe fn kill() -> ! {
|
||||||
|
|
||||||
unsafe extern "C" fn sigbus(sig: i32, info: &c::siginfo_t, _ucontext: *mut c::c_void) {
|
unsafe extern "C" fn sigbus(sig: i32, info: &c::siginfo_t, _ucontext: *mut c::c_void) {
|
||||||
assert_eq!(sig, c::SIGBUS);
|
assert_eq!(sig, c::SIGBUS);
|
||||||
let mut memr_ptr = MEM;
|
let mut memr_ptr = MEM.get();
|
||||||
while !memr_ptr.is_null() {
|
while !memr_ptr.is_null() {
|
||||||
let memr = &*memr_ptr;
|
let memr = &*memr_ptr;
|
||||||
let mem = &*memr.mem;
|
let mem = &*memr.mem;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
std::rc::Rc,
|
std::{cell::Cell, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -36,8 +36,9 @@ impl Drop for EglContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static mut CURRENT: EGLContext = EGLContext::none();
|
static CURRENT: Cell<EGLContext> = const { Cell::new(EGLContext::none()) };
|
||||||
|
}
|
||||||
|
|
||||||
impl EglContext {
|
impl EglContext {
|
||||||
pub fn reset_status(&self) -> Option<ResetStatus> {
|
pub fn reset_status(&self) -> Option<ResetStatus> {
|
||||||
|
|
@ -63,7 +64,7 @@ impl EglContext {
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<T, RenderError> {
|
) -> Result<T, RenderError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if CURRENT == self.ctx {
|
if CURRENT.get() == self.ctx {
|
||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
self.with_current_slow(f)
|
self.with_current_slow(f)
|
||||||
|
|
@ -84,15 +85,15 @@ impl EglContext {
|
||||||
{
|
{
|
||||||
return Err(RenderError::MakeCurrent);
|
return Err(RenderError::MakeCurrent);
|
||||||
}
|
}
|
||||||
let prev = CURRENT;
|
let prev = CURRENT.get();
|
||||||
CURRENT = self.ctx;
|
CURRENT.set(self.ctx);
|
||||||
let res = f();
|
let res = f();
|
||||||
if (self.dpy.egl.eglMakeCurrent)(self.dpy.dpy, EGLSurface::none(), EGLSurface::none(), prev)
|
if (self.dpy.egl.eglMakeCurrent)(self.dpy.dpy, EGLSurface::none(), EGLSurface::none(), prev)
|
||||||
== EGL_FALSE
|
== EGL_FALSE
|
||||||
{
|
{
|
||||||
panic!("Could not restore EGLContext");
|
panic!("Could not restore EGLContext");
|
||||||
}
|
}
|
||||||
CURRENT = prev;
|
CURRENT.set(prev);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,8 @@ impl Drop for VulkanInstance {
|
||||||
|
|
||||||
const REQUIRED_INSTANCE_EXTENSIONS: &[&CStr] = &[ExtDebugUtilsFn::name()];
|
const REQUIRED_INSTANCE_EXTENSIONS: &[&CStr] = &[ExtDebugUtilsFn::name()];
|
||||||
|
|
||||||
const VALIDATION_LAYER: &CStr = c"VK_LAYER_KHRONOS_validation";
|
const VALIDATION_LAYER: &CStr =
|
||||||
|
unsafe { CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0") };
|
||||||
|
|
||||||
pub type Extensions = AHashMap<CString, u32>;
|
pub type Extensions = AHashMap<CString, u32>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,26 +27,25 @@ pub static TEST_CONFIG_ENTRY: ConfigEntry = ConfigEntry {
|
||||||
handle_msg,
|
handle_msg,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static mut CONFIG: *const TestConfig = ptr::null();
|
static CONFIG: Cell<*const TestConfig> = const { Cell::new(ptr::null()) };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_test_config<T, F>(f: F) -> T
|
pub fn with_test_config<T, F>(f: F) -> T
|
||||||
where
|
where
|
||||||
F: FnOnce(Rc<TestConfig>) -> T,
|
F: FnOnce(Rc<TestConfig>) -> T,
|
||||||
{
|
{
|
||||||
unsafe {
|
let tc = Rc::new(TestConfig {
|
||||||
let tc = Rc::new(TestConfig {
|
srv: Cell::new(None),
|
||||||
srv: Cell::new(None),
|
responses: Default::default(),
|
||||||
responses: Default::default(),
|
invoked_shortcuts: Default::default(),
|
||||||
invoked_shortcuts: Default::default(),
|
graphics_initialized: Cell::new(false),
|
||||||
graphics_initialized: Cell::new(false),
|
});
|
||||||
});
|
let old = CONFIG.get();
|
||||||
let old = CONFIG;
|
CONFIG.set(tc.deref());
|
||||||
CONFIG = tc.deref();
|
let res = f(tc.clone());
|
||||||
let res = f(tc.clone());
|
CONFIG.set(old);
|
||||||
CONFIG = old;
|
res
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn init(
|
unsafe extern "C" fn init(
|
||||||
|
|
@ -56,7 +55,7 @@ unsafe extern "C" fn init(
|
||||||
_msg: *const u8,
|
_msg: *const u8,
|
||||||
_size: usize,
|
_size: usize,
|
||||||
) -> *const u8 {
|
) -> *const u8 {
|
||||||
let tc = CONFIG;
|
let tc = CONFIG.get();
|
||||||
assert!(tc.is_not_null());
|
assert!(tc.is_not_null());
|
||||||
Rc::increment_strong_count(tc);
|
Rc::increment_strong_count(tc);
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ use {
|
||||||
|
|
||||||
static LEVEL: AtomicUsize = AtomicUsize::new(Level::Info as usize);
|
static LEVEL: AtomicUsize = AtomicUsize::new(Level::Info as usize);
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static FILE: CloneCell<Option<Rc<OwnedFd>>> = CloneCell::new(None);
|
static FILE: CloneCell<Option<Rc<OwnedFd>>> = CloneCell::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn install() {
|
pub fn install() {
|
||||||
log::set_logger(&Logger).unwrap();
|
log::set_logger(&Logger).unwrap();
|
||||||
|
|
@ -27,11 +28,11 @@ pub fn set_level(level: Level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_file(file: Rc<OwnedFd>) {
|
pub fn set_file(file: Rc<OwnedFd>) {
|
||||||
FILE.set(Some(file));
|
FILE.with(|f| f.set(Some(file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset_file() {
|
pub fn unset_file() {
|
||||||
FILE.set(None);
|
FILE.with(|f| f.set(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Logger;
|
struct Logger;
|
||||||
|
|
@ -65,7 +66,7 @@ impl Log for Logger {
|
||||||
record.args(),
|
record.args(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let mut fd = match FILE.get() {
|
let mut fd = match FILE.with(|f| f.get()) {
|
||||||
Some(f) => f.borrow(),
|
Some(f) => f.borrow(),
|
||||||
_ => Fd::new(2),
|
_ => Fd::new(2),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
55
src/leaks.rs
55
src/leaks.rs
|
|
@ -52,27 +52,27 @@ mod leaks {
|
||||||
std::{
|
std::{
|
||||||
alloc::{GlobalAlloc, Layout},
|
alloc::{GlobalAlloc, Layout},
|
||||||
any,
|
any,
|
||||||
|
cell::Cell,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem, ptr,
|
mem, ptr,
|
||||||
},
|
},
|
||||||
uapi::c,
|
uapi::c,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static mut MAP: *mut AHashMap<u64, Tracked> = ptr::null_mut();
|
static MAP: Cell<*mut AHashMap<u64, Tracked>> = const { Cell::new(ptr::null_mut()) };
|
||||||
|
static ID: Cell<u64> = const { Cell::new(0) };
|
||||||
#[thread_local]
|
}
|
||||||
static mut ID: u64 = 0;
|
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
unsafe {
|
unsafe {
|
||||||
if INITIALIZED {
|
if INITIALIZED {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MAP = Box::into_raw(Box::new(AHashMap::new()));
|
MAP.set(Box::into_raw(Box::new(AHashMap::new())));
|
||||||
ALLOCATIONS = Box::into_raw(Box::new(AHashMap::new()));
|
ALLOCATIONS.set(Box::into_raw(Box::new(AHashMap::new())));
|
||||||
IN_ALLOCATOR = 0;
|
IN_ALLOCATOR.set(0);
|
||||||
INITIALIZED = true;
|
INITIALIZED.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ mod leaks {
|
||||||
|
|
||||||
pub fn log_leaked() {
|
pub fn log_leaked() {
|
||||||
unsafe {
|
unsafe {
|
||||||
IN_ALLOCATOR += 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() + 1);
|
||||||
let mut map: AHashMap<ClientId, Vec<(u64, Tracked)>> = AHashMap::new();
|
let mut map: AHashMap<ClientId, Vec<(u64, Tracked)>> = AHashMap::new();
|
||||||
for (id, obj) in MAP.deref_mut().drain() {
|
for (id, obj) in MAP.deref_mut().drain() {
|
||||||
map.entry(obj.client).or_default().push((id, obj));
|
map.entry(obj.client).or_default().push((id, obj));
|
||||||
|
|
@ -176,7 +176,7 @@ mod leaks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IN_ALLOCATOR -= 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
@ -210,8 +210,8 @@ mod leaks {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: unsafe {
|
id: unsafe {
|
||||||
let id = ID;
|
let id = ID.get();
|
||||||
ID += 1;
|
ID.set(id + 1);
|
||||||
id
|
id
|
||||||
},
|
},
|
||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
|
|
@ -227,7 +227,7 @@ mod leaks {
|
||||||
tv_nsec: 0,
|
tv_nsec: 0,
|
||||||
};
|
};
|
||||||
uapi::clock_gettime(c::CLOCK_REALTIME, &mut time).unwrap();
|
uapi::clock_gettime(c::CLOCK_REALTIME, &mut time).unwrap();
|
||||||
IN_ALLOCATOR += 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() + 1);
|
||||||
MAP.deref_mut().insert(
|
MAP.deref_mut().insert(
|
||||||
self.id,
|
self.id,
|
||||||
Tracked {
|
Tracked {
|
||||||
|
|
@ -237,7 +237,7 @@ mod leaks {
|
||||||
time: (time.tv_sec as i64, time.tv_nsec as u32),
|
time: (time.tv_sec as i64, time.tv_nsec as u32),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
IN_ALLOCATOR -= 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,20 +262,17 @@ mod leaks {
|
||||||
pub backtrace: Backtrace,
|
pub backtrace: Backtrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static mut ALLOCATIONS: *mut AHashMap<*mut u8, Allocation> = ptr::null_mut();
|
static ALLOCATIONS: Cell<*mut AHashMap<*mut u8, Allocation>> = const { Cell::new(ptr::null_mut()) };
|
||||||
|
static IN_ALLOCATOR: Cell<u32> = const { Cell::new(1) };
|
||||||
#[thread_local]
|
static INITIALIZED: Cell<bool> = const { Cell::new(false) };
|
||||||
static mut IN_ALLOCATOR: u32 = 1;
|
}
|
||||||
|
|
||||||
#[thread_local]
|
|
||||||
static mut INITIALIZED: bool = false;
|
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for TracingAllocator {
|
unsafe impl GlobalAlloc for TracingAllocator {
|
||||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||||
let res = c::calloc(layout.size(), 1) as *mut u8;
|
let res = c::calloc(layout.size(), 1) as *mut u8;
|
||||||
if IN_ALLOCATOR == 0 {
|
if IN_ALLOCATOR.get() == 0 {
|
||||||
IN_ALLOCATOR = 1;
|
IN_ALLOCATOR.set(1);
|
||||||
ALLOCATIONS.deref_mut().insert(
|
ALLOCATIONS.deref_mut().insert(
|
||||||
res,
|
res,
|
||||||
Allocation {
|
Allocation {
|
||||||
|
|
@ -301,7 +298,7 @@ mod leaks {
|
||||||
|
|
||||||
fn find_allocations_pointing_to(addr: *mut u8) -> Vec<(Allocation, usize)> {
|
fn find_allocations_pointing_to(addr: *mut u8) -> Vec<(Allocation, usize)> {
|
||||||
unsafe {
|
unsafe {
|
||||||
IN_ALLOCATOR += 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() + 1);
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
for allocation in ALLOCATIONS.deref().values() {
|
for allocation in ALLOCATIONS.deref().values() {
|
||||||
let num = allocation.len / mem::size_of::<usize>();
|
let num = allocation.len / mem::size_of::<usize>();
|
||||||
|
|
@ -313,14 +310,14 @@ mod leaks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IN_ALLOCATOR -= 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() - 1);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_allocation_containing(addr: usize) -> Option<Allocation> {
|
fn find_allocation_containing(addr: usize) -> Option<Allocation> {
|
||||||
unsafe {
|
unsafe {
|
||||||
IN_ALLOCATOR += 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() + 1);
|
||||||
let mut res = None;
|
let mut res = None;
|
||||||
for allocation in ALLOCATIONS.deref().values() {
|
for allocation in ALLOCATIONS.deref().values() {
|
||||||
let aaddr = allocation.addr as usize;
|
let aaddr = allocation.addr as usize;
|
||||||
|
|
@ -329,7 +326,7 @@ mod leaks {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IN_ALLOCATOR -= 1;
|
IN_ALLOCATOR.set(IN_ALLOCATOR.get() - 1);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,11 @@ use {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
udev::UdevError,
|
udev::UdevError,
|
||||||
utils::{
|
utils::{errorfmt::ErrorFmt, oserror::OsError, ptr_ext::PtrExt, trim::AsciiTrim},
|
||||||
errorfmt::ErrorFmt, oserror::OsError, ptr_ext::PtrExt, trim::AsciiTrim,
|
|
||||||
vasprintf::vasprintf_,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
bstr::ByteSlice,
|
bstr::ByteSlice,
|
||||||
std::{
|
isnt::std_1::primitive::IsntConstPtrExt,
|
||||||
ffi::{CStr, VaList},
|
std::{ffi::CStr, rc::Rc},
|
||||||
rc::Rc,
|
|
||||||
},
|
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
uapi::{c, Errno, IntoUstr, OwnedFd},
|
uapi::{c, Errno, IntoUstr, OwnedFd},
|
||||||
};
|
};
|
||||||
|
|
@ -91,6 +86,10 @@ pub struct LibInput {
|
||||||
li: *mut libinput,
|
li: *mut libinput,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn jay_libinput_log_handler_bridge();
|
||||||
|
}
|
||||||
|
|
||||||
impl LibInput {
|
impl LibInput {
|
||||||
pub fn new(adapter: Rc<dyn LibInputAdapter>) -> Result<Self, LibInputError> {
|
pub fn new(adapter: Rc<dyn LibInputAdapter>) -> Result<Self, LibInputError> {
|
||||||
let mut ud = Box::new(UserData { adapter });
|
let mut ud = Box::new(UserData { adapter });
|
||||||
|
|
@ -101,7 +100,7 @@ impl LibInput {
|
||||||
return Err(LibInputError::New);
|
return Err(LibInputError::New);
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
libinput_log_set_handler(li, log_handler);
|
libinput_log_set_handler(li, jay_libinput_log_handler_bridge);
|
||||||
let priority = if log::log_enabled!(log::Level::Debug) {
|
let priority = if log::log_enabled!(log::Level::Debug) {
|
||||||
LIBINPUT_LOG_PRIORITY_DEBUG
|
LIBINPUT_LOG_PRIORITY_DEBUG
|
||||||
} else if log::log_enabled!(log::Level::Info) {
|
} else if log::log_enabled!(log::Level::Info) {
|
||||||
|
|
@ -167,19 +166,14 @@ impl Drop for LibInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn log_handler(
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn jay_libinput_log_handler(
|
||||||
_libinput: *mut libinput,
|
_libinput: *mut libinput,
|
||||||
priority: libinput_log_priority,
|
priority: libinput_log_priority,
|
||||||
format: *const c::c_char,
|
line: *const c::c_char,
|
||||||
args: VaList,
|
|
||||||
) {
|
) {
|
||||||
let str = match vasprintf_(format, args) {
|
assert!(line.is_not_null());
|
||||||
Some(s) => s,
|
let str = CStr::from_ptr(line);
|
||||||
_ => {
|
|
||||||
log::error!("Could not format log message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let priority = match LogPriority(priority as _) {
|
let priority = match LogPriority(priority as _) {
|
||||||
LIBINPUT_LOG_PRIORITY_DEBUG => log::Level::Debug,
|
LIBINPUT_LOG_PRIORITY_DEBUG => log::Level::Debug,
|
||||||
LIBINPUT_LOG_PRIORITY_INFO => log::Level::Info,
|
LIBINPUT_LOG_PRIORITY_INFO => log::Level::Info,
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
use {std::ffi::VaList, uapi::c};
|
use uapi::c;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/libinput_tys.rs"));
|
include!(concat!(env!("OUT_DIR"), "/libinput_tys.rs"));
|
||||||
|
|
||||||
pub type libinput_log_handler = unsafe extern "C" fn(
|
pub type libinput_log_handler = unsafe extern "C" fn();
|
||||||
libinput: *mut libinput,
|
|
||||||
priority: libinput_log_priority,
|
#[repr(transparent)]
|
||||||
format: *const c::c_char,
|
pub struct libinput(u8);
|
||||||
args: VaList,
|
#[repr(transparent)]
|
||||||
);
|
pub struct libinput_device(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct libinput_event(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct libinput_event_keyboard(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct libinput_event_pointer(u8);
|
||||||
|
|
||||||
#[link(name = "input")]
|
#[link(name = "input")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub type libinput;
|
|
||||||
pub type libinput_device;
|
|
||||||
pub type libinput_event;
|
|
||||||
pub type libinput_event_keyboard;
|
|
||||||
pub type libinput_event_pointer;
|
|
||||||
|
|
||||||
pub fn libinput_log_set_handler(libinput: *mut libinput, log_handler: libinput_log_handler);
|
pub fn libinput_log_set_handler(libinput: *mut libinput, log_handler: libinput_log_handler);
|
||||||
pub fn libinput_log_set_priority(libinput: *mut libinput, priority: libinput_log_priority);
|
pub fn libinput_log_set_priority(libinput: *mut libinput, priority: libinput_log_priority);
|
||||||
pub fn libinput_path_create_context(
|
pub fn libinput_path_create_context(
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,11 @@ use {
|
||||||
bstr::{BStr, BString, ByteSlice},
|
bstr::{BStr, BString, ByteSlice},
|
||||||
log::{Level, Log, Metadata, Record},
|
log::{Level, Log, Metadata, Record},
|
||||||
std::{
|
std::{
|
||||||
|
cell::Cell,
|
||||||
fs::DirBuilder,
|
fs::DirBuilder,
|
||||||
io::Write,
|
io::Write,
|
||||||
os::unix::{ffi::OsStringExt, fs::DirBuilderExt},
|
os::unix::{ffi::OsStringExt, fs::DirBuilderExt},
|
||||||
|
ptr,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU32, Ordering::Relaxed},
|
atomic::{AtomicU32, Ordering::Relaxed},
|
||||||
Arc,
|
Arc,
|
||||||
|
|
@ -16,8 +18,9 @@ use {
|
||||||
uapi::{c, format_ustr, Errno, Fd, OwnedFd},
|
uapi::{c, format_ustr, Errno, Fd, OwnedFd},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static mut BUFFER: Vec<u8> = Vec::new();
|
static BUFFER: Cell<*mut Vec<u8>> = const { Cell::new(ptr::null_mut()) };
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Logger {
|
pub struct Logger {
|
||||||
level: AtomicU32,
|
level: AtomicU32,
|
||||||
|
|
@ -141,7 +144,12 @@ impl Log for LogWrapper {
|
||||||
if record.level() as u32 > self.logger.level.load(Relaxed) {
|
if record.level() as u32 > self.logger.level.load(Relaxed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let buffer = unsafe { &mut BUFFER };
|
let mut buffer = BUFFER.get();
|
||||||
|
if buffer.is_null() {
|
||||||
|
buffer = Box::into_raw(Box::default());
|
||||||
|
BUFFER.set(buffer);
|
||||||
|
}
|
||||||
|
let buffer = unsafe { &mut *buffer };
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
let now = SystemTime::now();
|
let now = SystemTime::now();
|
||||||
let _ = if let Some(mp) = record.module_path() {
|
let _ = if let Some(mp) = record.module_path() {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
#![feature(
|
|
||||||
c_variadic, // https://github.com/rust-lang/rust/issues/44930
|
|
||||||
thread_local, // https://github.com/rust-lang/rust/issues/29594
|
|
||||||
extern_types, // https://github.com/rust-lang/rust/issues/43467
|
|
||||||
c_str_literals, // https://github.com/rust-lang/rust/issues/105723
|
|
||||||
)]
|
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::len_zero,
|
clippy::len_zero,
|
||||||
clippy::needless_lifetimes,
|
clippy::needless_lifetimes,
|
||||||
|
|
|
||||||
26
src/pango.rs
26
src/pango.rs
|
|
@ -14,11 +14,13 @@ pub mod consts;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/pango_tys.rs"));
|
include!(concat!(env!("OUT_DIR"), "/pango_tys.rs"));
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct cairo_surface_t(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct cairo_t(u8);
|
||||||
|
|
||||||
#[link(name = "cairo")]
|
#[link(name = "cairo")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
type cairo_surface_t;
|
|
||||||
type cairo_t;
|
|
||||||
|
|
||||||
fn cairo_image_surface_create(
|
fn cairo_image_surface_create(
|
||||||
format: cairo_format_t,
|
format: cairo_format_t,
|
||||||
width: c::c_int,
|
width: c::c_int,
|
||||||
|
|
@ -41,26 +43,30 @@ extern "C" {
|
||||||
fn cairo_move_to(cr: *mut cairo_t, x: f64, y: f64);
|
fn cairo_move_to(cr: *mut cairo_t, x: f64, y: f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct PangoContext_(u8);
|
||||||
|
|
||||||
#[link(name = "pangocairo-1.0")]
|
#[link(name = "pangocairo-1.0")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
type PangoContext_;
|
|
||||||
|
|
||||||
fn pango_cairo_create_context(cr: *mut cairo_t) -> *mut PangoContext_;
|
fn pango_cairo_create_context(cr: *mut cairo_t) -> *mut PangoContext_;
|
||||||
fn pango_cairo_show_layout(cr: *mut cairo_t, layout: *mut PangoLayout_);
|
fn pango_cairo_show_layout(cr: *mut cairo_t, layout: *mut PangoLayout_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct GObject(u8);
|
||||||
|
|
||||||
#[link(name = "gobject-2.0")]
|
#[link(name = "gobject-2.0")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
type GObject;
|
|
||||||
|
|
||||||
fn g_object_unref(object: *mut GObject);
|
fn g_object_unref(object: *mut GObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct PangoFontDescription_(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct PangoLayout_(u8);
|
||||||
|
|
||||||
#[link(name = "pango-1.0")]
|
#[link(name = "pango-1.0")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
type PangoFontDescription_;
|
|
||||||
type PangoLayout_;
|
|
||||||
|
|
||||||
fn pango_font_description_from_string(str: *const c::c_char) -> *mut PangoFontDescription_;
|
fn pango_font_description_from_string(str: *const c::c_char) -> *mut PangoFontDescription_;
|
||||||
fn pango_font_description_free(desc: *mut PangoFontDescription_);
|
fn pango_font_description_free(desc: *mut PangoFontDescription_);
|
||||||
fn pango_font_description_get_size(desc: *mut PangoFontDescription_) -> c::c_int;
|
fn pango_font_description_get_size(desc: *mut PangoFontDescription_) -> c::c_int;
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,17 @@ use {
|
||||||
region::{extents, rects_to_bands, subtract, union},
|
region::{extents, rects_to_bands, subtract, union},
|
||||||
RectRaw,
|
RectRaw,
|
||||||
},
|
},
|
||||||
once_cell::unsync::Lazy,
|
|
||||||
smallvec::SmallVec,
|
smallvec::SmallVec,
|
||||||
std::{mem, ops::Deref, rc::Rc},
|
std::{mem, ops::Deref, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[thread_local]
|
thread_local! {
|
||||||
static EMPTY: Lazy<Rc<Region>> = Lazy::new(|| {
|
static EMPTY: Rc<Region> =
|
||||||
Rc::new(Region {
|
Rc::new(Region {
|
||||||
rects: Default::default(),
|
rects: Default::default(),
|
||||||
extents: Default::default(),
|
extents: Default::default(),
|
||||||
})
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
impl Region {
|
impl Region {
|
||||||
pub fn new(rect: Rect) -> Rc<Self> {
|
pub fn new(rect: Rect) -> Rc<Self> {
|
||||||
|
|
@ -28,7 +27,7 @@ impl Region {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty() -> Rc<Self> {
|
pub fn empty() -> Rc<Self> {
|
||||||
EMPTY.clone()
|
EMPTY.with(|e| e.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_rects(rects: &[Rect]) -> Rc<Self> {
|
pub fn from_rects(rects: &[Rect]) -> Rc<Self> {
|
||||||
|
|
|
||||||
19
src/udev.rs
19
src/udev.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::utils::oserror::OsError,
|
crate::utils::oserror::OsError,
|
||||||
std::{ffi::CStr, marker::PhantomData, ptr, rc::Rc},
|
std::{ffi::CStr, marker::PhantomData, ptr, rc::Rc},
|
||||||
|
|
@ -5,14 +7,19 @@ use {
|
||||||
uapi::{c, ustr, Errno, IntoUstr, Ustr},
|
uapi::{c, ustr, Errno, IntoUstr, Ustr},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct udev(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct udev_monitor(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct udev_enumerate(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct udev_list_entry(u8);
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct udev_device(u8);
|
||||||
|
|
||||||
#[link(name = "udev")]
|
#[link(name = "udev")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
type udev;
|
|
||||||
type udev_monitor;
|
|
||||||
type udev_enumerate;
|
|
||||||
type udev_list_entry;
|
|
||||||
type udev_device;
|
|
||||||
|
|
||||||
fn udev_new() -> *mut udev;
|
fn udev_new() -> *mut udev;
|
||||||
fn udev_unref(udev: *mut udev) -> *mut udev;
|
fn udev_unref(udev: *mut udev) -> *mut udev;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ pub mod toplevel_identifier;
|
||||||
pub mod tri;
|
pub mod tri;
|
||||||
pub mod trim;
|
pub mod trim;
|
||||||
pub mod unlink_on_drop;
|
pub mod unlink_on_drop;
|
||||||
pub mod vasprintf;
|
|
||||||
pub mod vec_ext;
|
pub mod vec_ext;
|
||||||
pub mod vecstorage;
|
pub mod vecstorage;
|
||||||
pub mod windows;
|
pub mod windows;
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
use {
|
|
||||||
std::{
|
|
||||||
ffi::{CStr, VaList},
|
|
||||||
ops::Deref,
|
|
||||||
ptr,
|
|
||||||
},
|
|
||||||
uapi::c,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn vasprintf(strp: *mut *mut c::c_char, fmt: *const c::c_char, ap: VaList) -> c::c_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OwnedCStr {
|
|
||||||
val: &'static CStr,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for OwnedCStr {
|
|
||||||
type Target = CStr;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for OwnedCStr {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
c::free(self.val.as_ptr() as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn vasprintf_(fmt: *const c::c_char, ap: VaList) -> Option<OwnedCStr> {
|
|
||||||
let mut res = ptr::null_mut();
|
|
||||||
if vasprintf(&mut res, fmt, ap) == -1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(OwnedCStr {
|
|
||||||
val: CStr::from_ptr(res),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -7,13 +7,8 @@ include!(concat!(env!("OUT_DIR"), "/xkbcommon_tys.rs"));
|
||||||
pub use consts::*;
|
pub use consts::*;
|
||||||
use {
|
use {
|
||||||
bstr::{BStr, ByteSlice},
|
bstr::{BStr, ByteSlice},
|
||||||
std::{
|
isnt::std_1::primitive::IsntConstPtrExt,
|
||||||
ffi::{CStr, VaList},
|
std::{ffi::CStr, io::Write, ops::Deref, ptr, rc::Rc},
|
||||||
io::Write,
|
|
||||||
ops::Deref,
|
|
||||||
ptr,
|
|
||||||
rc::Rc,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
|
@ -69,15 +64,7 @@ extern "C" {
|
||||||
fn xkb_context_new(flags: xkb_context_flags) -> *mut xkb_context;
|
fn xkb_context_new(flags: xkb_context_flags) -> *mut xkb_context;
|
||||||
fn xkb_context_unref(context: *mut xkb_context);
|
fn xkb_context_unref(context: *mut xkb_context);
|
||||||
fn xkb_context_set_log_verbosity(context: *mut xkb_context, verbosity: c::c_int);
|
fn xkb_context_set_log_verbosity(context: *mut xkb_context, verbosity: c::c_int);
|
||||||
fn xkb_context_set_log_fn(
|
fn xkb_context_set_log_fn(context: *mut xkb_context, log_fn: unsafe extern "C" fn());
|
||||||
context: *mut xkb_context,
|
|
||||||
log_fn: unsafe extern "C" fn(
|
|
||||||
context: *mut xkb_context,
|
|
||||||
level: xkb_log_level,
|
|
||||||
format: *const c::c_char,
|
|
||||||
args: VaList,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
fn xkb_keymap_new_from_buffer(
|
fn xkb_keymap_new_from_buffer(
|
||||||
context: *mut xkb_context,
|
context: *mut xkb_context,
|
||||||
buffer: *const u8,
|
buffer: *const u8,
|
||||||
|
|
@ -116,6 +103,10 @@ pub struct XkbContext {
|
||||||
context: *mut xkb_context,
|
context: *mut xkb_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn jay_xkbcommon_log_handler_bridge();
|
||||||
|
}
|
||||||
|
|
||||||
impl XkbContext {
|
impl XkbContext {
|
||||||
pub fn new() -> Result<Self, XkbCommonError> {
|
pub fn new() -> Result<Self, XkbCommonError> {
|
||||||
let res = unsafe { xkb_context_new(XKB_CONTEXT_NO_FLAGS.raw() as _) };
|
let res = unsafe { xkb_context_new(XKB_CONTEXT_NO_FLAGS.raw() as _) };
|
||||||
|
|
@ -124,7 +115,7 @@ impl XkbContext {
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
xkb_context_set_log_verbosity(res, 10);
|
xkb_context_set_log_verbosity(res, 10);
|
||||||
xkb_context_set_log_fn(res, xkbcommon_logger);
|
xkb_context_set_log_fn(res, jay_xkbcommon_log_handler_bridge);
|
||||||
}
|
}
|
||||||
Ok(Self { context: res })
|
Ok(Self { context: res })
|
||||||
}
|
}
|
||||||
|
|
@ -303,22 +294,14 @@ impl Drop for XkbState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn xkbcommon_logger(
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn jay_xkbcommon_log_handler(
|
||||||
_ctx: *mut xkb_context,
|
_ctx: *mut xkb_context,
|
||||||
level: xkb_log_level,
|
level: xkb_log_level,
|
||||||
format: *const c::c_char,
|
line: *const c::c_char,
|
||||||
args: VaList,
|
|
||||||
) {
|
) {
|
||||||
extern "C" {
|
assert!(line.is_not_null());
|
||||||
fn vasprintf(buf: *mut *mut c::c_char, fmt: *const c::c_char, args: VaList) -> c::c_int;
|
let buf = CStr::from_ptr(line);
|
||||||
}
|
|
||||||
let mut buf = ptr::null_mut();
|
|
||||||
let res = vasprintf(&mut buf, format, args);
|
|
||||||
if res < 0 {
|
|
||||||
log::error!("Could not vasprintf");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let buf = std::slice::from_raw_parts(buf as *const u8, res as usize);
|
|
||||||
let level = match XkbLogLevel(level) {
|
let level = match XkbLogLevel(level) {
|
||||||
XKB_LOG_LEVEL_CRITICAL | XKB_LOG_LEVEL_ERROR => log::Level::Error,
|
XKB_LOG_LEVEL_CRITICAL | XKB_LOG_LEVEL_ERROR => log::Level::Error,
|
||||||
XKB_LOG_LEVEL_WARNING => log::Level::Warn,
|
XKB_LOG_LEVEL_WARNING => log::Level::Warn,
|
||||||
|
|
@ -326,5 +309,5 @@ unsafe extern "C" fn xkbcommon_logger(
|
||||||
XKB_LOG_LEVEL_DEBUG => log::Level::Debug,
|
XKB_LOG_LEVEL_DEBUG => log::Level::Debug,
|
||||||
_ => log::Level::Error,
|
_ => log::Level::Error,
|
||||||
};
|
};
|
||||||
log::log!(level, "xkbcommon: {}", buf.trim_end().as_bstr());
|
log::log!(level, "xkbcommon: {}", buf.to_bytes().trim_end().as_bstr());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue