x11 and examples: resize (#72)

* warnings / clippy

* x11: remove deprecated, ignored position hints

* x11: only non-resizable windows have fixed size

* x11: handle resizes of ximage
This commit is contained in:
Chris West 2019-04-01 09:19:23 +01:00 committed by Daniel Collin
parent d6271e513d
commit 2b8094cc6c
6 changed files with 101 additions and 65 deletions

View file

@ -10,6 +10,7 @@ fn main() {
let mut window = match Window::new("Mouse Draw - Press ESC to exit", WIDTH, HEIGHT,
WindowOptions {
resize: true,
scale: Scale::X2,
..WindowOptions::default()
}) {
@ -20,9 +21,29 @@ fn main() {
}
};
let (mut width, mut height) = (WIDTH, HEIGHT);
while window.is_open() && !window.is_key_down(Key::Escape) {
window.get_mouse_pos(MouseMode::Discard).map(|mouse| {
let screen_pos = ((mouse.1 as usize) * WIDTH) + mouse.0 as usize;
{
let (new_width, new_height) = window.get_size();
if new_width != width || new_height != height {
// copy valid bits of old buffer to new buffer
let mut new_buffer = vec![0; new_width * new_height / 2 / 2];
for y in 0..(height / 2).min(new_height / 2) {
for x in 0..(width / 2).min(new_width / 2) {
new_buffer[y * (new_width / 2) + x] = buffer[y * (width / 2) + x];
}
}
buffer = new_buffer;
width = new_width;
height = new_height;
}
}
window.get_mouse_pos(MouseMode::Discard).map(|(x, y)| {
let screen_pos = ((y as usize) * width / 2) + x as usize;
println!("{:?}", window.get_unscaled_mouse_pos(MouseMode::Discard).unwrap());
if window.get_mouse_down(MouseButton::Left) {

View file

@ -6,16 +6,16 @@ fn main() {
let width = 640;
let height = 320;
let mut buffer = vec![0u32; width * height];
let mut orig = Window::new("Smaller", width, height, WindowOptions {
resize: true,
..WindowOptions::default()
}).unwrap();
let mut double = Window::new("Larger", width, height, WindowOptions {
resize: true,
scale: Scale::X2,
..WindowOptions::default()
}).unwrap();
let mut orig = Window::new("Smaller", width, height, WindowOptions {
..WindowOptions::default()
}).unwrap();
let mut pos = 13;
while orig.is_open() && double.is_open()

View file

@ -2,7 +2,7 @@ extern crate minifb;
use minifb::{Window, Key, Scale, WindowOptions};
const WIDTH: usize = 640;
const WIDTH: usize = 2560;
const HEIGHT: usize = 360;
fn main() {
@ -10,7 +10,6 @@ fn main() {
let mut carry;
let mut seed = 0xbeefu32;
let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];
let mut window = match Window::new("Noise Test - Press ESC to exit", WIDTH, HEIGHT,
WindowOptions {
@ -25,7 +24,19 @@ fn main() {
}
};
let mut buffer: Vec<u32> = Vec::with_capacity(WIDTH * HEIGHT);
let mut size = (0, 0);
while window.is_open() && !window.is_key_down(Key::Escape) {
{
let new_size = window.get_size();
if new_size != size {
size = new_size;
buffer.resize(size.0 * size.1 / 2 / 2, 0);
}
}
for i in buffer.iter_mut() {
noise = seed;
noise >>= 3;

View file

@ -45,7 +45,6 @@ fn main() {
WIDTH,
HEIGHT,
WindowOptions {
resize: true,
scale: Scale::X2,
..WindowOptions::default()
})

View file

@ -881,8 +881,8 @@ pub fn keysym_to_unicode(keysym: u32) -> Option<u32> {
}
// Also check for directly encoded 24-bit UCS characters
if (keysym & 0xff000000) == 0x01000000 {
return Some(keysym & 0x00ffffff);
if (keysym & 0xff00_0000) == 0x0100_0000 {
return Some(keysym & 0x00ff_ffff);
}
// Binary search in table
@ -905,9 +905,7 @@ pub fn test_it() {
}
// check ability to find every value in the table
for i in 0..LENGTH {
let p = keysymtab[i];
for p in keysymtab.iter() {
assert_eq!(keysym_to_unicode(p.0), Some(p.1));
}
}

View file

@ -45,7 +45,7 @@ struct DisplayInfo {
depth: i32,
screen_width: usize,
screen_height: usize,
context: xlib::XContext,
_context: xlib::XContext,
cursor_lib: x11_dl::xcursor::Xcursor,
cursors: [xlib::Cursor; 8],
keyb_ext: bool,
@ -66,20 +66,11 @@ impl DisplayInfo {
fn setup() -> Result<DisplayInfo> {
unsafe {
// load the Xlib library
let lib = match xlib::Xlib::open() {
Err(_) => {
return Err(Error::WindowCreate("failed to load Xlib".to_owned()));
}
Ok(v) => v,
};
let lib = xlib::Xlib::open()
.map_err(|e| Error::WindowCreate(format!("failed to load Xlib: {:?}", e)))?;
let cursor_lib = match xcursor::Xcursor::open() {
Err(_) => {
return Err(Error::WindowCreate("failed to load Xcursor".to_owned()));
}
Ok(v) => v,
};
let cursor_lib = xcursor::Xcursor::open()
.map_err(|e| Error::WindowCreate(format!("failed to load XCursor: {:?}", e)))?;
let display = (lib.XOpenDisplay)(ptr::null());
@ -110,7 +101,7 @@ impl DisplayInfo {
depth,
screen_width,
screen_height,
context,
_context: context,
cursor_lib,
// the following are determined later...
cursors: [0 as xlib::Cursor; 8],
@ -174,9 +165,6 @@ impl DisplayInfo {
}
fn init_cursors(&mut self) {
// andrewj: TODO: consider using the XCreateFontCursor() API, since
// some of these names are not working for me (they return zero).
self.cursors[0] = self.load_cursor("arrow");
self.cursors[1] = self.load_cursor("xterm");
self.cursors[2] = self.load_cursor("crosshair");
@ -320,12 +308,10 @@ impl Window {
| xlib::ButtonReleaseMask,
);
if opts.resize {
if !opts.resize {
let mut size_hints: xlib::XSizeHints = mem::zeroed();
size_hints.flags = xlib::PPosition | xlib::PMinSize | xlib::PMaxSize;
size_hints.x = 0;
size_hints.y = 0;
size_hints.flags = xlib::PMinSize | xlib::PMaxSize;
size_hints.min_width = width as i32;
size_hints.max_width = width as i32;
size_hints.min_height = height as i32;
@ -342,32 +328,17 @@ impl Window {
(d.lib.XMapRaised)(d.display, handle);
(d.lib.XFlush)(d.display);
let bytes_per_line = (width as i32) * 4;
let ximage = (d.lib.XCreateImage)(
d.display,
d.visual, /* TODO: this was CopyFromParent in the C code */
d.depth as u32,
xlib::ZPixmap,
0,
ptr::null_mut(),
width as u32,
height as u32,
32,
bytes_per_line,
);
if ximage == ptr::null_mut() {
(d.lib.XDestroyWindow)(d.display, handle);
return Err(Error::WindowCreate(
"Unable to create pixel buffer".to_owned(),
));
}
let mut draw_buffer: Vec<u32> = Vec::new();
draw_buffer.resize(width * height, 0);
(*ximage).data = draw_buffer[..].as_mut_ptr() as *mut c_char;
let ximage = match Self::alloc_image(&d, width, height, &mut draw_buffer) {
Some(ximage) => ximage,
None => {
(d.lib.XDestroyWindow)(d.display, handle);
return Err(Error::WindowCreate(
"Unable to create pixel buffer".to_owned(),
));
}
};
Ok(Window {
d,
@ -391,6 +362,37 @@ impl Window {
}
}
unsafe fn alloc_image(d: &DisplayInfo, width: usize, height: usize, draw_buffer: &mut Vec<u32>) -> Option<*mut xlib::XImage> {
let bytes_per_line = (width as i32) * 4;
draw_buffer.resize(width * height, 0);
let image = (d.lib.XCreateImage)(
d.display,
d.visual, /* TODO: this was CopyFromParent in the C code */
d.depth as u32,
xlib::ZPixmap,
0,
draw_buffer[..].as_mut_ptr() as *mut c_char,
width as u32,
height as u32,
32,
bytes_per_line,
);
if image.is_null() {
None
} else {
Some(image)
}
}
unsafe fn free_image(&mut self) {
(*self.ximage).data = ptr::null_mut();
(self.d.lib.XDestroyImage)(self.ximage);
self.ximage = ptr::null_mut();
}
pub fn set_title(&mut self, title: &str) {
match CString::new(title) {
Err(_) => {
@ -434,7 +436,7 @@ impl Window {
#[inline]
pub fn get_window_handle(&self) -> *mut raw::c_void {
unsafe { mem::transmute(self.handle as usize) }
self.handle as *mut raw::c_void
}
#[inline]
@ -765,6 +767,12 @@ impl Window {
// TODO : pass this onto the application
self.width = ev.configure.width as u32;
self.height = ev.configure.height as u32;
self.free_image();
self.ximage = Self::alloc_image(
&self.d,
cast::usize(self.width),
cast::usize(self.height),
&mut self.draw_buffer).expect("todo");
}
_ => {}
@ -992,13 +1000,12 @@ impl Window {
impl Drop for Window {
fn drop(&mut self) {
unsafe {
(*self.ximage).data = ptr::null_mut();
self.free_image();
// TODO [ andrewj: right now DisplayInfo is not shared, so doing this is
// probably pointless ]
// XSaveContext(s_display, info->window, s_context, (XPointer)0);
(self.d.lib.XDestroyImage)(self.ximage);
(self.d.lib.XDestroyWindow)(self.d.display, self.handle);
}
}
@ -1024,7 +1031,7 @@ impl Menu {
let handle = self.next_item_handle();
self.internal.items.push(UnixMenuItem {
label: name.to_owned(),
handle: handle,
handle,
sub_menu: Some(Box::new(sub_menu.internal.clone())),
id: 0,
enabled: true,