mirror of
https://github.com/wez/wezterm.git
synced 2024-12-18 02:42:05 +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;
|
||||
|
||||
/// Convert a rust string to a windows wide string
|
||||
|
@ -1,4 +1,6 @@
|
||||
use super::gdi::*;
|
||||
use super::*;
|
||||
use crate::bitmaps::*;
|
||||
use failure::Fallible;
|
||||
use std::io::Error as IoError;
|
||||
use std::ptr::{null, null_mut};
|
||||
@ -6,6 +8,7 @@ use std::sync::{Arc, Mutex};
|
||||
use winapi::shared::minwindef::*;
|
||||
use winapi::shared::windef::*;
|
||||
use winapi::um::libloaderapi::GetModuleHandleW;
|
||||
use winapi::um::wingdi::*;
|
||||
use winapi::um::winuser::*;
|
||||
|
||||
pub trait WindowCallbacks {
|
||||
@ -30,6 +33,14 @@ pub struct Window {
|
||||
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) {
|
||||
let mut rect = RECT {
|
||||
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) };
|
||||
|
||||
let width = rect.right - rect.left;
|
||||
let height = rect.bottom - rect.top;
|
||||
(width, height)
|
||||
(rect_width(&rect), rect_height(&rect))
|
||||
}
|
||||
|
||||
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> {
|
||||
match msg {
|
||||
WM_NCCREATE => return wm_nccreate(hwnd, msg, wparam, lparam),
|
||||
WM_NCDESTROY => return wm_ncdestroy(hwnd, msg, wparam, lparam),
|
||||
WM_NCCREATE => wm_nccreate(hwnd, msg, wparam, lparam),
|
||||
WM_NCDESTROY => wm_ncdestroy(hwnd, msg, wparam, lparam),
|
||||
WM_PAINT => wm_paint(hwnd, msg, wparam, lparam),
|
||||
WM_CLOSE => {
|
||||
if let Some(inner) = arc_from_hwnd(hwnd) {
|
||||
let mut inner = inner.lock().unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user