mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2025-01-11 03:21:32 +11:00
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:
parent
d6271e513d
commit
2b8094cc6c
|
@ -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) {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -45,7 +45,6 @@ fn main() {
|
|||
WIDTH,
|
||||
HEIGHT,
|
||||
WindowOptions {
|
||||
resize: true,
|
||||
scale: Scale::X2,
|
||||
..WindowOptions::default()
|
||||
})
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue