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