1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is Christopher Blizzard
20 * <blizzard@mozilla.org>. Portions created by the Initial Developer
21 * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
24 * Masayuki Nakano <masayuki@d-toybox.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef __nsGtkIMModule_h__
41 #define __nsGtkIMModule_h__
47 #include "nsAutoPtr.h"
49 #include "nsGUIEvent.h"
51 // If software keyboard is needed in password field and uses GTK2 IM module
52 // for inputting characters, we need to enable IME in password field too.
53 #ifdef MOZ_PLATFORM_MAEMO
54 #define NS_IME_ENABLED_ON_PASSWORD_FIELD 1
64 NS_PRECONDITION(PRInt32(mRefCnt
) >= 0, "mRefCnt is negative");
66 NS_LOG_ADDREF(this, mRefCnt
, "nsGtkIMModule", sizeof(*this));
71 NS_PRECONDITION(mRefCnt
!= 0, "mRefCnt is alrady zero");
73 NS_LOG_RELEASE(this, mRefCnt
, "nsGtkIMModule");
75 mRefCnt
= 1; /* stabilize */
86 // aOwnerWindow is a pointer of the owner window. When aOwnerWindow is
87 // destroyed, the related IME contexts are released (i.e., IME cannot be
88 // used with the instance after that).
89 nsGtkIMModule(nsWindow
* aOwnerWindow
);
92 // "Enabled" means the users can use all IMEs.
93 // I.e., the focus is in the normal editors.
96 // OnFocusWindow is a notification that aWindow is going to be focused.
97 void OnFocusWindow(nsWindow
* aWindow
);
98 // OnBlurWindow is a notification that aWindow is going to be unfocused.
99 void OnBlurWindow(nsWindow
* aWindow
);
100 // OnDestroyWindow is a notification that aWindow is going to be destroyed.
101 void OnDestroyWindow(nsWindow
* aWindow
);
102 // OnFocusChangeInGecko is a notification that an editor gets focus.
103 void OnFocusChangeInGecko(PRBool aFocus
);
105 // OnKeyEvent is called when aWindow gets a native key press event or a
106 // native key release event. If this returns TRUE, the key event was
107 // filtered by IME. Otherwise, this returns FALSE.
108 // NOTE: When the keypress event starts composition, this returns TRUE but
109 // this dispatches keydown event before compositionstart event.
110 PRBool
OnKeyEvent(nsWindow
* aWindow
, GdkEventKey
* aEvent
,
111 PRBool aKeyDownEventWasSent
= PR_FALSE
);
113 // IME related nsIWidget methods.
114 nsresult
ResetInputState(nsWindow
* aCaller
);
115 nsresult
SetInputMode(nsWindow
* aCaller
, const IMEContext
* aContext
);
116 nsresult
GetInputMode(IMEContext
* aContext
);
117 nsresult
CancelIMEComposition(nsWindow
* aCaller
);
119 // If a software keyboard has been opened, this returns TRUE.
121 static PRBool
IsVirtualKeyboardOpened();
124 // Owner of an instance of this class. This should be top level window.
125 // The owner window must release the contexts when it's destroyed because
126 // the IME contexts need the native window. If OnDestroyWindow() is called
127 // with the owner window, it'll release IME contexts. Otherwise, it'll
128 // just clean up any existing composition if it's related to the destroying
130 nsWindow
* mOwnerWindow
;
132 // A last focused window in this class's context.
133 nsWindow
* mLastFocusedWindow
;
135 // Actual context. This is used for handling the user's input.
136 GtkIMContext
*mContext
;
138 #ifndef NS_IME_ENABLED_ON_PASSWORD_FIELD
139 // mSimpleContext is used for the password field and
140 // the |ime-mode: disabled;| editors. These editors disable IME.
141 // But dead keys should work. Fortunately, the simple IM context of
142 // GTK2 support only them.
143 GtkIMContext
*mSimpleContext
;
144 #endif // NS_IME_ENABLED_ON_PASSWORD_FIELD
146 // mDummyContext is a dummy context and will be used in Focus()
147 // when the state of mEnabled means disabled. This context's IME state is
148 // always "closed", so it closes IME forcedly.
149 GtkIMContext
*mDummyContext
;
151 // IME enabled state and other things defined in IMEContext.
152 // Use following helper methods if you don't need the detail of the status.
153 IMEContext mIMEContext
;
155 // mCompositionStart is the start offset of the composition string in the
156 // current content. When <textarea> or <input> have focus, it means offset
157 // from the first character of them. When a HTML editor has focus, it
158 // means offset from the first character of the root element of the editor.
159 PRUint32 mCompositionStart
;
161 // mCompositionString is the current composing string. Even if this is
162 // empty, we can be composing. See mIsComposing.
163 nsString mCompositionString
;
165 // OnKeyEvent() temporarily sets mProcessingKeyEvent to the given native
167 GdkEventKey
* mProcessingKeyEvent
;
170 // mIsComposing is set to TRUE when we dispatch the composition start
171 // event. And it's set to FALSE when we dispatches the composition end
172 // event. Note that mCompositionString can be empty string even if this is
174 PRPackedBool mIsComposing
;
175 // mIsIMFocused is set to TRUE when we call gtk_im_context_focus_in(). And
176 // it's set to FALSE when we call gtk_im_context_focus_out().
177 PRPackedBool mIsIMFocused
;
178 // mFilterKeyEvent is used by OnKeyEvent(). If the commit event should
179 // be processed as simple key event, this is set to TRUE by the commit
181 PRPackedBool mFilterKeyEvent
;
182 // When mIgnoreNativeCompositionEvent is TRUE, all native composition
183 // should be ignored except that the compositon should be restarted in
184 // another content (nsIContent). Don't refer this value directly, use
185 // ShouldIgnoreNativeCompositionEvent().
186 PRPackedBool mIgnoreNativeCompositionEvent
;
187 // mKeyDownEventWasSent is used by OnKeyEvent() and
188 // DispatchCompositionStart(). DispatchCompositionStart() dispatches
189 // a keydown event if the composition start is caused by a native
190 // keypress event. If this is true, the keydown event has been dispatched.
191 // Then, DispatchCompositionStart() doesn't dispatch keydown event.
192 PRPackedBool mKeyDownEventWasSent
;
194 // sLastFocusedModule is a pointer to the last focused instance of this
195 // class. When a instance is destroyed and sLastFocusedModule refers it,
196 // this is cleared. So, this refers valid pointer always.
197 static nsGtkIMModule
* sLastFocusedModule
;
199 // Callback methods for native IME events. These methods should call
200 // the related instance methods simply.
201 static gboolean
OnRetrieveSurroundingCallback(GtkIMContext
*aContext
,
202 nsGtkIMModule
*aModule
);
203 static gboolean
OnDeleteSurroundingCallback(GtkIMContext
*aContext
,
206 nsGtkIMModule
*aModule
);
207 static void OnCommitCompositionCallback(GtkIMContext
*aContext
,
208 const gchar
*aString
,
209 nsGtkIMModule
* aModule
);
210 static void OnChangeCompositionCallback(GtkIMContext
*aContext
,
211 nsGtkIMModule
* aModule
);
212 static void OnStartCompositionCallback(GtkIMContext
*aContext
,
213 nsGtkIMModule
* aModule
);
214 static void OnEndCompositionCallback(GtkIMContext
*aContext
,
215 nsGtkIMModule
* aModule
);
217 // The instance methods for the native IME events.
218 gboolean
OnRetrieveSurroundingNative(GtkIMContext
*aContext
);
219 gboolean
OnDeleteSurroundingNative(GtkIMContext
*aContext
,
222 void OnCommitCompositionNative(GtkIMContext
*aContext
,
223 const gchar
*aString
);
224 void OnChangeCompositionNative(GtkIMContext
*aContext
);
225 void OnStartCompositionNative(GtkIMContext
*aContext
);
226 void OnEndCompositionNative(GtkIMContext
*aContext
);
229 // GetContext() returns current IM context which is chosen by the enabled
230 // state. So, this means *current* IM context.
231 GtkIMContext
* GetContext();
233 // "Editable" means the users can input characters. They may be not able to
234 // use IMEs but they can use dead keys.
235 // I.e., the focus is in the normal editors or the password editors or
236 // the |ime-mode: disabled;| editors.
239 // If the owner window and IM context have been destroyed, returns TRUE.
240 PRBool
IsDestroyed() { return !mOwnerWindow
; }
242 // Sets focus to the instance of this class.
245 // Steals focus from the instance of this class.
248 // Initializes the instance.
251 // Reset the current composition of IME. All native composition events
252 // during this processing are ignored.
255 // Gets the current composition string by the native APIs.
256 void GetCompositionString(nsAString
&aCompositionString
);
258 // Generates our text range list from current composition string.
259 void SetTextRangeList(nsTArray
<nsTextRange
> &aTextRangeList
);
261 // Sets the offset's cursor position to IME.
262 void SetCursorPosition(PRUint32 aTargetOffset
);
264 // Queries the current selection offset of the window.
265 PRUint32
GetSelectionOffset(nsWindow
* aWindow
);
267 // Get current paragraph text content and cursor position
268 nsresult
GetCurrentParagraph(nsAString
& aText
, PRUint32
& aCursorPos
);
270 // Delete text portion
271 nsresult
DeleteText(const PRInt32 aOffset
, const PRUint32 aNChars
);
273 // Initializes the GUI event.
274 void InitEvent(nsGUIEvent
& aEvent
);
276 // Called before destroying the context to work around some platform bugs.
277 void PrepareToDestroyContext(GtkIMContext
*aContext
);
279 PRBool
ShouldIgnoreNativeCompositionEvent();
283 * Following methods dispatch gecko events. Then, the focused widget
284 * can be destroyed, and also it can be stolen focus. If they returns
285 * FALSE, callers cannot continue the composition.
286 * - CommitCompositionBy
287 * - DispatchCompositionStart
288 * - DispatchCompositionEnd
289 * - DispatchTextEvent
292 // Commits the current composition by the aString.
293 PRBool
CommitCompositionBy(const nsAString
& aString
);
295 // Dispatches a composition start event or a composition end event.
296 PRBool
DispatchCompositionStart();
297 PRBool
DispatchCompositionEnd();
299 // Dispatches a text event. If aCheckAttr is TRUE, dispatches a committed
300 // text event. Otherwise, dispatches a composing text event.
301 PRBool
DispatchTextEvent(PRBool aCheckAttr
);
305 #endif // __nsGtkIMModule_h__