2005-12-12 20:59:55 +00:00
|
|
|
/*
|
|
|
|
* IMM32 library
|
|
|
|
*
|
|
|
|
* Copyright 1998 Patrik Stridvall
|
2007-09-14 08:03:04 +00:00
|
|
|
* Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
|
2005-12-12 20:59:55 +00:00
|
|
|
*
|
|
|
|
* 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
|
2006-07-06 11:22:04 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-12-12 20:59:55 +00:00
|
|
|
*/
|
|
|
|
|
2018-03-15 11:31:05 +00:00
|
|
|
#include <stdarg.h>
|
2010-03-07 11:27:14 +00:00
|
|
|
#include <stdio.h>
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2020-08-09 13:41:11 +00:00
|
|
|
#define WIN32_NO_STATUS
|
2021-07-11 00:48:15 +00:00
|
|
|
#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>
|
2021-07-03 23:18:15 +00:00
|
|
|
#include <stdlib.h>
|
2020-08-09 13:41:11 +00:00
|
|
|
#include <ndk/umtypes.h>
|
|
|
|
#include <ndk/pstypes.h>
|
2021-07-11 00:48:15 +00:00
|
|
|
#include <ndk/rtlfuncs.h>
|
2020-08-09 13:41:11 +00:00
|
|
|
#include "../../../win32ss/include/ntuser.h"
|
2021-07-03 23:18:15 +00:00
|
|
|
#include <imm32_undoc.h>
|
|
|
|
#include <strsafe.h>
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(imm);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
#define IMM_INIT_MAGIC 0x19650412
|
2021-07-15 18:04:00 +00:00
|
|
|
#define IMM_INVALID_CANDFORM ULONG_MAX
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
typedef struct _tagImmHkl{
|
|
|
|
struct list entry;
|
|
|
|
HKL hkl;
|
|
|
|
HMODULE hIME;
|
|
|
|
IMEINFO imeInfo;
|
|
|
|
WCHAR imeClassName[17]; /* 16 character max */
|
|
|
|
ULONG uSelected;
|
2013-02-03 20:58:12 +00:00
|
|
|
HWND UIWnd;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
/* Function Pointers */
|
2018-10-01 11:53:21 +00:00
|
|
|
BOOL (WINAPI *pImeInquire)(IMEINFO *, WCHAR *, const WCHAR *);
|
|
|
|
BOOL (WINAPI *pImeConfigure)(HKL, HWND, DWORD, void *);
|
|
|
|
BOOL (WINAPI *pImeDestroy)(UINT);
|
|
|
|
LRESULT (WINAPI *pImeEscape)(HIMC, UINT, void *);
|
|
|
|
BOOL (WINAPI *pImeSelect)(HIMC, BOOL);
|
|
|
|
BOOL (WINAPI *pImeSetActiveContext)(HIMC, BOOL);
|
|
|
|
UINT (WINAPI *pImeToAsciiEx)(UINT, UINT, const BYTE *, DWORD *, UINT, HIMC);
|
|
|
|
BOOL (WINAPI *pNotifyIME)(HIMC, DWORD, DWORD, DWORD);
|
|
|
|
BOOL (WINAPI *pImeRegisterWord)(const WCHAR *, DWORD, const WCHAR *);
|
|
|
|
BOOL (WINAPI *pImeUnregisterWord)(const WCHAR *, DWORD, const WCHAR *);
|
|
|
|
UINT (WINAPI *pImeEnumRegisterWord)(REGISTERWORDENUMPROCW, const WCHAR *, DWORD, const WCHAR *, void *);
|
|
|
|
BOOL (WINAPI *pImeSetCompositionString)(HIMC, DWORD, const void *, DWORD, const void *, DWORD);
|
|
|
|
DWORD (WINAPI *pImeConversionList)(HIMC, const WCHAR *, CANDIDATELIST *, DWORD, UINT);
|
|
|
|
BOOL (WINAPI *pImeProcessKey)(HIMC, UINT, LPARAM, const BYTE *);
|
|
|
|
UINT (WINAPI *pImeGetRegisterWordStyle)(UINT, STYLEBUFW *);
|
|
|
|
DWORD (WINAPI *pImeGetImeMenuItems)(HIMC, DWORD, DWORD, IMEMENUITEMINFOW *, IMEMENUITEMINFOW *, DWORD);
|
2008-04-04 13:20:27 +00:00
|
|
|
} ImmHkl;
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
typedef struct tagInputContextData
|
|
|
|
{
|
2007-09-14 08:03:04 +00:00
|
|
|
DWORD dwLock;
|
|
|
|
INPUTCONTEXT IMC;
|
2017-12-08 03:14:21 +00:00
|
|
|
DWORD threadID;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
ImmHkl *immKbd;
|
2010-03-07 11:27:14 +00:00
|
|
|
UINT lastVK;
|
2017-12-08 03:14:21 +00:00
|
|
|
BOOL threadDefault;
|
2014-09-28 18:27:58 +00:00
|
|
|
DWORD magic;
|
2005-12-12 20:59:55 +00:00
|
|
|
} InputContextData;
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
#define WINE_IMC_VALID_MAGIC 0x56434D49
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
typedef struct _tagTRANSMSG {
|
|
|
|
UINT message;
|
|
|
|
WPARAM wParam;
|
|
|
|
LPARAM lParam;
|
|
|
|
} TRANSMSG, *LPTRANSMSG;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
typedef struct _tagIMMThreadData {
|
2017-12-08 03:14:21 +00:00
|
|
|
struct list entry;
|
|
|
|
DWORD threadID;
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC defaultContext;
|
|
|
|
HWND hwndDefault;
|
2017-12-08 03:14:21 +00:00
|
|
|
BOOL disableIME;
|
|
|
|
DWORD windowRefs;
|
2010-03-07 11:27:14 +00:00
|
|
|
} IMMThreadData;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static struct list ImmHklList = LIST_INIT(ImmHklList);
|
2017-12-08 03:14:21 +00:00
|
|
|
static struct list ImmThreadDataList = LIST_INIT(ImmThreadDataList);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
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};
|
|
|
|
|
2013-02-03 20:58:12 +00:00
|
|
|
static const WCHAR szwIME[] = {'I','M','E',0};
|
2017-12-08 03:14:21 +00:00
|
|
|
static const WCHAR szwDefaultIME[] = {'D','e','f','a','u','l','t',' ','I','M','E',0};
|
2013-02-03 20:58:12 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static CRITICAL_SECTION threaddata_cs;
|
|
|
|
static CRITICAL_SECTION_DEBUG critsect_debug =
|
|
|
|
{
|
|
|
|
0, 0, &threaddata_cs,
|
|
|
|
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
|
|
|
0, 0, { (DWORD_PTR)(__FILE__ ": threaddata_cs") }
|
|
|
|
};
|
|
|
|
static CRITICAL_SECTION threaddata_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
|
|
|
static BOOL disable_ime;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
static inline BOOL is_himc_ime_unicode(const InputContextData *data)
|
|
|
|
{
|
|
|
|
return !!(data->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL is_kbd_ime_unicode(const ImmHkl *hkl)
|
|
|
|
{
|
|
|
|
return !!(hkl->imeInfo.fdwProperty & IME_PROP_UNICODE);
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
static BOOL IMM_DestroyContext(HIMC hIMC);
|
2017-12-08 03:14:21 +00:00
|
|
|
static InputContextData* get_imc_data(HIMC hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
static inline WCHAR *strdupAtoW( const char *str )
|
|
|
|
{
|
|
|
|
WCHAR *ret = NULL;
|
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
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 );
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline CHAR *strdupWtoA( const WCHAR *str )
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD convert_candidatelist_WtoA(
|
|
|
|
LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
DWORD ret, i, len;
|
|
|
|
|
|
|
|
ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst->dwOffset[0] = ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < lpSrc->dwCount; i++)
|
|
|
|
{
|
|
|
|
LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
|
|
|
|
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
|
|
|
|
|
|
|
|
len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1,
|
|
|
|
(LPSTR)dest, dwBufLen, NULL, NULL);
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
ret += len * sizeof(char);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( lpDst )
|
|
|
|
lpDst->dwSize = ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD convert_candidatelist_AtoW(
|
|
|
|
LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
DWORD ret, i, len;
|
|
|
|
|
|
|
|
ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst->dwOffset[0] = ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < lpSrc->dwCount; i++)
|
|
|
|
{
|
|
|
|
LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
|
|
|
|
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
|
|
|
|
|
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1,
|
|
|
|
(LPWSTR)dest, dwBufLen);
|
|
|
|
|
|
|
|
if ( i + 1 < lpSrc->dwCount )
|
|
|
|
lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(WCHAR);
|
|
|
|
dwBufLen -= len * sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, NULL, 0);
|
|
|
|
|
|
|
|
ret += len * sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( lpDst )
|
|
|
|
lpDst->dwSize = ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static IMMThreadData *IMM_GetThreadData(HWND hwnd, DWORD thread)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
IMMThreadData *data;
|
|
|
|
DWORD process;
|
|
|
|
|
|
|
|
if (hwnd)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!(thread = GetWindowThreadProcessId(hwnd, &process))) return NULL;
|
|
|
|
if (process != GetCurrentProcessId()) return NULL;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
else if (thread)
|
|
|
|
{
|
|
|
|
HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, FALSE, thread);
|
|
|
|
if (!h) return NULL;
|
|
|
|
process = GetProcessIdOfThread(h);
|
|
|
|
CloseHandle(h);
|
|
|
|
if (process != GetCurrentProcessId()) return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
thread = GetCurrentThreadId();
|
|
|
|
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
LIST_FOR_EACH_ENTRY(data, &ImmThreadDataList, IMMThreadData, entry)
|
|
|
|
if (data->threadID == thread) return data;
|
|
|
|
|
|
|
|
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
|
|
|
|
data->threadID = thread;
|
|
|
|
list_add_head(&ImmThreadDataList,&data->entry);
|
|
|
|
TRACE("Thread Data Created (%x)\n",thread);
|
2010-03-07 11:27:14 +00:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static BOOL IMM_IsDefaultContext(HIMC imc)
|
|
|
|
{
|
|
|
|
InputContextData *data = get_imc_data(imc);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return data->threadDefault;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static void IMM_FreeThreadData(void)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
IMMThreadData *data;
|
|
|
|
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
LIST_FOR_EACH_ENTRY(data, &ImmThreadDataList, IMMThreadData, entry)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (data->threadID == GetCurrentThreadId())
|
|
|
|
{
|
|
|
|
list_remove(&data->entry);
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
IMM_DestroyContext(data->defaultContext);
|
|
|
|
HeapFree(GetProcessHeap(),0,data);
|
|
|
|
TRACE("Thread Data Destroyed\n");
|
|
|
|
return;
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
static HMODULE load_graphics_driver(void)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
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};
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
HMODULE ret = 0;
|
|
|
|
HKEY hkey;
|
|
|
|
DWORD size;
|
|
|
|
WCHAR path[MAX_PATH];
|
2018-10-01 11:53:21 +00:00
|
|
|
WCHAR key[ARRAY_SIZE( key_pathW ) + ARRAY_SIZE( displayW ) + 40];
|
2014-09-28 18:27:58 +00:00
|
|
|
UINT guid_atom = HandleToULong( GetPropW( GetDesktopWindow(), display_device_guid_propW ));
|
|
|
|
|
|
|
|
if (!guid_atom) return 0;
|
|
|
|
memcpy( key, key_pathW, sizeof(key_pathW) );
|
2019-11-02 17:34:15 +00:00
|
|
|
if (!GlobalGetAtomNameW( guid_atom, key + lstrlenW(key), 40 )) return 0;
|
|
|
|
lstrcatW( key, displayW );
|
2014-09-28 18:27:58 +00:00
|
|
|
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;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/* 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];
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("Seeking ime for keyboard %p\n",hkl);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
|
|
|
|
{
|
|
|
|
if (ptr->hkl == hkl)
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
/* not found... create it */
|
|
|
|
|
|
|
|
ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
|
|
|
|
|
|
|
|
ptr->hkl = hkl;
|
|
|
|
if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
|
2014-09-28 18:27:58 +00:00
|
|
|
if (!ptr->hIME) ptr->hIME = load_graphics_driver();
|
2008-04-04 13:20:27 +00:00
|
|
|
if (ptr->hIME)
|
|
|
|
{
|
|
|
|
LOAD_FUNCPTR(ImeInquire);
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
|
|
|
FreeLibrary(ptr->hIME);
|
|
|
|
ptr->hIME = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
LOAD_FUNCPTR(ImeDestroy);
|
|
|
|
LOAD_FUNCPTR(ImeSelect);
|
|
|
|
if (!ptr->pImeSelect || !ptr->pImeDestroy)
|
|
|
|
{
|
|
|
|
FreeLibrary(ptr->hIME);
|
|
|
|
ptr->hIME = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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))
|
|
|
|
{
|
|
|
|
WCHAR bufW[17];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
|
|
|
|
-1, bufW, 17);
|
|
|
|
lstrcpyW(ptr->imeClassName, bufW);
|
|
|
|
}
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
list_add_head(&ImmHklList,&ptr->entry);
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
#undef LOAD_FUNCPTR
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
HWND WINAPI __wine_get_ui_window(HKL hkl)
|
|
|
|
{
|
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hkl);
|
|
|
|
return immHkl->UIWnd;
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static void IMM_FreeAllImmHkl(void)
|
|
|
|
{
|
|
|
|
ImmHkl *ptr,*cursor2;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
|
|
|
|
{
|
|
|
|
list_remove(&ptr->entry);
|
|
|
|
if (ptr->hIME)
|
|
|
|
{
|
|
|
|
ptr->pImeDestroy(1);
|
|
|
|
FreeLibrary(ptr->hIME);
|
|
|
|
}
|
2013-02-03 20:58:12 +00:00
|
|
|
if (ptr->UIWnd)
|
|
|
|
DestroyWindow(ptr->UIWnd);
|
2008-04-04 13:20:27 +00:00
|
|
|
HeapFree(GetProcessHeap(),0,ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
|
2005-12-12 20:59:55 +00:00
|
|
|
switch (fdwReason)
|
|
|
|
{
|
|
|
|
case DLL_PROCESS_ATTACH:
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2017-12-08 03:14:21 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
|
|
IMM_FreeThreadData();
|
2005-12-12 20:59:55 +00:00
|
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
2013-12-01 15:57:34 +00:00
|
|
|
if (lpReserved) break;
|
2010-03-07 11:27:14 +00:00
|
|
|
IMM_FreeThreadData();
|
2008-04-04 13:20:27 +00:00
|
|
|
IMM_FreeAllImmHkl();
|
2005-12-12 20:59:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for posting messages as the IME */
|
2008-04-04 13:20:27 +00:00
|
|
|
static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
|
|
|
HWND target = GetFocus();
|
|
|
|
if (!target)
|
2008-04-04 13:20:27 +00:00
|
|
|
PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
|
2007-09-14 08:03:04 +00:00
|
|
|
else
|
2005-12-12 20:59:55 +00:00
|
|
|
PostMessageW(target, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
/* for sending messages as the IME */
|
|
|
|
static void ImmInternalSendIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
HWND target = GetFocus();
|
|
|
|
if (!target)
|
|
|
|
SendMessageW(data->IMC.hWnd,msg,wParam,lParam);
|
|
|
|
else
|
|
|
|
SendMessageW(target, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
|
2007-03-14 14:34:47 +00:00
|
|
|
{
|
|
|
|
HWND target;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
target = data->IMC.hWnd;
|
2007-03-14 14:34:47 +00:00
|
|
|
if (!target) target = GetFocus();
|
|
|
|
|
|
|
|
if (target)
|
|
|
|
return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static HIMCC ImmCreateBlankCompStr(void)
|
|
|
|
{
|
|
|
|
HIMCC rc;
|
|
|
|
LPCOMPOSITIONSTRING ptr;
|
|
|
|
rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
|
2010-03-07 11:27:14 +00:00
|
|
|
ptr = ImmLockIMCC(rc);
|
2008-04-04 13:20:27 +00:00
|
|
|
memset(ptr,0,sizeof(COMPOSITIONSTRING));
|
|
|
|
ptr->dwSize = sizeof(COMPOSITIONSTRING);
|
|
|
|
ImmUnlockIMCC(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
static InputContextData* get_imc_data(HIMC hIMC)
|
|
|
|
{
|
|
|
|
InputContextData *data = hIMC;
|
|
|
|
|
|
|
|
if (hIMC == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if(IsBadReadPtr(data, sizeof(InputContextData)) || data->magic != WINE_IMC_VALID_MAGIC)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static HIMC get_default_context( HWND hwnd )
|
|
|
|
{
|
|
|
|
HIMC ret;
|
|
|
|
IMMThreadData* thread_data = IMM_GetThreadData( hwnd, 0 );
|
|
|
|
|
|
|
|
if (!thread_data) return 0;
|
|
|
|
|
|
|
|
if (thread_data->defaultContext)
|
|
|
|
{
|
|
|
|
ret = thread_data->defaultContext;
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* can't create a default context in another thread */
|
|
|
|
if (thread_data->threadID != GetCurrentThreadId())
|
|
|
|
{
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
ret = ImmCreateContext();
|
|
|
|
if (!ret) return 0;
|
|
|
|
((InputContextData*)ret)->threadDefault = TRUE;
|
|
|
|
|
|
|
|
/* thread_data is in the current thread so we can assume it's still valid */
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
if (thread_data->defaultContext) /* someone beat us */
|
|
|
|
{
|
|
|
|
IMM_DestroyContext( ret );
|
|
|
|
ret = thread_data->defaultContext;
|
|
|
|
}
|
|
|
|
else thread_data->defaultContext = ret;
|
|
|
|
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL IMM_IsCrossThreadAccess(HWND hWnd, HIMC hIMC)
|
|
|
|
{
|
|
|
|
InputContextData *data;
|
|
|
|
|
|
|
|
if (hWnd)
|
|
|
|
{
|
|
|
|
DWORD thread = GetWindowThreadProcessId(hWnd, NULL);
|
|
|
|
if (thread != GetCurrentThreadId()) return TRUE;
|
|
|
|
}
|
|
|
|
data = get_imc_data(hIMC);
|
|
|
|
if (data && data->threadID != GetCurrentThreadId())
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmAssociateContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
|
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
HIMC old = NULL;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
TRACE("(%p, %p):\n", hWnd, hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if(hIMC && !data)
|
|
|
|
return NULL;
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/*
|
|
|
|
* If already associated just return
|
|
|
|
*/
|
2008-04-04 13:20:27 +00:00
|
|
|
if (hIMC && data->IMC.hWnd == hWnd)
|
2006-07-06 11:22:04 +00:00
|
|
|
return hIMC;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (hIMC && IMM_IsCrossThreadAccess(hWnd, hIMC))
|
|
|
|
return NULL;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
if (hWnd)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
HIMC defaultContext = get_default_context( hWnd );
|
2010-03-07 11:27:14 +00:00
|
|
|
old = RemovePropW(hWnd,szwWineIMCProperty);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
if (old == NULL)
|
2017-12-08 03:14:21 +00:00
|
|
|
old = defaultContext;
|
2008-04-04 13:20:27 +00:00
|
|
|
else if (old == (HIMC)-1)
|
|
|
|
old = NULL;
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (hIMC != defaultContext)
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
|
|
|
if (hIMC == NULL) /* Meaning disable imm for that window*/
|
|
|
|
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
|
|
|
|
else
|
2010-03-07 11:27:14 +00:00
|
|
|
SetPropW(hWnd,szwWineIMCProperty,hIMC);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (old)
|
|
|
|
{
|
|
|
|
InputContextData *old_data = old;
|
|
|
|
if (old_data->IMC.hWnd == hWnd)
|
|
|
|
old_data->IMC.hWnd = NULL;
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hIMC)
|
|
|
|
return old;
|
|
|
|
|
2019-01-26 12:10:01 +00:00
|
|
|
if(GetActiveWindow() == data->IMC.hWnd)
|
|
|
|
{
|
|
|
|
SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
|
|
|
|
data->IMC.hWnd = hWnd;
|
|
|
|
SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
return old;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper function for ImmAssociateContextEx
|
|
|
|
*/
|
|
|
|
static BOOL CALLBACK _ImmAssociateContextExEnumProc(HWND hwnd, LPARAM lParam)
|
|
|
|
{
|
|
|
|
HIMC hImc = (HIMC)lParam;
|
|
|
|
ImmAssociateContext(hwnd,hImc);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmAssociateContextEx (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!hWnd)
|
|
|
|
return FALSE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
|
|
|
|
switch (dwFlags)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case 0:
|
|
|
|
ImmAssociateContext(hWnd,hIMC);
|
|
|
|
return TRUE;
|
|
|
|
case IACE_DEFAULT:
|
2017-12-08 03:14:21 +00:00
|
|
|
{
|
|
|
|
HIMC defaultContext = get_default_context( hWnd );
|
|
|
|
if (!defaultContext) return FALSE;
|
|
|
|
ImmAssociateContext(hWnd,defaultContext);
|
2010-03-07 11:27:14 +00:00
|
|
|
return TRUE;
|
2017-12-08 03:14:21 +00:00
|
|
|
}
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case IACE_IGNORENOCONTEXT:
|
2010-03-07 11:27:14 +00:00
|
|
|
if (GetPropW(hWnd,szwWineIMCProperty))
|
|
|
|
ImmAssociateContext(hWnd,hIMC);
|
|
|
|
return TRUE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case IACE_CHILDREN:
|
2010-03-07 11:27:14 +00:00
|
|
|
EnumChildWindows(hWnd,_ImmAssociateContextExEnumProc,(LPARAM)hIMC);
|
|
|
|
return TRUE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
default:
|
|
|
|
FIXME("Unknown dwFlags 0x%x\n",dwFlags);
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmConfigureIMEA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmConfigureIMEA(
|
|
|
|
HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
|
|
|
|
|
|
|
|
if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeConfigure)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmConfigureIMEW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmConfigureIMEW(
|
|
|
|
HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
|
|
|
|
|
|
|
|
if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeConfigure)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmCreateContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmCreateContext(void)
|
|
|
|
{
|
|
|
|
InputContextData *new_context;
|
2010-03-07 11:27:14 +00:00
|
|
|
LPGUIDELINE gl;
|
|
|
|
LPCANDIDATEINFO ci;
|
2014-09-28 18:27:58 +00:00
|
|
|
int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/* Load the IME */
|
|
|
|
new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
|
|
|
|
|
|
|
|
if (!new_context->immKbd->hIME)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
TRACE("IME dll could not be loaded\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
HeapFree(GetProcessHeap(),0,new_context);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/* the HIMCCs are never NULL */
|
2008-04-04 13:20:27 +00:00
|
|
|
new_context->IMC.hCompStr = ImmCreateBlankCompStr();
|
2010-03-07 11:27:14 +00:00
|
|
|
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);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2018-10-01 11:53:21 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(new_context->IMC.cfCandForm); i++)
|
2014-09-28 18:27:58 +00:00
|
|
|
new_context->IMC.cfCandForm[i].dwIndex = ~0u;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/* Initialize the IME Private */
|
|
|
|
new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
new_context->IMC.fdwConversion = new_context->immKbd->imeInfo.fdwConversionCaps;
|
|
|
|
new_context->IMC.fdwSentence = new_context->immKbd->imeInfo.fdwSentenceCaps;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!new_context->immKbd->pImeSelect(new_context, TRUE))
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
|
|
|
TRACE("Selection of IME failed\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
IMM_DestroyContext(new_context);
|
2008-04-04 13:20:27 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
new_context->threadID = GetCurrentThreadId();
|
|
|
|
SendMessageW(GetFocus(), WM_IME_SELECT, TRUE, (LPARAM)new_context->immKbd);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
new_context->immKbd->uSelected++;
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("Created context %p\n",new_context);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
new_context->magic = WINE_IMC_VALID_MAGIC;
|
2010-03-07 11:27:14 +00:00
|
|
|
return new_context;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static BOOL IMM_DestroyContext(HIMC hIMC)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
TRACE("Destroying %p\n",hIMC);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
data->immKbd->uSelected --;
|
|
|
|
data->immKbd->pImeSelect(hIMC, FALSE);
|
2017-12-08 03:14:21 +00:00
|
|
|
SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)data->immKbd);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
|
|
|
ImmDestroyIMCC(data->IMC.hCompStr);
|
|
|
|
ImmDestroyIMCC(data->IMC.hCandInfo);
|
|
|
|
ImmDestroyIMCC(data->IMC.hGuideLine);
|
|
|
|
ImmDestroyIMCC(data->IMC.hPrivate);
|
|
|
|
ImmDestroyIMCC(data->IMC.hMsgBuf);
|
|
|
|
|
|
|
|
data->magic = 0;
|
|
|
|
HeapFree(GetProcessHeap(),0,data);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroyContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!IMM_IsDefaultContext(hIMC) && !IMM_IsCrossThreadAccess(NULL, hIMC))
|
2010-03-07 11:27:14 +00:00
|
|
|
return IMM_DestroyContext(hIMC);
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmDisableIME (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDisableIME(DWORD idThread)
|
|
|
|
{
|
2021-07-01 09:03:42 +00:00
|
|
|
return NtUserDisableThreadIme(idThread);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumRegisterWordA (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmEnumRegisterWordA(
|
|
|
|
HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
|
|
|
|
LPCSTR lpszReading, DWORD dwStyle,
|
|
|
|
LPCSTR lpszRegister, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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_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;
|
|
|
|
|
|
|
|
rc = immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
|
|
|
|
lpszwReading, dwStyle, lpszwRegister,
|
|
|
|
lpData);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwRegister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumRegisterWordW (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmEnumRegisterWordW(
|
|
|
|
HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
|
|
|
|
LPCWSTR lpszReading, DWORD dwStyle,
|
|
|
|
LPCWSTR lpszRegister, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaRegister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
return TRUE;
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEscapeA (IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmEscapeA(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
UINT uEscape, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeEscape)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEscapeW (IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmEscapeW(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
UINT uEscape, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeEscape)
|
|
|
|
{
|
|
|
|
if (!EscapeRequiresWA(uEscape) || is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeEscape(hIMC,uEscape,lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
#define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */
|
|
|
|
|
|
|
|
HANDLE g_hImm32Heap = NULL;
|
2021-07-15 12:59:53 +00:00
|
|
|
DWORD g_dwImm32Flags = 0;
|
|
|
|
|
|
|
|
/* flags for g_dwImm32Flags */
|
|
|
|
#define IMM32_FLAG_UNKNOWN 0x4
|
|
|
|
#define IMM32_FLAG_CICERO_ENABLED 0x20
|
2021-07-11 00:48:15 +00:00
|
|
|
|
|
|
|
LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes)
|
|
|
|
{
|
|
|
|
if (!g_hImm32Heap)
|
|
|
|
{
|
|
|
|
g_hImm32Heap = GetProcessHeap(); // FIXME: Use TEB
|
|
|
|
if (g_hImm32Heap == NULL)
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return HeapAlloc(g_hImm32Heap, dwFlags, dwBytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD_PTR APIENTRY
|
|
|
|
Imm32GetThreadState(DWORD Routine)
|
|
|
|
{
|
|
|
|
return NtUserGetThreadState(Routine);
|
|
|
|
}
|
|
|
|
|
2021-07-15 12:59:53 +00:00
|
|
|
static DWORD_PTR APIENTRY Imm32QueryWindow(HWND hWnd, DWORD Index)
|
|
|
|
{
|
|
|
|
return NtUserQueryWindow(hWnd, Index);
|
|
|
|
}
|
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
static DWORD APIENTRY
|
|
|
|
Imm32UpdateInputContext(HIMC hIMC, DWORD Unknown1, PCLIENTIMC pClientImc)
|
|
|
|
{
|
|
|
|
return NtUserUpdateInputContext(hIMC, Unknown1, pClientImc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PCLIENTIMC APIENTRY Imm32GetClientImcCache(void)
|
|
|
|
{
|
|
|
|
// FIXME: Do something properly here
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
|
|
|
|
{
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
|
|
|
|
TRACE("ImmLockClientImc(%p)\n", hImc);
|
|
|
|
|
|
|
|
if (hImc == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
pClientImc = Imm32GetClientImcCache();
|
|
|
|
if (!pClientImc)
|
|
|
|
{
|
|
|
|
pClientImc = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
|
|
|
if (!pClientImc)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
RtlInitializeCriticalSection(&pClientImc->cs);
|
|
|
|
pClientImc->unknown = Imm32GetThreadState(THREADSTATE_UNKNOWN13);
|
|
|
|
|
|
|
|
if (!Imm32UpdateInputContext(hImc, 0, pClientImc))
|
|
|
|
{
|
|
|
|
HeapFree(g_hImm32Heap, 0, pClientImc);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_DISABLED)
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
|
|
|
return pClientImc;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
|
|
|
|
{
|
|
|
|
LONG cLocks;
|
|
|
|
HIMC hImc;
|
|
|
|
|
|
|
|
TRACE("ImmUnlockClientImc(%p)\n", pClientImc);
|
|
|
|
|
|
|
|
cLocks = InterlockedDecrement(&pClientImc->cLockObj);
|
|
|
|
if (cLocks != 0 || (pClientImc->dwFlags & CLIENTIMC_DISABLED))
|
|
|
|
return;
|
|
|
|
|
|
|
|
hImc = pClientImc->hImc;
|
|
|
|
if (hImc)
|
|
|
|
LocalFree(hImc);
|
|
|
|
|
|
|
|
RtlDeleteCriticalSection(&pClientImc->cs);
|
|
|
|
HeapFree(g_hImm32Heap, 0, pClientImc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD APIENTRY
|
|
|
|
CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen,
|
|
|
|
UINT uCodePage)
|
|
|
|
{
|
|
|
|
BOOL bUsedDefault;
|
|
|
|
DWORD dwSize, dwIndex, cbGot, cbLeft;
|
|
|
|
const BYTE *pbWide;
|
|
|
|
LPBYTE pbAnsi;
|
|
|
|
LPDWORD pibOffsets;
|
|
|
|
|
|
|
|
/* calculate total ansi size */
|
|
|
|
if (pWideCL->dwCount > 0)
|
|
|
|
{
|
|
|
|
dwSize = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD));
|
|
|
|
for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex];
|
|
|
|
cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1, NULL, 0,
|
|
|
|
NULL, &bUsedDefault);
|
|
|
|
dwSize += cbGot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dwSize = sizeof(CANDIDATELIST);
|
|
|
|
}
|
|
|
|
|
|
|
|
dwSize = ROUNDUP4(dwSize);
|
|
|
|
if (dwBufLen == 0)
|
|
|
|
return dwSize;
|
|
|
|
if (dwBufLen < dwSize)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* store to ansi */
|
|
|
|
pAnsiCL->dwSize = dwBufLen;
|
|
|
|
pAnsiCL->dwStyle = pWideCL->dwStyle;
|
|
|
|
pAnsiCL->dwCount = pWideCL->dwCount;
|
|
|
|
pAnsiCL->dwSelection = pWideCL->dwSelection;
|
|
|
|
pAnsiCL->dwPageStart = pWideCL->dwPageStart;
|
|
|
|
pAnsiCL->dwPageSize = pWideCL->dwPageSize;
|
|
|
|
|
|
|
|
pibOffsets = pAnsiCL->dwOffset;
|
|
|
|
if (pWideCL->dwCount > 0)
|
|
|
|
{
|
|
|
|
pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD));
|
|
|
|
cbLeft = dwBufLen - pibOffsets[0];
|
|
|
|
|
|
|
|
for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex];
|
|
|
|
pbAnsi = (LPBYTE)pAnsiCL + pibOffsets[dwIndex];
|
|
|
|
|
|
|
|
/* convert to ansi */
|
|
|
|
cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1,
|
|
|
|
(LPSTR)pbAnsi, cbLeft, NULL, &bUsedDefault);
|
|
|
|
cbLeft -= cbGot;
|
|
|
|
|
|
|
|
if (dwIndex < pWideCL->dwCount - 1)
|
|
|
|
pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pibOffsets[0] = sizeof(CANDIDATELIST);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dwBufLen;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD APIENTRY
|
|
|
|
CandidateListAnsiToWide(const CANDIDATELIST *pAnsiCL, LPCANDIDATELIST pWideCL, DWORD dwBufLen,
|
|
|
|
UINT uCodePage)
|
|
|
|
{
|
|
|
|
DWORD dwSize, dwIndex, cchGot, cbGot, cbLeft;
|
|
|
|
const BYTE *pbAnsi;
|
|
|
|
LPBYTE pbWide;
|
|
|
|
LPDWORD pibOffsets;
|
|
|
|
|
|
|
|
/* calculate total wide size */
|
|
|
|
if (pAnsiCL->dwCount > 0)
|
|
|
|
{
|
|
|
|
dwSize = sizeof(CANDIDATELIST) + ((pAnsiCL->dwCount - 1) * sizeof(DWORD));
|
|
|
|
for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex];
|
|
|
|
cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)pbAnsi, -1, NULL, 0);
|
|
|
|
dwSize += cchGot * sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dwSize = sizeof(CANDIDATELIST);
|
|
|
|
}
|
|
|
|
|
|
|
|
dwSize = ROUNDUP4(dwSize);
|
|
|
|
if (dwBufLen == 0)
|
|
|
|
return dwSize;
|
|
|
|
if (dwBufLen < dwSize)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* store to wide */
|
|
|
|
pWideCL->dwSize = dwBufLen;
|
|
|
|
pWideCL->dwStyle = pAnsiCL->dwStyle;
|
|
|
|
pWideCL->dwCount = pAnsiCL->dwCount;
|
|
|
|
pWideCL->dwSelection = pAnsiCL->dwSelection;
|
|
|
|
pWideCL->dwPageStart = pAnsiCL->dwPageStart;
|
|
|
|
pWideCL->dwPageSize = pAnsiCL->dwPageSize;
|
|
|
|
|
|
|
|
pibOffsets = pWideCL->dwOffset;
|
|
|
|
if (pAnsiCL->dwCount > 0)
|
|
|
|
{
|
|
|
|
pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD));
|
|
|
|
cbLeft = dwBufLen - pibOffsets[0];
|
|
|
|
|
|
|
|
for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex];
|
|
|
|
pbWide = (LPBYTE)pWideCL + pibOffsets[dwIndex];
|
|
|
|
|
|
|
|
/* convert to wide */
|
|
|
|
cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)pbAnsi, -1,
|
|
|
|
(LPWSTR)pbWide, cbLeft / sizeof(WCHAR));
|
|
|
|
cbGot = cchGot * sizeof(WCHAR);
|
|
|
|
cbLeft -= cbGot;
|
|
|
|
|
|
|
|
if (dwIndex + 1 < pAnsiCL->dwCount)
|
|
|
|
pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pibOffsets[0] = sizeof(CANDIDATELIST);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dwBufLen;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD APIENTRY
|
|
|
|
ImmGetCandidateListAW(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen,
|
|
|
|
BOOL bAnsi)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
DWORD ret = 0;
|
2021-07-11 00:48:15 +00:00
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
LPCANDIDATEINFO pCI;
|
|
|
|
LPCANDIDATELIST pCL;
|
|
|
|
DWORD dwSize;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (!pClientImc)
|
|
|
|
return 0;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (pIC == NULL)
|
|
|
|
{
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
pCI = ImmLockIMCC(pIC->hCandInfo);
|
|
|
|
if (pCI == NULL)
|
|
|
|
{
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
if (pCI->dwSize < sizeof(CANDIDATEINFO) || pCI->dwCount <= dwIndex)
|
|
|
|
goto Quit;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
/* get required size */
|
|
|
|
pCL = (LPCANDIDATELIST)((LPBYTE)pCI + pCI->dwOffset[dwIndex]);
|
|
|
|
if (bAnsi)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2021-07-11 00:48:15 +00:00
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_WIDE)
|
|
|
|
dwSize = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP);
|
|
|
|
else
|
|
|
|
dwSize = pCL->dwSize;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
else
|
2021-07-11 00:48:15 +00:00
|
|
|
{
|
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_WIDE)
|
|
|
|
dwSize = pCL->dwSize;
|
|
|
|
else
|
|
|
|
dwSize = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP);
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
if (dwBufLen != 0 && dwSize != 0)
|
|
|
|
{
|
|
|
|
if (lpCandList == NULL || dwBufLen < dwSize)
|
|
|
|
goto Quit;
|
|
|
|
|
|
|
|
/* store */
|
|
|
|
if (bAnsi)
|
|
|
|
{
|
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_WIDE)
|
|
|
|
CandidateListAnsiToWide(pCL, lpCandList, dwSize, CP_ACP);
|
|
|
|
else
|
|
|
|
RtlCopyMemory(lpCandList, pCL, dwSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_WIDE)
|
|
|
|
RtlCopyMemory(lpCandList, pCL, dwSize);
|
|
|
|
else
|
|
|
|
CandidateListWideToAnsi(pCL, lpCandList, dwSize, CP_ACP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = dwSize;
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
ImmUnlockIMCC(pIC->hCandInfo);
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
2010-03-07 11:27:14 +00:00
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2021-07-13 11:17:17 +00:00
|
|
|
DWORD APIENTRY ImmGetCandidateListCountAW(HIMC hIMC, LPDWORD lpdwListCount, BOOL bAnsi)
|
|
|
|
{
|
|
|
|
DWORD ret = 0, cbGot, dwIndex;
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
const CANDIDATEINFO *pCI;
|
|
|
|
const BYTE *pb;
|
|
|
|
const CANDIDATELIST *pCL;
|
|
|
|
const DWORD *pdwOffsets;
|
|
|
|
|
|
|
|
if (lpdwListCount == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
*lpdwListCount = 0;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (pClientImc == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (pIC == NULL)
|
|
|
|
{
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pCI = ImmLockIMCC(pIC->hCandInfo);
|
|
|
|
if (pCI == NULL)
|
|
|
|
{
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pCI->dwSize < sizeof(CANDIDATEINFO))
|
|
|
|
goto Quit;
|
|
|
|
|
|
|
|
*lpdwListCount = pCI->dwCount; /* the number of candidate lists */
|
|
|
|
|
|
|
|
/* calculate total size of candidate lists */
|
|
|
|
if (bAnsi)
|
|
|
|
{
|
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_WIDE)
|
|
|
|
{
|
|
|
|
ret = ROUNDUP4(pCI->dwPrivateSize);
|
|
|
|
pdwOffsets = pCI->dwOffset;
|
|
|
|
for (dwIndex = 0; dwIndex < pCI->dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
pb = (const BYTE *)pCI + pdwOffsets[dwIndex];
|
|
|
|
pCL = (const CANDIDATELIST *)pb;
|
|
|
|
cbGot = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP);
|
|
|
|
ret += cbGot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = pCI->dwSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_WIDE)
|
|
|
|
{
|
|
|
|
ret = pCI->dwSize;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = ROUNDUP4(pCI->dwPrivateSize);
|
|
|
|
pdwOffsets = pCI->dwOffset;
|
|
|
|
for (dwIndex = 0; dwIndex < pCI->dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
pb = (const BYTE *)pCI + pdwOffsets[dwIndex];
|
|
|
|
pCL = (const CANDIDATELIST *)pb;
|
|
|
|
cbGot = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP);
|
|
|
|
ret += cbGot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
ImmUnlockIMCC(pIC->hCandInfo);
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListA(
|
|
|
|
HIMC hIMC, DWORD dwIndex,
|
|
|
|
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, TRUE);
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListCountA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListCountA(
|
|
|
|
HIMC hIMC, LPDWORD lpdwListCount)
|
|
|
|
{
|
2021-07-13 11:17:17 +00:00
|
|
|
return ImmGetCandidateListCountAW(hIMC, lpdwListCount, TRUE);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListCountW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListCountW(
|
|
|
|
HIMC hIMC, LPDWORD lpdwListCount)
|
|
|
|
{
|
2021-07-13 11:17:17 +00:00
|
|
|
return ImmGetCandidateListCountAW(hIMC, lpdwListCount, FALSE);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListW(
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC hIMC, DWORD dwIndex,
|
2005-12-12 20:59:55 +00:00
|
|
|
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
|
|
|
|
{
|
2021-07-11 00:48:15 +00:00
|
|
|
return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, FALSE);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCandidateWindow(
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2021-07-15 18:04:00 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
LPCANDIDATEFORM pCF;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-15 18:04:00 +00:00
|
|
|
TRACE("ImmGetCandidateWindow(%p, %lu, %p)\n", hIMC, dwIndex, lpCandidate);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-15 18:04:00 +00:00
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (pIC == NULL)
|
2014-09-28 18:27:58 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2021-07-15 18:04:00 +00:00
|
|
|
pCF = &pIC->cfCandForm[dwIndex];
|
|
|
|
if (pCF->dwIndex != IMM_INVALID_CANDFORM)
|
|
|
|
{
|
|
|
|
*lpCandidate = *pCF;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-15 18:04:00 +00:00
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
static VOID APIENTRY LogFontAnsiToWide(const LOGFONTA *plfA, LPLOGFONTW plfW)
|
|
|
|
{
|
|
|
|
size_t cch;
|
|
|
|
RtlCopyMemory(plfW, plfA, offsetof(LOGFONTA, lfFaceName));
|
|
|
|
StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cch);
|
|
|
|
cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, (INT)cch,
|
|
|
|
plfW->lfFaceName, _countof(plfW->lfFaceName));
|
|
|
|
if (cch > _countof(plfW->lfFaceName) - 1)
|
|
|
|
cch = _countof(plfW->lfFaceName) - 1;
|
|
|
|
plfW->lfFaceName[cch] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VOID APIENTRY LogFontWideToAnsi(const LOGFONTW *plfW, LPLOGFONTA plfA)
|
|
|
|
{
|
|
|
|
size_t cch;
|
|
|
|
RtlCopyMemory(plfA, plfW, offsetof(LOGFONTW, lfFaceName));
|
|
|
|
StringCchLengthW(plfW->lfFaceName, _countof(plfW->lfFaceName), &cch);
|
|
|
|
cch = WideCharToMultiByte(CP_ACP, 0, plfW->lfFaceName, (INT)cch,
|
|
|
|
plfA->lfFaceName, _countof(plfA->lfFaceName), NULL, NULL);
|
|
|
|
if (cch > _countof(plfA->lfFaceName) - 1)
|
|
|
|
cch = _countof(plfA->lfFaceName) - 1;
|
|
|
|
plfA->lfFaceName[cch] = 0;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionFontA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
|
|
|
|
{
|
2021-07-13 11:51:28 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
BOOL ret = FALSE, bWide;
|
|
|
|
LPINPUTCONTEXT pIC;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
TRACE("ImmGetCompositionFontA(%p, %p)\n", hIMC, lplf);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (pClientImc == NULL)
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
|
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (pIC == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (pIC->fdwInit & INIT_LOGFONT)
|
|
|
|
{
|
|
|
|
if (bWide)
|
|
|
|
LogFontWideToAnsi(&pIC->lfFont.W, lplf);
|
|
|
|
else
|
|
|
|
*lplf = pIC->lfFont.A;
|
|
|
|
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionFontW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
|
|
|
|
{
|
2021-07-13 11:51:28 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
BOOL bWide;
|
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
BOOL ret = FALSE;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
TRACE("ImmGetCompositionFontW(%p, %p)\n", hIMC, lplf);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (pClientImc == NULL)
|
2008-04-04 13:20:27 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-13 11:51:28 +00:00
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (pIC == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (pIC->fdwInit & INIT_LOGFONT)
|
|
|
|
{
|
|
|
|
if (bWide)
|
|
|
|
*lplf = pIC->lfFont.W;
|
|
|
|
else
|
|
|
|
LogFontAnsiToWide(&pIC->lfFont.A, lplf);
|
|
|
|
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
/* Helpers for the GetCompositionString functions */
|
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
/* Source encoding is defined by context, source length is always given in respective characters. Destination buffer
|
|
|
|
length is always in bytes. */
|
|
|
|
static INT CopyCompStringIMEtoClient(const InputContextData *data, const void *src, INT src_len, void *dst,
|
|
|
|
INT dst_len, BOOL unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
int char_size = unicode ? sizeof(WCHAR) : sizeof(char);
|
|
|
|
INT ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
if (is_himc_ime_unicode(data) ^ unicode)
|
|
|
|
{
|
|
|
|
if (unicode)
|
|
|
|
ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len / sizeof(WCHAR));
|
|
|
|
else
|
|
|
|
ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL);
|
|
|
|
ret *= char_size;
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else
|
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
if (dst_len)
|
|
|
|
{
|
|
|
|
ret = min(src_len * char_size, dst_len);
|
|
|
|
memcpy(dst, src, ret);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = src_len * char_size;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
return ret;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
/* Composition string encoding is defined by context, returned attributes correspond to string, converted according to
|
|
|
|
passed mode. String length is in characters, attributes are in byte arrays. */
|
|
|
|
static INT CopyCompAttrIMEtoClient(const InputContextData *data, const BYTE *src, INT src_len, const void *comp_string,
|
|
|
|
INT str_len, BYTE *dst, INT dst_len, BOOL unicode)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
union
|
|
|
|
{
|
|
|
|
const void *str;
|
|
|
|
const WCHAR *strW;
|
|
|
|
const char *strA;
|
|
|
|
} string;
|
2010-03-07 11:27:14 +00:00
|
|
|
INT rc;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
string.str = comp_string;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, string.strW, str_len, NULL, 0, NULL, NULL);
|
|
|
|
if (dst_len)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
|
|
|
int i, j = 0, k = 0;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
if (rc < dst_len)
|
|
|
|
dst_len = rc;
|
|
|
|
for (i = 0; i < str_len; ++i)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
len = WideCharToMultiByte(CP_ACP, 0, string.strW + i, 1, NULL, 0, NULL, NULL);
|
2010-03-07 11:27:14 +00:00
|
|
|
for (; len > 0; --len)
|
|
|
|
{
|
|
|
|
dst[j++] = src[k];
|
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
if (j >= dst_len)
|
2010-03-07 11:27:14 +00:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
++k;
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
rc = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
rc = MultiByteToWideChar(CP_ACP, 0, string.strA, str_len, NULL, 0);
|
|
|
|
if (dst_len)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
|
|
|
int i, j = 0;
|
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
if (rc < dst_len)
|
|
|
|
dst_len = rc;
|
|
|
|
for (i = 0; i < str_len; ++i)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
if (IsDBCSLeadByte(string.strA[i]))
|
2010-03-07 11:27:14 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
dst[j++] = src[i];
|
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
if (j >= dst_len)
|
2010-03-07 11:27:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
rc = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2019-11-02 17:34:15 +00:00
|
|
|
memcpy(dst, src, min(src_len, dst_len));
|
|
|
|
rc = src_len;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
|
|
|
}
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2011-12-15 00:40:35 +00:00
|
|
|
static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource,
|
2010-03-07 11:27:14 +00:00
|
|
|
LPBYTE target, INT tlen, BOOL unicode )
|
|
|
|
{
|
|
|
|
INT rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
if (tlen)
|
|
|
|
{
|
|
|
|
int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
if (tlen)
|
|
|
|
{
|
|
|
|
int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rc = slen;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
memcpy( target, source, min(slen,tlen));
|
|
|
|
rc = slen;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2007-03-14 14:34:47 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
2007-09-14 08:03:04 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
2007-09-14 08:03:04 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0);
|
2007-03-14 14:34:47 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
else
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = offset;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf,
|
|
|
|
DWORD dwBufLen, BOOL unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2006-04-16 17:04:45 +00:00
|
|
|
LONG rc = 0;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2007-09-14 08:03:04 +00:00
|
|
|
LPCOMPOSITIONSTRING compstr;
|
|
|
|
LPBYTE compdata;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
if (!data->IMC.hCompStr)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
compdata = ImmLockIMCC(data->IMC.hCompStr);
|
|
|
|
compstr = (LPCOMPOSITIONSTRING)compdata;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
switch (dwIndex)
|
|
|
|
{
|
|
|
|
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,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwCompStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_RESULTCLAUSE:
|
|
|
|
TRACE("GCS_RESULTCLAUSE\n");
|
|
|
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwResultStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
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,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwResultStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
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,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwCompStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_CURSORPOS:
|
|
|
|
TRACE("GCS_CURSORPOS\n");
|
|
|
|
rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_DELTASTART:
|
2007-09-14 08:03:04 +00:00
|
|
|
TRACE("GCS_DELTASTART\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode);
|
|
|
|
break;
|
|
|
|
default:
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("Unhandled index 0x%x\n",dwIndex);
|
2010-03-07 11:27:14 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
ImmUnlockIMCC(data->IMC.hCompStr);
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionStringA (IMM32.@)
|
|
|
|
*/
|
|
|
|
LONG WINAPI ImmGetCompositionStringA(
|
|
|
|
HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionStringW (IMM32.@)
|
|
|
|
*/
|
|
|
|
LONG WINAPI ImmGetCompositionStringW(
|
|
|
|
HIMC hIMC, DWORD dwIndex,
|
|
|
|
LPVOID lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
|
|
|
|
{
|
2021-07-13 12:13:39 +00:00
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
BOOL ret = FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-07-13 12:13:39 +00:00
|
|
|
TRACE("ImmGetCompositionWindow(%p, %p)\n", hIMC, lpCompForm);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-07-13 12:13:39 +00:00
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (!pIC)
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2021-07-13 12:13:39 +00:00
|
|
|
if (pIC->fdwInit & INIT_COMPFORM)
|
|
|
|
{
|
|
|
|
*lpCompForm = pIC->cfCompForm;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetContext (IMM32.@)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmGetContext(HWND hWnd)
|
|
|
|
{
|
2011-12-15 00:40:35 +00:00
|
|
|
HIMC rc;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2006-04-16 17:04:45 +00:00
|
|
|
TRACE("%p\n", hWnd);
|
2011-12-15 00:40:35 +00:00
|
|
|
|
|
|
|
if (!IsWindow(hWnd))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = GetPropW(hWnd,szwWineIMCProperty);
|
2008-04-04 13:20:27 +00:00
|
|
|
if (rc == (HIMC)-1)
|
|
|
|
rc = NULL;
|
|
|
|
else if (rc == NULL)
|
2017-12-08 03:14:21 +00:00
|
|
|
rc = get_default_context( hWnd );
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
if (rc)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data = rc;
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.hWnd = hWnd;
|
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
TRACE("returning %p\n", rc);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
return rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetConversionListA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetConversionListA(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
LPCSTR pSrc, LPCANDIDATELIST lpDst,
|
|
|
|
DWORD dwBufLen, UINT uFlag)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetConversionListW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetConversionListW(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
LPCWSTR pSrc, LPCANDIDATELIST lpDst,
|
|
|
|
DWORD dwBufLen, UINT uFlag)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetConversionStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetConversionStatus(
|
|
|
|
HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
|
|
|
|
{
|
2021-07-05 12:20:20 +00:00
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
|
|
|
|
TRACE("ImmGetConversionStatus(%p %p %p)\n", hIMC, lpfdwConversion, lpfdwSentence);
|
|
|
|
|
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (!pIC)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (lpfdwConversion)
|
|
|
|
*lpfdwConversion = pIC->fdwConversion;
|
|
|
|
if (lpfdwSentence)
|
|
|
|
*lpfdwSentence = pIC->fdwSentence;
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static BOOL needs_ime_window(HWND hwnd)
|
|
|
|
{
|
|
|
|
WCHAR classW[8];
|
|
|
|
|
2019-11-02 17:34:15 +00:00
|
|
|
if (GetClassNameW(hwnd, classW, ARRAY_SIZE(classW)) && !lstrcmpW(classW, szwIME))
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
|
|
|
if (GetClassLongPtrW(hwnd, GCL_STYLE) & CS_IME) return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* __wine_register_window (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI __wine_register_window(HWND hwnd)
|
|
|
|
{
|
|
|
|
HWND new = NULL;
|
|
|
|
IMMThreadData *thread_data;
|
|
|
|
TRACE("(%p)\n", hwnd);
|
|
|
|
|
|
|
|
if (!needs_ime_window(hwnd))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
thread_data = IMM_GetThreadData(hwnd, 0);
|
|
|
|
if (!thread_data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (thread_data->disableIME || disable_ime)
|
|
|
|
{
|
|
|
|
TRACE("IME for this thread is disabled\n");
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
thread_data->windowRefs++;
|
|
|
|
TRACE("windowRefs=%u, hwndDefault=%p\n",
|
|
|
|
thread_data->windowRefs, thread_data->hwndDefault);
|
|
|
|
|
|
|
|
/* Create default IME window */
|
|
|
|
if (thread_data->windowRefs == 1)
|
|
|
|
{
|
|
|
|
/* Do not create the window inside of a critical section */
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
new = CreateWindowExW( 0, szwIME, szwDefaultIME,
|
|
|
|
WS_POPUP | WS_DISABLED | WS_CLIPSIBLINGS,
|
|
|
|
0, 0, 1, 1, 0, 0, 0, 0);
|
|
|
|
/* thread_data is in the current thread so we can assume it's still valid */
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
/* See if anyone beat us */
|
|
|
|
if (thread_data->hwndDefault == NULL)
|
|
|
|
{
|
|
|
|
thread_data->hwndDefault = new;
|
|
|
|
new = NULL;
|
|
|
|
TRACE("Default is %p\n", thread_data->hwndDefault);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
/* Clean up an unused new window outside of the critical section */
|
|
|
|
if (new != NULL)
|
|
|
|
DestroyWindow(new);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* __wine_unregister_window (IMM32.@)
|
|
|
|
*/
|
|
|
|
void WINAPI __wine_unregister_window(HWND hwnd)
|
|
|
|
{
|
|
|
|
HWND to_destroy = 0;
|
|
|
|
IMMThreadData *thread_data;
|
|
|
|
TRACE("(%p)\n", hwnd);
|
|
|
|
|
|
|
|
thread_data = IMM_GetThreadData(hwnd, 0);
|
|
|
|
if (!thread_data) return;
|
|
|
|
|
|
|
|
thread_data->windowRefs--;
|
|
|
|
TRACE("windowRefs=%u, hwndDefault=%p\n",
|
|
|
|
thread_data->windowRefs, thread_data->hwndDefault);
|
|
|
|
|
|
|
|
/* Destroy default IME window */
|
|
|
|
if (thread_data->windowRefs == 0 && thread_data->hwndDefault)
|
|
|
|
{
|
|
|
|
to_destroy = thread_data->hwndDefault;
|
|
|
|
thread_data->hwndDefault = NULL;
|
|
|
|
}
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
if (to_destroy) DestroyWindow( to_destroy );
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetDefaultIMEWnd (IMM32.@)
|
|
|
|
*/
|
|
|
|
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
|
|
|
|
{
|
2021-07-15 12:59:53 +00:00
|
|
|
if (!(g_dwImm32Flags & IMM32_FLAG_UNKNOWN))
|
2017-12-08 03:14:21 +00:00
|
|
|
return NULL;
|
2021-07-15 12:59:53 +00:00
|
|
|
|
|
|
|
if (hWnd == NULL)
|
|
|
|
return (HWND)Imm32GetThreadState(THREADSTATE_ACTIVEWINDOW);
|
|
|
|
|
|
|
|
return (HWND)Imm32QueryWindow(hWnd, QUERY_WINDOW_DEFAULT_IME);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* CtfImmIsCiceroEnabled (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI CtfImmIsCiceroEnabled(VOID)
|
|
|
|
{
|
|
|
|
return !!(g_dwImm32Flags & IMM32_FLAG_CICERO_ENABLED);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetDescriptionA (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetDescriptionA(
|
|
|
|
HKL hKL, LPSTR lpszDescription, UINT uBufLen)
|
|
|
|
{
|
2021-07-03 23:18:15 +00:00
|
|
|
IMEINFOEX info;
|
|
|
|
size_t cch;
|
|
|
|
|
|
|
|
TRACE("ImmGetDescriptionA(%p,%p,%d)\n", hKL, lpszDescription, uBufLen);
|
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL))
|
2021-07-03 23:18:15 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch);
|
|
|
|
cch = WideCharToMultiByte(CP_ACP, 0, info.wszImeDescription, (INT)cch,
|
|
|
|
lpszDescription, uBufLen, NULL, NULL);
|
|
|
|
if (uBufLen)
|
|
|
|
lpszDescription[cch] = 0;
|
|
|
|
return cch;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetDescriptionW (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
|
|
|
|
{
|
2021-07-03 23:18:15 +00:00
|
|
|
IMEINFOEX info;
|
|
|
|
size_t cch;
|
|
|
|
|
|
|
|
TRACE("ImmGetDescriptionW(%p, %p, %d)\n", hKL, lpszDescription, uBufLen);
|
|
|
|
|
2021-07-11 00:48:15 +00:00
|
|
|
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL))
|
2021-07-03 23:18:15 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (uBufLen != 0)
|
|
|
|
StringCchCopyW(lpszDescription, uBufLen, info.wszImeDescription);
|
|
|
|
|
|
|
|
StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch);
|
|
|
|
return (UINT)cch;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetGuideLineA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetGuideLineA(
|
|
|
|
HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("(%p, %d, %s, %d): stub\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
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)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("(%p, %d, %s, %d): stub\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
|
|
|
|
);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMEFileNameA (IMM32.@)
|
|
|
|
*/
|
2008-04-04 13:20:27 +00:00
|
|
|
UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2021-07-15 14:01:50 +00:00
|
|
|
BOOL bDefUsed;
|
|
|
|
IMEINFOEX info;
|
|
|
|
size_t cch;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
TRACE("ImmGetIMEFileNameA(%p, %p, %u)\n", hKL, lpszFileName, uBufLen);
|
|
|
|
|
|
|
|
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL))
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
2021-07-15 14:01:50 +00:00
|
|
|
if (uBufLen > 0)
|
|
|
|
lpszFileName[0] = 0;
|
|
|
|
return 0;
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
StringCchLengthW(info.wszImeFile, _countof(info.wszImeFile), &cch);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
cch = WideCharToMultiByte(CP_ACP, 0, info.wszImeFile, (INT)cch,
|
|
|
|
lpszFileName, uBufLen, NULL, &bDefUsed);
|
|
|
|
if (uBufLen == 0)
|
|
|
|
return (UINT)cch;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
if (cch > uBufLen - 1)
|
|
|
|
cch = uBufLen - 1;
|
|
|
|
|
|
|
|
lpszFileName[cch] = 0;
|
|
|
|
return (UINT)cch;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMEFileNameW (IMM32.@)
|
|
|
|
*/
|
2008-04-04 13:20:27 +00:00
|
|
|
UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2021-07-15 14:01:50 +00:00
|
|
|
IMEINFOEX info;
|
|
|
|
size_t cch;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
TRACE("ImmGetIMEFileNameW(%p, %p, %u)\n", hKL, lpszFileName, uBufLen);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL))
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
2021-07-15 14:01:50 +00:00
|
|
|
if (uBufLen > 0)
|
|
|
|
lpszFileName[0] = 0;
|
2008-04-04 13:20:27 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
StringCchLengthW(info.wszImeFile, _countof(info.wszImeFile), &cch);
|
|
|
|
if (uBufLen == 0)
|
|
|
|
return (UINT)cch;
|
|
|
|
|
|
|
|
StringCchCopyNW(lpszFileName, uBufLen, info.wszImeFile, cch);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
if (cch > uBufLen - 1)
|
|
|
|
cch = uBufLen - 1;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-07-15 14:01:50 +00:00
|
|
|
lpszFileName[cch] = 0;
|
|
|
|
return (UINT)cch;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetOpenStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
|
|
|
|
{
|
2021-07-08 05:24:27 +00:00
|
|
|
BOOL ret;
|
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
|
|
|
|
TRACE("ImmGetOpenStatus(%p)\n", hIMC);
|
|
|
|
|
|
|
|
if (!hIMC)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (!pIC)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ret = pIC->fOpen;
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetProperty (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
|
|
|
|
{
|
|
|
|
DWORD rc = 0;
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *kbd;
|
|
|
|
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("(%p, %d)\n", hKL, fdwIndex);
|
2010-03-07 11:27:14 +00:00
|
|
|
kbd = IMM_GetImmHkl(hKL);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (kbd && kbd->hIME)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetRegisterWordStyleA (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetRegisterWordStyleA(
|
|
|
|
HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetRegisterWordStyleW (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetRegisterWordStyleW(
|
|
|
|
HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetStatusWindowPos (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
|
|
|
|
{
|
2021-07-15 22:30:55 +00:00
|
|
|
LPINPUTCONTEXT pIC;
|
|
|
|
BOOL ret;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-15 22:30:55 +00:00
|
|
|
TRACE("ImmGetStatusWindowPos(%p, %p)\n", hIMC, lpptPos);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-15 22:30:55 +00:00
|
|
|
pIC = ImmLockIMC(hIMC);
|
|
|
|
if (pIC == NULL)
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2021-07-15 22:30:55 +00:00
|
|
|
ret = !!(pIC->fdwInit & INIT_STATUSWNDPOS);
|
|
|
|
if (ret)
|
|
|
|
*lpptPos = pIC->ptStatusWndPos;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2021-07-15 22:30:55 +00:00
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetVirtualKey (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetVirtualKey(HWND hWnd)
|
|
|
|
{
|
|
|
|
OSVERSIONINFOA version;
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data = ImmGetContext( hWnd );
|
|
|
|
TRACE("%p\n", hWnd);
|
|
|
|
|
|
|
|
if ( data )
|
|
|
|
return data->lastVK;
|
|
|
|
|
2011-12-15 00:40:35 +00:00
|
|
|
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
2005-12-12 20:59:55 +00:00
|
|
|
GetVersionExA( &version );
|
|
|
|
switch(version.dwPlatformId)
|
|
|
|
{
|
|
|
|
case VER_PLATFORM_WIN32_WINDOWS:
|
|
|
|
return VK_PROCESSKEY;
|
|
|
|
case VER_PLATFORM_WIN32_NT:
|
|
|
|
return 0;
|
|
|
|
default:
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("%d not supported\n",version.dwPlatformId);
|
2005-12-12 20:59:55 +00:00
|
|
|
return VK_PROCESSKEY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmInstallIMEA (IMM32.@)
|
|
|
|
*/
|
|
|
|
HKL WINAPI ImmInstallIMEA(
|
|
|
|
LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmInstallIMEW (IMM32.@)
|
|
|
|
*/
|
|
|
|
HKL WINAPI ImmInstallIMEW(
|
|
|
|
LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
INT lcid = GetUserDefaultLCID();
|
|
|
|
INT count;
|
|
|
|
HKL hkl;
|
|
|
|
DWORD rc;
|
|
|
|
HKEY hkey;
|
2018-10-01 11:53:21 +00:00
|
|
|
WCHAR regKey[ARRAY_SIZE(szImeRegFmt)+8];
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (const BYTE*)lpszIMEFileName,
|
2010-03-07 11:27:14 +00:00
|
|
|
(lstrlenW(lpszIMEFileName) + 1) * sizeof(WCHAR));
|
|
|
|
if (rc == ERROR_SUCCESS)
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (const BYTE*)lpszLayoutText,
|
2010-03-07 11:27:14 +00:00
|
|
|
(lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR));
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
return hkl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WARN("Unable to set IME registry values\n");
|
|
|
|
return 0;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmIsIME (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmIsIME(HKL hKL)
|
|
|
|
{
|
2021-07-08 05:23:25 +00:00
|
|
|
IMEINFOEX info;
|
|
|
|
TRACE("ImmIsIME(%p)\n", hKL);
|
|
|
|
return !!ImmGetImeInfoEx(&info, ImeInfoExImeWindow, &hKL);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmIsUIMessageA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmIsUIMessageA(
|
|
|
|
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2007-09-14 08:03:04 +00:00
|
|
|
TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
|
2005-12-12 20:59:55 +00:00
|
|
|
if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
|
2011-12-15 00:40:35 +00:00
|
|
|
(msg == WM_IME_SETCONTEXT) ||
|
|
|
|
(msg == WM_IME_NOTIFY) ||
|
|
|
|
(msg == WM_IME_COMPOSITIONFULL) ||
|
|
|
|
(msg == WM_IME_SELECT) ||
|
2017-12-08 03:14:21 +00:00
|
|
|
(msg == 0x287 /* FIXME: WM_IME_SYSTEM */))
|
2011-12-15 00:40:35 +00:00
|
|
|
{
|
|
|
|
if (hWndIME)
|
|
|
|
SendMessageA(hWndIME, msg, wParam, lParam);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmIsUIMessageW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmIsUIMessageW(
|
|
|
|
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2011-12-15 00:40:35 +00:00
|
|
|
TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
|
2005-12-12 20:59:55 +00:00
|
|
|
if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
|
2011-12-15 00:40:35 +00:00
|
|
|
(msg == WM_IME_SETCONTEXT) ||
|
|
|
|
(msg == WM_IME_NOTIFY) ||
|
|
|
|
(msg == WM_IME_COMPOSITIONFULL) ||
|
|
|
|
(msg == WM_IME_SELECT) ||
|
2017-12-08 03:14:21 +00:00
|
|
|
(msg == 0x287 /* FIXME: WM_IME_SYSTEM */))
|
2011-12-15 00:40:35 +00:00
|
|
|
{
|
|
|
|
if (hWndIME)
|
|
|
|
SendMessageW(hWndIME, msg, wParam, lParam);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
return TRUE;
|
2011-12-15 00:40:35 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmNotifyIME (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmNotifyIME(
|
|
|
|
HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2006-04-16 17:04:45 +00:00
|
|
|
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("(%p, %d, %d, %d)\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwAction, dwIndex, dwValue);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (hIMC == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_SUCCESS);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || ! data->immKbd->pNotifyIME)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRegisterWordA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmRegisterWordA(
|
|
|
|
HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRegisterWordW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmRegisterWordW(
|
|
|
|
HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
2008-05-08 16:03:10 +00:00
|
|
|
* ImmReleaseContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
static BOOL shown = FALSE;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
if (!shown) {
|
|
|
|
FIXME("(%p, %p): stub\n", hWnd, hIMC);
|
2014-09-28 18:27:58 +00:00
|
|
|
shown = TRUE;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRequestMessageA(IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (data) return SendMessageA(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRequestMessageW(IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2008-05-06 09:16:21 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (data) return SendMessageW(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCandidateWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCandidateWindow(
|
|
|
|
HIMC hIMC, LPCANDIDATEFORM lpCandidate)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpCandidate);
|
|
|
|
|
|
|
|
if (!data || !lpCandidate)
|
|
|
|
return FALSE;
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
TRACE("\t%x, %x, %s, %s\n",
|
|
|
|
lpCandidate->dwIndex, lpCandidate->dwStyle,
|
|
|
|
wine_dbgstr_point(&lpCandidate->ptCurrentPos),
|
|
|
|
wine_dbgstr_rect(&lpCandidate->rcArea));
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2018-10-01 11:53:21 +00:00
|
|
|
if (lpCandidate->dwIndex >= ARRAY_SIZE(data->IMC.cfCandForm))
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
|
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
|
|
|
|
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionFontA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
TRACE("(%p, %p)\n", hIMC, lplf);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lplf)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
|
2005-12-12 20:59:55 +00:00
|
|
|
LF_FACESIZE);
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
|
2008-04-04 13:20:27 +00:00
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionFontW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
TRACE("(%p, %p)\n", hIMC, lplf);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lplf)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.lfFont.W = *lplf;
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
|
2008-04-04 13:20:27 +00:00
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
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;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %d, %p, %d, %p, %d):\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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);
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
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)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
DWORD comp_len;
|
|
|
|
DWORD read_len;
|
|
|
|
CHAR *CompBuffer = NULL;
|
|
|
|
CHAR *ReadBuffer = NULL;
|
|
|
|
BOOL rc;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %d, %p, %d, %p, %d):\n",
|
|
|
|
hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!(dwIndex == SCS_SETSTR ||
|
|
|
|
dwIndex == SCS_CHANGEATTR ||
|
|
|
|
dwIndex == SCS_CHANGECLAUSE ||
|
|
|
|
dwIndex == SCS_SETRECONVERTSTRING ||
|
|
|
|
dwIndex == SCS_QUERYRECONVERTSTRING))
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data))
|
|
|
|
return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
|
|
|
|
dwCompLen, lpRead, dwReadLen);
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
|
|
|
|
NULL);
|
|
|
|
if (comp_len)
|
2008-05-06 09:16:21 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
|
|
|
|
ReadBuffer, read_len);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, CompBuffer);
|
|
|
|
HeapFree(GetProcessHeap(), 0, ReadBuffer);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionWindow(
|
|
|
|
HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
|
|
|
|
{
|
|
|
|
BOOL reshow = FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpCompForm);
|
2017-12-08 03:14:21 +00:00
|
|
|
if (lpCompForm)
|
|
|
|
TRACE("\t%x, %s, %s\n", lpCompForm->dwStyle,
|
|
|
|
wine_dbgstr_point(&lpCompForm->ptCurrentPos),
|
|
|
|
wine_dbgstr_rect(&lpCompForm->rcArea));
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (!data)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.cfCompForm = *lpCompForm;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2013-02-03 20:58:12 +00:00
|
|
|
if (IsWindowVisible(data->immKbd->UIWnd))
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
|
|
|
reshow = TRUE;
|
2013-02-03 20:58:12 +00:00
|
|
|
ShowWindow(data->immKbd->UIWnd,SW_HIDE);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2006-04-16 17:04:45 +00:00
|
|
|
/* FIXME: this is a partial stub */
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (reshow)
|
2013-02-03 20:58:12 +00:00
|
|
|
ShowWindow(data->immKbd->UIWnd,SW_SHOWNOACTIVATE);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetConversionStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetConversionStatus(
|
|
|
|
HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
DWORD oldConversion, oldSentence;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2008-05-06 09:16:21 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
|
|
|
|
|
|
|
|
if (!data)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetOpenStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2006-04-16 17:04:45 +00:00
|
|
|
|
|
|
|
TRACE("%p %d\n", hIMC, fOpen);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-05-08 16:03:10 +00:00
|
|
|
if (!data)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2008-05-08 16:03:10 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2013-02-03 20:58:12 +00:00
|
|
|
if (data->immKbd->UIWnd == NULL)
|
2008-05-06 09:16:21 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
/* create the ime window */
|
2013-02-03 20:58:12 +00:00
|
|
|
data->immKbd->UIWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
|
2010-03-07 11:27:14 +00:00
|
|
|
data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
|
|
|
|
0, data->immKbd->hIME, 0);
|
2013-02-03 20:58:12 +00:00
|
|
|
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2013-02-03 20:58:12 +00:00
|
|
|
else if (fOpen)
|
|
|
|
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!fOpen != !data->IMC.fOpen)
|
|
|
|
{
|
|
|
|
data->IMC.fOpen = fOpen;
|
|
|
|
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetStatusWindowPos (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpptPos);
|
2008-05-06 09:16:21 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lpptPos)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
TRACE("\t%s\n", wine_dbgstr_point(lpptPos));
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
data->IMC.ptStatusWndPos = *lpptPos;
|
|
|
|
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETSTATUSWINDOWPOS, 0);
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
2010-03-07 11:27:14 +00:00
|
|
|
* ImmCreateSoftKeyboard(IMM32.@)
|
2008-05-06 09:16:21 +00:00
|
|
|
*/
|
2010-03-07 11:27:14 +00:00
|
|
|
HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
|
2008-05-06 09:16:21 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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)
|
|
|
|
{
|
2020-08-09 13:42:17 +00:00
|
|
|
TRACE("(%p)\n", hSoftWnd);
|
|
|
|
return DestroyWindow(hSoftWnd);
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmShowSoftKeyboard(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
|
|
|
|
{
|
2020-08-09 13:42:17 +00:00
|
|
|
TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
|
|
|
|
if (hSoftWnd)
|
|
|
|
return ShowWindow(hSoftWnd, nCmdShow);
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSimulateHotKey (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
|
2005-12-12 20:59:55 +00:00
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnregisterWordA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnregisterWordA(
|
|
|
|
HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnregisterWordW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnregisterWordW(
|
|
|
|
HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2007-03-14 14:34:47 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetImeMenuItemsA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
|
|
|
LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
|
|
|
|
DWORD dwSize)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
|
|
|
|
lpImeParentMenu, lpImeMenu, dwSize);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2007-03-14 14:34:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetImeMenuItemsW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
|
|
|
LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
|
|
|
|
DWORD dwSize)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
|
|
|
|
lpImeParentMenu, lpImeMenu, dwSize);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
|
|
|
|
lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
|
|
|
|
-1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
|
|
|
|
}
|
|
|
|
if (lpImeMenu && rc)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(),0,lpImeMenuA);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2007-03-14 14:34:47 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmLockIMC(IMM32.@)
|
|
|
|
*/
|
|
|
|
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2007-09-14 08:03:04 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return NULL;
|
|
|
|
data->dwLock++;
|
|
|
|
return &data->IMC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnlockIMC(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
|
|
|
|
{
|
2021-07-13 11:17:17 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
2021-07-11 00:48:15 +00:00
|
|
|
HIMC hClientImc;
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2021-07-13 11:17:17 +00:00
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (pClientImc == NULL)
|
2014-09-28 18:27:58 +00:00
|
|
|
return FALSE;
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2021-07-13 11:17:17 +00:00
|
|
|
hClientImc = pClientImc->hImc;
|
2021-07-11 00:48:15 +00:00
|
|
|
if (hClientImc)
|
|
|
|
LocalUnlock(hClientImc);
|
|
|
|
|
2021-07-13 11:17:17 +00:00
|
|
|
InterlockedDecrement(&pClientImc->cLockObj);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
2013-12-01 15:57:34 +00:00
|
|
|
return TRUE;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMCLockCount(IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
|
|
|
|
{
|
2021-07-11 00:48:15 +00:00
|
|
|
DWORD ret;
|
|
|
|
HIMC hClientImc;
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (pClientImc == NULL)
|
2014-09-28 18:27:58 +00:00
|
|
|
return 0;
|
2021-07-11 00:48:15 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
hClientImc = pClientImc->hImc;
|
|
|
|
if (hClientImc)
|
|
|
|
ret = (LocalFlags(hClientImc) & LMEM_LOCKCOUNT);
|
|
|
|
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return ret;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmCreateIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMCC WINAPI ImmCreateIMCC(DWORD size)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
if (size < 4)
|
|
|
|
size = 4;
|
|
|
|
return LocalAlloc(LHND, size);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroyIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
if (block)
|
|
|
|
return LocalFree(block);
|
|
|
|
return NULL;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmLockIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
if (imcc)
|
|
|
|
return LocalLock(imcc);
|
|
|
|
return NULL;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnlockIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
if (imcc)
|
|
|
|
return LocalUnlock(imcc);
|
|
|
|
return FALSE;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMCCLockCount(IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
return LocalFlags(imcc) & LMEM_LOCKCOUNT;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmReSizeIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
if (!imcc)
|
|
|
|
return NULL;
|
|
|
|
return LocalReAlloc(imcc, size, LHND);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMCCSize(IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
|
|
|
|
{
|
2021-07-07 01:04:30 +00:00
|
|
|
if (imcc)
|
|
|
|
return LocalSize(imcc);
|
|
|
|
return 0;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGenerateMessage(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
|
|
|
|
if (data->IMC.dwNumMsgBuf > 0)
|
|
|
|
{
|
|
|
|
LPTRANSMSG lpTransMsg;
|
2017-12-08 03:14:21 +00:00
|
|
|
HIMCC hMsgBuf;
|
|
|
|
DWORD i, dwNumMsgBuf;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
/* We are going to detach our hMsgBuff so that if processing messages
|
|
|
|
generates new messages they go into a new buffer */
|
|
|
|
hMsgBuf = data->IMC.hMsgBuf;
|
|
|
|
dwNumMsgBuf = data->IMC.dwNumMsgBuf;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
data->IMC.hMsgBuf = ImmCreateIMCC(0);
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.dwNumMsgBuf = 0;
|
2017-12-08 03:14:21 +00:00
|
|
|
|
|
|
|
lpTransMsg = ImmLockIMCC(hMsgBuf);
|
|
|
|
for (i = 0; i < dwNumMsgBuf; i++)
|
|
|
|
ImmInternalSendIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
|
|
|
|
|
|
|
|
ImmUnlockIMCC(hMsgBuf);
|
|
|
|
ImmDestroyIMCC(hMsgBuf);
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmTranslateMessage(IMM32.@)
|
|
|
|
* ( Undocumented, call internally and from user32.dll )
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
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;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (imc)
|
|
|
|
data = imc;
|
|
|
|
else
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
GetKeyboardState(state);
|
|
|
|
scancode = lKeyData >> 0x10 & 0xff;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD));
|
|
|
|
((DWORD*)list)[0] = list_count;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST)
|
|
|
|
{
|
|
|
|
WCHAR chr;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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);
|
2008-05-06 09:16:21 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else
|
|
|
|
uVirtKey = data->lastVK;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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));
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
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);
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
HeapFree(GetProcessHeap(),0,list);
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
data->lastVK = VK_PROCESSKEY;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return (msg_count > 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmProcessKey(IMM32.@)
|
|
|
|
* ( Undocumented, called from user32.dll )
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data;
|
|
|
|
HIMC imc = ImmGetContext(hwnd);
|
|
|
|
BYTE state[256];
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (imc)
|
|
|
|
data = imc;
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
/* Make sure we are inputting to the correct keyboard */
|
|
|
|
if (data->immKbd->hkl != hKL)
|
|
|
|
{
|
|
|
|
ImmHkl *new_hkl = IMM_GetImmHkl(hKL);
|
|
|
|
if (new_hkl)
|
|
|
|
{
|
|
|
|
data->immKbd->pImeSelect(imc, FALSE);
|
|
|
|
data->immKbd->uSelected--;
|
|
|
|
data->immKbd = new_hkl;
|
|
|
|
data->immKbd->pImeSelect(imc, TRUE);
|
|
|
|
data->immKbd->uSelected++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
GetKeyboardState(state);
|
|
|
|
if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
|
2008-05-08 16:03:10 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
data->lastVK = vKey;
|
|
|
|
return TRUE;
|
2008-05-08 16:03:10 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
data->lastVK = VK_PROCESSKEY;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDisableTextFrameService(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDisableTextFrameService(DWORD idThread)
|
|
|
|
{
|
|
|
|
FIXME("Stub\n");
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2011-12-15 00:40:35 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumInputContext(IMM32.@)
|
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL WINAPI ImmEnumInputContext(DWORD idThread, IMCENUMPROC lpfn, LPARAM lParam)
|
|
|
|
{
|
|
|
|
FIXME("Stub\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-03-15 21:42:01 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetHotKey(IMM32.@)
|
|
|
|
*/
|
|
|
|
|
2020-08-09 13:41:11 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
ImmGetHotKey(IN DWORD dwHotKey,
|
|
|
|
OUT LPUINT lpuModifiers,
|
|
|
|
OUT LPUINT lpuVKey,
|
|
|
|
OUT LPHKL lphKL)
|
|
|
|
{
|
|
|
|
TRACE("%lx, %p, %p, %p\n", dwHotKey, lpuModifiers, lpuVKey, lphKL);
|
|
|
|
if (lpuModifiers && lpuVKey)
|
|
|
|
return NtUserGetImeHotKey(dwHotKey, lpuModifiers, lpuVKey, lphKL);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2018-03-15 11:31:05 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
2018-06-04 02:36:30 +00:00
|
|
|
* ImmDisableLegacyIME(IMM32.@)
|
2018-03-15 11:31:05 +00:00
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDisableLegacyIME(void)
|
|
|
|
{
|
|
|
|
FIXME("stub\n");
|
|
|
|
return TRUE;
|
|
|
|
}
|
2020-08-08 00:46:13 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetActiveContext(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetActiveContext(HWND hwnd, HIMC hIMC, BOOL fFlag)
|
|
|
|
{
|
2020-08-09 13:42:17 +00:00
|
|
|
FIXME("(%p, %p, %d): stub\n", hwnd, hIMC, fFlag);
|
2020-08-08 00:46:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetActiveContextConsoleIME(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
|
|
|
|
{
|
2020-08-09 13:42:17 +00:00
|
|
|
HIMC hIMC;
|
|
|
|
TRACE("(%p, %d)\n", hwnd, fFlag);
|
|
|
|
|
|
|
|
hIMC = ImmGetContext(hwnd);
|
2020-08-08 00:46:13 +00:00
|
|
|
if (hIMC)
|
|
|
|
return ImmSetActiveContext(hwnd, hIMC, fFlag);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-08-09 13:49:00 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRegisterClient(IMM32.@)
|
|
|
|
* ( Undocumented, called from user32.dll )
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmRegisterClient(PVOID ptr, /* FIXME: should point to SHAREDINFO structure */
|
|
|
|
HINSTANCE hMod)
|
|
|
|
{
|
|
|
|
FIXME("Stub\n");
|
|
|
|
return TRUE;
|
|
|
|
}
|
2020-08-11 21:03:29 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetImeInfoEx (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI
|
|
|
|
ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx,
|
|
|
|
IMEINFOEXCLASS SearchType,
|
|
|
|
PVOID pvSearchKey)
|
|
|
|
{
|
|
|
|
switch (SearchType)
|
|
|
|
{
|
|
|
|
case ImeInfoExKeyboardLayout:
|
|
|
|
pImeInfoEx->hkl = *(LPHKL)pvSearchKey;
|
|
|
|
if (!IS_IME_HKL(pImeInfoEx->hkl))
|
|
|
|
return FALSE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ImeInfoExImeFileName:
|
|
|
|
lstrcpynW(pImeInfoEx->wszImeFile, (LPWSTR)pvSearchKey,
|
|
|
|
ARRAY_SIZE(pImeInfoEx->wszImeFile));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return NtUserGetImeInfoEx(pImeInfoEx, SearchType);
|
|
|
|
}
|