1 /* 2 * PROJECT: ReactOS IMM32 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Implementing IMM32 5 * COPYRIGHT: Copyright 1998 Patrik Stridvall 6 * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart 7 * Copyright 2017 James Tabor <james.tabor@reactos.org> 8 * Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org> 9 * Copyright 2020 Oleg Dubinskiy <oleg.dubinskij2013@yandex.ua> 10 * Copyright 2020-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 11 */ 12 13 #pragma once 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 18 /* PSDK/NDK Headers */ 19 #define WIN32_NO_STATUS 20 #include <windef.h> 21 #include <winbase.h> 22 #include <wingdi.h> 23 #include <winuser.h> 24 #include <winnls.h> 25 #include <winreg.h> 26 #include <winnls32.h> 27 #include <winver.h> 28 29 #include <imm.h> 30 #include <immdev.h> 31 #include <imm32_undoc.h> 32 33 #define NTOS_MODE_USER 34 #include <ndk/umtypes.h> 35 #include <ndk/pstypes.h> 36 #include <ndk/rtlfuncs.h> 37 38 /* Public Win32K Headers */ 39 #include "ntuser.h" 40 #include "ntwin32.h" 41 42 /* Undocumented user definitions */ 43 #include <undocuser.h> 44 45 #include <strsafe.h> 46 47 #include <wine/debug.h> 48 #include <wine/list.h> 49 50 #define IMM_INIT_MAGIC 0x19650412 51 #define IMM_INVALID_CANDFORM ULONG_MAX 52 #define INVALID_HOTKEY_ID 0xFFFFFFFF 53 #define MAX_CANDIDATEFORM 4 54 #define MAX_IMM_FILENAME 80 55 56 #define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) 57 #define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) 58 #define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT) 59 60 #define REGKEY_KEYBOARD_LAYOUTS L"System\\CurrentControlSet\\Control\\Keyboard Layouts" 61 62 #define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */ 63 64 typedef struct REG_IME 65 { 66 HKL hKL; 67 WCHAR szImeKey[20]; /* "E0XXYYYY": "E0XX" is the device handle. "YYYY" is a LANGID. */ 68 WCHAR szFileName[80]; /* The IME module filename */ 69 } REG_IME, *PREG_IME; 70 71 extern HMODULE ghImm32Inst; 72 extern RTL_CRITICAL_SECTION gcsImeDpi; 73 extern PIMEDPI gpImeDpiList; 74 extern PSERVERINFO gpsi; 75 extern SHAREDINFO gSharedInfo; 76 extern HANDLE ghImmHeap; 77 extern DWORD g_aimm_compat_flags; 78 79 BOOL Imm32GetSystemLibraryPath(LPWSTR pszPath, DWORD cchPath, LPCWSTR pszFileName); 80 VOID APIENTRY LogFontAnsiToWide(const LOGFONTA *plfA, LPLOGFONTW plfW); 81 VOID APIENTRY LogFontWideToAnsi(const LOGFONTW *plfW, LPLOGFONTA plfA); 82 LPVOID FASTCALL ValidateHandleNoErr(HANDLE hObject, UINT uType); 83 LPVOID FASTCALL ValidateHandle(HANDLE hObject, UINT uType); 84 #define ValidateHwndNoErr(hwnd) ValidateHandleNoErr((hwnd), TYPE_WINDOW) 85 #define ValidateHwnd(hwnd) ValidateHandle((hwnd), TYPE_WINDOW) 86 BOOL APIENTRY Imm32CheckImcProcess(PIMC pIMC); 87 88 LPVOID APIENTRY ImmLocalAlloc(DWORD dwFlags, DWORD dwBytes); 89 #define ImmLocalFree(lpData) HeapFree(ghImmHeap, 0, (lpData)) 90 91 LPWSTR APIENTRY Imm32WideFromAnsi(UINT uCodePage, LPCSTR pszA); 92 LPSTR APIENTRY Imm32AnsiFromWide(UINT uCodePage, LPCWSTR pszW); 93 LONG APIENTRY IchWideFromAnsi(LONG cchAnsi, LPCSTR pchAnsi, UINT uCodePage); 94 LONG APIENTRY IchAnsiFromWide(LONG cchWide, LPCWSTR pchWide, UINT uCodePage); 95 PIMEDPI APIENTRY Imm32FindOrLoadImeDpi(HKL hKL); 96 LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect); 97 BOOL APIENTRY Imm32ReleaseIME(HKL hKL); 98 BOOL APIENTRY Imm32IsSystemJapaneseOrKorean(VOID); 99 BOOL APIENTRY Imm32IsCrossThreadAccess(HIMC hIMC); 100 BOOL APIENTRY Imm32IsCrossProcessAccess(HWND hWnd); 101 BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC); 102 103 #if 0 104 #define UNEXPECTED() ASSERT(FALSE) 105 #else 106 #define UNEXPECTED() 0 107 #endif 108 109 /* 110 * Unexpected Condition Checkers 111 * --- Examine the condition, and then generate trace log if necessary. 112 */ 113 #ifdef NDEBUG /* on Release */ 114 #define FAILED_UNEXPECTEDLY(hr) (FAILED(hr)) 115 #define IS_NULL_UNEXPECTEDLY(p) (!(p)) 116 #define IS_ZERO_UNEXPECTEDLY(p) (!(p)) 117 #define IS_TRUE_UNEXPECTEDLY(x) (x) 118 #define IS_FALSE_UNEXPECTEDLY(x) (!(x)) 119 #define IS_ERROR_UNEXPECTEDLY(x) (!(x)) 120 #else /* on Debug */ 121 #define FAILED_UNEXPECTEDLY(hr) \ 122 (FAILED(hr) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \ 123 __FILE__, __FUNCTION__, __LINE__, "FAILED(%s)\n", #hr), UNEXPECTED(), TRUE) \ 124 : FALSE) 125 #define IS_NULL_UNEXPECTEDLY(p) \ 126 (!(p) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \ 127 __FILE__, __FUNCTION__, __LINE__, "%s was NULL\n", #p), UNEXPECTED(), TRUE) \ 128 : FALSE) 129 #define IS_ZERO_UNEXPECTEDLY(p) \ 130 (!(p) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \ 131 __FILE__, __FUNCTION__, __LINE__, "%s was zero\n", #p), UNEXPECTED(), TRUE) \ 132 : FALSE) 133 #define IS_TRUE_UNEXPECTEDLY(x) \ 134 ((x) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \ 135 __FILE__, __FUNCTION__, __LINE__, "%s was non-zero\n", #x), UNEXPECTED(), TRUE) \ 136 : FALSE) 137 #define IS_FALSE_UNEXPECTEDLY(x) \ 138 ((!(x)) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \ 139 __FILE__, __FUNCTION__, __LINE__, "%s was FALSE\n", #x), UNEXPECTED(), TRUE) \ 140 : FALSE) 141 #define IS_ERROR_UNEXPECTEDLY(x) \ 142 ((x) != ERROR_SUCCESS ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \ 143 __FILE__, __FUNCTION__, __LINE__, \ 144 "%s was 0x%X\n", #x, (x)), TRUE) \ 145 : FALSE) 146 #endif 147 148 #define IS_CROSS_THREAD_HIMC(hIMC) IS_TRUE_UNEXPECTEDLY(Imm32IsCrossThreadAccess(hIMC)) 149 #define IS_CROSS_PROCESS_HWND(hWnd) IS_TRUE_UNEXPECTEDLY(Imm32IsCrossProcessAccess(hWnd)) 150 #define ImeDpi_IsUnicode(pImeDpi) ((pImeDpi)->ImeInfo.fdwProperty & IME_PROP_UNICODE) 151 152 DWORD APIENTRY 153 CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen, 154 UINT uCodePage); 155 DWORD APIENTRY 156 CandidateListAnsiToWide(const CANDIDATELIST *pAnsiCL, LPCANDIDATELIST pWideCL, DWORD dwBufLen, 157 UINT uCodePage); 158 159 BOOL APIENTRY 160 Imm32MakeIMENotify(HIMC hIMC, HWND hwnd, DWORD dwAction, DWORD_PTR dwIndex, DWORD_PTR dwValue, 161 DWORD_PTR dwCommand, DWORD_PTR dwData); 162 163 DWORD APIENTRY Imm32BuildHimcList(DWORD dwThreadId, HIMC **pphList); 164 165 INT APIENTRY 166 Imm32ImeMenuAnsiToWide(const IMEMENUITEMINFOA *pItemA, LPIMEMENUITEMINFOW pItemW, 167 UINT uCodePage, BOOL bBitmap); 168 INT APIENTRY 169 Imm32ImeMenuWideToAnsi(const IMEMENUITEMINFOW *pItemW, LPIMEMENUITEMINFOA pItemA, 170 UINT uCodePage); 171 172 PIME_STATE APIENTRY Imm32FetchImeState(LPINPUTCONTEXTDX pIC, HKL hKL); 173 PIME_SUBSTATE APIENTRY Imm32FetchImeSubState(PIME_STATE pState, HKL hKL); 174 175 BOOL APIENTRY 176 Imm32LoadImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL); 177 BOOL APIENTRY 178 Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL); 179 180 DWORD APIENTRY 181 Imm32ReconvertAnsiFromWide(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage); 182 DWORD APIENTRY 183 Imm32ReconvertWideFromAnsi(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage); 184 185 HRESULT APIENTRY Imm32StrToUInt(LPCWSTR pszText, LPDWORD pdwValue, ULONG nBase); 186 HRESULT APIENTRY Imm32UIntToStr(DWORD dwValue, ULONG nBase, LPWSTR pszBuff, USHORT cchBuff); 187 BOOL APIENTRY Imm32LoadImeVerInfo(PIMEINFOEX pImeInfoEx); 188 UINT APIENTRY Imm32GetImeLayout(PREG_IME pLayouts, UINT cLayouts); 189 BOOL APIENTRY Imm32WriteImeLayout(HKL hKL, LPCWSTR pchFilePart, LPCWSTR pszLayoutText); 190 HKL APIENTRY Imm32AssignNewLayout(UINT cKLs, const REG_IME *pLayouts, WORD wLangID); 191 BOOL APIENTRY Imm32CopyImeFile(LPWSTR pszOldFile, LPCWSTR pszNewFile); 192 PTHREADINFO FASTCALL Imm32CurrentPti(VOID); 193 194 HBITMAP Imm32LoadBitmapFromBytes(const BYTE *pb); 195 BOOL Imm32StoreBitmapToBytes(HBITMAP hbm, LPBYTE pbData, DWORD cbDataMax); 196 197 HRESULT CtfImmTIMCreateInputContext(_In_ HIMC hIMC); 198 HRESULT CtfImmTIMDestroyInputContext(_In_ HIMC hIMC); 199 HRESULT CtfImmCoInitialize(VOID); 200 HRESULT CtfImeCreateThreadMgr(VOID); 201 HRESULT CtfImeDestroyThreadMgr(VOID); 202 HRESULT Imm32ActivateOrDeactivateTIM(_In_ BOOL bCreate); 203 204 HRESULT 205 CtfImeSetActiveContextAlways( 206 _In_ HIMC hIMC, 207 _In_ BOOL fActive, 208 _In_ HWND hWnd, 209 _In_ HKL hKL); 210 211 BOOL 212 CtfImeProcessCicHotkey( 213 _In_ HIMC hIMC, 214 _In_ UINT vKey, 215 _In_ LPARAM lParam); 216 217 LRESULT 218 CtfImmSetLangBand( 219 _In_ HWND hWnd, 220 _In_ BOOL fSet); 221