Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
kanru committed Sep 11, 2024
1 parent a7c01b8 commit 198408a
Show file tree
Hide file tree
Showing 6 changed files with 390 additions and 63 deletions.
19 changes: 18 additions & 1 deletion libIME/idl/libime2.idl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "unknwn.idl";
import "msctf.idl";

[
object,
Expand All @@ -24,14 +25,29 @@ interface IWindow : IUnknown
LRESULT wndProc(UINT msg, WPARAM wp, LPARAM lp);
}

typedef struct _KeyEvent {
UINT type;
UINT keyCode;
UINT charCode;
LPARAM lParapm;
BYTE keyStates[256];
} KeyEvent;

[
object,
uuid(d4eee9d6-60a0-4169-b3b8-d99f66ebe61a),
local
]
interface ICandidateWindow : IWindow
{
void setFontSize(float size);
void setFontSize(DWORD fontSize);
void add(LPCWSTR item, WCHAR selKey);
WCHAR currentSelKey();
void clear();
void setCandPerRow(int n);
void setUseCursor(boolean use);
boolean filterKeyEvent([in] KeyEvent *keyEvent);
boolean hasResult();
}

[
Expand All @@ -49,5 +65,6 @@ interface IMessageWindow : IWindow
[local] void LibIME2Init();
[local] void CreateImeWindow([out] void **window);
[local] void CreateMessageWindow(HWND parent, [out] void **messagewindow);
[local] void CreateCandidateWindow(HWND parent, [out] void **candidatewindow);
[local] IWindow *ImeWindowFromHwnd(HWND hwnd);
[local] boolean ImeWindowRegisterClass(HINSTANCE hinstance);
129 changes: 129 additions & 0 deletions libIME/src/gfx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use windows::core::*;
use windows::Foundation::Numerics::*;
use windows::Win32::Foundation::*;
use windows::Win32::Graphics::Direct2D::Common::*;
use windows::Win32::Graphics::Direct2D::*;
use windows::Win32::Graphics::Direct3D::*;
use windows::Win32::Graphics::Direct3D11::*;
use windows::Win32::Graphics::DirectWrite::*;
use windows::Win32::Graphics::Dxgi::Common::*;
use windows::Win32::Graphics::Dxgi::*;
use windows::Win32::Graphics::Gdi::*;

pub(crate) fn create_color(gdi_color_index: SYS_COLOR_INDEX) -> D2D1_COLOR_F {
let color = unsafe { GetSysColor(gdi_color_index) };
D2D1_COLOR_F {
r: (color & 0xFF) as f32 / 255.0,
g: ((color >> 8) & 0xFF) as f32 / 255.0,
b: ((color >> 16) & 0xFF) as f32 / 255.0,
a: 1.0,
}
}

pub(crate) fn create_brush(
target: &ID2D1DeviceContext,
color: D2D1_COLOR_F,
) -> Result<ID2D1SolidColorBrush> {
let properties = D2D1_BRUSH_PROPERTIES {
opacity: 0.8,
transform: Matrix3x2::identity(),
};

unsafe { target.CreateSolidColorBrush(&color, Some(&properties)) }
}

pub(crate) fn create_device_with_type(drive_type: D3D_DRIVER_TYPE) -> Result<ID3D11Device> {
let flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

let mut device = None;

unsafe {
D3D11CreateDevice(
None,
drive_type,
None,
flags,
None,
D3D11_SDK_VERSION,
Some(&mut device),
None,
None,
)
.map(|()| device.unwrap())
}
}

pub(crate) fn create_device() -> Result<ID3D11Device> {
let mut result = create_device_with_type(D3D_DRIVER_TYPE_HARDWARE);

if let Err(err) = &result {
if err.code() == DXGI_ERROR_UNSUPPORTED {
result = create_device_with_type(D3D_DRIVER_TYPE_WARP);
}
}

result
}

pub(crate) fn create_render_target(
factory: &ID2D1Factory1,
device: &ID3D11Device,
) -> Result<ID2D1DeviceContext> {
unsafe {
let d2device = factory.CreateDevice(&device.cast::<IDXGIDevice>()?)?;

let target = d2device.CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE)?;

target.SetUnitMode(D2D1_UNIT_MODE_DIPS);

Ok(target)
}
}

pub(crate) fn get_dxgi_factory(device: &ID3D11Device) -> Result<IDXGIFactory2> {
let dxdevice = device.cast::<IDXGIDevice>()?;
unsafe { dxdevice.GetAdapter()?.GetParent() }
}

pub(crate) fn create_swapchain_bitmap(
swapchain: &IDXGISwapChain1,
target: &ID2D1DeviceContext,
) -> Result<()> {
let surface: IDXGISurface = unsafe { swapchain.GetBuffer(0)? };

let props = D2D1_BITMAP_PROPERTIES1 {
pixelFormat: D2D1_PIXEL_FORMAT {
format: DXGI_FORMAT_B8G8R8A8_UNORM,
alphaMode: D2D1_ALPHA_MODE_IGNORE,
},
dpiX: 96.0,
dpiY: 96.0,
bitmapOptions: D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
..Default::default()
};

unsafe {
let bitmap = target.CreateBitmapFromDxgiSurface(&surface, Some(&props))?;
target.SetTarget(&bitmap);
};

Ok(())
}

pub(crate) fn create_swapchain(device: &ID3D11Device, window: HWND) -> Result<IDXGISwapChain1> {
let factory = get_dxgi_factory(device)?;

let props = DXGI_SWAP_CHAIN_DESC1 {
Format: DXGI_FORMAT_B8G8R8A8_UNORM,
SampleDesc: DXGI_SAMPLE_DESC {
Count: 1,
Quality: 0,
},
BufferUsage: DXGI_USAGE_RENDER_TARGET_OUTPUT,
BufferCount: 2,
SwapEffect: DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
..Default::default()
};

unsafe { factory.CreateSwapChainForHwnd(device, window, &props, None, None) }
}
1 change: 1 addition & 0 deletions libIME/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod gfx;
mod window;

#[cxx::bridge]
Expand Down
Loading

0 comments on commit 198408a

Please sign in to comment.