Cleanup: remove redundant doxygen \file argument
[blender.git] / intern / ghost / intern / GHOST_ImeWin32.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (c) 2010 The Chromium Authors. All rights reserved.
17  * All rights reserved.
18  *
19  * The Original Code is: some of this file.
20 */
21
22 /** \file \ingroup GHOST
23  */
24
25 #ifndef __GHOST_IME_H__
26 #define __GHOST_IME_H__
27
28 #ifdef WITH_INPUT_IME
29
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
32
33 #include <string>
34
35 #include "GHOST_Event.h"
36 #include "GHOST_Rect.h"
37 #include <vector>
38
39 class GHOST_EventIME : public GHOST_Event
40 {
41 public:
42         /**
43          * Constructor.
44          * \param msec  The time this event was generated.
45          * \param type  The type of key event.
46          * \param key   The key code of the key.
47          */
48         GHOST_EventIME(GHOST_TUns64 msec,
49                        GHOST_TEventType type,
50                        GHOST_IWindow *window, void *customdata)
51                        : GHOST_Event(msec, type, window)
52         {
53                 this->m_data = customdata;
54         }
55
56 };
57
58
59 /**
60  * This header file defines a struct and a class used for encapsulating IMM32
61  * APIs, controls IMEs attached to a window, and enables the 'on-the-spot'
62  * input without deep knowledge about the APIs, i.e. knowledge about the
63  * language-specific and IME-specific behaviors.
64  * The following items enumerates the simplest steps for an (window)
65  * application to control its IMEs with the struct and the class defined
66  * this file.
67  * 1. Add an instance of the GHOST_ImeWin32 class to its window class.
68  *    (The GHOST_ImeWin32 class needs a window handle.)
69  * 2. Add messages handlers listed in the following subsections, follow the
70  *    instructions written in each subsection, and use the GHOST_ImeWin32 class.
71  * 2.1. WM_IME_SETCONTEXT (0x0281)
72  *      Call the functions listed below:
73  *      - GHOST_ImeWin32::CreateImeWindow();
74  *      - GHOST_ImeWin32::CleanupComposition(), and;
75  *      - GHOST_ImeWin32::SetImeWindowStyle().
76  *      An application MUST prevent from calling ::DefWindowProc().
77  * 2.2. WM_IME_STARTCOMPOSITION (0x010D)
78  *      Call the functions listed below:
79  *      - GHOST_ImeWin32::CreateImeWindow(), and;
80  *      - GHOST_ImeWin32::ResetComposition().
81  *      An application MUST prevent from calling ::DefWindowProc().
82  * 2.3. WM_IME_COMPOSITION (0x010F)
83  *      Call the functions listed below:
84  *      - GHOST_ImeWin32::UpdateImeWindow();
85  *      - GHOST_ImeWin32::GetResult();
86  *      - GHOST_ImeWin32::GetComposition(), and;
87  *      - GHOST_ImeWin32::ResetComposition() (optional).
88  *      An application MUST prevent from calling ::DefWindowProc().
89  * 2.4. WM_IME_ENDCOMPOSITION (0x010E)
90  *      Call the functions listed below:
91  *      - GHOST_ImeWin32::ResetComposition(), and;
92  *      - GHOST_ImeWin32::DestroyImeWindow().
93  *      An application CAN call ::DefWindowProc().
94  * 2.5. WM_INPUTLANGCHANGE (0x0051)
95  *      Call the functions listed below:
96  *      - GHOST_ImeWin32::SetInputLanguage().
97  *      An application CAN call ::DefWindowProc().
98  */
99
100 /* This struct represents the status of an ongoing composition. */
101 struct ImeComposition {
102         /* Represents the cursor position in the IME composition. */
103         int cursor_position;
104
105         /* Represents the position of the beginning of the selection */
106         int target_start;
107
108         /* Represents the position of the end of the selection */
109         int target_end;
110
111         /**
112          * Represents the type of the string in the 'ime_string' parameter.
113          * Its possible values and description are listed below:
114          *   Value         Description
115          *   0             The parameter is not used.
116          *   GCS_RESULTSTR The parameter represents a result string.
117          *   GCS_COMPSTR   The parameter represents a composition string.
118          */
119         int string_type;
120
121         /* Represents the string retrieved from IME (Input Method Editor) */
122         std::wstring ime_string;
123         std::vector<char> utf8_buf;
124         std::vector<unsigned char> format;
125 };
126
127 /**
128  * This class controls the IMM (Input Method Manager) through IMM32 APIs and
129  * enables it to retrieve the string being controled by the IMM. (I wrote
130  * a note to describe the reason why I do not use 'IME' but 'IMM' below.)
131  * NOTE(hbono):
132  *   Fortunately or unfortunately, TSF (Text Service Framework) and
133  *   CUAS (Cicero Unaware Application Support) allows IMM32 APIs for
134  *   retrieving not only the inputs from IMEs (Input Method Editors), used
135  *   only for inputting East-Asian language texts, but also the ones from
136  *   tablets (on Windows XP Tablet PC Edition and Windows Vista), voice
137  *   recognizers (e.g. ViaVoice and Microsoft Office), etc.
138  *   We can disable TSF and CUAS in Windows XP Tablet PC Edition. On the other
139  *   hand, we can NEVER disable either TSF or CUAS in Windows Vista, i.e.
140  *   THIS CLASS IS NOT ONLY USED ON THE INPUT CONTEXTS OF EAST-ASIAN
141  *   LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES.
142  */
143 class GHOST_ImeWin32 {
144 public:
145         GHOST_ImeWin32();
146         ~GHOST_ImeWin32();
147
148         /* Retrieves whether or not there is an ongoing composition. */
149         bool is_composing() const {return is_composing_;}
150
151         /**
152          * Retrieves the input language from Windows and update it.
153          * Return values
154          *   * true
155          *     The given input language has IMEs.
156          *   * false
157          *     The given input language does not have IMEs.
158          */
159         bool SetInputLanguage();
160
161         /**
162          * Create the IME windows, and allocate required resources for them.
163          * Parameters
164          *   * window_handle [in] (HWND)
165          *     Represents the window handle of the caller.
166          */
167         void CreateImeWindow(HWND window_handle);
168
169         /**
170          * Update the style of the IME windows.
171          * Parameters
172          *   * window_handle [in] (HWND)
173          *     Represents the window handle of the caller.
174          *   * message [in] (UINT)
175          *   * wparam [in] (WPARAM)
176          *   * lparam [in] (LPARAM)
177          *     Represent the windows message of the caller.
178          *     These parameters are used for verifying if this function is called
179          *     in a handler function for WM_IME_SETCONTEXT messages because this
180          *     function uses ::DefWindowProc() to update the style.
181          *     A caller just has to pass the input parameters for the handler
182          *     function without modifications.
183          *   * handled [out] (BOOL*)
184          *     Returns ::DefWindowProc() is really called in this function.
185          *     PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE!
186          *     All the window styles set in this function are over-written when
187          *     calling ::DefWindowProc() after returning this function.
188          */
189         void SetImeWindowStyle(HWND window_handle, UINT message,
190                                WPARAM wparam, LPARAM lparam, BOOL* handled);
191
192         /**
193          * Destroy the IME windows and all the resources attached to them.
194          * Parameters
195          *   * window_handle [in] (HWND)
196          *     Represents the window handle of the caller.
197          */
198         void DestroyImeWindow(HWND window_handle);
199
200         /**
201          * Update the position of the IME windows.
202          * Parameters
203          *   * window_handle [in] (HWND)
204          *     Represents the window handle of the caller.
205          */
206         void UpdateImeWindow(HWND window_handle);
207
208         /**
209          * Clean up the all resources attached to the given GHOST_ImeWin32 object, and
210          * reset its composition status.
211          * Parameters
212          *   * window_handle [in] (HWND)
213          *     Represents the window handle of the caller.
214          */
215         void CleanupComposition(HWND window_handle);
216
217         /**
218          * Reset the composition status.
219          * Cancel the ongoing composition if it exists.
220          * NOTE(hbono): This method does not release the allocated resources.
221          * Parameters
222          *   * window_handle [in] (HWND)
223          *     Represents the window handle of the caller.
224          */
225         void ResetComposition(HWND window_handle);
226
227         /**
228          * Retrieve a composition result of the ongoing composition if it exists.
229          * Parameters
230          *   * window_handle [in] (HWND)
231          *     Represents the window handle of the caller.
232          *   * lparam [in] (LPARAM)
233          *     Specifies the updated members of the ongoing composition, and must be
234          *     the same parameter of a WM_IME_COMPOSITION message handler.
235          *     This parameter is used for checking if the ongoing composition has
236          *     its result string,
237          *   * composition [out] (ImeComposition)
238          *     Represents the struct contains the composition result.
239          * Return values
240          *   * true
241          *     The ongoing composition has a composition result.
242          *   * false
243          *     The ongoing composition does not have composition results.
244          * Remarks
245          *   This function is designed for being called from WM_IME_COMPOSITION
246          *   message handlers.
247          */
248         bool GetResult(HWND window_handle, LPARAM lparam,
249                        ImeComposition* composition);
250
251         /**
252          * Retrieve the current composition status of the ongoing composition.
253          * Parameters
254          *   * window_handle [in] (HWND)
255          *     Represents the window handle of the caller.
256          *   * lparam [in] (LPARAM)
257          *     Specifies the updated members of the ongoing composition, and must be
258          *     the same parameter of a WM_IME_COMPOSITION message handler.
259          *     This parameter is used for checking if the ongoing composition has
260          *     its result string,
261          *   * composition [out] (ImeComposition)
262          *     Represents the struct contains the composition status.
263          * Return values
264          *   * true
265          *     The status of the ongoing composition is updated.
266          *   * false
267          *     The status of the ongoing composition is not updated.
268          * Remarks
269          *   This function is designed for being called from WM_IME_COMPOSITION
270          *   message handlers.
271          */
272         bool GetComposition(HWND window_handle, LPARAM lparam,
273                             ImeComposition* composition);
274
275         /**
276          * Enable the IME attached to the given window, i.e. allows user-input
277          * events to be dispatched to the IME.
278          * In Chrome, this function is used when:
279          *   * a renderer process moves its input focus to another edit control, or;
280          *   * a renrerer process moves the position of the focused edit control.
281          * Parameters
282          *   * window_handle [in] (HWND)
283          *     Represents the window handle of the caller.
284          *   * caret_rect [in] (const gfx::Rect&)
285          *     Represent the rectangle of the input caret.
286          *     This rectangle is used for controlling the positions of IME windows.
287          *   * complete [in] (bool)
288          *     Represents whether or not to complete the ongoing composition.
289          *     + true
290          *       After finishing the ongoing composition and close its IME windows,
291          *       start another composition and display its IME windows to the given
292          *       position.
293          *     + false
294          *       Just move the IME windows of the ongoing composition to the given
295          *       position without finishing it.
296          */
297         void BeginIME(HWND window_handle,
298                        const GHOST_Rect& caret_rect,
299                        bool complete);
300
301         /**
302          * Disable the IME attached to the given window, i.e. prohibits any user-input
303          * events from being dispatched to the IME.
304          * In Chrome, this function is used when:
305          *   * a renreder process sets its input focus to a password input.
306          * Parameters
307          *   * window_handle [in] (HWND)
308          *     Represents the window handle of the caller.
309          */
310         void EndIME(HWND window_handle);
311
312         /* Updatg resultInfo and compInfo */
313         void UpdateInfo(HWND window_handle);
314
315         /* disable ime when start up */
316         void CheckFirst(HWND window_handle);
317
318         ImeComposition resultInfo, compInfo;
319         GHOST_TEventImeData eventImeData;
320
321 protected:
322         /* Determines whether or not the given attribute represents a target (a.k.a. a selection). */
323         bool IsTargetAttribute(char attribute) const {
324                 return (attribute == ATTR_TARGET_CONVERTED ||
325                         attribute == ATTR_TARGET_NOTCONVERTED);
326         }
327
328         /* Retrieve the target area. */
329         void GetCaret(HIMC imm_context, LPARAM lparam,
330                       ImeComposition* composition);
331
332         /* Update the position of the IME windows. */
333         void MoveImeWindow(HWND window_handle, HIMC imm_context);
334
335         /* Complete the ongoing composition if it exists. */
336         void CompleteComposition(HWND window_handle, HIMC imm_context);
337
338         /* Retrieve a string from the IMM. */
339         bool GetString(HIMC imm_context, WPARAM lparam, int type,
340                        ImeComposition* composition);
341
342 private:
343         /**
344          * Represents whether or not there is an ongoing composition in a browser
345          * process, i.e. whether or not a browser process is composing a text.
346          */
347         bool is_composing_;
348
349         /**
350          * This value represents whether or not the current input context has IMEs.
351          * The following table shows the list of IME status:
352          *   Value  Description
353          *   false  The current input language does not have IMEs.
354          *   true   The current input language has IMEs.
355          */
356         bool ime_status_;
357
358         /**
359          * The current input Language ID retrieved from Windows, which consists of:
360          *   * Primary Language ID (bit 0 to bit 9), which shows a natunal language
361          *     (English, Korean, Chinese, Japanese, etc.) and;
362          *   * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
363          *     the language is spoken (For English, United States, United Kingdom,
364          *     Australia, Canada, etc.)
365          * The following list enumerates some examples for the Language ID:
366          *   * "en-US" (0x0409)
367          *     MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
368          *   * "ko-KR" (0x0412)
369          *     MAKELANGID(LANG_KOREAN,  SUBLANG_KOREAN);
370          *   * "zh-TW" (0x0404)
371          *     MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
372          *   * "zh-CN" (0x0804)
373          *     MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
374          *   * "ja-JP" (0x0411)
375          *     MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
376          *   (See <winnt.h> for other available values.)
377          * This Language ID is used for processing language-specific operations in
378          * IME functions.
379          */
380         LANGID input_language_id_;
381
382         /**
383          * Represents whether or not the current input context has created a system
384          * caret to set the position of its IME candidate window.
385          *   * true: it creates a system caret.
386          *   * false: it does not create a system caret.
387          */
388         bool system_caret_;
389
390         /* The rectangle of the input caret retrieved from a renderer process. */
391         GHOST_Rect caret_rect_;
392
393         /* used for disable ime when start up */
394         bool is_first, is_enable;
395 };
396
397 #endif // WITH_INPUT_IME
398 #endif // __GHOST_IME_H__