pub use super::*;
use std::sync::atomic::{AtomicUsize, Ordering};
static hDibDC_PTR_GLOBAL: AtomicUsize = AtomicUsize::new(0);
static GLOBAL_WIN_WIDTH: AtomicUsize = AtomicUsize::new(300);
static GLOBAL_WIN_HEIGHT: AtomicUsize = AtomicUsize::new(200);
static PLEASE_INVALIDATE_FLAG: AtomicUsize = AtomicUsize::new(0);
unsafe extern "system" fn some_experiment(hWnd: winapi::shared::windef::HWND,
msg: winapi::shared::minwindef::UINT,
wParam: winapi::shared::minwindef::WPARAM,
lParam: winapi::shared::minwindef::LPARAM) -> winapi::shared::minwindef::LRESULT {
if msg == winapi::um::winuser::WM_PAINT {
println!("Painting!");
let mut paint: winapi::um::winuser::PAINTSTRUCT = mem::uninitialized();
println!(" !! hDibDC_PTR_GLOBAL.load(Ordering::SeqCst) = {}", hDibDC_PTR_GLOBAL.load(Ordering::SeqCst));
let hDibDC_PTR: winapi::shared::windef::HDC = hDibDC_PTR_GLOBAL.load(Ordering::SeqCst) as winapi::shared::windef::HDC;
let hw_dc = winapi::um::winuser::BeginPaint(hWnd, &mut paint);
winapi::um::wingdi::BitBlt(
hw_dc,
0, 0, GLOBAL_WIN_WIDTH.load(Ordering::SeqCst) as i32 , GLOBAL_WIN_HEIGHT.load(Ordering::SeqCst) as i32 ,
hDibDC_PTR, 0, 0, winapi::um::wingdi::SRCCOPY
);
winapi::um::winuser::EndPaint(hWnd, &mut paint);
}
else if PLEASE_INVALIDATE_FLAG.load(Ordering::SeqCst) == 1 {
let rect = winapi::shared::windef::RECT {
left: 0, top: 0,
right: GLOBAL_WIN_WIDTH.load(Ordering::SeqCst) as i32, bottom: GLOBAL_WIN_HEIGHT.load(Ordering::SeqCst) as i32
};
winapi::um::winuser::InvalidateRect(hWnd, &rect, winapi::shared::minwindef::FALSE);
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
impl RenderBack for CWin {
fn init(&mut self) {
GLOBAL_WIN_WIDTH.store(self.rep.width as usize, Ordering::SeqCst);
GLOBAL_WIN_HEIGHT.store(self.rep.height as usize, Ordering::SeqCst);
let name = win32_string(&self.rep.title);
let title = win32_string(&self.rep.title);
let res: Result<Window, Error> = unsafe {
let hinstance = GetModuleHandleW( null_mut() );
let wnd_class = WNDCLASSW {
style : CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
lpfnWndProc : Some( some_experiment ),
hInstance : hinstance,
lpszClassName : name.as_ptr(),
cbClsExtra : 0,
cbWndExtra : 0,
hIcon: null_mut(),
hCursor: null_mut(),
hbrBackground: null_mut(),
lpszMenuName: null_mut(),
};
RegisterClassW( &wnd_class );
let handle = CreateWindowExW(
0,
name.as_ptr(),
title.as_ptr(),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, self.rep.width as i32,
self.rep.height as i32,
null_mut(),
null_mut(),
hinstance,
null_mut() );
if handle.is_null() {
Err( Error::last_os_error() )
} else {
Ok( Window { handle } )
}
};
match res {
Err(_) => {
println!("CGui: Fatal error, cannot create win32 window object");
}
Ok (win_ptr) => {
self.rep.win32_win_ptr = win_ptr;
}
}
}
fn redraw_dirty(&mut self) {
let x1 = self.rep.dirty_extents[0];
let y1 = self.rep.dirty_extents[1];
let x2 = self.rep.dirty_extents[2];
let y2 = self.rep.dirty_extents[3];
self.redraw_box(x1, y1, x2, y2);
self.rep.dirty_extents = [self.rep.width, self.rep.height, 0, 0]; }
fn redraw_box(&mut self, x1: usize, y1: usize, x2: usize, y2: usize) {
if x1 == x2 || y1 == y2 {
return;
}
if x1 > x2 || y1 > y2 {
return;
}
self.rep.redraw_box(x1, y1, x2, y2);
}
fn event_tick(&self) -> String {
let evt_str : String = unsafe {
let mut message : MSG = mem::uninitialized();
if GetMessageW( &mut message as *mut MSG, self.rep.win32_win_ptr.handle, 0, 0 ) > 0 {
TranslateMessage( &message as *const MSG );
DispatchMessageW( &message as *const MSG );
if message.message == 258 {
let possible_char : char = message.wParam as u8 as char;
if possible_char.is_alphabetic() || possible_char.is_numeric() {
format!("KeyPress,{}", possible_char)
}
else {
"UNKNOWN_EVT".to_string()
}
}
else if message.message == 161 {
"WinShown".to_string()
}
else if message.message == winapi::um::winuser::WM_PAINT {
"WM_PAINT".to_string()
}
else {
"UNKNOWN_EVT".to_string()
}
}
else {
"WinClose".to_string() }
};
return evt_str;
}
fn event_loop(&mut self) {
if ! self.rep.init_flag {
self.init();
}
while ! self.rep.exit_flag {
let evt_mess = self.event_tick();
self.call_callbacks(evt_mess);
}
}
}
pub struct Window {
handle : HWND,
}
fn win32_string( value : &str ) -> Vec<u16> {
OsStr::new( value ).encode_wide().chain( once( 0 ) ).collect()
}
impl RenderBack for CWinRep {
fn init(&mut self) {
println!("CWinRep has no need to have the RenderBack::init() function called");
}
fn redraw_dirty(&mut self) {
let x1 = self.dirty_extents[0];
let y1 = self.dirty_extents[1];
let x2 = self.dirty_extents[2];
let y2 = self.dirty_extents[3];
self.redraw_box(x1, y1, x2, y2);
self.dirty_extents = [self.width, self.height, 0, 0]; }
fn redraw_box(&mut self, x1: usize, y1: usize, x2: usize, y2: usize) {
if x1 == x2 || y1 == y2 {
return;
}
if x1 > x2 || y1 > y2 {
return;
}
unsafe {
let mut bitmapinfo: winapi::um::wingdi::BITMAPINFO = mem::zeroed();
bitmapinfo.bmiHeader.biSize = mem::size_of::<winapi::um::wingdi::BITMAPINFOHEADER>() as u32;
bitmapinfo.bmiHeader.biWidth = self.width as i32;
bitmapinfo.bmiHeader.biHeight = self.height as i32;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biBitCount = 32;
bitmapinfo.bmiHeader.biCompression = winapi::um::wingdi::BI_RGB;
let mut null_p: *mut winapi::ctypes::c_void = mem::zeroed();
let mut ppvBits: *mut winapi::ctypes::c_void = mem::zeroed();
println!("ppvBits norm={:?}", ppvBits);
println!("ppvBits={:p}", ppvBits);
let mem_hdc = winapi::um::winuser::GetDC(winapi::um::winuser::GetDesktopWindow());
println!("mem_hdc={:p} {:?}", mem_hdc, mem_hdc);
let hbitmap = winapi::um::wingdi::CreateDIBSection(
mem_hdc,
&bitmapinfo,
winapi::um::wingdi::DIB_RGB_COLORS,
&mut ppvBits,
null_p, 0, );
println!("hbitmap={:p} {:?}", hbitmap, hbitmap);
let h_dib_dc: winapi::shared::windef::HDC = winapi::um::wingdi::CreateCompatibleDC(mem_hdc);
hDibDC_PTR_GLOBAL.store(h_dib_dc as usize, Ordering::SeqCst);
println!(" !! h_dib_dc={:?}", h_dib_dc);
let hOldObj = winapi::um::wingdi::SelectObject(h_dib_dc, hbitmap as *mut winapi::ctypes::c_void);
println!("hOldObj={:?}", hOldObj);
println!("ppvBits norm={:?}", ppvBits);
println!("ppvBits={:p} (should be non-zero)", ppvBits);
{
let mut ppvBits: *mut u8 = ppvBits as *mut u8;
println!("ppvBits={:p} (should be non-zero)", ppvBits);
for x in 0..self.width {
for y in 0..self.height {
let color = self.pixels.get_pixel(x as u32, y as u32).to_rgb().data;
let offset = ((( ((self.width-1)-y) * self.width) + x) * 3) as isize;
ptr::write(ppvBits.offset(offset+0), color[0]);
ptr::write(ppvBits.offset(offset+1), color[1]);
ptr::write(ppvBits.offset(offset+2), color[2]);
}
}
}
PLEASE_INVALIDATE_FLAG.store(1, Ordering::SeqCst);
winapi::um::winuser::ReleaseDC(winapi::um::winuser::GetDesktopWindow(), h_dib_dc);
winapi::um::winuser::ReleaseDC(winapi::um::winuser::GetDesktopWindow(), mem_hdc);
}
}
fn event_tick(&self) -> String {
let evt_str : String = unsafe {
let mut message : MSG = mem::uninitialized();
if GetMessageW( &mut message as *mut MSG, self.win32_win_ptr.handle, 0, 0 ) > 0 {
TranslateMessage( &message as *const MSG );
DispatchMessageW( &message as *const MSG );
if message.message == 258 {
let possible_char : char = message.wParam as u8 as char;
if possible_char.is_alphabetic() || possible_char.is_numeric() {
format!("KeyPress,{}", possible_char)
}
else {
"UNKNOWN_EVT".to_string()
}
}
else if message.message == 161 {
"WinShown".to_string()
}
else {
"UNKNOWN_EVT".to_string()
}
}
else {
"WinClose".to_string() }
};
return evt_str;
}
fn event_loop(&mut self) {
}
}