diff --git a/win32/dll/gdi32.dll b/win32/dll/gdi32.dll index 78772891..d11c7273 100755 Binary files a/win32/dll/gdi32.dll and b/win32/dll/gdi32.dll differ diff --git a/win32/src/winapi/builtin.rs b/win32/src/winapi/builtin.rs index 17595ded..8b55bab2 100644 --- a/win32/src/winapi/builtin.rs +++ b/win32/src/winapi/builtin.rs @@ -1533,6 +1533,11 @@ pub mod gdi32 { ) .to_raw() } + pub unsafe fn CreatePalette(machine: &mut Machine, esp: u32) -> u32 { + let mem = machine.mem().detach(); + let plpal = ::from_stack(mem, esp + 4u32); + winapi::gdi32::CreatePalette(machine, plpal).to_raw() + } pub unsafe fn CreatePen(machine: &mut Machine, esp: u32) -> u32 { let mem = machine.mem().detach(); let iStyle = >::from_stack(mem, esp + 4u32); @@ -1661,12 +1666,24 @@ pub mod gdi32 { let y = ::from_stack(mem, esp + 12u32); winapi::gdi32::PtVisible(machine, hdc, x, y).to_raw() } + pub unsafe fn RealizePalette(machine: &mut Machine, esp: u32) -> u32 { + let mem = machine.mem().detach(); + let hdc = ::from_stack(mem, esp + 4u32); + winapi::gdi32::RealizePalette(machine, hdc).to_raw() + } pub unsafe fn SelectObject(machine: &mut Machine, esp: u32) -> u32 { let mem = machine.mem().detach(); let hdc = ::from_stack(mem, esp + 4u32); let hGdiObj = ::from_stack(mem, esp + 8u32); winapi::gdi32::SelectObject(machine, hdc, hGdiObj).to_raw() } + pub unsafe fn SelectPalette(machine: &mut Machine, esp: u32) -> u32 { + let mem = machine.mem().detach(); + let hdc = ::from_stack(mem, esp + 4u32); + let hpal = ::from_stack(mem, esp + 8u32); + let bForceBackground = ::from_stack(mem, esp + 12u32); + winapi::gdi32::SelectPalette(machine, hdc, hpal, bForceBackground).to_raw() + } pub unsafe fn SetBkColor(machine: &mut Machine, esp: u32) -> u32 { let mem = machine.mem().detach(); let hdc = ::from_stack(mem, esp + 4u32); @@ -1822,6 +1839,12 @@ pub mod gdi32 { stack_consumed: 56u32, is_async: false, }; + pub const CreatePalette: Shim = Shim { + name: "CreatePalette", + func: impls::CreatePalette, + stack_consumed: 4u32, + is_async: false, + }; pub const CreatePen: Shim = Shim { name: "CreatePen", func: impls::CreatePen, @@ -1936,12 +1959,24 @@ pub mod gdi32 { stack_consumed: 12u32, is_async: false, }; + pub const RealizePalette: Shim = Shim { + name: "RealizePalette", + func: impls::RealizePalette, + stack_consumed: 4u32, + is_async: false, + }; pub const SelectObject: Shim = Shim { name: "SelectObject", func: impls::SelectObject, stack_consumed: 8u32, is_async: false, }; + pub const SelectPalette: Shim = Shim { + name: "SelectPalette", + func: impls::SelectPalette, + stack_consumed: 12u32, + is_async: false, + }; pub const SetBkColor: Shim = Shim { name: "SetBkColor", func: impls::SetBkColor, @@ -2009,13 +2044,14 @@ pub mod gdi32 { is_async: false, }; } - const SHIMS: [Shim; 37usize] = [ + const SHIMS: [Shim; 40usize] = [ shims::BitBlt, shims::CreateBitmap, shims::CreateCompatibleBitmap, shims::CreateCompatibleDC, shims::CreateDIBSection, shims::CreateFontA, + shims::CreatePalette, shims::CreatePen, shims::CreateSolidBrush, shims::DeleteDC, @@ -2035,7 +2071,9 @@ pub mod gdi32 { shims::MoveToEx, shims::PatBlt, shims::PtVisible, + shims::RealizePalette, shims::SelectObject, + shims::SelectPalette, shims::SetBkColor, shims::SetBkMode, shims::SetBrushOrgEx, diff --git a/win32/src/winapi/gdi32/dc.rs b/win32/src/winapi/gdi32/dc.rs index 8084839a..472cc2be 100644 --- a/win32/src/winapi/gdi32/dc.rs +++ b/win32/src/winapi/gdi32/dc.rs @@ -37,6 +37,7 @@ pub struct DC { // per object type. pub brush: HGDIOBJ, pub pen: HGDIOBJ, + pub palette: HGDIOBJ, } impl DC { @@ -48,6 +49,7 @@ impl DC { y: 0, brush: Default::default(), pen: Default::default(), + palette: Default::default(), } } @@ -134,7 +136,8 @@ pub fn GetDeviceCaps( GetDeviceCapsArg::NUMCOLORS => -1i32 as u32, // true color GetDeviceCapsArg::HORZRES => 640, GetDeviceCapsArg::VERTRES => 480, - _ => unimplemented!(), + GetDeviceCapsArg::RASTERCAPS => 0x100, // RC_PALETTE + index => unimplemented!("GetDeviceCaps index={:?}", index), } } diff --git a/win32/src/winapi/gdi32/mod.rs b/win32/src/winapi/gdi32/mod.rs index 7dad3fc5..4d131d16 100644 --- a/win32/src/winapi/gdi32/mod.rs +++ b/win32/src/winapi/gdi32/mod.rs @@ -5,12 +5,14 @@ mod bitmap; mod dc; mod draw; mod object; +mod palette; mod state; mod text; pub use bitmap::*; pub use dc::*; pub use draw::*; pub use object::*; +pub use palette::*; pub use state::*; pub use text::*; diff --git a/win32/src/winapi/gdi32/object.rs b/win32/src/winapi/gdi32/object.rs index 93157e88..adcf518d 100644 --- a/win32/src/winapi/gdi32/object.rs +++ b/win32/src/winapi/gdi32/object.rs @@ -1,4 +1,4 @@ -use super::{Brush, DCTarget, Pen, BITMAP, COLORREF, HDC}; +use super::{Brush, DCTarget, Palette, Pen, BITMAP, COLORREF, HDC}; use crate::{ winapi::{ bitmap::{Bitmap, BitmapMono, BitmapRGBA32}, @@ -29,6 +29,7 @@ impl BitmapType { pub enum Object { Brush(Brush), Bitmap(BitmapType), + Palette(Palette), Pen(Pen), } @@ -98,6 +99,7 @@ pub fn SelectObject(machine: &mut Machine, hdc: HDC, hGdiObj: HGDIOBJ) -> HGDIOB DCTarget::DirectDrawSurface(_) => todo!(), }, Object::Brush(_) => std::mem::replace(&mut dc.brush, hGdiObj), + Object::Palette(_) => panic!("SelectObject called with a palette (use SelectPalette)"), Object::Pen(_) => std::mem::replace(&mut dc.pen, hGdiObj), } } @@ -126,6 +128,7 @@ pub fn GetObjectA(machine: &mut Machine, handle: HGDIOBJ, bytes: u32, out: u32) }; bytes } + Object::Palette(_) => todo!(), Object::Pen(_) => todo!(), } } diff --git a/win32/src/winapi/gdi32/palette.rs b/win32/src/winapi/gdi32/palette.rs new file mode 100644 index 00000000..107730b9 --- /dev/null +++ b/win32/src/winapi/gdi32/palette.rs @@ -0,0 +1,74 @@ +use crate::{winapi::{gdi32::{Object, HDC, HGDIOBJ}, types::WORD}, Machine}; + +const TRACE_CONTEXT: &'static str = "gdi32/palette"; + +#[repr(C)] +#[derive(Clone, Debug)] +pub struct LOGPALETTE_HEADER { + palVersion: WORD, + palNumEntries: WORD, +} +unsafe impl memory::Pod for LOGPALETTE_HEADER {} + +#[repr(C)] +#[derive(Clone, Debug)] +pub struct PALETTEENTRY { + pub peRed: u8, + pub peGreen: u8, + pub peBlue: u8, + pub peFlags: u8, +} +unsafe impl memory::Pod for PALETTEENTRY {} + +#[derive(Debug)] +pub struct Palette(LOGPALETTE_HEADER, Vec); + +#[win32_derive::dllexport] +pub fn CreatePalette(machine: &mut Machine, plpal: u32) -> HGDIOBJ { + let header = machine.mem().view::(plpal).clone(); + + let entries = plpal + size_of::() as u32; + let entries = machine.mem().view_n::(entries, header.palNumEntries as u32).to_vec(); + + machine.state.gdi32.objects.add(Object::Palette(Palette(header, entries))) +} + +#[win32_derive::dllexport] +pub fn SelectPalette(machine: &mut Machine, hdc: HDC, hpal: HGDIOBJ, bForceBackground: bool) -> HGDIOBJ { + let dc = match machine.state.gdi32.dcs.get_mut(hdc) { + None => return HGDIOBJ::null(), // TODO: HGDI_ERROR + Some(dc) => dc, + }; + + let pal = match machine.state.gdi32.objects.get(hpal) { + None => return HGDIOBJ::null(), // TODO: HGDI_ERROR + Some(pal) => pal, + }; + + match pal { + Object::Bitmap(_) => panic!("SelectPalette called with a bitmap (use SelectObject)"), + Object::Brush(_) => panic!("SelectPalette called with a brush (use SelectObject)"), + Object::Palette(_) => std::mem::replace(&mut dc.palette, hpal), + Object::Pen(_) => panic!("SelectPalette called with a pen (use SelectObject)"), + } +} + +#[win32_derive::dllexport] +pub fn RealizePalette(machine: &mut Machine, hdc: HDC) -> u32 { + let dc = match machine.state.gdi32.dcs.get_mut(hdc) { + None => return !0, + Some(dc) => dc, + }; + + let pal = match machine.state.gdi32.objects.get(dc.palette) { + None => return !0, + Some(pal) => pal, + }; + + match pal { + Object::Bitmap(_) => panic!("RealizePalette called with a bitmap"), + Object::Brush(_) => panic!("RealizePalette called with a brush"), + Object::Palette(palette) => palette.1.len() as u32, + Object::Pen(_) => panic!("RealizePalette called with a pen"), + } +}