dynamically reallocate buffer; release mutex before callback

This commit is contained in:
Determinant 2017-07-01 12:24:35 -04:00
parent 5e5debc48f
commit 75856e0e39

View file

@ -290,14 +290,26 @@ impl EventsLoop {
let written = unsafe { let written = unsafe {
use std::str; use std::str;
const BUFF_SIZE: usize = 512; const INIT_BUFF_SIZE: usize = 16;
let mut windows = self.windows.lock().unwrap(); let mut windows = self.windows.lock().unwrap();
let window_data = windows.get_mut(&WindowId(xwindow)).unwrap(); let window_data = windows.get_mut(&WindowId(xwindow)).unwrap();
let mut buffer: [u8; BUFF_SIZE] = [mem::uninitialized(); BUFF_SIZE]; /* buffer allocated on heap instead of stack, due to the possible
let mut keysym = 0; * reallocation */
let count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev, let mut buffer: Vec<u8> = vec![mem::uninitialized(); INIT_BUFF_SIZE];
let mut keysym: ffi::KeySym = 0;
let mut status: ffi::Status = 0;
let mut count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev,
mem::transmute(buffer.as_mut_ptr()), mem::transmute(buffer.as_mut_ptr()),
buffer.len() as libc::c_int, &mut keysym, ptr::null_mut()); buffer.len() as libc::c_int,
&mut keysym, &mut status);
/* buffer overflowed, dynamically reallocate */
if status == ffi::XBufferOverflow {
buffer = vec![mem::uninitialized(); count as usize];
count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev,
mem::transmute(buffer.as_mut_ptr()),
buffer.len() as libc::c_int,
&mut keysym, &mut status);
}
{ {
// Translate x event state to mods // Translate x event state to mods
@ -443,16 +455,20 @@ impl EventsLoop {
} }
ffi::XI_FocusIn => { ffi::XI_FocusIn => {
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) }; let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
let mut windows = self.windows.lock().unwrap(); unsafe {
let window_data = windows.get_mut(&WindowId(xev.event)).unwrap(); let mut windows = self.windows.lock().unwrap();
unsafe { (self.display.xlib.XSetICFocus)(window_data.ic) }; let window_data = windows.get_mut(&WindowId(xev.event)).unwrap();
(self.display.xlib.XSetICFocus)(window_data.ic);
}
callback(Event::WindowEvent { window_id: mkwid(xev.event), event: Focused(true) }) callback(Event::WindowEvent { window_id: mkwid(xev.event), event: Focused(true) })
} }
ffi::XI_FocusOut => { ffi::XI_FocusOut => {
let xev: &ffi::XIFocusOutEvent = unsafe { &*(xev.data as *const _) }; let xev: &ffi::XIFocusOutEvent = unsafe { &*(xev.data as *const _) };
let mut windows = self.windows.lock().unwrap(); unsafe {
let window_data = windows.get_mut(&WindowId(xev.event)).unwrap(); let mut windows = self.windows.lock().unwrap();
unsafe { (self.display.xlib.XUnsetICFocus)(window_data.ic) }; let window_data = windows.get_mut(&WindowId(xev.event)).unwrap();
(self.display.xlib.XUnsetICFocus)(window_data.ic);
}
callback(Event::WindowEvent { window_id: mkwid(xev.event), event: Focused(false) }) callback(Event::WindowEvent { window_id: mkwid(xev.event), event: Focused(false) })
} }