Commit d8fa4337 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winemac: Use the default IME UI window proc implementation.

This slightly changes ime_ui_update_window to match what was previously in winex11.drv, since e5f0cdfc, which seems to be a more recent change.
parent bc1b1521
......@@ -43,20 +43,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
#define FROM_MACDRV ((HIMC)0xcafe1337)
static const WCHAR UI_CLASS_NAME[] = {'W','i','n','e',' ','M','a','c',' ','I','M','E',0};
static HIMC *hSelectedFrom = NULL;
static INT hSelectedCount = 0;
/* MSIME messages */
static UINT WM_MSIME_SERVICE;
static UINT WM_MSIME_RECONVERTOPTIONS;
static UINT WM_MSIME_MOUSE;
static UINT WM_MSIME_RECONVERTREQUEST;
static UINT WM_MSIME_RECONVERT;
static UINT WM_MSIME_QUERYPOSITION;
static UINT WM_MSIME_DOCUMENTFEED;
static WCHAR *input_context_get_comp_str( INPUTCONTEXT *ctx, BOOL result, UINT *length )
{
COMPOSITIONSTRING *string;
......@@ -544,15 +533,6 @@ static void UpdateDataInDefaultIMEWindow(INPUTCONTEXT *lpIMC, HWND hwnd, BOOL sh
ImmUnlockIMCC(lpIMC->hCompStr);
}
BOOL WINAPI ImeDestroy(UINT uForce)
{
TRACE("\n");
HeapFree(GetProcessHeap(), 0, hSelectedFrom);
hSelectedFrom = NULL;
hSelectedCount = 0;
return TRUE;
}
BOOL WINAPI ImeProcessKey(HIMC hIMC, UINT vKey, LPARAM lKeyData, const LPBYTE lpbKeyState)
{
LPINPUTCONTEXT lpIMC;
......@@ -949,377 +929,6 @@ static void IME_NotifyComplete(void* hIMC)
NotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
}
/*****
* Internal functions to help with IME window management
*/
static void PaintDefaultIMEWnd(HIMC hIMC, HWND hwnd)
{
PAINTSTRUCT ps;
RECT rect;
HDC hdc;
HMONITOR monitor;
MONITORINFO mon_info;
INT offX = 0, offY = 0;
LPINPUTCONTEXT lpIMC;
WCHAR *str;
UINT len;
lpIMC = ImmLockIMC(hIMC);
if (lpIMC == NULL)
return;
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
if ((str = input_context_get_comp_str( lpIMC, FALSE, &len )))
{
HFONT font = input_context_select_ui_font( lpIMC, hdc );
SIZE size;
POINT pt;
GetTextExtentPoint32W( hdc, str, len, &size );
pt.x = size.cx;
pt.y = size.cy;
LPtoDP(hdc, &pt, 1);
/*
* How this works based on tests on windows:
* CFS_POINT: then we start our window at the point and grow it as large
* as it needs to be for the string.
* CFS_RECT: we still use the ptCurrentPos as a starting point and our
* window is only as large as we need for the string, but we do not
* grow such that our window exceeds the given rect. Wrapping if
* needed and possible. If our ptCurrentPos is outside of our rect
* then no window is displayed.
* CFS_FORCE_POSITION: appears to behave just like CFS_POINT
* maybe because the default MSIME does not do any IME adjusting.
*/
if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT)
{
POINT cpt = lpIMC->cfCompForm.ptCurrentPos;
ClientToScreen(lpIMC->hWnd, &cpt);
rect.left = cpt.x;
rect.top = cpt.y;
rect.right = rect.left + pt.x;
rect.bottom = rect.top + pt.y;
monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
}
else /* CFS_DEFAULT */
{
/* Windows places the default IME window in the bottom left */
HWND target = lpIMC->hWnd;
if (!target) target = GetFocus();
GetWindowRect(target, &rect);
rect.top = rect.bottom;
rect.right = rect.left + pt.x + 20;
rect.bottom = rect.top + pt.y + 20;
offX=offY=10;
monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
}
if (lpIMC->cfCompForm.dwStyle == CFS_RECT)
{
RECT client;
client =lpIMC->cfCompForm.rcArea;
MapWindowPoints(lpIMC->hWnd, 0, (POINT *)&client, 2);
IntersectRect(&rect, &rect, &client);
/* TODO: Wrap the input if needed */
}
if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT)
{
/* make sure we are on the desktop */
mon_info.cbSize = sizeof(mon_info);
GetMonitorInfoW(monitor, &mon_info);
if (rect.bottom > mon_info.rcWork.bottom)
{
int shift = rect.bottom - mon_info.rcWork.bottom;
rect.top -= shift;
rect.bottom -= shift;
}
if (rect.left < 0)
{
rect.right -= rect.left;
rect.left = 0;
}
if (rect.right > mon_info.rcWork.right)
{
int shift = rect.right - mon_info.rcWork.right;
rect.left -= shift;
rect.right -= shift;
}
}
SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, SWP_NOACTIVATE);
TextOutW( hdc, offX, offY, str, len );
if (font) SelectObject( hdc, font );
free( str );
}
ImmUnlockIMCC(lpIMC->hCompStr);
EndPaint(hwnd, &ps);
ImmUnlockIMC(hIMC);
}
static void DefaultIMEComposition(HIMC hIMC, HWND hwnd, LPARAM lParam)
{
INPUTCONTEXT *ctx;
TRACE("IME message WM_IME_COMPOSITION 0x%Ix\n", lParam);
if (lParam & GCS_RESULTSTR) return;
if (!(ctx = ImmLockIMC( hIMC ))) return;
UpdateDataInDefaultIMEWindow( ctx, hwnd, TRUE );
ImmUnlockIMC(hIMC);
}
static void DefaultIMEStartComposition(HIMC hIMC, HWND hwnd)
{
LPINPUTCONTEXT lpIMC;
lpIMC = ImmLockIMC(hIMC);
if (lpIMC == NULL)
return;
TRACE("IME message WM_IME_STARTCOMPOSITION\n");
lpIMC->hWnd = GetFocus();
ShowWindow(hwnd, SW_SHOWNOACTIVATE);
ImmUnlockIMC(hIMC);
}
static LRESULT ImeHandleNotify(HIMC hIMC, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case IMN_OPENSTATUSWINDOW:
FIXME("WM_IME_NOTIFY:IMN_OPENSTATUSWINDOW\n");
break;
case IMN_CLOSESTATUSWINDOW:
FIXME("WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOW\n");
break;
case IMN_OPENCANDIDATE:
FIXME("WM_IME_NOTIFY:IMN_OPENCANDIDATE\n");
break;
case IMN_CHANGECANDIDATE:
FIXME("WM_IME_NOTIFY:IMN_CHANGECANDIDATE\n");
break;
case IMN_CLOSECANDIDATE:
FIXME("WM_IME_NOTIFY:IMN_CLOSECANDIDATE\n");
break;
case IMN_SETCONVERSIONMODE:
FIXME("WM_IME_NOTIFY:IMN_SETCONVERSIONMODE\n");
break;
case IMN_SETSENTENCEMODE:
FIXME("WM_IME_NOTIFY:IMN_SETSENTENCEMODE\n");
break;
case IMN_SETOPENSTATUS:
FIXME("WM_IME_NOTIFY:IMN_SETOPENSTATUS\n");
break;
case IMN_SETCANDIDATEPOS:
FIXME("WM_IME_NOTIFY:IMN_SETCANDIDATEPOS\n");
break;
case IMN_SETCOMPOSITIONFONT:
FIXME("WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONT\n");
break;
case IMN_SETCOMPOSITIONWINDOW:
FIXME("WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOW\n");
break;
case IMN_GUIDELINE:
FIXME("WM_IME_NOTIFY:IMN_GUIDELINE\n");
break;
case IMN_SETSTATUSWINDOWPOS:
FIXME("WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOS\n");
break;
default:
FIXME("WM_IME_NOTIFY:<Unknown 0x%Ix>\n", wParam);
break;
}
return 0;
}
static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LRESULT rc = 0;
HIMC hIMC;
TRACE("Incoming Message 0x%x (0x%08Ix, 0x%08Ix)\n", msg, wParam, lParam);
/*
* Each UI window contains the current Input Context.
* This Input Context can be obtained by calling GetWindowLong
* with IMMGWL_IMC when the UI window receives a WM_IME_xxx message.
* The UI window can refer to this Input Context and handles the
* messages.
*/
hIMC = (HIMC)GetWindowLongPtrW(hwnd, IMMGWL_IMC);
/* if we have no hIMC there are many messages we cannot process */
if (hIMC == NULL)
{
switch (msg) {
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_NOTIFY:
case WM_IME_CONTROL:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case WM_IME_CHAR:
return 0L;
default:
break;
}
}
switch (msg)
{
case WM_CREATE:
{
LPIMEPRIVATE myPrivate;
LPINPUTCONTEXT lpIMC;
SetWindowTextA(hwnd, "Wine Ime Active");
lpIMC = ImmLockIMC(hIMC);
if (lpIMC)
{
myPrivate = ImmLockIMCC(lpIMC->hPrivate);
myPrivate->hwndDefault = hwnd;
ImmUnlockIMCC(lpIMC->hPrivate);
}
ImmUnlockIMC(hIMC);
return TRUE;
}
case WM_PAINT:
PaintDefaultIMEWnd(hIMC, hwnd);
return FALSE;
case WM_NCCREATE:
return TRUE;
case WM_SETFOCUS:
if (wParam)
SetFocus((HWND)wParam);
else
FIXME("Received focus, should never have focus\n");
break;
case WM_IME_COMPOSITION:
DefaultIMEComposition(hIMC, hwnd, lParam);
break;
case WM_IME_STARTCOMPOSITION:
DefaultIMEStartComposition(hIMC, hwnd);
break;
case WM_IME_ENDCOMPOSITION:
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_IME_ENDCOMPOSITION", wParam, lParam);
ShowWindow(hwnd, SW_HIDE);
break;
case WM_IME_SELECT:
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_IME_SELECT", wParam, lParam);
break;
case WM_IME_CONTROL:
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_IME_CONTROL", wParam, lParam);
rc = 1;
break;
case WM_IME_NOTIFY:
rc = ImeHandleNotify(hIMC, hwnd, msg, wParam, lParam);
break;
default:
TRACE("Non-standard message 0x%x\n", msg);
}
/* check the MSIME messages */
if (msg == WM_MSIME_SERVICE)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_SERVICE", wParam, lParam);
rc = FALSE;
}
else if (msg == WM_MSIME_RECONVERTOPTIONS)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_RECONVERTOPTIONS", wParam, lParam);
}
else if (msg == WM_MSIME_MOUSE)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_MOUSE", wParam, lParam);
}
else if (msg == WM_MSIME_RECONVERTREQUEST)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_RECONVERTREQUEST", wParam, lParam);
}
else if (msg == WM_MSIME_RECONVERT)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_RECONVERT", wParam, lParam);
}
else if (msg == WM_MSIME_QUERYPOSITION)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_QUERYPOSITION", wParam, lParam);
}
else if (msg == WM_MSIME_DOCUMENTFEED)
{
TRACE("IME message %s, 0x%Ix, 0x%Ix\n", "WM_MSIME_DOCUMENTFEED", wParam, lParam);
}
/* DefWndProc if not an IME message */
if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
(msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
rc = DefWindowProcW(hwnd, msg, wParam, lParam);
return rc;
}
static BOOL WINAPI register_classes( INIT_ONCE *once, void *param, void **context )
{
WNDCLASSW wndClass;
ZeroMemory(&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 2 * sizeof(LONG_PTR);
wndClass.hInstance = macdrv_module;
wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
wndClass.hIcon = LoadIconW(NULL, (LPWSTR)IDI_APPLICATION);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszMenuName = 0;
wndClass.lpszClassName = UI_CLASS_NAME;
RegisterClassW(&wndClass);
WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
return TRUE;
}
BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo, LPWSTR lpszUIClass, DWORD flags)
{
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
TRACE("\n");
InitOnceExecuteOnce( &init_once, register_classes, NULL, NULL );
lpIMEInfo->dwPrivateDataSize = sizeof(IMEPRIVATE);
lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET;
lpIMEInfo->fdwConversionCaps = IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE;
lpIMEInfo->fdwSentenceCaps = IME_SMODE_AUTOMATIC;
lpIMEInfo->fdwUICaps = UI_CAP_2700;
/* Tell App we cannot accept ImeSetCompositionString calls */
/* FIXME: Can we? */
lpIMEInfo->fdwSCSCaps = 0;
lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
lstrcpyW(lpszUIClass, UI_CLASS_NAME);
return TRUE;
}
/* Interfaces to other parts of the Mac driver */
/***********************************************************************
......
......@@ -2,8 +2,6 @@
@ cdecl wine_notify_icon(long ptr)
# IME
@ stdcall ImeDestroy(long)
@ stdcall ImeInquire(ptr wstr wstr)
@ stdcall ImeProcessKey(long long long ptr)
@ stdcall ImeSelect(long long)
@ stdcall ImeSetCompositionString(long long ptr long ptr long)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment