CLOSED TREE: TraceMonkey merge head. (a=blockers)
[mozilla-central.git] / widget / src / gtk2 / nsGtkIMModule.h
blobc07ecbf5b716abb689e893b7a1bbdbbded8e1172
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
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
15 * License.
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.
23 * Contributor(s):
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__
43 #include <gdk/gdk.h>
44 #include <gtk/gtk.h>
46 #include "nsString.h"
47 #include "nsAutoPtr.h"
48 #include "nsTArray.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
55 #endif
57 class nsWindow;
59 class nsGtkIMModule
61 public:
62 nsrefcnt AddRef()
64 NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "mRefCnt is negative");
65 ++mRefCnt;
66 NS_LOG_ADDREF(this, mRefCnt, "nsGtkIMModule", sizeof(*this));
67 return mRefCnt;
69 nsrefcnt Release()
71 NS_PRECONDITION(mRefCnt != 0, "mRefCnt is alrady zero");
72 --mRefCnt;
73 NS_LOG_RELEASE(this, mRefCnt, "nsGtkIMModule");
74 if (mRefCnt == 0) {
75 mRefCnt = 1; /* stabilize */
76 delete this;
77 return 0;
79 return mRefCnt;
82 protected:
83 nsAutoRefCnt mRefCnt;
85 public:
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);
90 ~nsGtkIMModule();
92 // "Enabled" means the users can use all IMEs.
93 // I.e., the focus is in the normal editors.
94 PRBool IsEnabled();
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.
120 // Otherwise, FALSE.
121 static PRBool IsVirtualKeyboardOpened();
123 protected:
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
129 // child window.
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
166 // event.
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
173 // TRUE.
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
180 // handler.
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,
204 gint aOffset,
205 gint aNChars,
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,
220 gint aOffset,
221 gint aNChars);
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.
237 PRBool IsEditable();
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.
243 void Focus();
245 // Steals focus from the instance of this class.
246 void Blur();
248 // Initializes the instance.
249 void Init();
251 // Reset the current composition of IME. All native composition events
252 // during this processing are ignored.
253 void ResetIME();
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();
282 * WARNING:
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__