/*
- * IMM32 library
- *
- * Copyright 1998 Patrik Stridvall
- * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ * PROJECT: ReactOS IMM32
+ * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
+ * PURPOSE: Implementing Far-Eastern languages input
+ * COPYRIGHT: Copyright 1998 Patrik Stridvall
+ * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
+ * Copyright 2017 James Tabor <james.tabor@reactos.org>
+ * Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org>
+ * Copyright 2020-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
-#define WIN32_NO_STATUS
-
-//#include <stdarg.h>
-#include <stdio.h>
-
-#include <windef.h>
-#include <winbase.h>
-//#include "wingdi.h"
-#include <winuser.h>
-//#include "winerror.h"
-#include <wine/debug.h>
-//#include "imm.h"
-#include <ddk/imm.h>
-#include <winnls.h>
-#include <winreg.h>
-#include <wine/list.h>
-#include <wine/unicode.h>
+#include "precomp.h"
+#include <ndk/exfuncs.h>
WINE_DEFAULT_DEBUG_CHANNEL(imm);
-#define MAKE_FUNCPTR(f) typeof(f) * p##f
-typedef struct _tagImmHkl{
- struct list entry;
- HKL hkl;
- HMODULE hIME;
- IMEINFO imeInfo;
- WCHAR imeClassName[17]; /* 16 character max */
- ULONG uSelected;
- HWND UIWnd;
-
- /* Function Pointers */
- MAKE_FUNCPTR(ImeInquire);
- MAKE_FUNCPTR(ImeConfigure);
- MAKE_FUNCPTR(ImeDestroy);
- MAKE_FUNCPTR(ImeEscape);
- MAKE_FUNCPTR(ImeSelect);
- MAKE_FUNCPTR(ImeSetActiveContext);
- MAKE_FUNCPTR(ImeToAsciiEx);
- MAKE_FUNCPTR(NotifyIME);
- MAKE_FUNCPTR(ImeRegisterWord);
- MAKE_FUNCPTR(ImeUnregisterWord);
- MAKE_FUNCPTR(ImeEnumRegisterWord);
- MAKE_FUNCPTR(ImeSetCompositionString);
- MAKE_FUNCPTR(ImeConversionList);
- MAKE_FUNCPTR(ImeProcessKey);
- MAKE_FUNCPTR(ImeGetRegisterWordStyle);
- MAKE_FUNCPTR(ImeGetImeMenuItems);
-} ImmHkl;
-#undef MAKE_FUNCPTR
-
-typedef struct tagInputContextData
-{
- DWORD dwLock;
- INPUTCONTEXT IMC;
-
- ImmHkl *immKbd;
- UINT lastVK;
- DWORD magic;
-} InputContextData;
-
-#define WINE_IMC_VALID_MAGIC 0x56434D49
-
-typedef struct _tagTRANSMSG {
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
-} TRANSMSG, *LPTRANSMSG;
-
-typedef struct _tagIMMThreadData {
- HIMC defaultContext;
- HWND hwndDefault;
-} IMMThreadData;
-
-static DWORD tlsIndex = 0;
-static struct list ImmHklList = LIST_INIT(ImmHklList);
-
-/* MSIME messages */
-static UINT WM_MSIME_SERVICE;
-static UINT WM_MSIME_RECONVERTOPTIONS;
-static UINT WM_MSIME_MOUSE;
-static UINT WM_MSIME_RECONVERTREQUEST;
-static UINT WM_MSIME_RECONVERT;
-static UINT WM_MSIME_QUERYPOSITION;
-static UINT WM_MSIME_DOCUMENTFEED;
-
-static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
-
-static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
-static const WCHAR szLayoutTextW[] = {'L','a','y','o','u','t',' ','T','e','x','t',0};
-static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\\','%','0','8','l','x',0};
+HMODULE ghImm32Inst = NULL; /* The IMM32 instance */
+PSERVERINFO gpsi = NULL;
+SHAREDINFO gSharedInfo = { NULL };
+BYTE gfImmInitialized = FALSE; /* Is IMM32 initialized? */
+ULONG_PTR gHighestUserAddress = 0;
-static const WCHAR szwIME[] = {'I','M','E',0};
+static BOOL APIENTRY ImmInitializeGlobals(HMODULE hMod)
+{
+ NTSTATUS status;
+ SYSTEM_BASIC_INFORMATION SysInfo;
-static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam);
+ if (hMod)
+ ghImm32Inst = hMod;
-#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
-#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
+ if (gfImmInitialized)
+ return TRUE;
-static BOOL IMM_DestroyContext(HIMC hIMC);
+ status = RtlInitializeCriticalSection(&gcsImeDpi);
+ if (NT_ERROR(status))
+ {
+ ERR("\n");
+ return FALSE;
+ }
-static inline WCHAR *strdupAtoW( const char *str )
-{
- WCHAR *ret = NULL;
- if (str)
+ status = NtQuerySystemInformation(SystemBasicInformation, &SysInfo, sizeof(SysInfo), NULL);
+ if (NT_ERROR(status))
{
- DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
- if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
- MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+ ERR("\n");
+ return FALSE;
}
- return ret;
+ gHighestUserAddress = SysInfo.MaximumUserModeAddress;
+
+ gfImmInitialized = TRUE;
+ return TRUE;
}
-static inline CHAR *strdupWtoA( const WCHAR *str )
+/***********************************************************************
+ * ImmRegisterClient(IMM32.@)
+ * ( Undocumented, called from user32.dll )
+ */
+BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod)
{
- CHAR *ret = NULL;
- if (str)
- {
- DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
- if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
- WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
- }
- return ret;
+ gSharedInfo = *ptr;
+ gpsi = gSharedInfo.psi;
+ return ImmInitializeGlobals(hMod);
}
-static DWORD convert_candidatelist_WtoA(
- LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
+/***********************************************************************
+ * ImmLoadLayout (IMM32.@)
+ */
+BOOL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
{
- DWORD ret, i, len;
+ DWORD cbData, dwType;
+ HKEY hKey;
+ LSTATUS error;
+ WCHAR szLayout[MAX_PATH];
+ LPCWSTR pszSubKey;
+
+ TRACE("(%p, %p)\n", hKL, pImeInfoEx);
- ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
- if ( lpDst && dwBufLen > 0 )
+ /* Choose a key */
+ if (IS_IME_HKL(hKL) || !IS_CICERO_MODE() || IS_16BIT_MODE()) /* Non-Cicero? */
{
- *lpDst = *lpSrc;
- lpDst->dwOffset[0] = ret;
+ StringCchPrintfW(szLayout, _countof(szLayout), L"%s\\%08lX",
+ REGKEY_KEYBOARD_LAYOUTS, HandleToUlong(hKL));
+ pszSubKey = szLayout;
}
-
- for ( i = 0; i < lpSrc->dwCount; i++)
+ else /* Cicero */
{
- LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
+ pszSubKey = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM";
+ }
- if ( lpDst && dwBufLen > 0 )
- {
- LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
+ /* Open the key */
+ error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pszSubKey, 0, KEY_READ, &hKey);
+ if (IS_ERROR_UNEXPECTEDLY(error))
+ return FALSE;
- len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1,
- (LPSTR)dest, dwBufLen, NULL, NULL);
+ /* Load "IME File" value */
+ cbData = sizeof(pImeInfoEx->wszImeFile);
+ error = RegQueryValueExW(hKey, L"IME File", NULL, &dwType,
+ (LPBYTE)pImeInfoEx->wszImeFile, &cbData);
- if ( i + 1 < lpSrc->dwCount )
- lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(char);
- dwBufLen -= len * sizeof(char);
- }
- else
- len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, NULL, 0, NULL, NULL);
+ /* Avoid buffer overrun */
+ pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = UNICODE_NULL;
- ret += len * sizeof(char);
- }
+ RegCloseKey(hKey);
- if ( lpDst )
- lpDst->dwSize = ret;
+ if (error != ERROR_SUCCESS || dwType != REG_SZ)
+ return FALSE; /* Failed */
- return ret;
+ pImeInfoEx->hkl = hKL;
+ pImeInfoEx->fLoadFlag = 0;
+ return Imm32LoadImeVerInfo(pImeInfoEx);
}
-static DWORD convert_candidatelist_AtoW(
- LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
+/***********************************************************************
+ * ImmFreeLayout (IMM32.@)
+ */
+BOOL WINAPI ImmFreeLayout(DWORD dwUnknown)
{
- DWORD ret, i, len;
+ WCHAR szKBD[KL_NAMELENGTH];
+ UINT iKL, cKLs;
+ HKL hOldKL, hNewKL, *pList;
+ PIMEDPI pImeDpi;
+ LANGID LangID;
- ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
- if ( lpDst && dwBufLen > 0 )
- {
- *lpDst = *lpSrc;
- lpDst->dwOffset[0] = ret;
- }
+ TRACE("(0x%lX)\n", dwUnknown);
+
+ hOldKL = GetKeyboardLayout(0);
- for ( i = 0; i < lpSrc->dwCount; i++)
+ if (dwUnknown == 1)
{
- LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
+ if (!IS_IME_HKL(hOldKL))
+ return TRUE;
+
+ LangID = LANGIDFROMLCID(GetSystemDefaultLCID());
- if ( lpDst && dwBufLen > 0 )
+ cKLs = GetKeyboardLayoutList(0, NULL);
+ if (cKLs)
{
- LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
+ pList = ImmLocalAlloc(0, cKLs * sizeof(HKL));
+ if (IS_NULL_UNEXPECTEDLY(pList))
+ return FALSE;
- len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1,
- (LPWSTR)dest, dwBufLen);
+ cKLs = GetKeyboardLayoutList(cKLs, pList);
+ for (iKL = 0; iKL < cKLs; ++iKL)
+ {
+ if (!IS_IME_HKL(pList[iKL]))
+ {
+ LangID = LOWORD(pList[iKL]);
+ break;
+ }
+ }
- if ( i + 1 < lpSrc->dwCount )
- lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(WCHAR);
- dwBufLen -= len * sizeof(WCHAR);
+ ImmLocalFree(pList);
}
- else
- len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, NULL, 0);
- ret += len * sizeof(WCHAR);
+ StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
+ if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
+ {
+ WARN("Default to English US\n");
+ LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
+ }
+ }
+ else if (dwUnknown == 2)
+ {
+ RtlEnterCriticalSection(&gcsImeDpi);
+Retry:
+ for (pImeDpi = gpImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
+ {
+ if (Imm32ReleaseIME(pImeDpi->hKL))
+ goto Retry;
+ }
+ RtlLeaveCriticalSection(&gcsImeDpi);
+ }
+ else
+ {
+ hNewKL = (HKL)(DWORD_PTR)dwUnknown;
+ if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
+ Imm32ReleaseIME(hNewKL);
}
- if ( lpDst )
- lpDst->dwSize = ret;
-
- return ret;
+ return TRUE;
}
-static IMMThreadData* IMM_GetThreadData(void)
+VOID APIENTRY Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
{
- IMMThreadData* data = TlsGetValue(tlsIndex);
- if (!data)
+ PCLIENTIMC pClientImc;
+ LPINPUTCONTEXTDX pIC;
+ LPGUIDELINE pGL;
+ LPCANDIDATEINFO pCI;
+ LPCOMPOSITIONSTRING pCS;
+ LOGFONTA LogFontA;
+ LOGFONTW LogFontW;
+ BOOL fOldOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
+ DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwOldConversion, dwOldSentence, dwSize, dwNewSize;
+ PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
+ HANDLE hPrivate;
+ PIME_STATE pNewState = NULL, pOldState = NULL;
+
+ pClientImc = ImmLockClientImc(hIMC);
+ if (IS_NULL_UNEXPECTEDLY(pClientImc))
+ return;
+
+ pNewImeDpi = ImmLockImeDpi(hNewKL);
+
+ if (hNewKL != hOldKL)
+ pOldImeDpi = ImmLockImeDpi(hOldKL);
+
+ if (pNewImeDpi)
{
- data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(IMMThreadData));
- TlsSetValue(tlsIndex,data);
- TRACE("Thread Data Created\n");
+ cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
+ pClientImc->uCodePage = pNewImeDpi->uCodePage;
}
- return data;
-}
-
-static void IMM_FreeThreadData(void)
-{
- IMMThreadData* data = TlsGetValue(tlsIndex);
- if (data)
+ else
{
- IMM_DestroyContext(data->defaultContext);
- DestroyWindow(data->hwndDefault);
- HeapFree(GetProcessHeap(),0,data);
- TRACE("Thread Data Destroyed\n");
+ pClientImc->uCodePage = CP_ACP;
}
-}
-
-static HMODULE load_graphics_driver(void)
-{
- static const WCHAR display_device_guid_propW[] = {
- '_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
- 'd','e','v','i','c','e','_','g','u','i','d',0 };
- static const WCHAR key_pathW[] = {
- 'S','y','s','t','e','m','\\',
- 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'C','o','n','t','r','o','l','\\',
- 'V','i','d','e','o','\\','{',0};
- static const WCHAR displayW[] = {'}','\\','0','0','0','0',0};
- static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
-
- HMODULE ret = 0;
- HKEY hkey;
- DWORD size;
- WCHAR path[MAX_PATH];
- WCHAR key[(sizeof(key_pathW) + sizeof(displayW)) / sizeof(WCHAR) + 40];
- UINT guid_atom = HandleToULong( GetPropW( GetDesktopWindow(), display_device_guid_propW ));
-
- if (!guid_atom) return 0;
- memcpy( key, key_pathW, sizeof(key_pathW) );
- if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0;
- strcatW( key, displayW );
- if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0;
- size = sizeof(path);
- if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) ret = LoadLibraryW( path );
- RegCloseKey( hkey );
- TRACE( "%s %p\n", debugstr_w(path), ret );
- return ret;
-}
-/* ImmHkl loading and freeing */
-#define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
-static ImmHkl *IMM_GetImmHkl(HKL hkl)
-{
- ImmHkl *ptr;
- WCHAR filename[MAX_PATH];
+ if (pOldImeDpi)
+ cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
- TRACE("Seeking ime for keyboard %p\n",hkl);
+ cbNewPrivate = max(cbNewPrivate, sizeof(DWORD));
+ cbOldPrivate = max(cbOldPrivate, sizeof(DWORD));
- LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
+ if (pClientImc->hKL == hOldKL)
{
- if (ptr->hkl == hkl)
- return ptr;
+ if (pOldImeDpi)
+ {
+ if (IS_IME_HKL(hOldKL))
+ pOldImeDpi->ImeSelect(hIMC, FALSE);
+ else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
+ pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
+ }
+ pClientImc->hKL = NULL;
}
- /* not found... create it */
- ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
+ if (CtfImmIsTextFrameServiceDisabled() && IS_CICERO_MODE() && !IS_16BIT_MODE())
+ {
+ bIsNewHKLIme = IS_IME_HKL(hNewKL);
+ bIsOldHKLIme = IS_IME_HKL(hOldKL);
+ }
- ptr->hkl = hkl;
- if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
- if (!ptr->hIME) ptr->hIME = load_graphics_driver();
- if (ptr->hIME)
+ pIC = (LPINPUTCONTEXTDX)Imm32InternalLockIMC(hIMC, FALSE);
+ if (!pIC)
{
- LOAD_FUNCPTR(ImeInquire);
- if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
+ if (pNewImeDpi)
{
- FreeLibrary(ptr->hIME);
- ptr->hIME = NULL;
+ if (IS_IME_HKL(hNewKL))
+ pNewImeDpi->ImeSelect(hIMC, TRUE);
+ else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
+ pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
+
+ pClientImc->hKL = hNewKL;
}
- else
+ }
+ else
+ {
+ dwOldConversion = pIC->fdwConversion;
+ dwOldSentence = pIC->fdwSentence;
+ fOldOpen = pIC->fOpen;
+
+ if (pNewImeDpi)
{
- LOAD_FUNCPTR(ImeDestroy);
- LOAD_FUNCPTR(ImeSelect);
- if (!ptr->pImeSelect || !ptr->pImeDestroy)
+ bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
+ bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
+ if (bClientWide && !bNewDpiWide)
{
- FreeLibrary(ptr->hIME);
- ptr->hIME = NULL;
+ if (pIC->fdwInit & INIT_LOGFONT)
+ {
+ LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
+ pIC->lfFont.A = LogFontA;
+ }
+ pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
}
- else
+ else if (!bClientWide && bNewDpiWide)
{
- LOAD_FUNCPTR(ImeConfigure);
- LOAD_FUNCPTR(ImeEscape);
- LOAD_FUNCPTR(ImeSetActiveContext);
- LOAD_FUNCPTR(ImeToAsciiEx);
- LOAD_FUNCPTR(NotifyIME);
- LOAD_FUNCPTR(ImeRegisterWord);
- LOAD_FUNCPTR(ImeUnregisterWord);
- LOAD_FUNCPTR(ImeEnumRegisterWord);
- LOAD_FUNCPTR(ImeSetCompositionString);
- LOAD_FUNCPTR(ImeConversionList);
- LOAD_FUNCPTR(ImeProcessKey);
- LOAD_FUNCPTR(ImeGetRegisterWordStyle);
- LOAD_FUNCPTR(ImeGetImeMenuItems);
- /* make sure our classname is WCHAR */
- if (!is_kbd_ime_unicode(ptr))
+ if (pIC->fdwInit & INIT_LOGFONT)
{
- WCHAR bufW[17];
- MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
- -1, bufW, 17);
- lstrcpyW(ptr->imeClassName, bufW);
+ LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
+ pIC->lfFont.W = LogFontW;
}
+ pClientImc->dwFlags |= CLIENTIMC_WIDE;
}
}
- }
- list_add_head(&ImmHklList,&ptr->entry);
- return ptr;
-}
-#undef LOAD_FUNCPTR
+ if (cbOldPrivate != cbNewPrivate)
+ {
+ hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
+ if (!hPrivate)
+ {
+ ImmDestroyIMCC(pIC->hPrivate);
+ hPrivate = ImmCreateIMCC(cbNewPrivate);
+ }
+ pIC->hPrivate = hPrivate;
+ }
-static void IMM_FreeAllImmHkl(void)
-{
- ImmHkl *ptr,*cursor2;
+#define MAX_IMCC_SIZE 0x1000
+ dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
+ if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hMsgBuf);
+ pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
+ pIC->dwNumMsgBuf = 0;
+ }
- LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
- {
- list_remove(&ptr->entry);
- if (ptr->hIME)
+ dwSize = ImmGetIMCCSize(pIC->hGuideLine);
+ dwNewSize = sizeof(GUIDELINE);
+ if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
+ dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
{
- ptr->pImeDestroy(1);
- FreeLibrary(ptr->hIME);
+ ImmDestroyIMCC(pIC->hGuideLine);
+ pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
+ pGL = ImmLockIMCC(pIC->hGuideLine);
+ if (pGL)
+ {
+ pGL->dwSize = dwNewSize;
+ ImmUnlockIMCC(pIC->hGuideLine);
+ }
}
- if (ptr->UIWnd)
- DestroyWindow(ptr->UIWnd);
- HeapFree(GetProcessHeap(),0,ptr);
- }
-}
-static void IMM_RegisterMessages(void)
-{
- WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
- WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
- WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
- WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
- WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
- WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
- WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
-}
+ dwSize = ImmGetIMCCSize(pIC->hCandInfo);
+ dwNewSize = sizeof(CANDIDATEINFO);
+ if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
+ dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hCandInfo);
+ pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
+ pCI = ImmLockIMCC(pIC->hCandInfo);
+ if (pCI)
+ {
+ pCI->dwSize = dwNewSize;
+ ImmUnlockIMCC(pIC->hCandInfo);
+ }
+ }
-static void IMM_RegisterIMEClass(void)
-{
- WNDCLASSW wndClass;
+ dwSize = ImmGetIMCCSize(pIC->hCompStr);
+ dwNewSize = sizeof(COMPOSITIONSTRING);
+ if (ImmGetIMCCLockCount(pIC->hCompStr) ||
+ dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hCompStr);
+ pIC->hCompStr = ImmCreateIMCC(dwNewSize);
+ pCS = ImmLockIMCC(pIC->hCompStr);
+ if (pCS)
+ {
+ pCS->dwSize = dwNewSize;
+ ImmUnlockIMCC(pIC->hCompStr);
+ }
+ }
+#undef MAX_IMCC_SIZE
- ZeroMemory(&wndClass, sizeof(WNDCLASSW));
+ if (pOldImeDpi && bIsOldHKLIme)
+ {
+ pOldState = Imm32FetchImeState(pIC, hOldKL);
+ if (pOldState)
+ Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
+ }
- wndClass.style = CS_GLOBALCLASS;
- wndClass.lpfnWndProc = (WNDPROC) DefIME_WindowProc;
- wndClass.cbWndExtra = 2 * sizeof(LONG_PTR);
- wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
- wndClass.lpszClassName = szwIME;
+ if (pNewImeDpi && bIsNewHKLIme)
+ pNewState = Imm32FetchImeState(pIC, hNewKL);
- RegisterClassW(&wndClass);
-}
+ if (pOldState != pNewState)
+ {
+ if (pOldState)
+ {
+ pOldState->fOpen = !!pIC->fOpen;
+ pOldState->dwConversion = pIC->fdwConversion;
+ pOldState->dwConversion &= ~IME_CMODE_EUDC;
+ pOldState->dwSentence = pIC->fdwSentence;
+ pOldState->dwInit = pIC->fdwInit;
+ }
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
-{
- TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- IMM_RegisterMessages();
- tlsIndex = TlsAlloc();
- if (tlsIndex == TLS_OUT_OF_INDEXES)
- return FALSE;
- IMM_RegisterIMEClass();
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- IMM_FreeThreadData();
- break;
- case DLL_PROCESS_DETACH:
- if (lpReserved) break;
- IMM_FreeThreadData();
- IMM_FreeAllImmHkl();
- TlsFree(tlsIndex);
- UnregisterClassW(szwIME, NULL);
- break;
- }
- return TRUE;
-}
+ if (pNewState)
+ {
+ if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
+ {
+ pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
+ pIC->fOpen = TRUE;
+ }
+ else
+ {
+ pIC->fOpen = pNewState->fOpen;
+ }
-/* for posting messages as the IME */
-static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND target = GetFocus();
- if (!target)
- PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
- else
- PostMessageW(target, msg, wParam, lParam);
-}
+ pIC->fdwConversion = pNewState->dwConversion;
+ pIC->fdwConversion &= ~IME_CMODE_EUDC;
+ pIC->fdwSentence = pNewState->dwSentence;
+ pIC->fdwInit = pNewState->dwInit;
+ }
+ }
-static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
-{
- HWND target;
+ if (pNewState)
+ Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
- target = data->IMC.hWnd;
- if (!target) target = GetFocus();
+ if (pNewImeDpi)
+ {
+ if (IS_IME_HKL(hNewKL))
+ pNewImeDpi->ImeSelect(hIMC, TRUE);
+ else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
+ pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
- if (target)
- return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
+ pClientImc->hKL = hNewKL;
+ }
- return 0;
-}
+ pIC->dwChange = 0;
+ if (pIC->fOpen != fOldOpen)
+ pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
+ if (pIC->fdwConversion != dwOldConversion)
+ pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
+ if (pIC->fdwSentence != dwOldSentence)
+ pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
-static HIMCC ImmCreateBlankCompStr(void)
-{
- HIMCC rc;
- LPCOMPOSITIONSTRING ptr;
- rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
- ptr = ImmLockIMCC(rc);
- memset(ptr,0,sizeof(COMPOSITIONSTRING));
- ptr->dwSize = sizeof(COMPOSITIONSTRING);
- ImmUnlockIMCC(rc);
- return rc;
+ ImmUnlockIMC(hIMC);
+ }
+
+ ImmUnlockImeDpi(pOldImeDpi);
+ ImmUnlockImeDpi(pNewImeDpi);
+ ImmUnlockClientImc(pClientImc);
}
-static InputContextData* get_imc_data(HIMC hIMC)
+typedef struct SELECT_LAYOUT
{
- InputContextData *data = hIMC;
+ HKL hNewKL;
+ HKL hOldKL;
+} SELECT_LAYOUT, *LPSELECT_LAYOUT;
- if (hIMC == NULL)
- return NULL;
+// Win: SelectContextProc
+static BOOL CALLBACK Imm32SelectContextProc(HIMC hIMC, LPARAM lParam)
+{
+ LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
+ Imm32SelectInputContext(pSelect->hNewKL, pSelect->hOldKL, hIMC);
+ return TRUE;
+}
- if(IsBadReadPtr(data, sizeof(InputContextData)) || data->magic != WINE_IMC_VALID_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return NULL;
- }
- return data;
+// Win: NotifyIMEProc
+static BOOL CALLBACK Imm32NotifyIMEProc(HIMC hIMC, LPARAM lParam)
+{
+ ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
+ return TRUE;
}
/***********************************************************************
- * ImmAssociateContext (IMM32.@)
+ * ImmActivateLayout (IMM32.@)
*/
-HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
+BOOL WINAPI ImmActivateLayout(HKL hKL)
{
- HIMC old = NULL;
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %p):\n", hWnd, hIMC);
+ PIMEDPI pImeDpi;
+ HKL hOldKL;
+ LPARAM lParam;
+ HWND hwndDefIME = NULL;
+ SELECT_LAYOUT SelectLayout;
- if(hIMC && !data)
- return NULL;
+ hOldKL = GetKeyboardLayout(0);
- if (!IMM_GetThreadData()->defaultContext)
- IMM_GetThreadData()->defaultContext = ImmCreateContext();
+ if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
+ return TRUE;
- /*
- * If already associated just return
- */
- if (hIMC && data->IMC.hWnd == hWnd)
- return hIMC;
+ ImmLoadIME(hKL);
- if (hWnd)
+ if (hOldKL != hKL)
{
- old = RemovePropW(hWnd,szwWineIMCProperty);
-
- if (old == NULL)
- old = IMM_GetThreadData()->defaultContext;
- else if (old == (HIMC)-1)
- old = NULL;
-
- if (hIMC != IMM_GetThreadData()->defaultContext)
+ pImeDpi = ImmLockImeDpi(hOldKL);
+ if (pImeDpi)
{
- if (hIMC == NULL) /* Meaning disable imm for that window*/
- SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
+ if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
+ lParam = CPS_COMPLETE;
else
- SetPropW(hWnd,szwWineIMCProperty,hIMC);
- }
+ lParam = CPS_CANCEL;
+ ImmUnlockImeDpi(pImeDpi);
- if (old)
- {
- InputContextData *old_data = old;
- if (old_data->IMC.hWnd == hWnd)
- old_data->IMC.hWnd = NULL;
+ ImmEnumInputContext(0, Imm32NotifyIMEProc, lParam);
}
- }
- if (!hIMC)
- return old;
+ hwndDefIME = ImmGetDefaultIMEWnd(NULL);
+ if (IsWindow(hwndDefIME))
+ SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
- if (IsWindow(data->IMC.hWnd))
- {
- /*
- * Post a message that your context is switching
- */
- SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
- }
-
- data->IMC.hWnd = hWnd;
-
- if (IsWindow(data->IMC.hWnd))
- {
- /*
- * Post a message that your context is switching
- */
- SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
+ NtUserSetThreadLayoutHandles(hKL, hOldKL);
}
- return old;
-}
+ SelectLayout.hNewKL = hKL;
+ SelectLayout.hOldKL = hOldKL;
+ ImmEnumInputContext(0, Imm32SelectContextProc, (LPARAM)&SelectLayout);
+ if (IsWindow(hwndDefIME))
+ SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
-/*
- * Helper function for ImmAssociateContextEx
- */
-static BOOL CALLBACK _ImmAssociateContextExEnumProc(HWND hwnd, LPARAM lParam)
-{
- HIMC hImc = (HIMC)lParam;
- ImmAssociateContext(hwnd,hImc);
return TRUE;
}
/***********************************************************************
- * ImmAssociateContextEx (IMM32.@)
+ * ImmAssociateContext (IMM32.@)
*/
-BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
+HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
{
- TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags);
-
- if (!IMM_GetThreadData()->defaultContext)
- IMM_GetThreadData()->defaultContext = ImmCreateContext();
+ PWND pWnd;
+ HWND hwndFocus;
+ DWORD dwValue;
+ HIMC hOldIMC;
- if (!hWnd) return FALSE;
+ TRACE("(%p, %p)\n", hWnd, hIMC);
- switch (dwFlags)
+ if (!IS_IMM_MODE())
{
- case 0:
- ImmAssociateContext(hWnd,hIMC);
- return TRUE;
- case IACE_DEFAULT:
- ImmAssociateContext(hWnd,IMM_GetThreadData()->defaultContext);
- return TRUE;
- case IACE_IGNORENOCONTEXT:
- if (GetPropW(hWnd,szwWineIMCProperty))
- ImmAssociateContext(hWnd,hIMC);
- return TRUE;
- case IACE_CHILDREN:
- EnumChildWindows(hWnd,_ImmAssociateContextExEnumProc,(LPARAM)hIMC);
- return TRUE;
- default:
- FIXME("Unknown dwFlags 0x%x\n",dwFlags);
- return FALSE;
+ TRACE("\n");
+ return NULL;
}
-}
-/***********************************************************************
- * ImmConfigureIMEA (IMM32.@)
- */
-BOOL WINAPI ImmConfigureIMEA(
- HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ pWnd = ValidateHwnd(hWnd);
+ if (IS_NULL_UNEXPECTEDLY(pWnd))
+ return NULL;
- TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
+ if (hIMC && IS_CROSS_THREAD_HIMC(hIMC))
+ return NULL;
- if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
- return FALSE;
+ hOldIMC = pWnd->hImc;
+ if (hOldIMC == hIMC)
+ return hIMC;
- if (immHkl->hIME && immHkl->pImeConfigure)
+ dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
+ switch (dwValue)
{
- if (dwMode != IME_CONFIG_REGISTERWORD || !is_kbd_ime_unicode(immHkl))
- return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
- else
- {
- REGISTERWORDW rww;
- REGISTERWORDA *rwa = lpData;
- BOOL rc;
-
- rww.lpReading = strdupAtoW(rwa->lpReading);
- rww.lpWord = strdupAtoW(rwa->lpWord);
- rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rww);
- HeapFree(GetProcessHeap(),0,rww.lpReading);
- HeapFree(GetProcessHeap(),0,rww.lpWord);
- return rc;
- }
+ case 0:
+ return hOldIMC;
+
+ case 1:
+ hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
+ if (hwndFocus == hWnd)
+ {
+ ImmSetActiveContext(hWnd, hOldIMC, FALSE);
+ ImmSetActiveContext(hWnd, hIMC, TRUE);
+ }
+ return hOldIMC;
+
+ default:
+ return NULL;
}
- else
- return FALSE;
}
/***********************************************************************
- * ImmConfigureIMEW (IMM32.@)
+ * ImmAssociateContextEx (IMM32.@)
*/
-BOOL WINAPI ImmConfigureIMEW(
- HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
+BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ HWND hwndFocus;
+ PWND pFocusWnd;
+ HIMC hOldIMC = NULL;
+ DWORD dwValue;
+
+ TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
- TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
+ if (!IS_IMM_MODE())
+ {
+ TRACE("\n");
+ return FALSE;
+ }
- if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
+ if (hIMC && !(dwFlags & IACE_DEFAULT) && IS_CROSS_THREAD_HIMC(hIMC))
return FALSE;
- if (immHkl->hIME && immHkl->pImeConfigure)
+ hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
+ pFocusWnd = ValidateHwnd(hwndFocus);
+ if (pFocusWnd)
+ hOldIMC = pFocusWnd->hImc;
+
+ dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
+ switch (dwValue)
{
- if (dwMode != IME_CONFIG_REGISTERWORD || is_kbd_ime_unicode(immHkl))
- return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
- else
- {
- REGISTERWORDW *rww = lpData;
- REGISTERWORDA rwa;
- BOOL rc;
-
- rwa.lpReading = strdupWtoA(rww->lpReading);
- rwa.lpWord = strdupWtoA(rww->lpWord);
- rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rwa);
- HeapFree(GetProcessHeap(),0,rwa.lpReading);
- HeapFree(GetProcessHeap(),0,rwa.lpWord);
- return rc;
- }
+ case 0:
+ return TRUE;
+
+ case 1:
+ pFocusWnd = ValidateHwnd(hwndFocus);
+ if (pFocusWnd)
+ {
+ hIMC = pFocusWnd->hImc;
+ if (hIMC != hOldIMC)
+ {
+ ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
+ ImmSetActiveContext(hwndFocus, hIMC, TRUE);
+ }
+ }
+ return TRUE;
+
+ default:
+ return FALSE;
}
- else
- return FALSE;
}
/***********************************************************************
*/
HIMC WINAPI ImmCreateContext(void)
{
- InputContextData *new_context;
- LPGUIDELINE gl;
- LPCANDIDATEINFO ci;
- int i;
-
- new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
+ PCLIENTIMC pClientImc;
+ HIMC hIMC;
- /* Load the IME */
- new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
+ TRACE("()\n");
- if (!new_context->immKbd->hIME)
+ if (!IS_IMM_MODE())
{
- TRACE("IME dll could not be loaded\n");
- HeapFree(GetProcessHeap(),0,new_context);
- return 0;
+ TRACE("\n");
+ return NULL;
}
- /* the HIMCCs are never NULL */
- new_context->IMC.hCompStr = ImmCreateBlankCompStr();
- new_context->IMC.hMsgBuf = ImmCreateIMCC(0);
- new_context->IMC.hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
- ci = ImmLockIMCC(new_context->IMC.hCandInfo);
- memset(ci,0,sizeof(CANDIDATEINFO));
- ci->dwSize = sizeof(CANDIDATEINFO);
- ImmUnlockIMCC(new_context->IMC.hCandInfo);
- new_context->IMC.hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
- gl = ImmLockIMCC(new_context->IMC.hGuideLine);
- memset(gl,0,sizeof(GUIDELINE));
- gl->dwSize = sizeof(GUIDELINE);
- ImmUnlockIMCC(new_context->IMC.hGuideLine);
-
- for (i = 0; i < sizeof(new_context->IMC.cfCandForm) / sizeof(CANDIDATEFORM); i++)
- new_context->IMC.cfCandForm[i].dwIndex = ~0u;
-
- /* Initialize the IME Private */
- new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
-
- new_context->IMC.fdwConversion = new_context->immKbd->imeInfo.fdwConversionCaps;
- new_context->IMC.fdwSentence = new_context->immKbd->imeInfo.fdwSentenceCaps;
-
- if (!new_context->immKbd->pImeSelect(new_context, TRUE))
+ pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
+ if (IS_NULL_UNEXPECTEDLY(pClientImc))
+ return NULL;
+
+ hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
+ if (IS_NULL_UNEXPECTEDLY(hIMC))
{
- TRACE("Selection of IME failed\n");
- IMM_DestroyContext(new_context);
- return 0;
+ ImmLocalFree(pClientImc);
+ return NULL;
}
- SendMessageW(GetFocus(), WM_IME_SELECT, TRUE, (LPARAM)GetKeyboardLayout(0));
- new_context->immKbd->uSelected++;
- TRACE("Created context %p\n",new_context);
+ RtlInitializeCriticalSection(&pClientImc->cs);
- new_context->magic = WINE_IMC_VALID_MAGIC;
- return new_context;
+ pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
+
+ return hIMC;
}
-static BOOL IMM_DestroyContext(HIMC hIMC)
+// Win: DestroyImeModeSaver
+static VOID APIENTRY Imm32DestroyImeModeSaver(LPINPUTCONTEXTDX pIC)
{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("Destroying %p\n",hIMC);
-
- if (!data)
- return FALSE;
+ PIME_STATE pState, pNext;
+ PIME_SUBSTATE pSubState, pSubNext;
- data->immKbd->uSelected --;
- data->immKbd->pImeSelect(hIMC, FALSE);
- SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)GetKeyboardLayout(0));
+ for (pState = pIC->pState; pState; pState = pNext)
+ {
+ pNext = pState->pNext;
- ImmDestroyIMCC(data->IMC.hCompStr);
- ImmDestroyIMCC(data->IMC.hCandInfo);
- ImmDestroyIMCC(data->IMC.hGuideLine);
- ImmDestroyIMCC(data->IMC.hPrivate);
- ImmDestroyIMCC(data->IMC.hMsgBuf);
+ for (pSubState = pState->pSubState; pSubState; pSubState = pSubNext)
+ {
+ pSubNext = pSubState->pNext;
+ ImmLocalFree(pSubState);
+ }
- data->magic = 0;
- HeapFree(GetProcessHeap(),0,data);
+ ImmLocalFree(pState);
+ }
- return TRUE;
+ pIC->pState = NULL;
}
-/***********************************************************************
- * ImmDestroyContext (IMM32.@)
- */
-BOOL WINAPI ImmDestroyContext(HIMC hIMC)
+// Win: DestroyInputContext
+BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep)
{
- if (hIMC != IMM_GetThreadData()->defaultContext)
- return IMM_DestroyContext(hIMC);
- else
- return FALSE;
-}
+ PIMEDPI pImeDpi;
+ LPINPUTCONTEXTDX pIC;
+ PCLIENTIMC pClientImc;
+ PIMC pIMC;
-/***********************************************************************
- * ImmDisableIME (IMM32.@)
- */
-BOOL WINAPI ImmDisableIME(DWORD idThread)
-{
- FIXME("(%d): stub\n", idThread);
- return TRUE;
-}
+ if (hIMC == NULL)
+ return FALSE;
-/***********************************************************************
- * ImmEnumRegisterWordA (IMM32.@)
- */
-UINT WINAPI ImmEnumRegisterWordA(
- HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
- LPCSTR lpszReading, DWORD dwStyle,
- LPCSTR lpszRegister, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
- debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister), lpData);
- if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
+ if (!IS_IMM_MODE())
{
- if (!is_kbd_ime_unicode(immHkl))
- return immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
- (LPCWSTR)lpszReading, dwStyle, (LPCWSTR)lpszRegister, lpData);
- else
- {
- LPWSTR lpszwReading = strdupAtoW(lpszReading);
- LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
- BOOL rc;
+ TRACE("\n");
+ return FALSE;
+ }
- rc = immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
- lpszwReading, dwStyle, lpszwRegister,
- lpData);
+ pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
+ if (IS_NULL_UNEXPECTEDLY(pIMC))
+ return FALSE;
- HeapFree(GetProcessHeap(),0,lpszwReading);
- HeapFree(GetProcessHeap(),0,lpszwRegister);
- return rc;
- }
+ if (pIMC->head.pti != Imm32CurrentPti())
+ {
+ ERR("Thread mismatch\n");
+ return FALSE;
}
- else
- return 0;
-}
-/***********************************************************************
- * ImmEnumRegisterWordW (IMM32.@)
- */
-UINT WINAPI ImmEnumRegisterWordW(
- HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
- LPCWSTR lpszReading, DWORD dwStyle,
- LPCWSTR lpszRegister, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
- debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister), lpData);
- if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
+ pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
+ if (pClientImc == NULL)
{
- if (is_kbd_ime_unicode(immHkl))
- return immHkl->pImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle,
- lpszRegister, lpData);
- else
- {
- LPSTR lpszaReading = strdupWtoA(lpszReading);
- LPSTR lpszaRegister = strdupWtoA(lpszRegister);
- BOOL rc;
-
- rc = immHkl->pImeEnumRegisterWord(lpfnEnumProc, (LPCWSTR)lpszaReading,
- dwStyle, (LPCWSTR)lpszaRegister, lpData);
+ TRACE("pClientImc == NULL\n");
+ goto Finish;
+ }
- HeapFree(GetProcessHeap(),0,lpszaReading);
- HeapFree(GetProcessHeap(),0,lpszaRegister);
- return rc;
- }
+ if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
+ {
+ ERR("Can't destroy for CLIENTIMC_UNKNOWN2\n");
+ return FALSE;
}
- else
- return 0;
-}
-static inline BOOL EscapeRequiresWA(UINT uEscape)
-{
- if (uEscape == IME_ESC_GET_EUDC_DICTIONARY ||
- uEscape == IME_ESC_SET_EUDC_DICTIONARY ||
- uEscape == IME_ESC_IME_NAME ||
- uEscape == IME_ESC_GETHELPFILENAME)
+ if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
return TRUE;
- return FALSE;
-}
-/***********************************************************************
- * ImmEscapeA (IMM32.@)
- */
-LRESULT WINAPI ImmEscapeA(
- HKL hKL, HIMC hIMC,
- UINT uEscape, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
+ InterlockedIncrement(&pClientImc->cLockObj);
- if (immHkl->hIME && immHkl->pImeEscape)
+ if (IS_NULL_UNEXPECTEDLY(pClientImc->hInputContext))
+ goto Quit;
+
+ pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
+ if (IS_NULL_UNEXPECTEDLY(pIC))
{
- if (!EscapeRequiresWA(uEscape) || !is_kbd_ime_unicode(immHkl))
- return immHkl->pImeEscape(hIMC,uEscape,lpData);
- else
- {
- WCHAR buffer[81]; /* largest required buffer should be 80 */
- LRESULT rc;
- if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
- {
- MultiByteToWideChar(CP_ACP,0,lpData,-1,buffer,81);
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- }
- else
- {
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- WideCharToMultiByte(CP_ACP,0,buffer,-1,lpData,80, NULL, NULL);
- }
- return rc;
- }
+ ImmUnlockClientImc(pClientImc);
+ return FALSE;
}
- else
- return 0;
-}
-/***********************************************************************
- * ImmEscapeW (IMM32.@)
- */
-LRESULT WINAPI ImmEscapeW(
- HKL hKL, HIMC hIMC,
- UINT uEscape, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
+ CtfImmTIMDestroyInputContext(hIMC);
- if (immHkl->hIME && immHkl->pImeEscape)
+ if (pClientImc->hKL == hKL)
{
- if (!EscapeRequiresWA(uEscape) || is_kbd_ime_unicode(immHkl))
- return immHkl->pImeEscape(hIMC,uEscape,lpData);
- else
+ pImeDpi = ImmLockImeDpi(hKL);
+ if (pImeDpi)
{
- CHAR buffer[81]; /* largest required buffer should be 80 */
- LRESULT rc;
- if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
- {
- WideCharToMultiByte(CP_ACP,0,lpData,-1,buffer,81, NULL, NULL);
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- }
- else
- {
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- MultiByteToWideChar(CP_ACP,0,buffer,-1,lpData,80);
- }
- return rc;
+ if (IS_IME_HKL(hKL))
+ pImeDpi->ImeSelect(hIMC, FALSE);
+ else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
+ pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL);
+
+ ImmUnlockImeDpi(pImeDpi);
}
+
+ pClientImc->hKL = NULL;
}
- else
- return 0;
+
+ ImmDestroyIMCC(pIC->hPrivate);
+ ImmDestroyIMCC(pIC->hMsgBuf);
+ ImmDestroyIMCC(pIC->hGuideLine);
+ ImmDestroyIMCC(pIC->hCandInfo);
+ ImmDestroyIMCC(pIC->hCompStr);
+ Imm32DestroyImeModeSaver(pIC);
+ ImmUnlockIMC(hIMC);
+
+Quit:
+ pClientImc->dwFlags |= CLIENTIMC_DESTROY;
+ ImmUnlockClientImc(pClientImc);
+
+Finish:
+ if (bKeep)
+ return TRUE;
+ return NtUserDestroyInputContext(hIMC);
}
-/***********************************************************************
- * ImmGetCandidateListA (IMM32.@)
- */
-DWORD WINAPI ImmGetCandidateListA(
- HIMC hIMC, DWORD dwIndex,
- LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+// NOTE: Windows does recursive call ImmLockIMC here but we don't do so.
+// Win: BOOL CreateInputContext(HIMC hIMC, HKL hKL, BOOL fSelect)
+BOOL APIENTRY
+Imm32CreateInputContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
{
- InputContextData *data = get_imc_data(hIMC);
- LPCANDIDATEINFO candinfo;
- LPCANDIDATELIST candlist;
- DWORD ret = 0;
+ DWORD dwIndex, cbPrivate;
+ PIMEDPI pImeDpi = NULL;
+ LPCOMPOSITIONSTRING pCS;
+ LPCANDIDATEINFO pCI;
+ LPGUIDELINE pGL;
+
+ /* Create IC components */
+ pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
+ pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
+ pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
+ pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
+ if (IS_NULL_UNEXPECTEDLY(pIC->hCompStr) ||
+ IS_NULL_UNEXPECTEDLY(pIC->hCandInfo) ||
+ IS_NULL_UNEXPECTEDLY(pIC->hGuideLine) ||
+ IS_NULL_UNEXPECTEDLY(pIC->hMsgBuf))
+ {
+ goto Fail;
+ }
+
+ /* Initialize IC components */
+ pCS = ImmLockIMCC(pIC->hCompStr);
+ if (IS_NULL_UNEXPECTEDLY(pCS))
+ goto Fail;
+ pCS->dwSize = sizeof(COMPOSITIONSTRING);
+ ImmUnlockIMCC(pIC->hCompStr);
- TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
+ pCI = ImmLockIMCC(pIC->hCandInfo);
+ if (IS_NULL_UNEXPECTEDLY(pCI))
+ goto Fail;
+ pCI->dwSize = sizeof(CANDIDATEINFO);
+ ImmUnlockIMCC(pIC->hCandInfo);
- if (!data || !data->IMC.hCandInfo)
- return 0;
+ pGL = ImmLockIMCC(pIC->hGuideLine);
+ if (IS_NULL_UNEXPECTEDLY(pGL))
+ goto Fail;
+ pGL->dwSize = sizeof(GUIDELINE);
+ ImmUnlockIMCC(pIC->hGuideLine);
- candinfo = ImmLockIMCC(data->IMC.hCandInfo);
- if ( dwIndex >= candinfo->dwCount ||
- dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
- goto done;
+ pIC->dwNumMsgBuf = 0;
+ pIC->fOpen = FALSE;
+ pIC->fdwConversion = pIC->fdwSentence = 0;
- candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
- if ( !candlist->dwSize || !candlist->dwCount )
- goto done;
+ for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
+ pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
- if ( !is_himc_ime_unicode(data) )
+ /* Get private data size */
+ pImeDpi = ImmLockImeDpi(hKL);
+ if (!pImeDpi)
{
- ret = candlist->dwSize;
- if ( lpCandList && dwBufLen >= ret )
- memcpy(lpCandList, candlist, ret);
+ cbPrivate = sizeof(DWORD);
}
else
- ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
+ {
+ /* Update CLIENTIMC */
+ pClientImc->uCodePage = pImeDpi->uCodePage;
+ if (ImeDpi_IsUnicode(pImeDpi))
+ pClientImc->dwFlags |= CLIENTIMC_WIDE;
-done:
- ImmUnlockIMCC(data->IMC.hCandInfo);
- return ret;
+ cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
+ }
+
+ /* Create private data */
+ pIC->hPrivate = ImmCreateIMCC(cbPrivate);
+ if (IS_NULL_UNEXPECTEDLY(pIC->hPrivate))
+ goto Fail;
+
+ CtfImmTIMCreateInputContext(hIMC);
+
+ if (pImeDpi)
+ {
+ /* Select the IME */
+ if (fSelect)
+ {
+ if (IS_IME_HKL(hKL))
+ pImeDpi->ImeSelect(hIMC, TRUE);
+ else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
+ pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
+ }
+
+ /* Set HKL */
+ pClientImc->hKL = hKL;
+
+ ImmUnlockImeDpi(pImeDpi);
+ }
+
+ return TRUE;
+
+Fail:
+ if (pImeDpi)
+ ImmUnlockImeDpi(pImeDpi);
+
+ pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
+ pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
+ pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
+ pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
+ return FALSE;
}
-/***********************************************************************
- * ImmGetCandidateListCountA (IMM32.@)
- */
-DWORD WINAPI ImmGetCandidateListCountA(
- HIMC hIMC, LPDWORD lpdwListCount)
+LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
{
- InputContextData *data = get_imc_data(hIMC);
- LPCANDIDATEINFO candinfo;
- DWORD ret, count;
+ HANDLE hIC;
+ LPINPUTCONTEXT pIC = NULL;
+ PCLIENTIMC pClientImc;
+ WORD LangID;
+ DWORD dwThreadId;
+ HKL hOldKL, hNewKL;
+ PIMEDPI pImeDpi = NULL;
- TRACE("%p, %p\n", hIMC, lpdwListCount);
+ pClientImc = ImmLockClientImc(hIMC);
+ if (!pClientImc)
+ return NULL;
- if (!data || !lpdwListCount || !data->IMC.hCandInfo)
- return 0;
+ RtlEnterCriticalSection(&pClientImc->cs);
- candinfo = ImmLockIMCC(data->IMC.hCandInfo);
+ if (pClientImc->hInputContext)
+ {
+ pIC = LocalLock(pClientImc->hInputContext);
+ if (IS_NULL_UNEXPECTEDLY(pIC))
+ goto Failure;
- *lpdwListCount = count = candinfo->dwCount;
+ CtfImmTIMCreateInputContext(hIMC);
+ goto Success;
+ }
- if ( !is_himc_ime_unicode(data) )
- ret = candinfo->dwSize;
- else
+ dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
+ if (dwThreadId == GetCurrentThreadId() && IS_CICERO_MODE() && !IS_16BIT_MODE())
+ {
+ hOldKL = GetKeyboardLayout(0);
+ LangID = LOWORD(hOldKL);
+ hNewKL = (HKL)(DWORD_PTR)MAKELONG(LangID, LangID);
+
+ pImeDpi = Imm32FindOrLoadImeDpi(hNewKL);
+ if (pImeDpi)
+ {
+ CtfImmTIMActivate(hNewKL);
+ }
+ }
+
+ if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
{
- ret = sizeof(CANDIDATEINFO);
- while ( count-- )
- ret += ImmGetCandidateListA(hIMC, count, NULL, 0);
+ ERR("No default IME window\n");
+ goto Failure;
}
- ImmUnlockIMCC(data->IMC.hCandInfo);
- return ret;
+ hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
+ pIC = LocalLock(hIC);
+ if (IS_NULL_UNEXPECTEDLY(pIC))
+ {
+ LocalFree(hIC);
+ goto Failure;
+ }
+ pClientImc->hInputContext = hIC;
+
+ hNewKL = GetKeyboardLayout(dwThreadId);
+ if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect))
+ {
+ LocalUnlock(hIC);
+ pClientImc->hInputContext = LocalFree(hIC);
+ goto Failure;
+ }
+
+Success:
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ InterlockedIncrement(&pClientImc->cLockObj);
+ ImmUnlockClientImc(pClientImc);
+ return pIC;
+
+Failure:
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ ImmUnlockClientImc(pClientImc);
+ return NULL;
}
/***********************************************************************
- * ImmGetCandidateListCountW (IMM32.@)
+ * ImmDestroyContext (IMM32.@)
*/
-DWORD WINAPI ImmGetCandidateListCountW(
- HIMC hIMC, LPDWORD lpdwListCount)
+BOOL WINAPI ImmDestroyContext(HIMC hIMC)
{
- InputContextData *data = get_imc_data(hIMC);
- LPCANDIDATEINFO candinfo;
- DWORD ret, count;
-
- TRACE("%p, %p\n", hIMC, lpdwListCount);
+ HKL hKL;
- if (!data || !lpdwListCount || !data->IMC.hCandInfo)
- return 0;
+ TRACE("(%p)\n", hIMC);
- candinfo = ImmLockIMCC(data->IMC.hCandInfo);
-
- *lpdwListCount = count = candinfo->dwCount;
-
- if ( is_himc_ime_unicode(data) )
- ret = candinfo->dwSize;
- else
+ if (!IS_IMM_MODE())
{
- ret = sizeof(CANDIDATEINFO);
- while ( count-- )
- ret += ImmGetCandidateListW(hIMC, count, NULL, 0);
+ TRACE("\n");
+ return FALSE;
}
- ImmUnlockIMCC(data->IMC.hCandInfo);
- return ret;
+ if (IS_CROSS_THREAD_HIMC(hIMC))
+ return FALSE;
+
+ hKL = GetKeyboardLayout(0);
+ return Imm32DestroyInputContext(hIMC, hKL, FALSE);
}
/***********************************************************************
- * ImmGetCandidateListW (IMM32.@)
+ * ImmLockClientImc (IMM32.@)
*/
-DWORD WINAPI ImmGetCandidateListW(
- HIMC hIMC, DWORD dwIndex,
- LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
{
- InputContextData *data = get_imc_data(hIMC);
- LPCANDIDATEINFO candinfo;
- LPCANDIDATELIST candlist;
- DWORD ret = 0;
+ PIMC pIMC;
+ PCLIENTIMC pClientImc;
+
+ TRACE("(%p)\n", hImc);
- TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
+ if (IS_NULL_UNEXPECTEDLY(hImc))
+ return NULL;
+
+ pIMC = ValidateHandle(hImc, TYPE_INPUTCONTEXT);
+ if (!pIMC || !Imm32CheckImcProcess(pIMC))
+ return NULL;
- if (!data || !data->IMC.hCandInfo)
- return 0;
+ pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
+ if (pClientImc)
+ {
+ if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
+ return NULL;
+ goto Finish;
+ }
- candinfo = ImmLockIMCC(data->IMC.hCandInfo);
- if ( dwIndex >= candinfo->dwCount ||
- dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
- goto done;
+ pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
+ if (IS_NULL_UNEXPECTEDLY(pClientImc))
+ return NULL;
- candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
- if ( !candlist->dwSize || !candlist->dwCount )
- goto done;
+ RtlInitializeCriticalSection(&pClientImc->cs);
+ pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
- if ( is_himc_ime_unicode(data) )
+ if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
{
- ret = candlist->dwSize;
- if ( lpCandList && dwBufLen >= ret )
- memcpy(lpCandList, candlist, ret);
+ ERR("\n");
+ ImmLocalFree(pClientImc);
+ return NULL;
}
- else
- ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
-done:
- ImmUnlockIMCC(data->IMC.hCandInfo);
- return ret;
+ pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
+
+Finish:
+ InterlockedIncrement(&pClientImc->cLockObj);
+ return pClientImc;
}
/***********************************************************************
- * ImmGetCandidateWindow (IMM32.@)
+ * ImmUnlockClientImc (IMM32.@)
*/
-BOOL WINAPI ImmGetCandidateWindow(
- HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
+VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
{
- InputContextData *data = get_imc_data(hIMC);
+ LONG cLocks;
+ HANDLE hInputContext;
- TRACE("%p, %d, %p\n", hIMC, dwIndex, lpCandidate);
+ TRACE("(%p)\n", pClientImc);
- if (!data || !lpCandidate)
- return FALSE;
+ cLocks = InterlockedDecrement(&pClientImc->cLockObj);
+ if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
+ return;
- if ( dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
- return FALSE;
+ hInputContext = pClientImc->hInputContext;
+ if (hInputContext)
+ LocalFree(hInputContext);
- if (data->IMC.cfCandForm[dwIndex].dwIndex != dwIndex)
- return FALSE;
+ RtlDeleteCriticalSection(&pClientImc->cs);
+ ImmLocalFree(pClientImc);
+}
- *lpCandidate = data->IMC.cfCandForm[dwIndex];
+// Win: ImmGetSaveContext
+static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags)
+{
+ HIMC hIMC;
+ PCLIENTIMC pClientImc;
+ PWND pWnd;
- return TRUE;
+ if (!IS_IMM_MODE())
+ {
+ TRACE("Not IMM mode.\n");
+ return NULL;
+ }
+
+ if (!hWnd)
+ {
+ hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
+ goto Quit;
+ }
+
+ pWnd = ValidateHwnd(hWnd);
+ if (IS_NULL_UNEXPECTEDLY(pWnd) || IS_CROSS_PROCESS_HWND(hWnd))
+ return NULL;
+
+ hIMC = pWnd->hImc;
+ if (!hIMC && (dwContextFlags & 1))
+ hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
+
+Quit:
+ pClientImc = ImmLockClientImc(hIMC);
+ if (IS_NULL_UNEXPECTEDLY(pClientImc))
+ return NULL;
+
+ if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_DISABLEIME))
+ hIMC = NULL;
+
+ ImmUnlockClientImc(pClientImc);
+ return hIMC;
}
/***********************************************************************
- * ImmGetCompositionFontA (IMM32.@)
+ * ImmGetContext (IMM32.@)
*/
-BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
+HIMC WINAPI ImmGetContext(HWND hWnd)
{
- LOGFONTW lfW;
- BOOL rc;
-
- TRACE("(%p, %p):\n", hIMC, lplf);
-
- rc = ImmGetCompositionFontW(hIMC,&lfW);
- if (!rc || !lplf)
- return FALSE;
-
- memcpy(lplf,&lfW,sizeof(LOGFONTA));
- WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
- LF_FACESIZE, NULL, NULL);
- return TRUE;
+ TRACE("(%p)\n", hWnd);
+ if (IS_NULL_UNEXPECTEDLY(hWnd))
+ return NULL;
+ return ImmGetSaveContext(hWnd, 2);
}
/***********************************************************************
- * ImmGetCompositionFontW (IMM32.@)
+ * ImmLockIMC(IMM32.@)
+ *
+ * NOTE: This is not ImmLockIMCC. Don't confuse.
*/
-BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
+LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
{
- InputContextData *data = get_imc_data(hIMC);
+ TRACE("(%p)\n", hIMC);
+ return Imm32InternalLockIMC(hIMC, TRUE);
+}
- TRACE("(%p, %p):\n", hIMC, lplf);
+/***********************************************************************
+* ImmUnlockIMC(IMM32.@)
+*/
+BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
+{
+ PCLIENTIMC pClientImc;
- if (!data || !lplf)
+ pClientImc = ImmLockClientImc(hIMC);
+ if (IS_NULL_UNEXPECTEDLY(pClientImc))
return FALSE;
- *lplf = data->IMC.lfFont.W;
+ if (pClientImc->hInputContext)
+ LocalUnlock(pClientImc->hInputContext);
+ InterlockedDecrement(&pClientImc->cLockObj);
+ ImmUnlockClientImc(pClientImc);
return TRUE;
}
+/***********************************************************************
+ * ImmReleaseContext (IMM32.@)
+ */
+BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
+{
+ TRACE("(%p, %p)\n", hWnd, hIMC);
+ UNREFERENCED_PARAMETER(hWnd);
+ UNREFERENCED_PARAMETER(hIMC);
+ return TRUE; // Do nothing. This is correct.
+}
-/* Helpers for the GetCompositionString functions */
-
-static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen,
- BOOL unicode )
+/***********************************************************************
+ * ImmEnumInputContext(IMM32.@)
+ */
+BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM lParam)
{
- INT rc;
+ HIMC *phList;
+ DWORD dwIndex, dwCount;
+ BOOL ret = TRUE;
+ HIMC hIMC;
- if (is_himc_ime_unicode(data) && !unicode)
- rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL);
- else if (!is_himc_ime_unicode(data) && unicode)
- rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR);
- else
+ TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
+
+ dwCount = Imm32BuildHimcList(dwThreadId, &phList);
+ if (IS_ZERO_UNEXPECTEDLY(dwCount))
+ return FALSE;
+
+ for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
{
- int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR);
- memcpy( target, source, min(slen,tlen)*dlen);
- rc = slen*dlen;
+ hIMC = phList[dwIndex];
+ ret = (*lpfn)(hIMC, lParam);
+ if (!ret)
+ break;
}
- return rc;
+ ImmLocalFree(phList);
+ return ret;
}
-static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
- LPBYTE target, INT tlen, BOOL unicode )
+/***********************************************************************
+ * ImmSetActiveContext(IMM32.@)
+ */
+BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, BOOL fActive)
{
- INT rc;
+ PCLIENTIMC pClientImc;
+ LPINPUTCONTEXTDX pIC;
+ PIMEDPI pImeDpi;
+ HIMC hOldIMC;
+ HKL hKL;
+ BOOL fOpen = FALSE;
+ DWORD dwConversion = 0, dwShowFlags = ISC_SHOWUIALL;
+ HWND hwndDefIME;
- if (is_himc_ime_unicode(data) && !unicode)
- {
- rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, sslen, NULL, 0, NULL, NULL);
- if (tlen)
- {
- const BYTE *src = source;
- LPBYTE dst = target;
- int i, j = 0, k = 0;
+ TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
- if (rc < tlen)
- tlen = rc;
- for (i = 0; i < sslen; ++i)
- {
- int len;
+ if (!IS_IMM_MODE())
+ {
+ TRACE("\n");
+ return FALSE;
+ }
- len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ssource + i, 1,
- NULL, 0, NULL, NULL);
- for (; len > 0; --len)
- {
- dst[j++] = src[k];
+ pClientImc = ImmLockClientImc(hIMC);
- if (j >= tlen)
- goto end;
- }
- ++k;
- }
- end:
- rc = j;
- }
+ if (!fActive)
+ {
+ if (pClientImc)
+ pClientImc->dwFlags &= ~CLIENTIMC_ACTIVE;
}
- else if (!is_himc_ime_unicode(data) && unicode)
+ else if (hIMC)
{
- rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, sslen, NULL, 0);
- if (tlen)
- {
- const BYTE *src = source;
- LPBYTE dst = target;
- int i, j = 0;
-
- if (rc < tlen)
- tlen = rc;
- for (i = 0; i < sslen; ++i)
- {
- if (IsDBCSLeadByte(((LPSTR)ssource)[i]))
- continue;
-
- dst[j++] = src[i];
+ if (IS_NULL_UNEXPECTEDLY(pClientImc))
+ return FALSE;
- if (j >= tlen)
- break;
- }
- rc = j;
+ pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
+ if (IS_NULL_UNEXPECTEDLY(pIC))
+ {
+ ImmUnlockClientImc(pClientImc);
+ return FALSE;
}
- }
- else
- {
- memcpy( target, source, min(slen,tlen));
- rc = slen;
- }
- return rc;
-}
+ pIC->hWnd = hWnd;
+ pClientImc->dwFlags |= CLIENTIMC_ACTIVE;
-static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource,
- LPBYTE target, INT tlen, BOOL unicode )
-{
- INT rc;
+ if (pIC->dwUIFlags & 2)
+ dwShowFlags = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
- if (is_himc_ime_unicode(data) && !unicode)
- {
- if (tlen)
- {
- int i;
+ fOpen = pIC->fOpen;
+ dwConversion = pIC->fdwConversion;
- if (slen < tlen)
- tlen = slen;
- tlen /= sizeof (DWORD);
- for (i = 0; i < tlen; ++i)
- {
- ((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource,
- ((DWORD *)source)[i],
- NULL, 0,
- NULL, NULL);
- }
- rc = sizeof (DWORD) * i;
- }
- else
- rc = slen;
+ ImmUnlockIMC(hIMC);
}
- else if (!is_himc_ime_unicode(data) && unicode)
+ else
{
- if (tlen)
+ hOldIMC = ImmGetSaveContext(hWnd, 1);
+ pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hOldIMC);
+ if (pIC)
{
- int i;
-
- if (slen < tlen)
- tlen = slen;
- tlen /= sizeof (DWORD);
- for (i = 0; i < tlen; ++i)
- {
- ((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource,
- ((DWORD *)source)[i],
- NULL, 0);
- }
- rc = sizeof (DWORD) * i;
+ pIC->hWnd = hWnd;
+ ImmUnlockIMC(hOldIMC);
}
- else
- rc = slen;
}
- else
+
+ hKL = GetKeyboardLayout(0);
+ if (IS_CICERO_MODE() && !IS_16BIT_MODE())
{
- memcpy( target, source, min(slen,tlen));
- rc = slen;
+ CtfImeSetActiveContextAlways(hIMC, fActive, hWnd, hKL);
+ hKL = GetKeyboardLayout(0);
}
- return rc;
-}
-
-static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode)
-{
- int rc;
-
- if (is_himc_ime_unicode(data) && !unicode)
+ pImeDpi = ImmLockImeDpi(hKL);
+ if (pImeDpi)
{
- rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL);
+ if (IS_IME_HKL(hKL))
+ pImeDpi->ImeSetActiveContext(hIMC, fActive);
+ ImmUnlockImeDpi(pImeDpi);
}
- else if (!is_himc_ime_unicode(data) && unicode)
+
+ if (IsWindow(hWnd))
{
- rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0);
+ SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, dwShowFlags);
+ if (fActive)
+ NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
}
- else
- rc = offset;
-
- return rc;
-}
-
-static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf,
- DWORD dwBufLen, BOOL unicode)
-{
- LONG rc = 0;
- InputContextData *data = get_imc_data(hIMC);
- LPCOMPOSITIONSTRING compstr;
- LPBYTE compdata;
-
- TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
-
- if (!data)
- return FALSE;
-
- if (!data->IMC.hCompStr)
- return FALSE;
-
- compdata = ImmLockIMCC(data->IMC.hCompStr);
- compstr = (LPCOMPOSITIONSTRING)compdata;
-
- switch (dwIndex)
+ else if (!fActive)
{
- case GCS_RESULTSTR:
- TRACE("GCS_RESULTSTR\n");
- rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen, lpBuf, dwBufLen, unicode);
- break;
- case GCS_COMPSTR:
- TRACE("GCS_COMPSTR\n");
- rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, lpBuf, dwBufLen, unicode);
- break;
- case GCS_COMPATTR:
- TRACE("GCS_COMPATTR\n");
- rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompAttrOffset, compstr->dwCompAttrLen,
- compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
- lpBuf, dwBufLen, unicode);
- break;
- case GCS_COMPCLAUSE:
- TRACE("GCS_COMPCLAUSE\n");
- rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompClauseOffset,compstr->dwCompClauseLen,
- compdata + compstr->dwCompStrOffset,
- lpBuf, dwBufLen, unicode);
- break;
- case GCS_RESULTCLAUSE:
- TRACE("GCS_RESULTCLAUSE\n");
- rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen,
- compdata + compstr->dwResultStrOffset,
- lpBuf, dwBufLen, unicode);
- break;
- case GCS_RESULTREADSTR:
- TRACE("GCS_RESULTREADSTR\n");
- rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultReadStrOffset, compstr->dwResultReadStrLen, lpBuf, dwBufLen, unicode);
- break;
- case GCS_RESULTREADCLAUSE:
- TRACE("GCS_RESULTREADCLAUSE\n");
- rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultReadClauseOffset,compstr->dwResultReadClauseLen,
- compdata + compstr->dwResultStrOffset,
- lpBuf, dwBufLen, unicode);
- break;
- case GCS_COMPREADSTR:
- TRACE("GCS_COMPREADSTR\n");
- rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, lpBuf, dwBufLen, unicode);
- break;
- case GCS_COMPREADATTR:
- TRACE("GCS_COMPREADATTR\n");
- rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompReadAttrOffset, compstr->dwCompReadAttrLen,
- compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen,
- lpBuf, dwBufLen, unicode);
- break;
- case GCS_COMPREADCLAUSE:
- TRACE("GCS_COMPREADCLAUSE\n");
- rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompReadClauseOffset,compstr->dwCompReadClauseLen,
- compdata + compstr->dwCompStrOffset,
- lpBuf, dwBufLen, unicode);
- break;
- case GCS_CURSORPOS:
- TRACE("GCS_CURSORPOS\n");
- rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode);
- break;
- case GCS_DELTASTART:
- TRACE("GCS_DELTASTART\n");
- rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode);
- break;
- default:
- FIXME("Unhandled index 0x%x\n",dwIndex);
- break;
+ hwndDefIME = ImmGetDefaultIMEWnd(NULL);
+ if (hwndDefIME)
+ SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, dwShowFlags);
}
- ImmUnlockIMCC(data->IMC.hCompStr);
+ if (pClientImc)
+ ImmUnlockClientImc(pClientImc);
- return rc;
+ return TRUE;
}
/***********************************************************************
- * ImmGetCompositionStringA (IMM32.@)
+ * ImmWINNLSGetEnableStatus (IMM32.@)
*/
-LONG WINAPI ImmGetCompositionStringA(
- HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+
+BOOL WINAPI ImmWINNLSGetEnableStatus(HWND hWnd)
{
- return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
-}
+ if (!Imm32IsSystemJapaneseOrKorean())
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+ }
+ return !!ImmGetSaveContext(hWnd, 2);
+}
/***********************************************************************
- * ImmGetCompositionStringW (IMM32.@)
+ * ImmSetActiveContextConsoleIME(IMM32.@)
*/
-LONG WINAPI ImmGetCompositionStringW(
- HIMC hIMC, DWORD dwIndex,
- LPVOID lpBuf, DWORD dwBufLen)
+BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
{
- return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
+ HIMC hIMC;
+ TRACE("(%p, %d)\n", hwnd, fFlag);
+
+ hIMC = ImmGetContext(hwnd);
+ if (IS_NULL_UNEXPECTEDLY(hIMC))
+ return FALSE;
+ return ImmSetActiveContext(hwnd, hIMC, fFlag);
}
/***********************************************************************
- * ImmGetCompositionWindow (IMM32.@)
+ * GetKeyboardLayoutCP (IMM32.@)
*/
-BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
+UINT WINAPI GetKeyboardLayoutCP(_In_ LANGID wLangId)
{
- InputContextData *data = get_imc_data(hIMC);
+ WCHAR szText[8];
+ static LANGID s_wKeyboardLangIdCache = 0;
+ static UINT s_uKeyboardLayoutCPCache = 0;
- TRACE("(%p, %p)\n", hIMC, lpCompForm);
+ TRACE("(%u)\n", wLangId);
- if (!data)
- return FALSE;
+ if (wLangId == s_wKeyboardLangIdCache)
+ return s_uKeyboardLayoutCPCache;
- *lpCompForm = data->IMC.cfCompForm;
- return TRUE;
+ if (!GetLocaleInfoW(wLangId, LOCALE_IDEFAULTANSICODEPAGE, szText, _countof(szText)))
+ return 0;
+
+ s_wKeyboardLangIdCache = wLangId;
+ szText[_countof(szText) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
+ s_uKeyboardLayoutCPCache = wcstol(szText, NULL, 10);
+ return s_uKeyboardLayoutCPCache;
}
-/***********************************************************************
- * ImmGetContext (IMM32.@)
- *
- */
-HIMC WINAPI ImmGetContext(HWND hWnd)
+#ifndef NDEBUG
+VOID APIENTRY Imm32UnitTest(VOID)
{
- HIMC rc;
+ if (0)
+ {
+ DWORD dwValue;
+ WCHAR szText[64];
- TRACE("%p\n", hWnd);
+ Imm32StrToUInt(L"123", &dwValue, 10);
+ ASSERT(dwValue == 123);
+ Imm32StrToUInt(L"100", &dwValue, 16);
+ ASSERT(dwValue == 0x100);
- if (!IsWindow(hWnd))
- {
- SetLastError(ERROR_INVALID_WINDOW_HANDLE);
- return NULL;
+ Imm32UIntToStr(123, 10, szText, _countof(szText));
+ ASSERT(lstrcmpW(szText, L"123") == 0);
+ Imm32UIntToStr(0x100, 16, szText, _countof(szText));
+ ASSERT(lstrcmpW(szText, L"100") == 0);
}
- if (!IMM_GetThreadData()->defaultContext)
- IMM_GetThreadData()->defaultContext = ImmCreateContext();
+}
+#endif
- rc = GetPropW(hWnd,szwWineIMCProperty);
- if (rc == (HIMC)-1)
- rc = NULL;
- else if (rc == NULL)
- rc = IMM_GetThreadData()->defaultContext;
+BOOL WINAPI User32InitializeImmEntryTable(DWORD);
- if (rc)
- {
- InputContextData *data = rc;
- data->IMC.hWnd = hWnd;
- }
- TRACE("returning %p\n", rc);
-
- return rc;
-}
-
-/***********************************************************************
- * ImmGetConversionListA (IMM32.@)
- */
-DWORD WINAPI ImmGetConversionListA(
- HKL hKL, HIMC hIMC,
- LPCSTR pSrc, LPCANDIDATELIST lpDst,
- DWORD dwBufLen, UINT uFlag)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_a(pSrc), lpDst,
- dwBufLen, uFlag);
- if (immHkl->hIME && immHkl->pImeConversionList)
- {
- if (!is_kbd_ime_unicode(immHkl))
- return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
- else
- {
- LPCANDIDATELIST lpwDst;
- DWORD ret = 0, len;
- LPWSTR pwSrc = strdupAtoW(pSrc);
-
- len = immHkl->pImeConversionList(hIMC, pwSrc, NULL, 0, uFlag);
- lpwDst = HeapAlloc(GetProcessHeap(), 0, len);
- if ( lpwDst )
- {
- immHkl->pImeConversionList(hIMC, pwSrc, lpwDst, len, uFlag);
- ret = convert_candidatelist_WtoA( lpwDst, lpDst, dwBufLen);
- HeapFree(GetProcessHeap(), 0, lpwDst);
- }
- HeapFree(GetProcessHeap(), 0, pwSrc);
-
- return ret;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
- * ImmGetConversionListW (IMM32.@)
- */
-DWORD WINAPI ImmGetConversionListW(
- HKL hKL, HIMC hIMC,
- LPCWSTR pSrc, LPCANDIDATELIST lpDst,
- DWORD dwBufLen, UINT uFlag)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_w(pSrc), lpDst,
- dwBufLen, uFlag);
- if (immHkl->hIME && immHkl->pImeConversionList)
- {
- if (is_kbd_ime_unicode(immHkl))
- return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
- else
- {
- LPCANDIDATELIST lpaDst;
- DWORD ret = 0, len;
- LPSTR paSrc = strdupWtoA(pSrc);
-
- len = immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, NULL, 0, uFlag);
- lpaDst = HeapAlloc(GetProcessHeap(), 0, len);
- if ( lpaDst )
- {
- immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, lpaDst, len, uFlag);
- ret = convert_candidatelist_AtoW( lpaDst, lpDst, dwBufLen);
- HeapFree(GetProcessHeap(), 0, lpaDst);
- }
- HeapFree(GetProcessHeap(), 0, paSrc);
-
- return ret;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
- * ImmGetConversionStatus (IMM32.@)
- */
-BOOL WINAPI ImmGetConversionStatus(
- HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
-
- if (!data)
- return FALSE;
-
- if (lpfdwConversion)
- *lpfdwConversion = data->IMC.fdwConversion;
- if (lpfdwSentence)
- *lpfdwSentence = data->IMC.fdwSentence;
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmGetDefaultIMEWnd (IMM32.@)
- */
-HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
-{
- if (IMM_GetThreadData()->hwndDefault == NULL)
- IMM_GetThreadData()->hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW,
- szwIME, NULL, WS_POPUP, 0, 0, 1, 1, 0, 0, 0, 0);
- TRACE("Default is %p\n",IMM_GetThreadData()->hwndDefault);
- return IMM_GetThreadData()->hwndDefault;
-}
-
-/***********************************************************************
- * ImmGetDescriptionA (IMM32.@)
- */
-UINT WINAPI ImmGetDescriptionA(
- HKL hKL, LPSTR lpszDescription, UINT uBufLen)
-{
- WCHAR *buf;
- DWORD len;
-
- TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
-
- /* find out how many characters in the unicode buffer */
- len = ImmGetDescriptionW( hKL, NULL, 0 );
- if (!len)
- return 0;
-
- /* allocate a buffer of that size */
- buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
- if( !buf )
- return 0;
-
- /* fetch the unicode buffer */
- len = ImmGetDescriptionW( hKL, buf, len + 1 );
-
- /* convert it back to ASCII */
- len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
- lpszDescription, uBufLen, NULL, NULL );
-
- HeapFree( GetProcessHeap(), 0, buf );
-
- if (len == 0)
- return 0;
-
- return len - 1;
-}
-
-/***********************************************************************
- * ImmGetDescriptionW (IMM32.@)
- */
-UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
-{
- static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
-
- FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
-
- if (!hKL) return 0;
- if (!uBufLen) return lstrlenW( name );
- lstrcpynW( lpszDescription, name, uBufLen );
- return lstrlenW( lpszDescription );
-}
-
-/***********************************************************************
- * ImmGetGuideLineA (IMM32.@)
- */
-DWORD WINAPI ImmGetGuideLineA(
- HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
-{
- FIXME("(%p, %d, %s, %d): stub\n",
- hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * ImmGetGuideLineW (IMM32.@)
- */
-DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
-{
- FIXME("(%p, %d, %s, %d): stub\n",
- hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * ImmGetIMEFileNameA (IMM32.@)
- */
-UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
-{
- LPWSTR bufW = NULL;
- UINT wBufLen = uBufLen;
- UINT rc;
-
- if (uBufLen && lpszFileName)
- bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
- else /* We need this to get the number of byte required */
- {
- bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
- wBufLen = MAX_PATH;
- }
-
- rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
-
- if (rc > 0)
- {
- if (uBufLen && lpszFileName)
- rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
- uBufLen, NULL, NULL);
- else /* get the length */
- rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
- NULL);
- }
-
- HeapFree(GetProcessHeap(),0,bufW);
- return rc;
-}
-
-/***********************************************************************
- * ImmGetIMEFileNameW (IMM32.@)
- */
-UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
-{
- HKEY hkey;
- DWORD length;
- DWORD rc;
- WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8];
-
- wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hKL );
- rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- return 0;
- }
-
- length = 0;
- rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
-
- if (rc != ERROR_SUCCESS)
- {
- RegCloseKey(hkey);
- SetLastError(rc);
- return 0;
- }
- if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
- {
- RegCloseKey(hkey);
- if (lpszFileName)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return 0;
- }
- else
- return length / sizeof(WCHAR);
- }
-
- RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
-
- RegCloseKey(hkey);
-
- return length / sizeof(WCHAR);
-}
-
-/***********************************************************************
- * ImmGetOpenStatus (IMM32.@)
- */
-BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
-{
- InputContextData *data = get_imc_data(hIMC);
- static int i;
-
- if (!data)
- return FALSE;
-
- TRACE("(%p): semi-stub\n", hIMC);
-
- if (!i++)
- FIXME("(%p): semi-stub\n", hIMC);
-
- return data->IMC.fOpen;
-}
-
-/***********************************************************************
- * ImmGetProperty (IMM32.@)
- */
-DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
-{
- DWORD rc = 0;
- ImmHkl *kbd;
-
- TRACE("(%p, %d)\n", hKL, fdwIndex);
- kbd = IMM_GetImmHkl(hKL);
-
- if (kbd && kbd->hIME)
- {
- switch (fdwIndex)
- {
- case IGP_PROPERTY: rc = kbd->imeInfo.fdwProperty; break;
- case IGP_CONVERSION: rc = kbd->imeInfo.fdwConversionCaps; break;
- case IGP_SENTENCE: rc = kbd->imeInfo.fdwSentenceCaps; break;
- case IGP_SETCOMPSTR: rc = kbd->imeInfo.fdwSCSCaps; break;
- case IGP_SELECT: rc = kbd->imeInfo.fdwSelectCaps; break;
- case IGP_GETIMEVERSION: rc = IMEVER_0400; break;
- case IGP_UI: rc = 0; break;
- default: rc = 0;
- }
- }
- return rc;
-}
-
-/***********************************************************************
- * ImmGetRegisterWordStyleA (IMM32.@)
- */
-UINT WINAPI ImmGetRegisterWordStyleA(
- HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
- if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
- {
- if (!is_kbd_ime_unicode(immHkl))
- return immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)lpStyleBuf);
- else
- {
- STYLEBUFW sbw;
- UINT rc;
-
- rc = immHkl->pImeGetRegisterWordStyle(nItem,&sbw);
- WideCharToMultiByte(CP_ACP, 0, sbw.szDescription, -1,
- lpStyleBuf->szDescription, 32, NULL, NULL);
- lpStyleBuf->dwStyle = sbw.dwStyle;
- return rc;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
- * ImmGetRegisterWordStyleW (IMM32.@)
- */
-UINT WINAPI ImmGetRegisterWordStyleW(
- HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
- if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
- {
- if (is_kbd_ime_unicode(immHkl))
- return immHkl->pImeGetRegisterWordStyle(nItem,lpStyleBuf);
- else
- {
- STYLEBUFA sba;
- UINT rc;
-
- rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
- MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
- lpStyleBuf->szDescription, 32);
- lpStyleBuf->dwStyle = sba.dwStyle;
- return rc;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
- * ImmGetStatusWindowPos (IMM32.@)
- */
-BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %p)\n", hIMC, lpptPos);
-
- if (!data || !lpptPos)
- return FALSE;
-
- *lpptPos = data->IMC.ptStatusWndPos;
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmGetVirtualKey (IMM32.@)
- */
-UINT WINAPI ImmGetVirtualKey(HWND hWnd)
-{
- OSVERSIONINFOA version;
- InputContextData *data = ImmGetContext( hWnd );
- TRACE("%p\n", hWnd);
-
- if ( data )
- return data->lastVK;
-
- version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
- GetVersionExA( &version );
- switch(version.dwPlatformId)
- {
- case VER_PLATFORM_WIN32_WINDOWS:
- return VK_PROCESSKEY;
- case VER_PLATFORM_WIN32_NT:
- return 0;
- default:
- FIXME("%d not supported\n",version.dwPlatformId);
- return VK_PROCESSKEY;
- }
-}
-
-/***********************************************************************
- * ImmInstallIMEA (IMM32.@)
- */
-HKL WINAPI ImmInstallIMEA(
- LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
-{
- LPWSTR lpszwIMEFileName;
- LPWSTR lpszwLayoutText;
- HKL hkl;
-
- TRACE ("(%s, %s)\n", debugstr_a(lpszIMEFileName),
- debugstr_a(lpszLayoutText));
-
- lpszwIMEFileName = strdupAtoW(lpszIMEFileName);
- lpszwLayoutText = strdupAtoW(lpszLayoutText);
-
- hkl = ImmInstallIMEW(lpszwIMEFileName, lpszwLayoutText);
-
- HeapFree(GetProcessHeap(),0,lpszwIMEFileName);
- HeapFree(GetProcessHeap(),0,lpszwLayoutText);
- return hkl;
-}
-
-/***********************************************************************
- * ImmInstallIMEW (IMM32.@)
- */
-HKL WINAPI ImmInstallIMEW(
- LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
-{
- INT lcid = GetUserDefaultLCID();
- INT count;
- HKL hkl;
- DWORD rc;
- HKEY hkey;
- WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8];
-
- TRACE ("(%s, %s):\n", debugstr_w(lpszIMEFileName),
- debugstr_w(lpszLayoutText));
-
- /* Start with 2. e001 will be blank and so default to the wine internal IME */
- count = 2;
-
- while (count < 0xfff)
- {
- DWORD disposition = 0;
-
- hkl = (HKL)MAKELPARAM( lcid, 0xe000 | count );
- wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hkl);
-
- rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, &disposition);
- if (rc == ERROR_SUCCESS && disposition == REG_CREATED_NEW_KEY)
- break;
- else if (rc == ERROR_SUCCESS)
- RegCloseKey(hkey);
-
- count++;
- }
-
- if (count == 0xfff)
- {
- WARN("Unable to find slot to install IME\n");
- return 0;
- }
-
- if (rc == ERROR_SUCCESS)
- {
- rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (const BYTE*)lpszIMEFileName,
- (lstrlenW(lpszIMEFileName) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (const BYTE*)lpszLayoutText,
- (lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR));
- RegCloseKey(hkey);
- return hkl;
- }
- else
- {
- WARN("Unable to set IME registry values\n");
- return 0;
- }
-}
-
-/***********************************************************************
- * ImmIsIME (IMM32.@)
- */
-BOOL WINAPI ImmIsIME(HKL hKL)
-{
- ImmHkl *ptr;
- TRACE("(%p):\n", hKL);
- ptr = IMM_GetImmHkl(hKL);
- return (ptr && ptr->hIME);
-}
-
-/***********************************************************************
- * ImmIsUIMessageA (IMM32.@)
- */
-BOOL WINAPI ImmIsUIMessageA(
- HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- BOOL rc = FALSE;
-
- TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
- if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
- (msg == WM_IME_SETCONTEXT) ||
- (msg == WM_IME_NOTIFY) ||
- (msg == WM_IME_COMPOSITIONFULL) ||
- (msg == WM_IME_SELECT) ||
- (msg == 0x287 /* FIXME: WM_IME_SYSTEM */) ||
- (msg == WM_MSIME_RECONVERTOPTIONS) ||
- (msg == WM_MSIME_MOUSE) ||
- (msg == WM_MSIME_RECONVERTREQUEST) ||
- (msg == WM_MSIME_RECONVERT) ||
- (msg == WM_MSIME_QUERYPOSITION) ||
- (msg == WM_MSIME_DOCUMENTFEED))
- {
- if (hWndIME)
- SendMessageA(hWndIME, msg, wParam, lParam);
-
- rc = TRUE;
- }
- return rc;
-}
-
-/***********************************************************************
- * ImmIsUIMessageW (IMM32.@)
- */
-BOOL WINAPI ImmIsUIMessageW(
- HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- BOOL rc = FALSE;
-
- TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
- if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
- (msg == WM_IME_SETCONTEXT) ||
- (msg == WM_IME_NOTIFY) ||
- (msg == WM_IME_COMPOSITIONFULL) ||
- (msg == WM_IME_SELECT) ||
- (msg == 0x287 /* FIXME: WM_IME_SYSTEM */) ||
- (msg == WM_MSIME_RECONVERTOPTIONS) ||
- (msg == WM_MSIME_MOUSE) ||
- (msg == WM_MSIME_RECONVERTREQUEST) ||
- (msg == WM_MSIME_RECONVERT) ||
- (msg == WM_MSIME_QUERYPOSITION) ||
- (msg == WM_MSIME_DOCUMENTFEED))
- {
- if (hWndIME)
- SendMessageW(hWndIME, msg, wParam, lParam);
-
- rc = TRUE;
- }
- return rc;
-}
-
-/***********************************************************************
- * ImmNotifyIME (IMM32.@)
- */
-BOOL WINAPI ImmNotifyIME(
- HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %d, %d, %d)\n",
- hIMC, dwAction, dwIndex, dwValue);
-
- if (hIMC == NULL)
- {
- SetLastError(ERROR_SUCCESS);
- return FALSE;
- }
-
- if (!data || ! data->immKbd->pNotifyIME)
- {
- return FALSE;
- }
-
- return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
-}
-
-/***********************************************************************
- * ImmRegisterWordA (IMM32.@)
- */
-BOOL WINAPI ImmRegisterWordA(
- HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
- debugstr_a(lpszRegister));
- if (immHkl->hIME && immHkl->pImeRegisterWord)
- {
- if (!is_kbd_ime_unicode(immHkl))
- return immHkl->pImeRegisterWord((LPCWSTR)lpszReading,dwStyle,
- (LPCWSTR)lpszRegister);
- else
- {
- LPWSTR lpszwReading = strdupAtoW(lpszReading);
- LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
- BOOL rc;
-
- rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
- HeapFree(GetProcessHeap(),0,lpszwReading);
- HeapFree(GetProcessHeap(),0,lpszwRegister);
- return rc;
- }
- }
- else
- return FALSE;
-}
-
-/***********************************************************************
- * ImmRegisterWordW (IMM32.@)
- */
-BOOL WINAPI ImmRegisterWordW(
- HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
- debugstr_w(lpszRegister));
- if (immHkl->hIME && immHkl->pImeRegisterWord)
- {
- if (is_kbd_ime_unicode(immHkl))
- return immHkl->pImeRegisterWord(lpszReading,dwStyle,lpszRegister);
- else
- {
- LPSTR lpszaReading = strdupWtoA(lpszReading);
- LPSTR lpszaRegister = strdupWtoA(lpszRegister);
- BOOL rc;
-
- rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
- (LPCWSTR)lpszaRegister);
- HeapFree(GetProcessHeap(),0,lpszaReading);
- HeapFree(GetProcessHeap(),0,lpszaRegister);
- return rc;
- }
- }
- else
- return FALSE;
-}
-
-/***********************************************************************
- * ImmReleaseContext (IMM32.@)
- */
-BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
-{
- static BOOL shown = FALSE;
-
- if (!shown) {
- FIXME("(%p, %p): stub\n", hWnd, hIMC);
- shown = TRUE;
- }
- return TRUE;
-}
-
-/***********************************************************************
-* ImmRequestMessageA(IMM32.@)
-*/
-LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
- if (!data)
- SetLastError(ERROR_INVALID_HANDLE);
-
- if (data && IsWindow(data->IMC.hWnd))
- return SendMessageA(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
-
- return 0;
-}
-
-/***********************************************************************
-* ImmRequestMessageW(IMM32.@)
-*/
-LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
-
- if (!data)
- SetLastError(ERROR_INVALID_HANDLE);
-
- if (data && IsWindow(data->IMC.hWnd))
- return SendMessageW(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
-
- return 0;
-}
-
-/***********************************************************************
- * ImmSetCandidateWindow (IMM32.@)
- */
-BOOL WINAPI ImmSetCandidateWindow(
- HIMC hIMC, LPCANDIDATEFORM lpCandidate)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %p)\n", hIMC, lpCandidate);
-
- if (!data || !lpCandidate)
- return FALSE;
-
- TRACE("\t%x, %x, (%i,%i), (%i,%i - %i,%i)\n",
- lpCandidate->dwIndex, lpCandidate->dwStyle,
- lpCandidate->ptCurrentPos.x, lpCandidate->ptCurrentPos.y,
- lpCandidate->rcArea.top, lpCandidate->rcArea.left,
- lpCandidate->rcArea.bottom, lpCandidate->rcArea.right);
-
- if ( lpCandidate->dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
- return FALSE;
-
- data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
- ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
- ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmSetCompositionFontA (IMM32.@)
- */
-BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
-{
- InputContextData *data = get_imc_data(hIMC);
- TRACE("(%p, %p)\n", hIMC, lplf);
-
- if (!data || !lplf)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
- MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
- LF_FACESIZE);
- ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
- ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmSetCompositionFontW (IMM32.@)
- */
-BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
-{
- InputContextData *data = get_imc_data(hIMC);
- TRACE("(%p, %p)\n", hIMC, lplf);
-
- if (!data || !lplf)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- data->IMC.lfFont.W = *lplf;
- ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
- ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmSetCompositionStringA (IMM32.@)
- */
-BOOL WINAPI ImmSetCompositionStringA(
- HIMC hIMC, DWORD dwIndex,
- LPCVOID lpComp, DWORD dwCompLen,
- LPCVOID lpRead, DWORD dwReadLen)
-{
- DWORD comp_len;
- DWORD read_len;
- WCHAR *CompBuffer = NULL;
- WCHAR *ReadBuffer = NULL;
- BOOL rc;
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %d, %p, %d, %p, %d):\n",
- hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
-
- if (!data)
- return FALSE;
-
- if (!(dwIndex == SCS_SETSTR ||
- dwIndex == SCS_CHANGEATTR ||
- dwIndex == SCS_CHANGECLAUSE ||
- dwIndex == SCS_SETRECONVERTSTRING ||
- dwIndex == SCS_QUERYRECONVERTSTRING))
- return FALSE;
-
- if (!is_himc_ime_unicode(data))
- return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
- dwCompLen, lpRead, dwReadLen);
-
- comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
- if (comp_len)
- {
- CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
- }
-
- read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
- if (read_len)
- {
- ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
- }
-
- rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
- ReadBuffer, read_len);
-
- HeapFree(GetProcessHeap(), 0, CompBuffer);
- HeapFree(GetProcessHeap(), 0, ReadBuffer);
-
- return rc;
-}
-
-/***********************************************************************
- * ImmSetCompositionStringW (IMM32.@)
- */
-BOOL WINAPI ImmSetCompositionStringW(
- HIMC hIMC, DWORD dwIndex,
- LPCVOID lpComp, DWORD dwCompLen,
- LPCVOID lpRead, DWORD dwReadLen)
-{
- DWORD comp_len;
- DWORD read_len;
- CHAR *CompBuffer = NULL;
- CHAR *ReadBuffer = NULL;
- BOOL rc;
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %d, %p, %d, %p, %d):\n",
- hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
-
- if (!data)
- return FALSE;
-
- if (!(dwIndex == SCS_SETSTR ||
- dwIndex == SCS_CHANGEATTR ||
- dwIndex == SCS_CHANGECLAUSE ||
- dwIndex == SCS_SETRECONVERTSTRING ||
- dwIndex == SCS_QUERYRECONVERTSTRING))
- return FALSE;
-
- if (is_himc_ime_unicode(data))
- return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
- dwCompLen, lpRead, dwReadLen);
-
- comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
- NULL);
- if (comp_len)
- {
- CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
- WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
- NULL, NULL);
- }
-
- read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
- NULL);
- if (read_len)
- {
- ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
- WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
- NULL, NULL);
- }
-
- rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
- ReadBuffer, read_len);
-
- HeapFree(GetProcessHeap(), 0, CompBuffer);
- HeapFree(GetProcessHeap(), 0, ReadBuffer);
-
- return rc;
-}
-
-/***********************************************************************
- * ImmSetCompositionWindow (IMM32.@)
- */
-BOOL WINAPI ImmSetCompositionWindow(
- HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
-{
- BOOL reshow = FALSE;
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %p)\n", hIMC, lpCompForm);
- TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
- lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
- lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
-
- if (!data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- data->IMC.cfCompForm = *lpCompForm;
-
- if (IsWindowVisible(data->immKbd->UIWnd))
- {
- reshow = TRUE;
- ShowWindow(data->immKbd->UIWnd,SW_HIDE);
- }
-
- /* FIXME: this is a partial stub */
-
- if (reshow)
- ShowWindow(data->immKbd->UIWnd,SW_SHOWNOACTIVATE);
-
- ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
- return TRUE;
-}
-
-/***********************************************************************
- * ImmSetConversionStatus (IMM32.@)
- */
-BOOL WINAPI ImmSetConversionStatus(
- HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
-{
- DWORD oldConversion, oldSentence;
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
-
- if (!data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if ( fdwConversion != data->IMC.fdwConversion )
- {
- oldConversion = data->IMC.fdwConversion;
- data->IMC.fdwConversion = fdwConversion;
- ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldConversion, IMC_SETCONVERSIONMODE);
- ImmInternalSendIMENotify(data, IMN_SETCONVERSIONMODE, 0);
- }
- if ( fdwSentence != data->IMC.fdwSentence )
- {
- oldSentence = data->IMC.fdwSentence;
- data->IMC.fdwSentence = fdwSentence;
- ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldSentence, IMC_SETSENTENCEMODE);
- ImmInternalSendIMENotify(data, IMN_SETSENTENCEMODE, 0);
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmSetOpenStatus (IMM32.@)
- */
-BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("%p %d\n", hIMC, fOpen);
-
- if (!data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (data->immKbd->UIWnd == NULL)
- {
- /* create the ime window */
- data->immKbd->UIWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
- data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
- 0, data->immKbd->hIME, 0);
- SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
- }
- else if (fOpen)
- SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
-
- if (!fOpen != !data->IMC.fOpen)
- {
- data->IMC.fOpen = fOpen;
- ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
- ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmSetStatusWindowPos (IMM32.@)
- */
-BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- TRACE("(%p, %p)\n", hIMC, lpptPos);
-
- if (!data || !lpptPos)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- TRACE("\t(%i,%i)\n", lpptPos->x, lpptPos->y);
-
- data->IMC.ptStatusWndPos = *lpptPos;
- ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS);
- ImmInternalSendIMENotify(data, IMN_SETSTATUSWINDOWPOS, 0);
-
- return TRUE;
-}
-
-/***********************************************************************
- * ImmCreateSoftKeyboard(IMM32.@)
- */
-HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
-{
- FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * ImmDestroySoftKeyboard(IMM32.@)
- */
-BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
-{
- FIXME("(%p): stub\n", hSoftWnd);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * ImmShowSoftKeyboard(IMM32.@)
- */
-BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
-{
- FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * ImmSimulateHotKey (IMM32.@)
- */
-BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
-{
- FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * ImmUnregisterWordA (IMM32.@)
- */
-BOOL WINAPI ImmUnregisterWordA(
- HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
- debugstr_a(lpszUnregister));
- if (immHkl->hIME && immHkl->pImeUnregisterWord)
- {
- if (!is_kbd_ime_unicode(immHkl))
- return immHkl->pImeUnregisterWord((LPCWSTR)lpszReading,dwStyle,
- (LPCWSTR)lpszUnregister);
- else
- {
- LPWSTR lpszwReading = strdupAtoW(lpszReading);
- LPWSTR lpszwUnregister = strdupAtoW(lpszUnregister);
- BOOL rc;
-
- rc = immHkl->pImeUnregisterWord(lpszwReading,dwStyle,lpszwUnregister);
- HeapFree(GetProcessHeap(),0,lpszwReading);
- HeapFree(GetProcessHeap(),0,lpszwUnregister);
- return rc;
- }
- }
- else
- return FALSE;
-}
-
-/***********************************************************************
- * ImmUnregisterWordW (IMM32.@)
- */
-BOOL WINAPI ImmUnregisterWordW(
- HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
- debugstr_w(lpszUnregister));
- if (immHkl->hIME && immHkl->pImeUnregisterWord)
- {
- if (is_kbd_ime_unicode(immHkl))
- return immHkl->pImeUnregisterWord(lpszReading,dwStyle,lpszUnregister);
- else
- {
- LPSTR lpszaReading = strdupWtoA(lpszReading);
- LPSTR lpszaUnregister = strdupWtoA(lpszUnregister);
- BOOL rc;
-
- rc = immHkl->pImeUnregisterWord((LPCWSTR)lpszaReading,dwStyle,
- (LPCWSTR)lpszaUnregister);
- HeapFree(GetProcessHeap(),0,lpszaReading);
- HeapFree(GetProcessHeap(),0,lpszaUnregister);
- return rc;
- }
- }
- else
- return FALSE;
-}
-
-/***********************************************************************
- * ImmGetImeMenuItemsA (IMM32.@)
- */
-DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
- LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
- DWORD dwSize)
-{
- InputContextData *data = get_imc_data(hIMC);
- TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
- lpImeParentMenu, lpImeMenu, dwSize);
-
- if (!data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
- {
- if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
- return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
- (IMEMENUITEMINFOW*)lpImeParentMenu,
- (IMEMENUITEMINFOW*)lpImeMenu, dwSize);
- else
- {
- IMEMENUITEMINFOW lpImeParentMenuW;
- IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
- DWORD rc;
-
- if (lpImeParentMenu)
- parent = &lpImeParentMenuW;
- if (lpImeMenu)
- {
- int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
- dwSize = count * sizeof(IMEMENUITEMINFOW);
- lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
- }
- else
- lpImeMenuW = NULL;
-
- rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
- parent, lpImeMenuW, dwSize);
-
- if (lpImeParentMenu)
- {
- memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
- lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
- WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
- -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
- NULL, NULL);
- }
- if (lpImeMenu && rc)
- {
- unsigned int i;
- for (i = 0; i < rc; i++)
- {
- memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
- lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
- WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
- -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
- NULL, NULL);
- }
- }
- HeapFree(GetProcessHeap(),0,lpImeMenuW);
- return rc;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
-* ImmGetImeMenuItemsW (IMM32.@)
-*/
-DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
- LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
- DWORD dwSize)
+BOOL
+WINAPI
+ImmDllInitialize(
+ _In_ HINSTANCE hDll,
+ _In_ ULONG dwReason,
+ _In_opt_ PVOID pReserved)
{
- InputContextData *data = get_imc_data(hIMC);
- TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
- lpImeParentMenu, lpImeMenu, dwSize);
+ HKL hKL;
+ HIMC hIMC;
- if (!data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return 0;
- }
+ TRACE("(%p, 0x%X, %p)\n", hDll, dwReason, pReserved);
- if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
+ switch (dwReason)
{
- if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
- return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
- lpImeParentMenu, lpImeMenu, dwSize);
- else
- {
- IMEMENUITEMINFOA lpImeParentMenuA;
- IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
- DWORD rc;
-
- if (lpImeParentMenu)
- parent = &lpImeParentMenuA;
- if (lpImeMenu)
- {
- int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
- dwSize = count * sizeof(IMEMENUITEMINFOA);
- lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
- }
- else
- lpImeMenuA = NULL;
-
- rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
- (IMEMENUITEMINFOW*)parent,
- (IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
-
- if (lpImeParentMenu)
+ case DLL_PROCESS_ATTACH:
+ if (!ImmInitializeGlobals(hDll))
{
- memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
- lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
- MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
- -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
+ ERR("ImmInitializeGlobals failed\n");
+ return FALSE;
}
- if (lpImeMenu && rc)
+ if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
{
- unsigned int i;
- for (i = 0; i < rc; i++)
- {
- memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
- lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
- MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
- -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
- }
+ ERR("User32InitializeImmEntryTable failed\n");
+ return FALSE;
}
- HeapFree(GetProcessHeap(),0,lpImeMenuA);
- return rc;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
-* ImmLockIMC(IMM32.@)
-*/
-LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- if (!data)
- return NULL;
- data->dwLock++;
- return &data->IMC;
-}
-
-/***********************************************************************
-* ImmUnlockIMC(IMM32.@)
-*/
-BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- if (!data)
- return FALSE;
- if (data->dwLock)
- data->dwLock--;
- return TRUE;
-}
-
-/***********************************************************************
-* ImmGetIMCLockCount(IMM32.@)
-*/
-DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
-{
- InputContextData *data = get_imc_data(hIMC);
- if (!data)
- return 0;
- return data->dwLock;
-}
-
-/***********************************************************************
-* ImmCreateIMCC(IMM32.@)
-*/
-HIMCC WINAPI ImmCreateIMCC(DWORD size)
-{
- return GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, size);
-}
-
-/***********************************************************************
-* ImmDestroyIMCC(IMM32.@)
-*/
-HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
-{
- return GlobalFree(block);
-}
-
-/***********************************************************************
-* ImmLockIMCC(IMM32.@)
-*/
-LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
-{
- return GlobalLock(imcc);
-}
-
-/***********************************************************************
-* ImmUnlockIMCC(IMM32.@)
-*/
-BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
-{
- return GlobalUnlock(imcc);
-}
-
-/***********************************************************************
-* ImmGetIMCCLockCount(IMM32.@)
-*/
-DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
-{
- return GlobalFlags(imcc) & GMEM_LOCKCOUNT;
-}
-
-/***********************************************************************
-* ImmReSizeIMCC(IMM32.@)
-*/
-HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
-{
- return GlobalReAlloc(imcc, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
-}
-
-/***********************************************************************
-* ImmGetIMCCSize(IMM32.@)
-*/
-DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
-{
- return GlobalSize(imcc);
-}
-
-/***********************************************************************
-* ImmGenerateMessage(IMM32.@)
-*/
-BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
-{
- InputContextData *data = get_imc_data(hIMC);
-
- if (!data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
+#ifndef NDEBUG
+ Imm32UnitTest();
+#endif
+ break;
- TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
- if (data->IMC.dwNumMsgBuf > 0)
- {
- LPTRANSMSG lpTransMsg;
- DWORD i;
+ case DLL_THREAD_ATTACH:
+ break;
- lpTransMsg = ImmLockIMCC(data->IMC.hMsgBuf);
- for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
- ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
+ case DLL_THREAD_DETACH:
+ if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
+ return TRUE;
- ImmUnlockIMCC(data->IMC.hMsgBuf);
+ hKL = GetKeyboardLayout(0);
+ hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
+ Imm32DestroyInputContext(hIMC, hKL, TRUE);
+ break;
- data->IMC.dwNumMsgBuf = 0;
+ case DLL_PROCESS_DETACH:
+ RtlDeleteCriticalSection(&gcsImeDpi);
+ TRACE("imm32.dll is unloaded\n");
+ break;
}
return TRUE;
}
-
-/***********************************************************************
-* ImmTranslateMessage(IMM32.@)
-* ( Undocumented, call internally and from user32.dll )
-*/
-BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
-{
- InputContextData *data;
- HIMC imc = ImmGetContext(hwnd);
- BYTE state[256];
- UINT scancode;
- LPVOID list = 0;
- UINT msg_count;
- UINT uVirtKey;
- static const DWORD list_count = 10;
-
- TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
-
- if (imc)
- data = imc;
- else
- return FALSE;
-
- if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
- return FALSE;
-
- GetKeyboardState(state);
- scancode = lKeyData >> 0x10 & 0xff;
-
- list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD));
- ((DWORD*)list)[0] = list_count;
-
- if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST)
- {
- WCHAR chr;
-
- if (!is_himc_ime_unicode(data))
- ToAscii(data->lastVK, scancode, state, &chr, 0);
- else
- ToUnicodeEx(data->lastVK, scancode, state, &chr, 1, 0, GetKeyboardLayout(0));
- uVirtKey = MAKELONG(data->lastVK,chr);
- }
- else
- uVirtKey = data->lastVK;
-
- msg_count = data->immKbd->pImeToAsciiEx(uVirtKey, scancode, state, list, 0, imc);
- TRACE("%i messages generated\n",msg_count);
- if (msg_count && msg_count <= list_count)
- {
- UINT i;
- LPTRANSMSG msgs = (LPTRANSMSG)((LPBYTE)list + sizeof(DWORD));
-
- for (i = 0; i < msg_count; i++)
- ImmInternalPostIMEMessage(data, msgs[i].message, msgs[i].wParam, msgs[i].lParam);
- }
- else if (msg_count > list_count)
- ImmGenerateMessage(imc);
-
- HeapFree(GetProcessHeap(),0,list);
-
- data->lastVK = VK_PROCESSKEY;
-
- return (msg_count > 0);
-}
-
-/***********************************************************************
-* ImmProcessKey(IMM32.@)
-* ( Undocumented, called from user32.dll )
-*/
-BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
-{
- InputContextData *data;
- HIMC imc = ImmGetContext(hwnd);
- BYTE state[256];
-
- TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
-
- if (imc)
- data = imc;
- else
- return FALSE;
-
- if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
- return FALSE;
-
- GetKeyboardState(state);
- if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
- {
- data->lastVK = vKey;
- return TRUE;
- }
-
- data->lastVK = VK_PROCESSKEY;
- return FALSE;
-}
-
-/***********************************************************************
-* ImmDisableTextFrameService(IMM32.@)
-*/
-BOOL WINAPI ImmDisableTextFrameService(DWORD idThread)
-{
- FIXME("Stub\n");
- return FALSE;
-}
-
-/***********************************************************************
- * ImmEnumInputContext(IMM32.@)
- */
-
-BOOL WINAPI ImmEnumInputContext(DWORD idThread, IMCENUMPROC lpfn, LPARAM lParam)
-{
- FIXME("Stub\n");
- return FALSE;
-}
-
-/***********************************************************************
- * ImmGetHotKey(IMM32.@)
- */
-
-BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl)
-{
- FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl);
- return FALSE;
-}
-
-
-/*
- * Window Proc for the Default IME window class
- */
-static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_CREATE:
- case WM_NCCREATE:
- return TRUE;
- case WM_IME_STARTCOMPOSITION:
- case WM_IME_ENDCOMPOSITION:
- case WM_IME_COMPOSITION:
- case WM_IME_SETCONTEXT:
- case WM_IME_NOTIFY:
- case WM_IME_CONTROL:
- case WM_IME_COMPOSITIONFULL:
- case WM_IME_SELECT:
- case WM_IME_CHAR:
- case WM_IME_REQUEST:
- case WM_IME_KEYDOWN:
- case WM_IME_KEYUP:
- {
- ImmHkl *immHkl = IMM_GetImmHkl(GetKeyboardLayout(0));
- if (immHkl->UIWnd)
- return SendMessageW(immHkl->UIWnd,uMsg,wParam,lParam);
- else
- return FALSE;
- }
- default:
- if ((uMsg == WM_MSIME_RECONVERTOPTIONS) ||
- (uMsg == WM_MSIME_SERVICE) ||
- (uMsg == WM_MSIME_MOUSE) ||
- (uMsg == WM_MSIME_RECONVERTREQUEST) ||
- (uMsg == WM_MSIME_RECONVERT) ||
- (uMsg == WM_MSIME_QUERYPOSITION) ||
- (uMsg == WM_MSIME_DOCUMENTFEED))
- {
- ImmHkl *immHkl = IMM_GetImmHkl(GetKeyboardLayout(0));
- if (immHkl->UIWnd)
- return SendMessageW(immHkl->UIWnd,uMsg,wParam,lParam);
- else
- return FALSE;
- }
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
-}