From 75856e0e39be2635984ee26cf60f93e00d4185f4 Mon Sep 17 00:00:00 2001 From: Determinant Date: Sat, 1 Jul 2017 12:24:35 -0400 Subject: [PATCH] dynamically reallocate buffer; release mutex before callback --- src/platform/linux/x11/mod.rs | 38 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/platform/linux/x11/mod.rs b/src/platform/linux/x11/mod.rs index c046ac25..501ed90f 100644 --- a/src/platform/linux/x11/mod.rs +++ b/src/platform/linux/x11/mod.rs @@ -290,14 +290,26 @@ impl EventsLoop { let written = unsafe { use std::str; - const BUFF_SIZE: usize = 512; + const INIT_BUFF_SIZE: usize = 16; let mut windows = self.windows.lock().unwrap(); let window_data = windows.get_mut(&WindowId(xwindow)).unwrap(); - let mut buffer: [u8; BUFF_SIZE] = [mem::uninitialized(); BUFF_SIZE]; - let mut keysym = 0; - let count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev, + /* buffer allocated on heap instead of stack, due to the possible + * reallocation */ + let mut buffer: Vec = 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()), - 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 @@ -443,16 +455,20 @@ impl EventsLoop { } ffi::XI_FocusIn => { let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) }; - let mut windows = self.windows.lock().unwrap(); - let window_data = windows.get_mut(&WindowId(xev.event)).unwrap(); - unsafe { (self.display.xlib.XSetICFocus)(window_data.ic) }; + unsafe { + let mut windows = self.windows.lock().unwrap(); + 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) }) } ffi::XI_FocusOut => { let xev: &ffi::XIFocusOutEvent = unsafe { &*(xev.data as *const _) }; - let mut windows = self.windows.lock().unwrap(); - let window_data = windows.get_mut(&WindowId(xev.event)).unwrap(); - unsafe { (self.display.xlib.XUnsetICFocus)(window_data.ic) }; + unsafe { + let mut windows = self.windows.lock().unwrap(); + 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) }) }