Autosyncing with Wine HEAD

svn path=/trunk/; revision=32844
This commit is contained in:
The Wine Synchronizer 2008-04-04 13:20:27 +00:00
parent 9adffe12c6
commit 9374baba9d
3 changed files with 362 additions and 76 deletions

View file

@ -30,6 +30,8 @@
#include "imm.h"
#include "ddk/imm.h"
#include "winnls.h"
#include "winreg.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
@ -43,6 +45,35 @@ typedef struct tagIMCCInternal
DWORD dwSize;
} IMCCInternal;
#define MAKE_FUNCPTR(f) typeof(f) * p##f
typedef struct _tagImmHkl{
struct list entry;
HKL hkl;
HMODULE hIME;
IMEINFO imeInfo;
WCHAR imeClassName[17]; /* 16 character max */
ULONG uSelected;
/* Function Pointers */
MAKE_FUNCPTR(ImeInquire);
MAKE_FUNCPTR(ImeConfigure);
MAKE_FUNCPTR(ImeDestroy);
MAKE_FUNCPTR(ImeEscape);
MAKE_FUNCPTR(ImeSelect);
MAKE_FUNCPTR(ImeSetActiveContext);
MAKE_FUNCPTR(ImeToAsciiEx);
MAKE_FUNCPTR(NotifyIME);
MAKE_FUNCPTR(ImeRegisterWord);
MAKE_FUNCPTR(ImeUnregisterWord);
MAKE_FUNCPTR(ImeEnumRegisterWord);
MAKE_FUNCPTR(ImeSetCompositionString);
MAKE_FUNCPTR(ImeConversionList);
MAKE_FUNCPTR(ImeProcessKey);
MAKE_FUNCPTR(ImeGetRegisterWordStyle);
MAKE_FUNCPTR(ImeGetImeMenuItems);
} ImmHkl;
#undef MAKE_FUNCPTR
typedef struct tagInputContextData
{
BOOL bInternalState;
@ -52,14 +83,24 @@ typedef struct tagInputContextData
DWORD dwLock;
INPUTCONTEXT IMC;
ImmHkl *immKbd;
} InputContextData;
typedef struct _tagTRANSMSG {
UINT message;
WPARAM wParam;
LPARAM lParam;
} TRANSMSG, *LPTRANSMSG;
static InputContextData *root_context = NULL;
static HWND hwndDefault = NULL;
static HANDLE hImeInst;
static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
static ATOM atIMEClass = 0;
static struct list ImmHklList = LIST_INIT(ImmHklList);
/* MSIME messages */
static UINT WM_MSIME_SERVICE;
static UINT WM_MSIME_RECONVERTOPTIONS;
@ -69,16 +110,87 @@ static UINT WM_MSIME_RECONVERT;
static UINT WM_MSIME_QUERYPOSITION;
static UINT WM_MSIME_DOCUMENTFEED;
static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
/*
* prototypes
*/
static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable);
static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
static void ImmInternalPostIMEMessage(InputContextData*, UINT, WPARAM, LPARAM);
static void ImmInternalSetOpenStatus(BOOL fOpen);
static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
/* 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];
TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl);
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);
if (ptr->hIME)
{
LOAD_FUNCPTR(ImeInquire);
LOAD_FUNCPTR(ImeDestroy);
LOAD_FUNCPTR(ImeSelect);
if (!ptr->pImeInquire || !ptr->pImeDestroy || !ptr->pImeSelect)
{
FreeLibrary(ptr->hIME);
ptr->hIME = NULL;
}
else
{
ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL);
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);
}
}
list_add_head(&ImmHklList,&ptr->entry);
return ptr;
}
#undef LOAD_FUNCPTR
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);
}
HeapFree(GetProcessHeap(),0,ptr);
}
}
static VOID IMM_PostResult(InputContextData *data)
{
unsigned int i;
@ -93,7 +205,7 @@ static VOID IMM_PostResult(InputContextData *data)
ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
for (i = 0; i < compstr->dwResultStrLen; i++)
ImmInternalPostIMEMessage (WM_IME_CHAR, ResultStr[i], 1);
ImmInternalPostIMEMessage (root_context, WM_IME_CHAR, ResultStr[i], 1);
ImmUnlockIMCC(root_context->IMC.hCompStr);
@ -160,26 +272,27 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
hwndDefault = 0;
}
IMM_Unregister();
IMM_FreeAllImmHkl();
break;
}
return TRUE;
}
/* for posting messages as the IME */
static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND target = GetFocus();
if (!target)
PostMessageW(root_context->IMC.hWnd,msg,wParam,lParam);
PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
else
PostMessageW(target, msg, wParam, lParam);
}
static LRESULT ImmInternalSendIMENotify(WPARAM notify, LPARAM lParam)
static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
{
HWND target;
target = root_context->IMC.hWnd;
target = data->IMC.hWnd;
if (!target) target = GetFocus();
if (target)
@ -188,23 +301,33 @@ static LRESULT ImmInternalSendIMENotify(WPARAM notify, LPARAM lParam)
return 0;
}
static HIMCC ImmCreateBlankCompStr(void)
{
HIMCC rc;
LPCOMPOSITIONSTRING ptr;
rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
memset(ptr,0,sizeof(COMPOSITIONSTRING));
ptr->dwSize = sizeof(COMPOSITIONSTRING);
ImmUnlockIMCC(rc);
return rc;
}
static void ImmInternalSetOpenStatus(BOOL fOpen)
{
TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
root_context->IMC.fOpen = fOpen;
root_context->bInternalState = fOpen;
if (fOpen == FALSE)
{
if (root_context->IMC.fOpen && fOpen == FALSE)
{
ShowWindow(hwndDefault,SW_HIDE);
ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = NULL;
root_context->IMC.hCompStr = ImmCreateBlankCompStr();
}
else
ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
root_context->IMC.fOpen = fOpen;
root_context->bInternalState = fOpen;
ImmInternalSendIMENotify(root_context, IMN_SETOPENSTATUS, 0);
}
static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
@ -501,12 +624,10 @@ static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
*/
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
{
HIMC old = NULL;
InputContextData *data = (InputContextData*)hIMC;
WARN("(%p, %p): semi-stub\n", hWnd, hIMC);
if (!hIMC)
return NULL;
TRACE("(%p, %p):\n", hWnd, hIMC);
/*
* WINE SPECIFIC! MAY CONFLICT
@ -520,9 +641,30 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
/*
* If already associated just return
*/
if (data->IMC.hWnd == hWnd)
if (hIMC && data->IMC.hWnd == hWnd)
return hIMC;
if (hWnd)
{
old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
if (old == NULL)
old = (HIMC)root_context;
else if (old == (HIMC)-1)
old = NULL;
if (hIMC != (HIMC)root_context)
{
if (hIMC == NULL) /* Meaning disable imm for that window*/
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
else
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC);
}
}
if (!hIMC)
return old;
if (IsWindow(data->IMC.hWnd))
{
/*
@ -541,11 +683,7 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
}
/*
* TODO: We need to keep track of the old context associated
* with a window and return it for now we will return NULL;
*/
return NULL;
return old;
}
/***********************************************************************
@ -593,6 +731,34 @@ HIMC WINAPI ImmCreateContext(void)
new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
/* Load the IME */
new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
/*
* Once we depend on the IME for all the processing like we should
* these will become hard errors and result in creation failures
*/
if (!new_context->immKbd->hIME)
TRACE("IME dll could not be loaded\n");
/* hCompStr is never NULL */
new_context->IMC.hCompStr = ImmCreateBlankCompStr();
new_context->IMC.hMsgBuf = ImmCreateIMCC(1);
/* Initialize the IME Private */
new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
if (new_context->immKbd->hIME &&
!new_context->immKbd->pImeSelect(new_context, TRUE))
{
TRACE("Selection of IME failed\n");
ImmDestroyContext(new_context);
return 0;
}
new_context->immKbd->uSelected++;
TRACE("Created context 0x%x\n",(UINT)new_context);
return (HIMC)new_context;
}
@ -607,11 +773,15 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
if (hIMC)
{
ImmDestroyIMCC(root_context->IMC.hCompStr);
ImmDestroyIMCC(root_context->IMC.hCandInfo);
ImmDestroyIMCC(root_context->IMC.hGuideLine);
ImmDestroyIMCC(root_context->IMC.hPrivate);
ImmDestroyIMCC(root_context->IMC.hMsgBuf);
data->immKbd->uSelected --;
if (data->immKbd->hIME)
data->immKbd->pImeSelect(hIMC, FALSE);
ImmDestroyIMCC(data->IMC.hCompStr);
ImmDestroyIMCC(data->IMC.hCandInfo);
ImmDestroyIMCC(data->IMC.hGuideLine);
ImmDestroyIMCC(data->IMC.hPrivate);
ImmDestroyIMCC(data->IMC.hMsgBuf);
if (data->textfont)
{
@ -763,9 +933,19 @@ BOOL WINAPI ImmGetCandidateWindow(
*/
BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
{
FIXME("(%p, %p): stub\n", hIMC, lplf);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
LOGFONTW lfW;
BOOL rc;
TRACE("(%p, %p):\n", hIMC, lplf);
rc = ImmGetCompositionFontW(hIMC,&lfW);
if (rc)
{
memcpy(lplf,&lfW,sizeof(LOGFONTA));
WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
LF_FACESIZE, NULL, NULL);
}
return rc;
}
/***********************************************************************
@ -773,9 +953,16 @@ BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
*/
BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
{
FIXME("(%p, %p): stub\n", hIMC, lplf);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
InputContextData *data = (InputContextData*)hIMC;
TRACE("(%p, %p):\n", hIMC, lplf);
if (!data)
return FALSE;
*lplf = data->IMC.lfFont.W;
return TRUE;
}
/***********************************************************************
@ -995,7 +1182,7 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
if (!data)
return FALSE;
memcpy(lpCompForm,&(data->IMC.cfCompForm),sizeof(COMPOSITIONFORM));
*lpCompForm = data->IMC.cfCompForm;
return 1;
}
@ -1005,13 +1192,24 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
*/
HIMC WINAPI ImmGetContext(HWND hWnd)
{
HIMC rc = NULL;
TRACE("%p\n", hWnd);
if (!root_context)
return NULL;
rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
if (rc == (HIMC)-1)
rc = NULL;
else if (rc == NULL)
rc = (HIMC)root_context;
root_context->IMC.hWnd = hWnd;
return (HIMC)root_context;
if (rc)
{
InputContextData *data = (InputContextData*)rc;
data->IMC.hWnd = hWnd;
}
TRACE("returning %p\n", rc);
return rc;
}
/***********************************************************************
@ -1158,23 +1356,83 @@ DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBu
/***********************************************************************
* ImmGetIMEFileNameA (IMM32.@)
*/
UINT WINAPI ImmGetIMEFileNameA(
HKL hKL, LPSTR lpszFileName, UINT uBufLen)
UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
{
FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
LPWSTR bufW = NULL;
UINT wBufLen = uBufLen;
UINT rc;
if (uBufLen && lpszFileName)
bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
else /* We need this to get the number of byte required */
{
bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
wBufLen = MAX_PATH;
}
rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
if (rc > 0)
{
if (uBufLen && lpszFileName)
rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
uBufLen, NULL, NULL);
else /* get the length */
rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
NULL);
}
HeapFree(GetProcessHeap(),0,bufW);
return rc;
}
/***********************************************************************
* ImmGetIMEFileNameW (IMM32.@)
*/
UINT WINAPI ImmGetIMEFileNameW(
HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
{
FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
static const WCHAR fmt[] = {'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','x',0};
HKEY hkey;
DWORD length;
DWORD rc;
WCHAR regKey[sizeof(fmt)/sizeof(WCHAR)+8];
wsprintfW( regKey, fmt, (unsigned)hKL );
rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
return 0;
}
length = 0;
rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
if (rc != ERROR_SUCCESS)
{
RegCloseKey(hkey);
SetLastError(rc);
return 0;
}
if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
{
RegCloseKey(hkey);
if (lpszFileName)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
else
return length / sizeof(WCHAR);
}
RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
RegCloseKey(hkey);
return length / sizeof(WCHAR);
}
/***********************************************************************
@ -1407,17 +1665,20 @@ BOOL WINAPI ImmNotifyIME(
TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
{
BOOL send;
LPCOMPOSITIONSTRING lpCompStr;
if (pX11DRV_ForceXIMReset)
pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
send = (root_context->IMC.hCompStr!=NULL);
lpCompStr = ImmLockIMCC(root_context->IMC.hCompStr);
send = (lpCompStr->dwCompStrLen != 0);
ImmUnlockIMCC(root_context->IMC.hCompStr);
ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = NULL;
root_context->IMC.hCompStr = ImmCreateBlankCompStr();
if (send)
ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, 0,
GCS_COMPSTR);
rc = TRUE;
}
@ -1458,15 +1719,15 @@ BOOL WINAPI ImmNotifyIME(
root_context->bRead = FALSE;
ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, 0,
GCS_COMPSTR);
ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION,
param,
GCS_RESULTSTR|GCS_RESULTCLAUSE);
}
ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
ImmInternalPostIMEMessage(root_context, WM_IME_ENDCOMPOSITION, 0, 0);
root_context->bInComposition = FALSE;
}
break;
@ -1569,7 +1830,7 @@ BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
LF_FACESIZE);
ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
if (data->textfont)
{
@ -1592,8 +1853,8 @@ BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
if (!data)
return FALSE;
memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTW));
ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
data->IMC.lfFont.W = *lplf;
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
if (data->textfont)
{
@ -1682,7 +1943,7 @@ BOOL WINAPI ImmSetCompositionStringW(
HIMCC newCompStr;
if (!root_context->bInComposition)
{
ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
ImmInternalPostIMEMessage(root_context, WM_IME_STARTCOMPOSITION, 0, 0);
root_context->bInComposition = TRUE;
}
@ -1707,7 +1968,7 @@ BOOL WINAPI ImmSetCompositionStringW(
UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, wParam, flags);
return TRUE;
}
@ -1729,7 +1990,7 @@ BOOL WINAPI ImmSetCompositionWindow(
if (!data)
return FALSE;
memcpy(&data->IMC.cfCompForm,lpCompForm,sizeof(COMPOSITIONFORM));
data->IMC.cfCompForm = *lpCompForm;
if (IsWindowVisible(hwndDefault))
{
@ -1742,7 +2003,7 @@ BOOL WINAPI ImmSetCompositionWindow(
if (reshow)
ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
ImmInternalSendIMENotify(IMN_SETCOMPOSITIONWINDOW, 0);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
return TRUE;
}
@ -1776,7 +2037,7 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
if (hIMC == (HIMC)FROM_IME)
{
ImmInternalSetOpenStatus(fOpen);
ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
ImmInternalSendIMENotify(root_context, IMN_SETOPENSTATUS, 0);
return TRUE;
}
@ -1789,17 +2050,17 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
pX11DRV_ForceXIMReset(data->IMC.hWnd);
if (fOpen == FALSE)
ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0);
else
ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0);
ImmInternalSetOpenStatus(fOpen);
ImmInternalSetOpenStatus(!fOpen);
if (data->IMC.fOpen == FALSE)
ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0);
else
ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0);
return FALSE;
}
@ -1995,6 +2256,31 @@ DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
return internal->dwSize;
}
/***********************************************************************
* ImmGenerateMessage(IMM32.@)
*/
BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
{
InputContextData *data = (InputContextData*)hIMC;
TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
if (data->IMC.dwNumMsgBuf > 0)
{
LPTRANSMSG lpTransMsg;
INT i;
lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
ImmUnlockIMCC(data->IMC.hMsgBuf);
data->IMC.dwNumMsgBuf = 0;
}
return TRUE;
}
/*****
* Internal functions to help with IME window management
*/
@ -2052,7 +2338,6 @@ static void PaintDefaultIMEWnd(HWND hwnd)
rect.top = cpt.y;
rect.right = rect.left + pt.x;
rect.bottom = rect.top + pt.y;
offX=offY=10;
monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
}
else /* CFS_DEFAULT */

View file

@ -8,13 +8,14 @@
<define name="__WINESRC__" />
<define name="WINVER">0x600</define>
<define name="_WIN32_WINNT">0x600</define>
<library>wine</library>
<library>user32</library>
<library>gdi32</library>
<library>kernel32</library>
<library>ntdll</library>
<file>imm.c</file>
<file>version.rc</file>
<file>imm32.spec</file>
<library>wine</library>
<library>user32</library>
<library>gdi32</library>
<library>advapi32</library>
<library>kernel32</library>
<library>ntdll</library>
</module>
</group>

View file

@ -17,7 +17,7 @@
@ stdcall ImmEscapeA(long long long ptr)
@ stdcall ImmEscapeW(long long long ptr)
@ stub ImmFreeLayout
@ stub ImmGenerateMessage
@ stdcall ImmGenerateMessage(ptr)
@ stdcall ImmGetCandidateListA(long long ptr long)
@ stdcall ImmGetCandidateListCountA(long ptr)
@ stdcall ImmGetCandidateListCountW(long ptr)