imm.c (e6a51b54) imm.c (66ef3149)
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing Far-Eastern languages input
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>

--- 154 unchanged lines hidden (view full) ---

163 hNewKL = (HKL)(DWORD_PTR)dwUnknown;
164 if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
165 Imm32ReleaseIME(hNewKL);
166 }
167
168 return TRUE;
169}
170
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing Far-Eastern languages input
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>

--- 154 unchanged lines hidden (view full) ---

163 hNewKL = (HKL)(DWORD_PTR)dwUnknown;
164 if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
165 Imm32ReleaseIME(hNewKL);
166 }
167
168 return TRUE;
169}
170
171VOID APIENTRY Imm32SelectLayout(HKL hNewKL, HKL hOldKL, HIMC hIMC)
172{
173 PCLIENTIMC pClientImc;
174 LPINPUTCONTEXTDX pIC;
175 LPGUIDELINE pGL;
176 LPCANDIDATEINFO pCI;
177 LPCOMPOSITIONSTRING pCS;
178 LOGFONTA LogFontA;
179 LOGFONTW LogFontW;
180 BOOL fOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
181 DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwConversion, dwSentence, dwSize, dwNewSize;
182 PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
183 HANDLE hPrivate;
184 PIME_STATE pNewState = NULL, pOldState = NULL;
185
186 pClientImc = ImmLockClientImc(hIMC);
187 if (!pClientImc)
188 return;
189
190 pNewImeDpi = ImmLockImeDpi(hNewKL);
191
192 if (hNewKL != hOldKL)
193 pOldImeDpi = ImmLockImeDpi(hOldKL);
194
195 if (pNewImeDpi)
196 {
197 cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
198 pClientImc->uCodePage = pNewImeDpi->uCodePage;
199 }
200 else
201 {
202 pClientImc->uCodePage = CP_ACP;
203 }
204
205 if (cbNewPrivate < 4)
206 cbNewPrivate = 4;
207
208 if (pOldImeDpi)
209 cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
210
211 if (cbOldPrivate < 4)
212 cbOldPrivate = 4;
213
214 if (pClientImc->hKL == hOldKL)
215 {
216 if (pOldImeDpi)
217 {
218 if (IS_IME_HKL(hOldKL))
219 pOldImeDpi->ImeSelect(hIMC, FALSE);
220 else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pOldImeDpi->CtfImeSelectEx)
221 pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
222 }
223 pClientImc->hKL = NULL;
224 }
225
226 if (CtfImmIsTextFrameServiceDisabled())
227 {
228 if (Imm32IsImmMode() && !Imm32IsCiceroMode())
229 {
230 bIsNewHKLIme = IS_IME_HKL(hNewKL);
231 bIsOldHKLIme = IS_IME_HKL(hOldKL);
232 }
233 }
234
235 pIC = (LPINPUTCONTEXTDX)Imm32LockIMCEx(hIMC, FALSE);
236 if (!pIC)
237 {
238 if (pNewImeDpi)
239 {
240 if (IS_IME_HKL(hNewKL))
241 pNewImeDpi->ImeSelect(hIMC, TRUE);
242 else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
243 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
244
245 pClientImc->hKL = hNewKL;
246 }
247 }
248 else
249 {
250 dwConversion = pIC->fdwConversion;
251 dwSentence = pIC->fdwSentence;
252 fOpen = pIC->fOpen;
253
254 if (pNewImeDpi)
255 {
256 bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
257 bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
258 if (bClientWide && !bNewDpiWide)
259 {
260 if (pIC->fdwInit & INIT_LOGFONT)
261 {
262 LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
263 pIC->lfFont.A = LogFontA;
264 }
265 pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
266 }
267 else if (!bClientWide && bNewDpiWide)
268 {
269 if (pIC->fdwInit & INIT_LOGFONT)
270 {
271 LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
272 pIC->lfFont.W = LogFontW;
273 }
274 pClientImc->dwFlags |= CLIENTIMC_WIDE;
275 }
276 }
277
278 if (cbOldPrivate != cbNewPrivate)
279 {
280 hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
281 if (!hPrivate)
282 {
283 ImmDestroyIMCC(pIC->hPrivate);
284 hPrivate = ImmCreateIMCC(cbNewPrivate);
285 }
286 pIC->hPrivate = hPrivate;
287 }
288
289#define MAX_IMCC_SIZE 0x1000
290 dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
291 if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
292 {
293 ImmDestroyIMCC(pIC->hMsgBuf);
294 pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
295 pIC->dwNumMsgBuf = 0;
296 }
297
298 dwSize = ImmGetIMCCSize(pIC->hGuideLine);
299 dwNewSize = sizeof(GUIDELINE);
300 if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
301 dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
302 {
303 ImmDestroyIMCC(pIC->hGuideLine);
304 pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
305 pGL = ImmLockIMCC(pIC->hGuideLine);
306 if (pGL)
307 {
308 pGL->dwSize = dwNewSize;
309 ImmUnlockIMCC(pIC->hGuideLine);
310 }
311 }
312
313 dwSize = ImmGetIMCCSize(pIC->hCandInfo);
314 dwNewSize = sizeof(CANDIDATEINFO);
315 if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
316 dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
317 {
318 ImmDestroyIMCC(pIC->hCandInfo);
319 pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
320 pCI = ImmLockIMCC(pIC->hCandInfo);
321 if (pCI)
322 {
323 pCI->dwSize = dwNewSize;
324 ImmUnlockIMCC(pIC->hCandInfo);
325 }
326 }
327
328 dwSize = ImmGetIMCCSize(pIC->hCompStr);
329 dwNewSize = sizeof(COMPOSITIONSTRING);
330 if (ImmGetIMCCLockCount(pIC->hCompStr) ||
331 dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
332 {
333 ImmDestroyIMCC(pIC->hCompStr);
334 pIC->hCompStr = ImmCreateIMCC(dwNewSize);
335 pCS = ImmLockIMCC(pIC->hCompStr);
336 if (pCS)
337 {
338 pCS->dwSize = dwNewSize;
339 ImmUnlockIMCC(pIC->hCompStr);
340 }
341 }
342#undef MAX_IMCC_SIZE
343
344 if (pOldImeDpi && bIsOldHKLIme)
345 {
346 pOldState = Imm32FetchImeState(pIC, hOldKL);
347 if (pOldState)
348 Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
349 }
350
351 if (pNewImeDpi && bIsNewHKLIme)
352 pNewState = Imm32FetchImeState(pIC, hNewKL);
353
354 if (pOldState != pNewState)
355 {
356 if (pOldState)
357 {
358 pOldState->fOpen = !!pIC->fOpen;
359 pOldState->dwConversion = (pIC->fdwConversion & ~IME_CMODE_EUDC);
360 pOldState->dwSentence = pIC->fdwSentence;
361 pOldState->dwInit = pIC->fdwInit;
362 }
363
364 if (pNewState)
365 {
366 if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
367 {
368 pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
369 pIC->fOpen = TRUE;
370 }
371 else
372 {
373 pIC->fOpen = pNewState->fOpen;
374 }
375
376 pIC->fdwConversion = (pNewState->dwConversion & ~IME_CMODE_EUDC);
377 pIC->fdwSentence = pNewState->dwSentence;
378 pIC->fdwInit = pNewState->dwInit;
379 }
380 }
381
382 if (pNewState)
383 Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
384
385 if (pNewImeDpi)
386 {
387 if (IS_IME_HKL(hNewKL))
388 pNewImeDpi->ImeSelect(hIMC, TRUE);
389 else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
390 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
391
392 pClientImc->hKL = hNewKL;
393 }
394
395 pIC->dwChange = 0;
396 if (pIC->fOpen != fOpen)
397 pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
398 if (pIC->fdwConversion != dwConversion)
399 pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
400 if (pIC->fdwSentence != dwSentence)
401 pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
402
403 ImmUnlockIMC(hIMC);
404 }
405
406 ImmUnlockImeDpi(pOldImeDpi);
407 ImmUnlockImeDpi(pNewImeDpi);
408 ImmUnlockClientImc(pClientImc);
409}
410
411typedef struct SELECT_LAYOUT
412{
413 HKL hNewKL;
414 HKL hOldKL;
415} SELECT_LAYOUT, *LPSELECT_LAYOUT;
416
417static BOOL CALLBACK Imm32SelectLayoutProc(HIMC hIMC, LPARAM lParam)
418{
419 LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
420 Imm32SelectLayout(pSelect->hNewKL, pSelect->hOldKL, hIMC);
421 return TRUE;
422}
423
424static BOOL CALLBACK Imm32NotifyCompStrProc(HIMC hIMC, LPARAM lParam)
425{
426 ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
427 return TRUE;
428}
429
430/***********************************************************************
431 * ImmActivateLayout (IMM32.@)
432 */
433BOOL WINAPI ImmActivateLayout(HKL hKL)
434{
435 PIMEDPI pImeDpi;
436 HKL hOldKL;
437 LPARAM lParam;
438 HWND hwndDefIME = NULL;
439 SELECT_LAYOUT SelectLayout;
440
441 hOldKL = GetKeyboardLayout(0);
442
443 if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
444 return TRUE;
445
446 ImmLoadIME(hKL);
447
448 if (hOldKL != hKL)
449 {
450 pImeDpi = ImmLockImeDpi(hOldKL);
451 if (pImeDpi)
452 {
453 if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
454 lParam = CPS_COMPLETE;
455 else
456 lParam = CPS_CANCEL;
457 ImmUnlockImeDpi(pImeDpi);
458
459 ImmEnumInputContext(0, Imm32NotifyCompStrProc, lParam);
460 }
461
462 hwndDefIME = ImmGetDefaultIMEWnd(NULL);
463 if (IsWindow(hwndDefIME))
464 SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
465
466 NtUserSetThreadLayoutHandles(hKL, hOldKL);
467 }
468
469 SelectLayout.hNewKL = hKL;
470 SelectLayout.hOldKL = hOldKL;
471 ImmEnumInputContext(0, Imm32SelectLayoutProc, (LPARAM)&SelectLayout);
472
473 if (IsWindow(hwndDefIME))
474 SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
475
476 return TRUE;
477}
478
171typedef struct _tagImmHkl
172{
173 struct list entry;
174 HKL hkl;
175 HMODULE hIME;
176 IMEINFO imeInfo;
177 WCHAR imeClassName[17]; /* 16 character max */
178 ULONG uSelected;

--- 178 unchanged lines hidden (view full) ---

357 RtlInitializeCriticalSection(&pClientImc->cs);
358
359 // FIXME: NtUserGetThreadState and enum ThreadStateRoutines are broken.
360 pClientImc->unknown = NtUserGetThreadState(13);
361
362 return hIMC;
363}
364
479typedef struct _tagImmHkl
480{
481 struct list entry;
482 HKL hkl;
483 HMODULE hIME;
484 IMEINFO imeInfo;
485 WCHAR imeClassName[17]; /* 16 character max */
486 ULONG uSelected;

--- 178 unchanged lines hidden (view full) ---

665 RtlInitializeCriticalSection(&pClientImc->cs);
666
667 // FIXME: NtUserGetThreadState and enum ThreadStateRoutines are broken.
668 pClientImc->unknown = NtUserGetThreadState(13);
669
670 return hIMC;
671}
672
365static VOID APIENTRY Imm32CleanupContextExtra(LPINPUTCONTEXT pIC)
673static VOID APIENTRY Imm32FreeImeStates(LPINPUTCONTEXTDX pIC)
366{
674{
367 FIXME("We have to do something do here");
675 PIME_STATE pState, pStateNext;
676 PIME_SUBSTATE pSubState, pSubStateNext;
677
678 pState = pIC->pState;
679 pIC->pState = NULL;
680 for (; pState; pState = pStateNext)
681 {
682 pStateNext = pState->pNext;
683 for (pSubState = pState->pSubState; pSubState; pSubState = pSubStateNext)
684 {
685 pSubStateNext = pSubState->pNext;
686 Imm32HeapFree(pSubState);
687 }
688 Imm32HeapFree(pState);
689 }
368}
369
370BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
371{
372 PIMEDPI pImeDpi;
690}
691
692BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
693{
694 PIMEDPI pImeDpi;
373 LPINPUTCONTEXT pIC;
695 LPINPUTCONTEXTDX pIC;
374 PCLIENTIMC pClientImc;
375 PIMC pIMC;
376
377 if (!Imm32IsImmMode() || hIMC == NULL)
378 return FALSE;
379
380 pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT);
381 if (!pIMC || pIMC->head.pti != NtCurrentTeb()->Win32ThreadInfo)

--- 7 unchanged lines hidden (view full) ---

389 {
390 pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
391 ImmUnlockClientImc(pClientImc);
392 if (!bKeep)
393 return NtUserDestroyInputContext(hIMC);
394 return TRUE;
395 }
396
696 PCLIENTIMC pClientImc;
697 PIMC pIMC;
698
699 if (!Imm32IsImmMode() || hIMC == NULL)
700 return FALSE;
701
702 pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT);
703 if (!pIMC || pIMC->head.pti != NtCurrentTeb()->Win32ThreadInfo)

--- 7 unchanged lines hidden (view full) ---

711 {
712 pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
713 ImmUnlockClientImc(pClientImc);
714 if (!bKeep)
715 return NtUserDestroyInputContext(hIMC);
716 return TRUE;
717 }
718
397 pIC = ImmLockIMC(hIMC);
719 pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
398 if (pIC == NULL)
399 {
400 ImmUnlockClientImc(pClientImc);
401 return FALSE;
402 }
403
404 FIXME("We have do something to do here\n");
405

--- 16 unchanged lines hidden (view full) ---

422 }
423
424 pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
425 pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
426 pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
427 pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
428 pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
429
720 if (pIC == NULL)
721 {
722 ImmUnlockClientImc(pClientImc);
723 return FALSE;
724 }
725
726 FIXME("We have do something to do here\n");
727

--- 16 unchanged lines hidden (view full) ---

744 }
745
746 pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
747 pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
748 pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
749 pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
750 pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
751
430 Imm32CleanupContextExtra(pIC);
752 Imm32FreeImeStates(pIC);
431
432 ImmUnlockIMC(hIMC);
433
434 pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
435 ImmUnlockClientImc(pClientImc);
436
437 if (!bKeep)
438 return NtUserDestroyInputContext(hIMC);

--- 1106 unchanged lines hidden ---
753
754 ImmUnlockIMC(hIMC);
755
756 pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
757 ImmUnlockClientImc(pClientImc);
758
759 if (!bKeep)
760 return NtUserDestroyInputContext(hIMC);

--- 1106 unchanged lines hidden ---