| OLD | NEW |
| (Empty) |
| 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/basictypes.h" | |
| 14 #include "base/i18n/rtl.h" | |
| 15 #include "base/strings/string16.h" | |
| 16 #include "ui/base/ime/text_input_mode.h" | |
| 17 #include "ui/base/ui_base_export.h" | |
| 18 #include "ui/gfx/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. | |
| 77 class UI_BASE_EXPORT 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 // Return values | |
| 87 // * true | |
| 88 // The given input language has IMEs. | |
| 89 // * false | |
| 90 // The given input language does not have IMEs. | |
| 91 bool SetInputLanguage(); | |
| 92 | |
| 93 // Creates the IME windows, and allocate required resources for them. | |
| 94 // Parameters | |
| 95 // * window_handle [in] (HWND) | |
| 96 // Represents the window handle of the caller. | |
| 97 void CreateImeWindow(HWND window_handle); | |
| 98 | |
| 99 // Updates the style of the IME windows. | |
| 100 // Parameters | |
| 101 // * window_handle [in] (HWND) | |
| 102 // Represents the window handle of the caller. | |
| 103 // * message [in] (UINT) | |
| 104 // * wparam [in] (WPARAM) | |
| 105 // * lparam [in] (LPARAM) | |
| 106 // Represent the windows message of the caller. | |
| 107 // These parameters are used for verifying if this function is called | |
| 108 // in a handler function for WM_IME_SETCONTEXT messages because this | |
| 109 // function uses ::DefWindowProc() to update the style. | |
| 110 // A caller just has to pass the input parameters for the handler | |
| 111 // function without modifications. | |
| 112 // * handled [out] (BOOL*) | |
| 113 // Returns ::DefWindowProc() is really called in this function. | |
| 114 // PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE! | |
| 115 // All the window styles set in this function are over-written when | |
| 116 // calling ::DefWindowProc() after returning this function. | |
| 117 // Returns the value returned by DefWindowProc. | |
| 118 LRESULT SetImeWindowStyle(HWND window_handle, UINT message, | |
| 119 WPARAM wparam, LPARAM lparam, BOOL* handled); | |
| 120 | |
| 121 // Destroys the IME windows and all the resources attached to them. | |
| 122 // Parameters | |
| 123 // * window_handle [in] (HWND) | |
| 124 // Represents the window handle of the caller. | |
| 125 void DestroyImeWindow(HWND window_handle); | |
| 126 | |
| 127 // Updates the position of the IME windows. | |
| 128 // Parameters | |
| 129 // * window_handle [in] (HWND) | |
| 130 // Represents the window handle of the caller. | |
| 131 void UpdateImeWindow(HWND window_handle); | |
| 132 | |
| 133 // Cleans up the all resources attached to the given IMM32Manager object, and | |
| 134 // reset its composition status. | |
| 135 // Parameters | |
| 136 // * window_handle [in] (HWND) | |
| 137 // Represents the window handle of the caller. | |
| 138 void CleanupComposition(HWND window_handle); | |
| 139 | |
| 140 // Resets the composition status. | |
| 141 // Cancel the ongoing composition if it exists. | |
| 142 // NOTE(hbono): This method does not release the allocated resources. | |
| 143 // Parameters | |
| 144 // * window_handle [in] (HWND) | |
| 145 // Represents the window handle of the caller. | |
| 146 void ResetComposition(HWND window_handle); | |
| 147 | |
| 148 // Retrieves a composition result of the ongoing composition if it exists. | |
| 149 // Parameters | |
| 150 // * window_handle [in] (HWND) | |
| 151 // Represents the window handle of the caller. | |
| 152 // * lparam [in] (LPARAM) | |
| 153 // Specifies the updated members of the ongoing composition, and must be | |
| 154 // the same parameter of a WM_IME_COMPOSITION message handler. | |
| 155 // This parameter is used for checking if the ongoing composition has | |
| 156 // its result string, | |
| 157 // * result [out] (base::string16) | |
| 158 // Represents the object contains the composition result. | |
| 159 // Return values | |
| 160 // * true | |
| 161 // The ongoing composition has a composition result. | |
| 162 // * false | |
| 163 // The ongoing composition does not have composition results. | |
| 164 // Remarks | |
| 165 // This function is designed for being called from WM_IME_COMPOSITION | |
| 166 // message handlers. | |
| 167 bool GetResult(HWND window_handle, LPARAM lparam, base::string16* result); | |
| 168 | |
| 169 // Retrieves the current composition status of the ongoing composition. | |
| 170 // Parameters | |
| 171 // * window_handle [in] (HWND) | |
| 172 // Represents the window handle of the caller. | |
| 173 // * lparam [in] (LPARAM) | |
| 174 // Specifies the updated members of the ongoing composition, and must be | |
| 175 // the same parameter of a WM_IME_COMPOSITION message handler. | |
| 176 // This parameter is used for checking if the ongoing composition has | |
| 177 // its result string, | |
| 178 // * composition [out] (Composition) | |
| 179 // Represents the struct contains the composition status. | |
| 180 // Return values | |
| 181 // * true | |
| 182 // The status of the ongoing composition is updated. | |
| 183 // * false | |
| 184 // The status of the ongoing composition is not updated. | |
| 185 // Remarks | |
| 186 // This function is designed for being called from WM_IME_COMPOSITION | |
| 187 // message handlers. | |
| 188 bool GetComposition(HWND window_handle, LPARAM lparam, | |
| 189 CompositionText* composition); | |
| 190 | |
| 191 // Enables the IME attached to the given window, i.e. allows user-input | |
| 192 // events to be dispatched to the IME. | |
| 193 // Parameters | |
| 194 // * window_handle [in] (HWND) | |
| 195 // Represents the window handle of the caller. | |
| 196 // * complete [in] (bool) | |
| 197 // Represents whether or not to complete the ongoing composition. | |
| 198 // + true | |
| 199 // After finishing the ongoing composition and close its IME windows, | |
| 200 // start another composition and display its IME windows to the given | |
| 201 // position. | |
| 202 // + false | |
| 203 // Just move the IME windows of the ongoing composition to the given | |
| 204 // position without finishing it. | |
| 205 void EnableIME(HWND window_handle); | |
| 206 | |
| 207 // Disables the IME attached to the given window, i.e. prohibits any | |
| 208 // user-input events from being dispatched to the IME. | |
| 209 // In Chrome, this function is used when: | |
| 210 // * a renreder process sets its input focus to a password input. | |
| 211 // Parameters | |
| 212 // * window_handle [in] (HWND) | |
| 213 // Represents the window handle of the caller. | |
| 214 void DisableIME(HWND window_handle); | |
| 215 | |
| 216 // Cancels an ongoing composition of the IME attached to the given window. | |
| 217 // Parameters | |
| 218 // * window_handle [in] (HWND) | |
| 219 // Represents the window handle of the caller. | |
| 220 void CancelIME(HWND window_handle); | |
| 221 | |
| 222 // Updates the caret position of the given window. | |
| 223 // Parameters | |
| 224 // * window_handle [in] (HWND) | |
| 225 // Represents the window handle of the caller. | |
| 226 // * caret_rect [in] (const gfx::Rect&) | |
| 227 // Represent the rectangle of the input caret. | |
| 228 // This rectangle is used for controlling the positions of IME windows. | |
| 229 void UpdateCaretRect(HWND window_handle, const gfx::Rect& caret_rect); | |
| 230 | |
| 231 // Updates the setting whether we want IME to render composition text. | |
| 232 void SetUseCompositionWindow(bool use_composition_window); | |
| 233 | |
| 234 // Returns the current input language id. | |
| 235 LANGID input_language_id() const { return input_language_id_; } | |
| 236 | |
| 237 // Returns BCP-47 tag name of the current input language. | |
| 238 std::string GetInputLanguageName() const; | |
| 239 | |
| 240 // Sets conversion status corresponding to |input_mode|. | |
| 241 virtual void SetTextInputMode(HWND window_handle, TextInputMode input_mode); | |
| 242 | |
| 243 // Helper functions ---------------------------------------------------------- | |
| 244 | |
| 245 // Checks if there is any RTL keyboard layout installed in the system. | |
| 246 static bool IsRTLKeyboardLayoutInstalled(); | |
| 247 | |
| 248 // Checks if the user pressed both Ctrl and right or left Shift keys to | |
| 249 // requrest to change the text direction and layout alignment explicitly. | |
| 250 // Returns true if only a Ctrl key and a Shift key are down. The desired text | |
| 251 // direction will be stored in |*direction|. | |
| 252 static bool IsCtrlShiftPressed(base::i18n::TextDirection* direction); | |
| 253 | |
| 254 // Gets parameters for ::ImmSetOpenStatus and ::ImmSetConversionStatus from | |
| 255 // |input_mode|. | |
| 256 static void ConvertInputModeToImmFlags(TextInputMode input_mode, | |
| 257 DWORD initial_conversion_mode, | |
| 258 BOOL* open, | |
| 259 DWORD* new_conversion_mode); | |
| 260 | |
| 261 | |
| 262 protected: | |
| 263 // Retrieves the composition information. | |
| 264 void GetCompositionInfo(HIMC imm_context, LPARAM lparam, | |
| 265 CompositionText* composition); | |
| 266 | |
| 267 // Updates the position of the IME windows. | |
| 268 void MoveImeWindow(HWND window_handle, HIMC imm_context); | |
| 269 | |
| 270 // Completes the ongoing composition if it exists. | |
| 271 void CompleteComposition(HWND window_handle, HIMC imm_context); | |
| 272 | |
| 273 // Retrieves a string from the IMM. | |
| 274 bool GetString(HIMC imm_context, | |
| 275 WPARAM lparam, | |
| 276 int type, | |
| 277 base::string16* result); | |
| 278 | |
| 279 private: | |
| 280 // Represents whether or not there is an ongoing composition in a browser | |
| 281 // process, i.e. whether or not a browser process is composing a text. | |
| 282 bool is_composing_; | |
| 283 | |
| 284 // This value represents whether or not the current input context has IMEs. | |
| 285 // The following table shows the list of IME status: | |
| 286 // Value Description | |
| 287 // false The current input language does not have IMEs. | |
| 288 // true The current input language has IMEs. | |
| 289 bool ime_status_; | |
| 290 | |
| 291 // The current input Language ID retrieved from Windows, which consists of: | |
| 292 // * Primary Language ID (bit 0 to bit 9), which shows a natunal language | |
| 293 // (English, Korean, Chinese, Japanese, etc.) and; | |
| 294 // * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region | |
| 295 // the language is spoken (For English, United States, United Kingdom, | |
| 296 // Australia, Canada, etc.) | |
| 297 // The following list enumerates some examples for the Language ID: | |
| 298 // * "en-US" (0x0409) | |
| 299 // MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); | |
| 300 // * "ko-KR" (0x0412) | |
| 301 // MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN); | |
| 302 // * "zh-TW" (0x0404) | |
| 303 // MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL); | |
| 304 // * "zh-CN" (0x0804) | |
| 305 // MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED); | |
| 306 // * "ja-JP" (0x0411) | |
| 307 // MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc. | |
| 308 // (See <winnt.h> for other available values.) | |
| 309 // This Language ID is used for processing language-specific operations in | |
| 310 // IME functions. | |
| 311 LANGID input_language_id_; | |
| 312 | |
| 313 // Represents whether or not the current input context has created a system | |
| 314 // caret to set the position of its IME candidate window. | |
| 315 // * true: it creates a system caret. | |
| 316 // * false: it does not create a system caret. | |
| 317 bool system_caret_; | |
| 318 | |
| 319 // The rectangle of the input caret retrieved from a renderer process. | |
| 320 gfx::Rect caret_rect_; | |
| 321 | |
| 322 // Indicates whether or not we want IME to render composition text. | |
| 323 bool use_composition_window_; | |
| 324 | |
| 325 DISALLOW_COPY_AND_ASSIGN(IMM32Manager); | |
| 326 }; | |
| 327 | |
| 328 } // namespace ui | |
| 329 | |
| 330 #endif // UI_BASE_IME_WIN_IMM32_MANAGER_H | |
| OLD | NEW |