1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef WinIMEHandler_h_
7 #define WinIMEHandler_h_
8 
9 #include "nscore.h"
10 #include "nsWindowBase.h"
11 #include "npapi.h"
12 #include <windows.h>
13 #include <inputscope.h>
14 
15 #define NS_WM_IMEFIRST WM_IME_SETCONTEXT
16 #define NS_WM_IMELAST WM_IME_KEYUP
17 
18 class nsWindow;
19 
20 namespace mozilla {
21 namespace widget {
22 
23 struct MSGResult;
24 
25 /**
26  * IMEHandler class is a mediator class.  On Windows, there are two IME API
27  * sets: One is IMM which is legacy API set. The other is TSF which is modern
28  * API set. By using this class, non-IME handler classes don't need to worry
29  * that we're in which mode.
30  */
31 class IMEHandler final {
32  private:
33   /**
34    * Initialize() initializes both TSF modules and IMM modules.  Some TIPs
35    * may require a normal window (i.e., not message window) belonging to
36    * this process.  Therefore, this is called immediately after first normal
37    * window is created.
38    */
39   static void Initialize();
40 
41  public:
42   static void Terminate();
43 
44   /**
45    * Returns TSF related native data or native IME context.
46    */
47   static void* GetNativeData(nsWindow* aWindow, uint32_t aDataType);
48 
49   /**
50    * ProcessRawKeyMessage() message is called before calling TranslateMessage()
51    * and DispatchMessage().  If this returns true, the message is consumed.
52    * Then, caller must not perform TranslateMessage() nor DispatchMessage().
53    */
54   static bool ProcessRawKeyMessage(const MSG& aMsg);
55 
56   /**
57    * When the message is not needed to handle anymore by the caller, this
58    * returns true.  Otherwise, false.
59    */
60   static bool ProcessMessage(nsWindow* aWindow, UINT aMessage, WPARAM& aWParam,
61                              LPARAM& aLParam, MSGResult& aResult);
62 
63   /**
64    * When there is a composition, returns true.  Otherwise, false.
65    */
66   static bool IsComposing();
67 
68   /**
69    * When there is a composition and it's in the window, returns true.
70    * Otherwise, false.
71    */
72   static bool IsComposingOn(nsWindow* aWindow);
73 
74   /**
75    * Notifies IME of the notification (a request or an event).
76    */
77   static nsresult NotifyIME(nsWindow* aWindow,
78                             const IMENotification& aIMENotification);
79 
80   /**
81    * Returns notification requests of IME.
82    */
83   static IMENotificationRequests GetIMENotificationRequests();
84 
85   /**
86    * Returns native text event dispatcher listener.
87    */
88   static TextEventDispatcherListener* GetNativeTextEventDispatcherListener();
89 
90   /**
91    * Returns IME open state on the window.
92    */
93   static bool GetOpenState(nsWindow* aWindow);
94 
95   /**
96    * Called when the window is destroying.
97    */
98   static void OnDestroyWindow(nsWindow* aWindow);
99 
100   /**
101    * Called when nsIWidget::SetInputContext() is called before the window's
102    * InputContext is modified actually.
103    */
104   static void SetInputContext(nsWindow* aWindow, InputContext& aInputContext,
105                               const InputContextAction& aAction);
106 
107   /**
108    * Associate or disassociate IME context to/from the aWindowBase.
109    */
110   static void AssociateIMEContext(nsWindowBase* aWindowBase, bool aEnable);
111 
112   /**
113    * Called when the window is created.
114    */
115   static void InitInputContext(nsWindow* aWindow, InputContext& aInputContext);
116 
117   /*
118    * For windowless plugin helper.
119    */
120   static void SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm);
121 
122   /*
123    * For WM_IME_*COMPOSITION messages and e10s with windowless plugin
124    */
125   static void DefaultProcOfPluginEvent(nsWindow* aWindow,
126                                        const NPEvent* aPluginEvent);
127 
128 #ifdef NS_ENABLE_TSF
129   /**
130    * This is called by TSFStaticSink when active IME is changed.
131    */
132   static void OnKeyboardLayoutChanged();
133 #endif  // #ifdef NS_ENABLE_TSF
134 
135 #ifdef DEBUG
136   /**
137    * Returns true when current keyboard layout has IME.  Otherwise, false.
138    */
139   static bool CurrentKeyboardLayoutHasIME();
140 #endif  // #ifdef DEBUG
141 
142  private:
143   static nsWindow* sFocusedWindow;
144   static InputContextAction::Cause sLastContextActionCause;
145 
146   static bool sForceDisableCurrentIMM_IME;
147   static bool sPluginHasFocus;
148 
149 #ifdef NS_ENABLE_TSF
150   static decltype(SetInputScopes)* sSetInputScopes;
151   static void SetInputScopeForIMM32(nsWindow* aWindow,
152                                     const nsAString& aHTMLInputType,
153                                     const nsAString& aHTMLInputInputmode);
154   static bool sIsInTSFMode;
155   // If sIMMEnabled is false, any IME messages are not handled in TSF mode.
156   // Additionally, IME context is always disassociated from focused window.
157   static bool sIsIMMEnabled;
158   static bool sAssociateIMCOnlyWhenIMM_IMEActive;
159 
IsTSFAvailable()160   static bool IsTSFAvailable() { return (sIsInTSFMode && !sPluginHasFocus); }
161   static bool IsIMMActive();
162 
163   static void MaybeShowOnScreenKeyboard();
164   static void MaybeDismissOnScreenKeyboard(nsWindow* aWindow);
165   static bool WStringStartsWithCaseInsensitive(const std::wstring& aHaystack,
166                                                const std::wstring& aNeedle);
167   static bool NeedOnScreenKeyboard();
168   static bool IsKeyboardPresentOnSlate();
169   static bool IsInTabletMode();
170   static bool AutoInvokeOnScreenKeyboardInDesktopMode();
171   static bool NeedsToAssociateIMC();
172 
173   /**
174    * Show the Windows on-screen keyboard. Only allowed for
175    * chrome documents and Windows 8 and higher.
176    */
177   static void ShowOnScreenKeyboard();
178 
179   /**
180    * Dismiss the Windows on-screen keyboard. Only allowed for
181    * Windows 8 and higher.
182    */
183   static void DismissOnScreenKeyboard();
184 
185   /**
186    * Get the HWND for the on-screen keyboard, if it's up. Only
187    * allowed for Windows 8 and higher.
188    */
189   static HWND GetOnScreenKeyboardWindow();
190 #endif  // #ifdef NS_ENABLE_TSF
191 };
192 
193 }  // namespace widget
194 }  // namespace mozilla
195 
196 #endif  // #ifndef WinIMEHandler_h_
197