Make CJK imes work better

This commit is contained in:
Soreepeong 2023-12-07 22:41:10 +09:00
parent 280a9d6b05
commit b6d88f798a
9 changed files with 1064 additions and 466 deletions

View file

@ -12,7 +12,6 @@ using Dalamud.Configuration.Internal;
using Dalamud.Game;
using Dalamud.Game.ClientState.GamePad;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.Gui.Internal;
using Dalamud.Game.Internal.DXGI;
using Dalamud.Hooking;
using Dalamud.Interface.GameFonts;
@ -73,12 +72,16 @@ internal class InterfaceManager : IDisposable, IServiceType
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service<Framework>.Get();
[ServiceManager.ServiceDependency]
private readonly WndProcHookManager wndProcHookManager = Service<WndProcHookManager>.Get();
[ServiceManager.ServiceDependency]
private readonly DalamudIme dalamudIme = Service<DalamudIme>.Get();
private readonly ManualResetEvent fontBuildSignal;
private readonly SwapChainVtableResolver address;
private readonly Hook<DispatchMessageWDelegate> dispatchMessageWHook;
private readonly Hook<SetCursorDelegate> setCursorHook;
private Hook<ProcessMessageDelegate> processMessageHook;
private RawDX11Scene? scene;
private Hook<PresentDelegate>? presentHook;
@ -92,8 +95,6 @@ internal class InterfaceManager : IDisposable, IServiceType
[ServiceManager.ServiceConstructor]
private InterfaceManager()
{
this.dispatchMessageWHook = Hook<DispatchMessageWDelegate>.FromImport(
null, "user32.dll", "DispatchMessageW", 0, this.DispatchMessageWDetour);
this.setCursorHook = Hook<SetCursorDelegate>.FromImport(
null, "user32.dll", "SetCursor", 0, this.SetCursorDetour);
@ -111,12 +112,6 @@ internal class InterfaceManager : IDisposable, IServiceType
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr SetCursorDelegate(IntPtr hCursor);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr DispatchMessageWDelegate(ref User32.MSG msg);
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr ProcessMessageDelegate(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled);
/// <summary>
/// This event gets called each frame to facilitate ImGui drawing.
/// </summary>
@ -236,10 +231,9 @@ internal class InterfaceManager : IDisposable, IServiceType
this.setCursorHook.Dispose();
this.presentHook?.Dispose();
this.resizeBuffersHook?.Dispose();
this.dispatchMessageWHook.Dispose();
this.processMessageHook?.Dispose();
}).Wait();
this.wndProcHookManager.PreWndProc -= this.WndProcHookManagerOnPreWndProc;
this.scene?.Dispose();
}
@ -660,6 +654,20 @@ internal class InterfaceManager : IDisposable, IServiceType
this.scene = newScene;
Service<InterfaceManagerWithScene>.Provide(new(this));
this.wndProcHookManager.PreWndProc += this.WndProcHookManagerOnPreWndProc;
}
private unsafe void WndProcHookManagerOnPreWndProc(ref WndProcHookManager.WndProcOverrideEventArgs args)
{
var r = this.scene?.ProcessWndProcW(args.Hwnd, (User32.WindowMessage)args.Message, args.WParam, args.LParam);
if (r is not null)
{
args.ReturnValue = r.Value;
args.SuppressCall = true;
}
this.dalamudIme.ProcessImeMessage(ref args);
}
/*
@ -1095,15 +1103,9 @@ internal class InterfaceManager : IDisposable, IServiceType
Log.Verbose($"Present address 0x{this.presentHook!.Address.ToInt64():X}");
Log.Verbose($"ResizeBuffers address 0x{this.resizeBuffersHook!.Address.ToInt64():X}");
var wndProcAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8");
Log.Verbose($"WndProc address 0x{wndProcAddress.ToInt64():X}");
this.processMessageHook = Hook<ProcessMessageDelegate>.FromAddress(wndProcAddress, this.ProcessMessageDetour);
this.setCursorHook.Enable();
this.presentHook.Enable();
this.resizeBuffersHook.Enable();
this.dispatchMessageWHook.Enable();
this.processMessageHook.Enable();
});
}
@ -1124,25 +1126,6 @@ internal class InterfaceManager : IDisposable, IServiceType
this.isRebuildingFonts = false;
}
private unsafe IntPtr ProcessMessageDetour(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled)
{
var ime = Service<DalamudIME>.GetNullable();
var res = ime?.ProcessWndProcW(hWnd, (User32.WindowMessage)msg, (void*)wParam, (void*)lParam);
return this.processMessageHook.Original(hWnd, msg, wParam, lParam, handeled);
}
private unsafe IntPtr DispatchMessageWDetour(ref User32.MSG msg)
{
if (msg.hwnd == this.GameWindowHandle && this.scene != null)
{
var res = this.scene.ProcessWndProcW(msg.hwnd, msg.message, (void*)msg.wParam, (void*)msg.lParam);
if (res != null)
return res.Value;
}
return this.dispatchMessageWHook.IsDisposed ? User32.DispatchMessage(ref msg) : this.dispatchMessageWHook.Original(ref msg);
}
private IntPtr ResizeBuffersDetour(IntPtr swapChain, uint bufferCount, uint width, uint height, uint newFormat, uint swapChainFlags)
{
#if DEBUG