spiegel-keyman/windows/src/engine/kmtip
2025-12-18 14:46:10 +10:00
..
build.sh feat(windows): remove quotes wxs rename lowercase 2025-12-02 12:05:01 +10:00
debug.cpp feat(windows): audit _WIN64 macro 2025-11-25 16:01:52 +10:00
dllmain.cpp [Windows] Debug logging and proof of concept tests for keyboarding support within metro-style apps 2018-10-18 20:00:49 +11:00
editsess.h Keyman Desktop and Keyman Developer open source 10.0 alpha seed (#121) 2017-07-25 10:53:06 +07:00
globals.cpp refactor(windows): clean up logging 2024-07-03 21:28:37 +10:00
globals.h Merge branch 'master' into refactor/windows/cleanup-engine-logging 2024-07-23 17:29:55 +10:00
inserttext.cpp Merge branch 'master' into refactor/windows/cleanup-engine-logging 2024-07-23 17:29:55 +10:00
keyman32interface.cpp fix(windows): add GetContextEx and TIPProcessKeyEx 2025-01-24 14:03:09 +10:00
keys.cpp Apply suggestions from code review 2024-07-23 17:40:37 +10:00
kmkey.cpp Merge pull request #13023 from keymanapp/fix/windows/api-additional-function 2025-01-30 16:28:31 +10:00
kmtip.cpp refactor(windows): clean up logging 2024-07-03 21:28:37 +10:00
kmtip.def chore(windows): remove RefreshPreservedKeys pt2 2023-05-11 14:57:01 +10:00
kmtip.h fix(windows): add GetContextEx and TIPProcessKeyEx 2025-01-24 14:03:09 +10:00
kmtip.rc Keyman Desktop and Keyman Developer open source 10.0 alpha seed (#121) 2017-07-25 10:53:06 +07:00
kmtip.res Keyman Desktop and Keyman Developer open source 10.0 alpha seed (#121) 2017-07-25 10:53:06 +07:00
kmtip.sln feat(windows): update engine solution 2025-12-01 17:03:28 +10:00
kmtip.vcxproj feat(windows): remove quotes wxs rename lowercase 2025-12-02 12:05:01 +10:00
kmtip.vcxproj.filters feat(windows): remove quotes wxs rename lowercase 2025-12-02 12:05:01 +10:00
kmtip64.def Keyman Desktop and Keyman Developer open source 10.0 alpha seed (#121) 2017-07-25 10:53:06 +07:00
kmtip_manifest.rc Keyman Desktop and Keyman Developer open source 10.0 alpha seed (#121) 2017-07-25 10:53:06 +07:00
kmtiparm64.def feat(windows): link keymanarm64.dll correctly 2025-11-19 14:07:21 +10:00
kmtiparm64x.def feat(windows): remove quotes wxs rename lowercase 2025-12-02 12:05:01 +10:00
pch.cpp [Windows] Debug logging and proof of concept tests for keyboarding support within metro-style apps 2018-10-18 20:00:49 +11:00
pch.h [Windows] Debug logging and proof of concept tests for keyboarding support within metro-style apps 2018-10-18 20:00:49 +11:00
README.md feat(windows): fix typo 2025-12-18 14:46:10 +10:00
register.cpp chore(windows): move various headers to common 2022-06-12 13:18:45 +10:00
registryw.cpp refactor(windows): clean up logging 2024-07-03 21:28:37 +10:00
registryw.h chore(windows): add const to argument definition 2024-02-09 11:11:27 +10:00
server.cpp chore(windows): move various headers to common 2022-06-12 13:18:45 +10:00
tmgrsink.cpp refactor(windows): clean up logging 2024-07-03 21:28:37 +10:00
version.rc chore(windows): move keymanversion.h to common 2022-06-12 13:56:13 +10:00

Overview

kmtip is an implementation of a Text Service for the Text Services Framework (TSF). This implementation is named Keyman Text Input Processor (TIP). Architecturally it sits between the TSF Manager and Keyman.exe.

Background

1. The "Mixed Architecture" Environment

Windows on both amd64(x86-64) and on Arm devices can run applications of differing architectures simultaneously:

On amd64 Devices:

  • Native x64 apps: (e.g., Windows Explorer, Notepad, Edge).
  • x86 apps (WOW64): (32-bit legacy apps).

On Arm Devices:

  • Native Arm64 apps: (e.g., Windows Explorer, Notepad, Edge).
  • Emulated x64 apps: (e.g., Older desktop applications).
  • Emulated x86 apps: (32-bit legacy apps).

A Text Input Processor (TIP) is a plugin that gets loaded directly into the process space of the application currently receiving text input. Therefore, the TIP DLL must match the architecture of the application it is running in. Setting all this up is different on Windows on Arm and Windows on amd64 devices.

kmtip.dll and kmtip64.dll - On amd64 Devices

On 64-bit Windows, there is a single registry entry (COM CLSID) for a 64-bit TIP: kmtip64.dll. HKLM\SOFTWARE\Classes\CLSID

For 32-bit applications, there exists a WOW6432Node in the Windows registry that allows a different DLL to be registered for the same Class ID: kmtip.dll. HKLM\SOFTWARE\WOW6432Node\Classes\CLSID It is essentially two views of the registry depending on whether the application is 32-bit or 64-bit.

kmtiparm64x.dll - Arm64 Devices

Single Registry Entry Problem for the two 64-bit architectures

On Windows on Arm there is a problem because there is only a single registry entry for the 64-bit CLSID. This means it is not possible to register both an amd64 DLL and an Arm64 DLL, for example kmtip64.dll and kmtiparm64.dll. (For 32-bit apps there is still the WOW6432Node that registers kmtip.dll.)

  • If we register a standard Arm64 DLL, x64 apps will crash or fail to load it because they cannot load a pure Arm64 binary.
  • If we register a standard x64 DLL, native Arm64 apps will fail to load it.

The Solution: Arm64X

Arm64X is a PE (Portable Executable) binary format. It is a dual-architecture library capable of servicing both native Arm64 applications and emulated x64 applications on Windows on Arm (WoA) devices.

kmtiparm64x.dll solves this problem by using the Arm64X format. It contains two complete sets of code within a single file:

  1. Arm64 Code: Used when the DLL is loaded by a native Arm64 process.
  2. Arm64EC (Emulation Compatible) Code: Used when the DLL is loaded by an x64 process.
    • Note: Arm64EC code runs at native speed but uses x64 data structures and calling conventions, allowing it to interoperate seamlessly with the x64 host app.

Runtime Behavior

When an application loads kmtiparm64x.dll:

  • The Windows loader automatically detects the process architecture.

  • Automatic Selection:

    • If the host process is x64, Windows exposes the Arm64EC section. The Arm64EC section is built against the keyman64.dll Keyman engine, causing it to be loaded dynamically.
    • If the host process is Arm64, Windows exposes the Arm64 section. The Arm64 section is built against the keymanarm64.dll Keyman engine, causing it to be loaded dynamically.
  • Transparency: The host application is unaware that the binary contains code for other platforms; it sees only what it expects

Build Composition

The kmtiparm64x.dll binary is the result of merging two distinct build targets from the source:

  1. kmtip (arm64): The pure native target.
  2. kmtip (arm64EC): The hybrid target for x64 compatibility.

Usage

  • Registration: This DLL is registered against the single Keyman TIP CLSID for 64-bit contexts.
  • x86 Support: Note that 32-bit (x86) applications still require the separate kmtip.dll (32-bit x86 build), as they use a completely different registry hive (WOW6432Node).