xref: /vim-8.2.3635/src/glbl_ime.cpp (revision 0eb035c9)
1*edf3f97aSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2071d4279SBram Moolenaar  *
3071d4279SBram Moolenaar  * VIM - Vi IMproved		by Bram Moolenaar
4071d4279SBram Moolenaar  *
5071d4279SBram Moolenaar  * Do ":help uganda"  in Vim to read copying and usage conditions.
6071d4279SBram Moolenaar  * Do ":help credits" in Vim to see a list of people who contributed.
7071d4279SBram Moolenaar  */
8071d4279SBram Moolenaar 
9071d4279SBram Moolenaar /*
10071d4279SBram Moolenaar  * DESCRIPTION:
11071d4279SBram Moolenaar  * This module produces Global IME for Vim, on Windows with Internet
12071d4279SBram Moolenaar  * Explorer 5.01 or higher.  You need three files "dimm.idl", "dimm.h", and
13071d4279SBram Moolenaar  * "dimm_i.c" when compile this module at your self.  "dimm.h", and
14071d4279SBram Moolenaar  * "dimm_i.c" are generated from "dimm.idl" by using MIDL.EXE as like
15071d4279SBram Moolenaar  * "if_ole.h".  You can get "dimm.idl" in MSDN web site.  I got it below
16071d4279SBram Moolenaar  * URL.
17071d4279SBram Moolenaar  *
18071d4279SBram Moolenaar  * WHAT IS THE GLOBAL IME?:
19071d4279SBram Moolenaar  * Global IME makes capability input Chinese, Japanese, and Korean text into
20071d4279SBram Moolenaar  * Vim buffer on any language version of Windows 98, Windows 95, and Windows
21071d4279SBram Moolenaar  * NT 4.0.  See below URL for detail of Global IME.  You can also find
22143c38cdSBram Moolenaar  * various language version of Global IME at same place.
23071d4279SBram Moolenaar  *
24071d4279SBram Moolenaar  * RUNTIME REQUIREMENTS:
25143c38cdSBram Moolenaar  * - Internet Explorer 5.01 or higher.
26071d4279SBram Moolenaar  * - Global IME (with language pack?).
27071d4279SBram Moolenaar  * - Of course Vim for Windows.
28071d4279SBram Moolenaar  *
29071d4279SBram Moolenaar  * URLS:
30071d4279SBram Moolenaar  * - Where you can probably get "dimm.idl".
31071d4279SBram Moolenaar  * http://msdn.microsoft.com/downloads/samples/internet/libraries/ie5_lib/sample.asp
32071d4279SBram Moolenaar  * - Global IME detailed information.
33071d4279SBram Moolenaar  * http://www.microsoft.com/windows/ie/features/ime.asp
34071d4279SBram Moolenaar  */
35071d4279SBram Moolenaar 
36071d4279SBram Moolenaar #ifdef GLOBAL_IME
37071d4279SBram Moolenaar 
38071d4279SBram Moolenaar #define WIN32_LEAN_AND_MEAN
39071d4279SBram Moolenaar #include <windows.h>
40071d4279SBram Moolenaar #include <objbase.h>
41071d4279SBram Moolenaar extern "C" {
42071d4279SBram Moolenaar #include "vim.h"
43071d4279SBram Moolenaar }
44071d4279SBram Moolenaar #include "dimm.h"
45071d4279SBram Moolenaar #include "glbl_ime.h"
46071d4279SBram Moolenaar 
47071d4279SBram Moolenaar static IActiveIMMApp *pIApp = NULL;
48071d4279SBram Moolenaar static IActiveIMMMessagePumpOwner *pIMsg = NULL;
49071d4279SBram Moolenaar static HWND s_hWnd = NULL;
50071d4279SBram Moolenaar static BOOL s_bStatus = FALSE; /* for evacuate */
51071d4279SBram Moolenaar 
52071d4279SBram Moolenaar /*
53071d4279SBram Moolenaar  * Initialize Global IME.
54071d4279SBram Moolenaar  * "atom" must be return value of RegisterClass(Ex).
55071d4279SBram Moolenaar  */
56071d4279SBram Moolenaar     void
global_ime_init(ATOM atom,HWND hWnd)57071d4279SBram Moolenaar global_ime_init(ATOM atom, HWND hWnd)
58071d4279SBram Moolenaar {
59071d4279SBram Moolenaar     IUnknown *pI;
60071d4279SBram Moolenaar     HRESULT hr;
61071d4279SBram Moolenaar 
62071d4279SBram Moolenaar     if (pIApp != NULL || pIMsg != NULL)
63071d4279SBram Moolenaar 	return;
64071d4279SBram Moolenaar     OleInitialize(NULL);
65071d4279SBram Moolenaar 
66071d4279SBram Moolenaar     /*
67071d4279SBram Moolenaar      * Get interface IUnknown
68071d4279SBram Moolenaar      */
69071d4279SBram Moolenaar     hr = CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_SERVER,
70071d4279SBram Moolenaar 	    IID_IUnknown, (void**)&pI);
71071d4279SBram Moolenaar     if (FAILED(hr) || !pI)
72071d4279SBram Moolenaar 	return;
73071d4279SBram Moolenaar 
74071d4279SBram Moolenaar     /*
75071d4279SBram Moolenaar      * Get interface IActiveIMMApp
76071d4279SBram Moolenaar      */
77071d4279SBram Moolenaar     hr = pI->QueryInterface(IID_IActiveIMMApp, (void**)&pIApp);
78071d4279SBram Moolenaar     if (FAILED(hr))
79071d4279SBram Moolenaar 	pIApp = NULL;
80071d4279SBram Moolenaar 
81071d4279SBram Moolenaar     /*
82071d4279SBram Moolenaar      * Get interface IActiveIMMMessagePumpOwner
83071d4279SBram Moolenaar      */
84071d4279SBram Moolenaar     hr = pI->QueryInterface(IID_IActiveIMMMessagePumpOwner, (void**)&pIMsg);
85071d4279SBram Moolenaar     if (FAILED(hr))
86071d4279SBram Moolenaar 	pIMsg = NULL;
87071d4279SBram Moolenaar 
88071d4279SBram Moolenaar     if (pIApp != NULL)
89071d4279SBram Moolenaar     {
90071d4279SBram Moolenaar 	pIApp->Activate(TRUE);
91071d4279SBram Moolenaar 	pIApp->FilterClientWindows(&atom, 1);
92071d4279SBram Moolenaar     }
93071d4279SBram Moolenaar     if (pIMsg != NULL)
94071d4279SBram Moolenaar 	pIMsg->Start();
95071d4279SBram Moolenaar 
96071d4279SBram Moolenaar     pI->Release();
97071d4279SBram Moolenaar     s_hWnd = hWnd;
98071d4279SBram Moolenaar }
99071d4279SBram Moolenaar 
100071d4279SBram Moolenaar /*
101071d4279SBram Moolenaar  * Reset and clear Global IME.
102071d4279SBram Moolenaar  */
103071d4279SBram Moolenaar     void
global_ime_end()104071d4279SBram Moolenaar global_ime_end()
105071d4279SBram Moolenaar {
106071d4279SBram Moolenaar     if (pIApp != NULL)
107071d4279SBram Moolenaar     {
108071d4279SBram Moolenaar 	IActiveIMMApp *p = pIApp;
109071d4279SBram Moolenaar 
110071d4279SBram Moolenaar 	pIApp = NULL;
111071d4279SBram Moolenaar 	p->FilterClientWindows(NULL, 0);
112071d4279SBram Moolenaar 	p->Deactivate();
113071d4279SBram Moolenaar 	p->Release();
114071d4279SBram Moolenaar     }
115071d4279SBram Moolenaar     if (pIMsg != NULL)
116071d4279SBram Moolenaar     {
117071d4279SBram Moolenaar 	IActiveIMMMessagePumpOwner *p = pIMsg;
118071d4279SBram Moolenaar 
119071d4279SBram Moolenaar 	pIMsg = NULL;
120071d4279SBram Moolenaar 	p->End();
121071d4279SBram Moolenaar 	p->Release();
122071d4279SBram Moolenaar     }
123071d4279SBram Moolenaar     OleUninitialize();
124071d4279SBram Moolenaar }
125071d4279SBram Moolenaar 
126071d4279SBram Moolenaar /*
127071d4279SBram Moolenaar  * Replacement for DefWindowProc().
128071d4279SBram Moolenaar  */
129071d4279SBram Moolenaar     LRESULT WINAPI
global_ime_DefWindowProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)130071d4279SBram Moolenaar global_ime_DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
131071d4279SBram Moolenaar {
132071d4279SBram Moolenaar     LRESULT lResult;
133071d4279SBram Moolenaar 
134071d4279SBram Moolenaar     if (pIApp == NULL || pIApp->OnDefWindowProc(hWnd, Msg,
135071d4279SBram Moolenaar 					    wParam, lParam, &lResult) != S_OK)
136ee0446cfSBram Moolenaar 	lResult = DefWindowProcW(hWnd, Msg, wParam, lParam);
137071d4279SBram Moolenaar     return lResult;
138071d4279SBram Moolenaar }
139071d4279SBram Moolenaar 
140071d4279SBram Moolenaar /*
141071d4279SBram Moolenaar  * Replace with TranslateMessage()
142071d4279SBram Moolenaar  */
143071d4279SBram Moolenaar     BOOL WINAPI
global_ime_TranslateMessage(CONST MSG * lpMsg)144071d4279SBram Moolenaar global_ime_TranslateMessage(CONST MSG *lpMsg)
145071d4279SBram Moolenaar {
146071d4279SBram Moolenaar     if (pIMsg == NULL || pIMsg->OnTranslateMessage(lpMsg) == S_FALSE)
147071d4279SBram Moolenaar 	return TranslateMessage(lpMsg);
148071d4279SBram Moolenaar     return TRUE;
149071d4279SBram Moolenaar }
150071d4279SBram Moolenaar 
151071d4279SBram Moolenaar /*
15284a05accSBram Moolenaar  * Set position of IME composition window.
153071d4279SBram Moolenaar  *
154071d4279SBram Moolenaar  * You have to call this before starting composition.  If once composition
155143c38cdSBram Moolenaar  * started, this can take no effect until that composition have finished.  So
156071d4279SBram Moolenaar  * you should handle WM_IME_STARTCOMPOSITION and call this function.
157071d4279SBram Moolenaar  */
158071d4279SBram Moolenaar     void WINAPI
global_ime_set_position(POINT * pPoint)159071d4279SBram Moolenaar global_ime_set_position(POINT *pPoint)
160071d4279SBram Moolenaar {
161071d4279SBram Moolenaar     HIMC hImc = NULL;
162071d4279SBram Moolenaar 
163071d4279SBram Moolenaar     if (pIApp == NULL || pPoint == NULL)
164071d4279SBram Moolenaar 	return;
165071d4279SBram Moolenaar 
166071d4279SBram Moolenaar     if (SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
167071d4279SBram Moolenaar     {
168071d4279SBram Moolenaar 	COMPOSITIONFORM CompForm;
169071d4279SBram Moolenaar 
170071d4279SBram Moolenaar 	CompForm.dwStyle = CFS_POINT;
171071d4279SBram Moolenaar 	CompForm.ptCurrentPos = *pPoint;
172071d4279SBram Moolenaar 	pIApp->SetCompositionWindow(hImc, &CompForm);
173071d4279SBram Moolenaar 	pIApp->ReleaseContext(s_hWnd, hImc);
174071d4279SBram Moolenaar     }
175071d4279SBram Moolenaar }
176071d4279SBram Moolenaar 
177071d4279SBram Moolenaar /*
178071d4279SBram Moolenaar  * Set font to Global IME
179071d4279SBram Moolenaar  */
180071d4279SBram Moolenaar /* GIME_TEST */
181071d4279SBram Moolenaar     void WINAPI
global_ime_set_font(LOGFONT * pFont)182071d4279SBram Moolenaar global_ime_set_font(LOGFONT *pFont)
183071d4279SBram Moolenaar {
184071d4279SBram Moolenaar     HIMC hImc = NULL;
185071d4279SBram Moolenaar 
186071d4279SBram Moolenaar     if (pIApp == NULL || pFont == NULL)
187071d4279SBram Moolenaar 	return;
188071d4279SBram Moolenaar 
189071d4279SBram Moolenaar     if (SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
190071d4279SBram Moolenaar     {
191071d4279SBram Moolenaar 	pIApp->SetCompositionFontA(hImc, pFont);
192071d4279SBram Moolenaar 	pIApp->ReleaseContext(s_hWnd, hImc);
193071d4279SBram Moolenaar     }
194071d4279SBram Moolenaar }
195071d4279SBram Moolenaar 
1969c96f592SBram Moolenaar #if 0
197071d4279SBram Moolenaar /*
198071d4279SBram Moolenaar  * for IME control.  Save current status of IME, and set force new-status to
1999c96f592SBram Moolenaar  * English (turn off).
200071d4279SBram Moolenaar  */
201071d4279SBram Moolenaar     void WINAPI
202071d4279SBram Moolenaar global_ime_status_evacuate()
203071d4279SBram Moolenaar {
204071d4279SBram Moolenaar     HIMC    hImc;
205071d4279SBram Moolenaar 
206071d4279SBram Moolenaar     if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
207071d4279SBram Moolenaar     {
208071d4279SBram Moolenaar 	s_bStatus = (pIApp->GetOpenStatus(hImc) == 0) ? TRUE : FALSE;
209071d4279SBram Moolenaar 	pIApp->SetOpenStatus(hImc, FALSE);
210071d4279SBram Moolenaar 	pIApp->ReleaseContext(s_hWnd, hImc);
211071d4279SBram Moolenaar     }
212071d4279SBram Moolenaar }
213071d4279SBram Moolenaar 
214071d4279SBram Moolenaar /*
215071d4279SBram Moolenaar  * for IME control.  Change IME status to last saved one.
216071d4279SBram Moolenaar  */
217071d4279SBram Moolenaar     void WINAPI
218071d4279SBram Moolenaar global_ime_status_restore()
219071d4279SBram Moolenaar {
220071d4279SBram Moolenaar     HIMC    hImc;
221071d4279SBram Moolenaar 
222071d4279SBram Moolenaar     if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
223071d4279SBram Moolenaar     {
224071d4279SBram Moolenaar 	pIApp->SetOpenStatus(hImc, s_bStatus);
225071d4279SBram Moolenaar 	pIApp->ReleaseContext(s_hWnd, hImc);
226071d4279SBram Moolenaar     }
227071d4279SBram Moolenaar }
2289c96f592SBram Moolenaar #endif
229071d4279SBram Moolenaar 
230071d4279SBram Moolenaar     void WINAPI
global_ime_set_status(int status)231071d4279SBram Moolenaar global_ime_set_status(int status)
232071d4279SBram Moolenaar {
233071d4279SBram Moolenaar     HIMC    hImc;
234071d4279SBram Moolenaar 
235071d4279SBram Moolenaar     if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
236071d4279SBram Moolenaar     {
237071d4279SBram Moolenaar 	pIApp->SetOpenStatus(hImc, status ? TRUE : FALSE);
238071d4279SBram Moolenaar 	pIApp->ReleaseContext(s_hWnd, hImc);
239071d4279SBram Moolenaar     }
240071d4279SBram Moolenaar }
241071d4279SBram Moolenaar 
242071d4279SBram Moolenaar     int WINAPI
global_ime_get_status()243071d4279SBram Moolenaar global_ime_get_status()
244071d4279SBram Moolenaar {
245071d4279SBram Moolenaar     int status = 0;
246071d4279SBram Moolenaar     HIMC    hImc;
247071d4279SBram Moolenaar 
248071d4279SBram Moolenaar     if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
249071d4279SBram Moolenaar     {
250071d4279SBram Moolenaar 	status = pIApp->GetOpenStatus(hImc) ? 1 : 0;
251071d4279SBram Moolenaar 	pIApp->ReleaseContext(s_hWnd, hImc);
252071d4279SBram Moolenaar     }
253071d4279SBram Moolenaar     return status;
254071d4279SBram Moolenaar }
255071d4279SBram Moolenaar 
256071d4279SBram Moolenaar #endif /* GLOBAL_IME */
257