xref: /reactos/dll/win32/imm32/precomp.h (revision 8ea93d2a)
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