1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef UI_BASE_IME_WIN_IMM32_MANAGER_H
6 #define UI_BASE_IME_WIN_IMM32_MANAGER_H
7
8 #include <windows.h>
9
10 #include <string>
11 #include <vector>
12
13 #include "base/component_export.h"
14 #include "base/i18n/rtl.h"
15 #include "base/macros.h"
16 #include "base/strings/string16.h"
17 #include "ui/base/ime/text_input_mode.h"
18 #include "ui/gfx/geometry/rect.h"
19
20 namespace ui {
21
22 struct CompositionText;
23
24 // This header file defines a struct and a class used for encapsulating IMM32
25 // APIs, controls IMEs attached to a window, and enables the 'on-the-spot'
26 // input without deep knowledge about the APIs, i.e. knowledge about the
27 // language-specific and IME-specific behaviors.
28 // The following items enumerates the simplest steps for an (window)
29 // application to control its IMEs with the struct and the class defined
30 // this file.
31 // 1. Add an instance of the IMM32Manager class to its window class.
32 // (The IMM32Manager class needs a window handle.)
33 // 2. Add messages handlers listed in the following subsections, follow the
34 // instructions written in each subsection, and use the IMM32Manager class.
35 // 2.1. WM_IME_SETCONTEXT (0x0281)
36 // Call the functions listed below:
37 // - IMM32Manager::CreateImeWindow();
38 // - IMM32Manager::CleanupComposition(), and;
39 // - IMM32Manager::SetImeWindowStyle().
40 // An application MUST prevent from calling ::DefWindowProc().
41 // 2.2. WM_IME_STARTCOMPOSITION (0x010D)
42 // Call the functions listed below:
43 // - IMM32Manager::CreateImeWindow(), and;
44 // - IMM32Manager::ResetComposition().
45 // An application MUST prevent from calling ::DefWindowProc().
46 // 2.3. WM_IME_COMPOSITION (0x010F)
47 // Call the functions listed below:
48 // - IMM32Manager::UpdateImeWindow();
49 // - IMM32Manager::GetResult();
50 // - IMM32Manager::GetComposition(), and;
51 // - IMM32Manager::ResetComposition() (optional).
52 // An application MUST prevent from calling ::DefWindowProc().
53 // 2.4. WM_IME_ENDCOMPOSITION (0x010E)
54 // Call the functions listed below:
55 // - IMM32Manager::ResetComposition(), and;
56 // - IMM32Manager::DestroyImeWindow().
57 // An application CAN call ::DefWindowProc().
58 // 2.5. WM_INPUTLANGCHANGE (0x0051)
59 // Call the functions listed below:
60 // - IMM32Manager::SetInputLanguage().
61 // An application CAN call ::DefWindowProc().
62
63 // This class controls the IMM (Input Method Manager) through IMM32 APIs and
64 // enables it to retrieve the string being controled by the IMM. (I wrote
65 // a note to describe the reason why I do not use 'IME' but 'IMM' below.)
66 // NOTE(hbono):
67 // Fortunately or unfortunately, TSF (Text Service Framework) and
68 // CUAS (Cicero Unaware Application Support) allows IMM32 APIs for
69 // retrieving not only the inputs from IMEs (Input Method Editors), used
70 // only for inputting East-Asian language texts, but also the ones from
71 // tablets (on Windows XP Tablet PC Edition and Windows Vista), voice
72 // recognizers (e.g. ViaVoice and Microsoft Office), etc.
73 // We can disable TSF and CUAS in Windows XP Tablet PC Edition. On the other
74 // hand, we can NEVER disable either TSF or CUAS in Windows Vista, i.e.
75 // THIS CLASS IS NOT ONLY USED ON THE INPUT CONTEXTS OF EAST-ASIAN
76 // LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES.
COMPONENT_EXPORT(UI_BASE_IME_WIN)77 class COMPONENT_EXPORT(UI_BASE_IME_WIN) IMM32Manager {
78 public:
79 IMM32Manager();
80 virtual ~IMM32Manager();
81
82 // Retrieves whether or not there is an ongoing composition.
83 bool is_composing() const { return is_composing_; }
84
85 // Retrieves the input language from Windows and update it.
86 void SetInputLanguage();
87
88 // Creates the IME windows, and allocate required resources for them.
89 // Parameters
90 // * window_handle [in] (HWND)
91 // Represents the window handle of the caller.
92 void CreateImeWindow(HWND window_handle);
93
94 // Updates the style of the IME windows.
95 // Parameters
96 // * window_handle [in] (HWND)
97 // Represents the window handle of the caller.
98 // * message [in] (UINT)
99 // * wparam [in] (WPARAM)
100 // * lparam [in] (LPARAM)
101 // Represent the windows message of the caller.
102 // These parameters are used for verifying if this function is called
103 // in a handler function for WM_IME_SETCONTEXT messages because this
104 // function uses ::DefWindowProc() to update the style.
105 // A caller just has to pass the input parameters for the handler
106 // function without modifications.
107 // * handled [out] (BOOL*)
108 // Returns ::DefWindowProc() is really called in this function.
109 // PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE!
110 // All the window styles set in this function are over-written when
111 // calling ::DefWindowProc() after returning this function.
112 // Returns the value returned by DefWindowProc.
113 LRESULT SetImeWindowStyle(HWND window_handle, UINT message,
114 WPARAM wparam, LPARAM lparam, BOOL* handled);
115
116 // Destroys the IME windows and all the resources attached to them.
117 // Parameters
118 // * window_handle [in] (HWND)
119 // Represents the window handle of the caller.
120 void DestroyImeWindow(HWND window_handle);
121
122 // Updates the position of the IME windows.
123 // Parameters
124 // * window_handle [in] (HWND)
125 // Represents the window handle of the caller.
126 void UpdateImeWindow(HWND window_handle);
127
128 // Cleans up the all resources attached to the given IMM32Manager object, and
129 // reset its composition status.
130 // Parameters
131 // * window_handle [in] (HWND)
132 // Represents the window handle of the caller.
133 void CleanupComposition(HWND window_handle);
134
135 // Resets the composition status.
136 // Cancel the ongoing composition if it exists.
137 // NOTE(hbono): This method does not release the allocated resources.
138 // Parameters
139 // * window_handle [in] (HWND)
140 // Represents the window handle of the caller.
141 void ResetComposition(HWND window_handle);
142
143 // Retrieves a composition result of the ongoing composition if it exists.
144 // Parameters
145 // * window_handle [in] (HWND)
146 // Represents the window handle of the caller.
147 // * lparam [in] (LPARAM)
148 // Specifies the updated members of the ongoing composition, and must be
149 // the same parameter of a WM_IME_COMPOSITION message handler.
150 // This parameter is used for checking if the ongoing composition has
151 // its result string,
152 // * result [out] (base::string16)
153 // Represents the object contains the composition result.
154 // Return values
155 // * true
156 // The ongoing composition has a composition result.
157 // * false
158 // The ongoing composition does not have composition results.
159 // Remarks
160 // This function is designed for being called from WM_IME_COMPOSITION
161 // message handlers.
162 bool GetResult(HWND window_handle, LPARAM lparam, base::string16* result);
163
164 // Retrieves the current composition status of the ongoing composition.
165 // Parameters
166 // * window_handle [in] (HWND)
167 // Represents the window handle of the caller.
168 // * lparam [in] (LPARAM)
169 // Specifies the updated members of the ongoing composition, and must be
170 // the same parameter of a WM_IME_COMPOSITION message handler.
171 // This parameter is used for checking if the ongoing composition has
172 // its result string,
173 // * composition [out] (Composition)
174 // Represents the struct contains the composition status.
175 // Return values
176 // * true
177 // The status of the ongoing composition is updated.
178 // * false
179 // The status of the ongoing composition is not updated.
180 // Remarks
181 // This function is designed for being called from WM_IME_COMPOSITION
182 // message handlers.
183 bool GetComposition(HWND window_handle, LPARAM lparam,
184 CompositionText* composition);
185
186 // Enables the IME attached to the given window, i.e. allows user-input
187 // events to be dispatched to the IME.
188 // Parameters
189 // * window_handle [in] (HWND)
190 // Represents the window handle of the caller.
191 // * complete [in] (bool)
192 // Represents whether or not to complete the ongoing composition.
193 // + true
194 // After finishing the ongoing composition and close its IME windows,
195 // start another composition and display its IME windows to the given
196 // position.
197 // + false
198 // Just move the IME windows of the ongoing composition to the given
199 // position without finishing it.
200 void EnableIME(HWND window_handle);
201
202 // Disables the IME attached to the given window, i.e. prohibits any
203 // user-input events from being dispatched to the IME.
204 // In Chrome, this function is used when:
205 // * a renreder process sets its input focus to a password input.
206 // Parameters
207 // * window_handle [in] (HWND)
208 // Represents the window handle of the caller.
209 void DisableIME(HWND window_handle);
210
211 // Cancels an ongoing composition of the IME attached to the given window.
212 // Parameters
213 // * window_handle [in] (HWND)
214 // Represents the window handle of the caller.
215 void CancelIME(HWND window_handle);
216
217 // Updates the caret position of the given window.
218 // Parameters
219 // * window_handle [in] (HWND)
220 // Represents the window handle of the caller.
221 // * caret_rect [in] (const gfx::Rect&)
222 // Represent the rectangle of the input caret.
223 // This rectangle is used for controlling the positions of IME windows.
224 void UpdateCaretRect(HWND window_handle, const gfx::Rect& caret_rect);
225
226 // Updates the setting whether we want IME to render composition text.
227 void SetUseCompositionWindow(bool use_composition_window);
228
229 // Returns the current input language id.
230 LANGID input_language_id() const { return input_language_id_; }
231
232 // Returns whether the system's input language is CJK.
233 bool IsInputLanguageCJK() const;
234
235 // Sets conversion status corresponding to |input_mode|.
236 virtual void SetTextInputMode(HWND window_handle, TextInputMode input_mode);
237
238 // Helper functions ----------------------------------------------------------
239
240 // Gets parameters for ::ImmSetOpenStatus and ::ImmSetConversionStatus from
241 // |input_mode|.
242 static void ConvertInputModeToImmFlags(TextInputMode input_mode,
243 DWORD initial_conversion_mode,
244 BOOL* open,
245 DWORD* new_conversion_mode);
246
247 // Return true if current active IME is IMM32-bassed.
248 bool IsImm32ImeActive();
249
250 protected:
251 // Retrieves the composition information.
252 void GetCompositionInfo(HIMC imm_context, LPARAM lparam,
253 CompositionText* composition);
254
255 // Updates the position of the IME windows.
256 void MoveImeWindow(HWND window_handle, HIMC imm_context);
257
258 // Completes the ongoing composition if it exists.
259 void CompleteComposition(HWND window_handle, HIMC imm_context);
260
261 // Retrieves a string from the IMM.
262 bool GetString(HIMC imm_context,
263 WPARAM lparam,
264 int type,
265 base::string16* result);
266
267 private:
268 // Represents whether or not there is an ongoing composition in a browser
269 // process, i.e. whether or not a browser process is composing a text.
270 bool is_composing_;
271
272 // The current input Language ID retrieved from Windows, which consists of:
273 // * Primary Language ID (bit 0 to bit 9), which shows a natunal language
274 // (English, Korean, Chinese, Japanese, etc.) and;
275 // * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
276 // the language is spoken (For English, United States, United Kingdom,
277 // Australia, Canada, etc.)
278 // The following list enumerates some examples for the Language ID:
279 // * "en-US" (0x0409)
280 // MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
281 // * "ko-KR" (0x0412)
282 // MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
283 // * "zh-TW" (0x0404)
284 // MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
285 // * "zh-CN" (0x0804)
286 // MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
287 // * "ja-JP" (0x0411)
288 // MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
289 // (See <winnt.h> for other available values.)
290 // This Language ID is used for processing language-specific operations in
291 // IME functions.
292 LANGID input_language_id_;
293
294 // Represents whether or not the current input context has created a system
295 // caret to set the position of its IME candidate window.
296 // * true: it creates a system caret.
297 // * false: it does not create a system caret.
298 bool system_caret_;
299
300 // The rectangle of the input caret retrieved from a renderer process.
301 gfx::Rect caret_rect_;
302
303 // Indicates whether or not we want IME to render composition text.
304 bool use_composition_window_;
305
306 DISALLOW_COPY_AND_ASSIGN(IMM32Manager);
307 };
308
309 } // namespace ui
310
311 #endif // UI_BASE_IME_WIN_IMM32_MANAGER_H
312