mirror of
https://github.com/wez/wezterm.git
synced 2024-12-18 10:52:16 +03:00
add beginnings of painting
This commit is contained in:
parent
f2928053aa
commit
de7446b172
106
window/src/os/windows/gdi.rs
Normal file
106
window/src/os/windows/gdi.rs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
use crate::bitmaps::BitmapImage;
|
||||||
|
use failure::Fallible;
|
||||||
|
use std::io::Error as IoError;
|
||||||
|
use winapi::shared::windef::*;
|
||||||
|
use winapi::um::wingdi::*;
|
||||||
|
|
||||||
|
pub struct GdiBitmap {
|
||||||
|
hdc: HDC,
|
||||||
|
hbitmap: HBITMAP,
|
||||||
|
data: *mut u8,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitmapImage for GdiBitmap {
|
||||||
|
unsafe fn pixel_data(&self) -> *const u8 {
|
||||||
|
self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn pixel_data_mut(&mut self) -> *mut u8 {
|
||||||
|
self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn image_dimensions(&self) -> (usize, usize) {
|
||||||
|
(self.width, self.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for GdiBitmap {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DeleteObject(self.hbitmap as _);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
DeleteObject(self.hdc as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GdiBitmap {
|
||||||
|
pub fn hdc(&self) -> HDC {
|
||||||
|
self.hdc
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hbitmap(&self) -> HBITMAP {
|
||||||
|
self.hbitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_compatible(width: usize, height: usize, hdc: HDC) -> Fallible<Self> {
|
||||||
|
let hdc = unsafe { CreateCompatibleDC(hdc) };
|
||||||
|
if hdc.is_null() {
|
||||||
|
let err = IoError::last_os_error();
|
||||||
|
failure::bail!("CreateCompatibleDC: {}", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut data = std::ptr::null_mut();
|
||||||
|
let bmi = BITMAPINFO {
|
||||||
|
bmiHeader: BITMAPINFOHEADER {
|
||||||
|
biSize: std::mem::size_of::<BITMAPINFOHEADER>() as u32,
|
||||||
|
biPlanes: 1,
|
||||||
|
biBitCount: 32,
|
||||||
|
biWidth: width as i32,
|
||||||
|
biHeight: height as i32,
|
||||||
|
biClrImportant: 0,
|
||||||
|
biClrUsed: 0,
|
||||||
|
biCompression: 0,
|
||||||
|
biSizeImage: width as u32 * height as u32 * 4,
|
||||||
|
biXPelsPerMeter: 0,
|
||||||
|
biYPelsPerMeter: 0,
|
||||||
|
},
|
||||||
|
bmiColors: [RGBQUAD {
|
||||||
|
rgbBlue: 0,
|
||||||
|
rgbRed: 0,
|
||||||
|
rgbGreen: 0,
|
||||||
|
rgbReserved: 0,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
let hbitmap = unsafe {
|
||||||
|
CreateDIBSection(
|
||||||
|
hdc,
|
||||||
|
&bmi,
|
||||||
|
DIB_RGB_COLORS,
|
||||||
|
&mut data,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if hbitmap.is_null() {
|
||||||
|
let err = IoError::last_os_error();
|
||||||
|
failure::bail!("CreateDIBSection: {}", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SelectObject(hdc, hbitmap as _);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
hdc,
|
||||||
|
hbitmap,
|
||||||
|
data: data as *mut u8,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
pub mod gdi;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|
||||||
/// Convert a rust string to a windows wide string
|
/// Convert a rust string to a windows wide string
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
use super::gdi::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::bitmaps::*;
|
||||||
use failure::Fallible;
|
use failure::Fallible;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::ptr::{null, null_mut};
|
use std::ptr::{null, null_mut};
|
||||||
@ -6,6 +8,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use winapi::shared::minwindef::*;
|
use winapi::shared::minwindef::*;
|
||||||
use winapi::shared::windef::*;
|
use winapi::shared::windef::*;
|
||||||
use winapi::um::libloaderapi::GetModuleHandleW;
|
use winapi::um::libloaderapi::GetModuleHandleW;
|
||||||
|
use winapi::um::wingdi::*;
|
||||||
use winapi::um::winuser::*;
|
use winapi::um::winuser::*;
|
||||||
|
|
||||||
pub trait WindowCallbacks {
|
pub trait WindowCallbacks {
|
||||||
@ -30,6 +33,14 @@ pub struct Window {
|
|||||||
inner: Arc<Mutex<WindowInner>>,
|
inner: Arc<Mutex<WindowInner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rect_width(r: &RECT) -> i32 {
|
||||||
|
r.right - r.left
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rect_height(r: &RECT) -> i32 {
|
||||||
|
r.bottom - r.top
|
||||||
|
}
|
||||||
|
|
||||||
fn adjust_client_to_window_dimensions(width: usize, height: usize) -> (i32, i32) {
|
fn adjust_client_to_window_dimensions(width: usize, height: usize) -> (i32, i32) {
|
||||||
let mut rect = RECT {
|
let mut rect = RECT {
|
||||||
left: 0,
|
left: 0,
|
||||||
@ -39,9 +50,7 @@ fn adjust_client_to_window_dimensions(width: usize, height: usize) -> (i32, i32)
|
|||||||
};
|
};
|
||||||
unsafe { AdjustWindowRect(&mut rect, WS_POPUP | WS_SYSMENU | WS_CAPTION, 0) };
|
unsafe { AdjustWindowRect(&mut rect, WS_POPUP | WS_SYSMENU | WS_CAPTION, 0) };
|
||||||
|
|
||||||
let width = rect.right - rect.left;
|
(rect_width(&rect), rect_height(&rect))
|
||||||
let height = rect.bottom - rect.top;
|
|
||||||
(width, height)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arc_to_pointer(arc: &Arc<Mutex<WindowInner>>) -> *const Mutex<WindowInner> {
|
fn arc_to_pointer(arc: &Arc<Mutex<WindowInner>>) -> *const Mutex<WindowInner> {
|
||||||
@ -229,10 +238,47 @@ fn enable_dark_mode(hwnd: HWND) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn wm_paint(hwnd: HWND, _msg: UINT, _wparam: WPARAM, _lparam: LPARAM) -> Option<LRESULT> {
|
||||||
|
if let Some(_inner) = arc_from_hwnd(hwnd) {
|
||||||
|
let dc = GetDC(hwnd);
|
||||||
|
|
||||||
|
let mut rect = RECT {
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
};
|
||||||
|
GetClientRect(hwnd, &mut rect);
|
||||||
|
let width = rect_width(&rect) as usize;
|
||||||
|
let height = rect_height(&rect) as usize;
|
||||||
|
|
||||||
|
let mut bitmap = GdiBitmap::new_compatible(width, height, dc).unwrap();
|
||||||
|
|
||||||
|
bitmap.clear(Color::rgb(0, 0, 0));
|
||||||
|
BitBlt(
|
||||||
|
dc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width as i32,
|
||||||
|
height as i32,
|
||||||
|
bitmap.hdc(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
SRCCOPY,
|
||||||
|
);
|
||||||
|
ValidateRect(hwnd, std::ptr::null());
|
||||||
|
|
||||||
|
Some(0)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn do_wnd_proc(hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> Option<LRESULT> {
|
unsafe fn do_wnd_proc(hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> Option<LRESULT> {
|
||||||
match msg {
|
match msg {
|
||||||
WM_NCCREATE => return wm_nccreate(hwnd, msg, wparam, lparam),
|
WM_NCCREATE => wm_nccreate(hwnd, msg, wparam, lparam),
|
||||||
WM_NCDESTROY => return wm_ncdestroy(hwnd, msg, wparam, lparam),
|
WM_NCDESTROY => wm_ncdestroy(hwnd, msg, wparam, lparam),
|
||||||
|
WM_PAINT => wm_paint(hwnd, msg, wparam, lparam),
|
||||||
WM_CLOSE => {
|
WM_CLOSE => {
|
||||||
if let Some(inner) = arc_from_hwnd(hwnd) {
|
if let Some(inner) = arc_from_hwnd(hwnd) {
|
||||||
let mut inner = inner.lock().unwrap();
|
let mut inner = inner.lock().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user