mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
Bug 520732 Separate IME related code to another file from gtk2/nsWindow.cp r=katakai+karlt
This commit is contained in:
parent
3fa0080345
commit
01d8b15eb3
@ -79,6 +79,7 @@ CPPSRCS = \
|
||||
nsImageToPixbuf.cpp \
|
||||
nsAccessibilityHelper.cpp \
|
||||
nsAccelerometerUnix.cpp \
|
||||
nsGtkIMModule.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_X11
|
||||
@ -152,7 +153,6 @@ CXXFLAGS += $(MOZ_GCONF_CFLAGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
DEFINES += -DUSE_XIM
|
||||
DEFINES += -DCAIRO_GFX
|
||||
|
||||
ifdef MOZ_ENABLE_POSTSCRIPT
|
||||
|
@ -51,7 +51,6 @@
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo *gWidgetLog = nsnull;
|
||||
PRLogModuleInfo *gWidgetFocusLog = nsnull;
|
||||
PRLogModuleInfo *gWidgetIMLog = nsnull;
|
||||
PRLogModuleInfo *gWidgetDragLog = nsnull;
|
||||
PRLogModuleInfo *gWidgetDrawLog = nsnull;
|
||||
#endif
|
||||
@ -89,8 +88,6 @@ nsAppShell::Init()
|
||||
gWidgetLog = PR_NewLogModule("Widget");
|
||||
if (!gWidgetFocusLog)
|
||||
gWidgetFocusLog = PR_NewLogModule("WidgetFocus");
|
||||
if (!gWidgetIMLog)
|
||||
gWidgetIMLog = PR_NewLogModule("WidgetIM");
|
||||
if (!gWidgetDragLog)
|
||||
gWidgetDragLog = PR_NewLogModule("WidgetDrag");
|
||||
if (!gWidgetDrawLog)
|
||||
|
1276
widget/src/gtk2/nsGtkIMModule.cpp
Normal file
1276
widget/src/gtk2/nsGtkIMModule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
282
widget/src/gtk2/nsGtkIMModule.h
Normal file
282
widget/src/gtk2/nsGtkIMModule.h
Normal file
@ -0,0 +1,282 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Christopher Blizzard
|
||||
* <blizzard@mozilla.org>. Portions created by the Initial Developer
|
||||
* are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Masayuki Nakano <masayuki@d-toybox.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __nsGtkIMModule_h__
|
||||
#define __nsGtkIMModule_h__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
// If software keyboard is needed in password field and uses GTK2 IM module
|
||||
// for inputting characters, we need to enable IME in password field too.
|
||||
#ifdef MOZ_PLATFORM_MAEMO
|
||||
#define NS_IME_ENABLED_ON_PASSWORD_FIELD 1
|
||||
#endif
|
||||
|
||||
class nsWindow;
|
||||
|
||||
class nsGtkIMModule
|
||||
{
|
||||
public:
|
||||
nsrefcnt AddRef()
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "mRefCnt is negative");
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "nsGtkIMModule", sizeof(*this));
|
||||
return mRefCnt;
|
||||
}
|
||||
nsrefcnt Release()
|
||||
{
|
||||
NS_PRECONDITION(mRefCnt != 0, "mRefCnt is alrady zero");
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "nsGtkIMModule");
|
||||
if (mRefCnt == 0) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
NS_DELETEXPCOM(this);
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
public:
|
||||
// aOwnerWindow is a pointer of the owner window. When aOwnerWindow is
|
||||
// destroyed, the related IME contexts are released (i.e., IME cannot be
|
||||
// used with the instance after that).
|
||||
nsGtkIMModule(nsWindow* aOwnerWindow);
|
||||
~nsGtkIMModule();
|
||||
|
||||
// OnFocusWindow is a notification that aWindow is going to be focused.
|
||||
void OnFocusWindow(nsWindow* aWindow);
|
||||
// OnBlurWindow is a notification that aWindow is going to be unfocused.
|
||||
void OnBlurWindow(nsWindow* aWindow);
|
||||
// OnDestroyWindow is a notification that aWindow is going to be destroyed.
|
||||
void OnDestroyWindow(nsWindow* aWindow);
|
||||
// OnFocusChangeInGecko is a notification that an editor gets focus.
|
||||
void OnFocusChangeInGecko(PRBool aFocus);
|
||||
|
||||
// OnKeyEvent is called when aWindow gets a native key press event or a
|
||||
// native key release event. If this returns TRUE, the key event was
|
||||
// filtered by IME. Otherwise, this returns FALSE.
|
||||
// NOTE: When the keypress event starts composition, this returns TRUE but
|
||||
// this dispatches keydown event before compositionstart event.
|
||||
PRBool OnKeyEvent(nsWindow* aWindow, GdkEventKey* aEvent);
|
||||
|
||||
// IME related nsIWidget methods.
|
||||
nsresult ResetInputState(nsWindow* aCaller);
|
||||
nsresult SetIMEEnabled(nsWindow* aCaller, PRUint32 aState);
|
||||
nsresult GetIMEEnabled(PRUint32* aState);
|
||||
nsresult CancelIMEComposition(nsWindow* aCaller);
|
||||
|
||||
// If a software keyboard has been opened, this returns TRUE.
|
||||
// Otherwise, FALSE.
|
||||
static PRBool IsVirtualKeyboardOpened();
|
||||
|
||||
protected:
|
||||
// Owner of an instance of this class. This should be top level window.
|
||||
// The owner window must release the contexts when it's destroyed because
|
||||
// the IME contexts need the native window. If OnDestroyWindow() is called
|
||||
// with the owner window, it'll release IME contexts. Otherwise, it'll
|
||||
// just clean up any existing composition if it's related to the destroying
|
||||
// child window.
|
||||
nsWindow* mOwnerWindow;
|
||||
|
||||
// A last focused window in this class's context.
|
||||
nsWindow* mLastFocusedWindow;
|
||||
|
||||
// Actual context. This is used for handling the user's input.
|
||||
GtkIMContext *mContext;
|
||||
|
||||
#ifndef NS_IME_ENABLED_ON_PASSWORD_FIELD
|
||||
// mSimpleContext is used for the password field and
|
||||
// the |ime-mode: disabled;| editors. These editors disable IME.
|
||||
// But dead keys should work. Fortunately, the simple IM context of
|
||||
// GTK2 support only them.
|
||||
GtkIMContext *mSimpleContext;
|
||||
#endif // NS_IME_ENABLED_ON_PASSWORD_FIELD
|
||||
|
||||
// mDummyContext is a dummy context and will be used in Focus()
|
||||
// when the state of mEnabled means disabled. This context's IME state is
|
||||
// always "closed", so it closes IME forcedly.
|
||||
GtkIMContext *mDummyContext;
|
||||
|
||||
// IME enabled state in this window. The values is nsIWidget::IME_STATUS_*.
|
||||
// Use following helper methods if you don't need the detail of the status.
|
||||
PRUint32 mEnabled;
|
||||
|
||||
// mCompositionStart is the start offset of the composition string in the
|
||||
// current content. When <textarea> or <input> have focus, it means offset
|
||||
// from the first character of them. When a HTML editor has focus, it
|
||||
// means offset from the first character of the root element of the editor.
|
||||
PRUint32 mCompositionStart;
|
||||
|
||||
// mCompositionString is the current composing string. Even if this is
|
||||
// empty, we can be composing. See mIsComposing.
|
||||
nsString mCompositionString;
|
||||
|
||||
// OnKeyEvent() temporarily sets mProcessingKeyEvent to the given native
|
||||
// event.
|
||||
GdkEventKey* mProcessingKeyEvent;
|
||||
|
||||
|
||||
// mIsComposing is set to TRUE when we dispatch the composition start
|
||||
// event. And it's set to FALSE when we dispatches the composition end
|
||||
// event. Note that mCompositionString can be empty string even if this is
|
||||
// TRUE.
|
||||
PRPackedBool mIsComposing;
|
||||
// mIsIMFocused is set to TRUE when we call gtk_im_context_focus_in(). And
|
||||
// it's set to FALSE when we call gtk_im_context_focus_out().
|
||||
PRPackedBool mIsIMFocused;
|
||||
// mFilterKeyEvent is used by OnKeyEvent(). If the commit event should
|
||||
// be processed as simple key event, this is set to TRUE by the commit
|
||||
// handler.
|
||||
PRPackedBool mFilterKeyEvent;
|
||||
// When mIgnoreNativeCompositionEvent is TRUE, all native composition
|
||||
// should be ignored except that the compositon should be restarted in
|
||||
// another content (nsIContent). Don't refer this value directly, use
|
||||
// ShouldIgnoreNativeCompositionEvent().
|
||||
PRPackedBool mIgnoreNativeCompositionEvent;
|
||||
|
||||
// sLastFocusedModule is a pointer to the last focused instance of this
|
||||
// class. When a instance is destroyed and sLastFocusedModule refers it,
|
||||
// this is cleared. So, this refers valid pointer always.
|
||||
static nsGtkIMModule* sLastFocusedModule;
|
||||
|
||||
// Callback methods for native IME events. These methods should call
|
||||
// the related instance methods simply.
|
||||
static void OnCommitCompositionCallback(GtkIMContext *aContext,
|
||||
const gchar *aString,
|
||||
nsGtkIMModule* aModule);
|
||||
static void OnChangeCompositionCallback(GtkIMContext *aContext,
|
||||
nsGtkIMModule* aModule);
|
||||
static void OnStartCompositionCallback(GtkIMContext *aContext,
|
||||
nsGtkIMModule* aModule);
|
||||
static void OnEndCompositionCallback(GtkIMContext *aContext,
|
||||
nsGtkIMModule* aModule);
|
||||
|
||||
// The instance methods for the native IME events.
|
||||
void OnCommitCompositionNative(GtkIMContext *aContext,
|
||||
const gchar *aString);
|
||||
void OnChangeCompositionNative(GtkIMContext *aContext);
|
||||
void OnStartCompositionNative(GtkIMContext *aContext);
|
||||
void OnEndCompositionNative(GtkIMContext *aContext);
|
||||
|
||||
|
||||
// GetContext() returns current IM context which is chosen by the enabled
|
||||
// state. So, this means *current* IM context.
|
||||
GtkIMContext* GetContext();
|
||||
|
||||
// "Enabled" means the users can use all IMEs.
|
||||
// I.e., the focus is in the normal editors.
|
||||
PRBool IsEnabled();
|
||||
|
||||
// "Editable" means the users can input characters. They may be not able to
|
||||
// use IMEs but they can use dead keys.
|
||||
// I.e., the focus is in the normal editors or the password editors or
|
||||
// the |ime-mode: disabled;| editors.
|
||||
PRBool IsEditable();
|
||||
|
||||
// If the owner window and IM context have been destroyed, returns TRUE.
|
||||
PRBool IsDestroyed() { return !mOwnerWindow; }
|
||||
|
||||
// Sets focus to the instance of this class.
|
||||
void Focus();
|
||||
|
||||
// Steals focus from the instance of this class.
|
||||
void Blur();
|
||||
|
||||
// Initializes the instance.
|
||||
void Init();
|
||||
|
||||
// Reset the current composition of IME. All native composition events
|
||||
// during this processing are ignored.
|
||||
void ResetIME();
|
||||
|
||||
// Gets the current composition string by the native APIs.
|
||||
void GetCompositionString(nsAString &aCompositionString);
|
||||
|
||||
// Generates our text range list from current composition string.
|
||||
void SetTextRangeList(nsTArray<nsTextRange> &aTextRangeList);
|
||||
|
||||
// Sets the offset's cursor position to IME.
|
||||
void SetCursorPosition(PRUint32 aTargetOffset);
|
||||
|
||||
// Queries the current selection offset of the window.
|
||||
PRUint32 GetSelectionOffset(nsWindow* aWindow);
|
||||
|
||||
// Initializes the GUI event.
|
||||
void InitEvent(nsGUIEvent& aEvent);
|
||||
|
||||
// Called before destroying the context to work around some platform bugs.
|
||||
void PrepareToDestroyContext(GtkIMContext *aContext);
|
||||
|
||||
PRBool ShouldIgnoreNativeCompositionEvent();
|
||||
|
||||
/**
|
||||
* WARNING:
|
||||
* Following methods dispatch gecko events. Then, the focused widget
|
||||
* can be destroyed, and also it can be stolen focus. If they returns
|
||||
* FALSE, callers cannot continue the composition.
|
||||
* - CommitCompositionBy
|
||||
* - DispatchCompositionStart
|
||||
* - DispatchCompositionEnd
|
||||
* - DispatchTextEvent
|
||||
*/
|
||||
|
||||
// Commits the current composition by the aString.
|
||||
PRBool CommitCompositionBy(const nsAString& aString);
|
||||
|
||||
// Dispatches a composition start event or a composition end event.
|
||||
PRBool DispatchCompositionStart();
|
||||
PRBool DispatchCompositionEnd();
|
||||
|
||||
// Dispatches a text event. If aCheckAttr is TRUE, dispatches a committed
|
||||
// text event. Otherwise, dispatches a composing text event.
|
||||
PRBool DispatchTextEvent(PRBool aCheckAttr);
|
||||
|
||||
};
|
||||
|
||||
#endif // __nsGtkIMModule_h__
|
File diff suppressed because it is too large
Load Diff
@ -81,15 +81,15 @@
|
||||
#include "prlog.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "nsGtkIMModule.h"
|
||||
|
||||
extern PRLogModuleInfo *gWidgetLog;
|
||||
extern PRLogModuleInfo *gWidgetFocusLog;
|
||||
extern PRLogModuleInfo *gWidgetIMLog;
|
||||
extern PRLogModuleInfo *gWidgetDragLog;
|
||||
extern PRLogModuleInfo *gWidgetDrawLog;
|
||||
|
||||
#define LOG(args) PR_LOG(gWidgetLog, 4, args)
|
||||
#define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args)
|
||||
#define LOGIM(args) PR_LOG(gWidgetIMLog, 4, args)
|
||||
#define LOGDRAG(args) PR_LOG(gWidgetDragLog, 4, args)
|
||||
#define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args)
|
||||
|
||||
@ -97,7 +97,6 @@ extern PRLogModuleInfo *gWidgetDrawLog;
|
||||
|
||||
#define LOG(args)
|
||||
#define LOGFOCUS(args)
|
||||
#define LOGIM(args)
|
||||
#define LOGDRAG(args)
|
||||
#define LOGDRAW(args)
|
||||
|
||||
@ -310,91 +309,22 @@ public:
|
||||
|
||||
NS_IMETHOD BeginResizeDrag (nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
|
||||
|
||||
#ifdef USE_XIM
|
||||
void IMEInitData (void);
|
||||
void IMEReleaseData (void);
|
||||
void IMEDestroyContext (void);
|
||||
void IMESetFocus (void);
|
||||
void IMELoseFocus (void);
|
||||
void IMEComposeStart (void);
|
||||
void IMEComposeText (const PRUnichar *aText,
|
||||
const PRInt32 aLen,
|
||||
const gchar *aPreeditString,
|
||||
const gint aCursorPos,
|
||||
const PangoAttrList *aFeedback);
|
||||
void IMEComposeEnd (void);
|
||||
GtkIMContext* IMEGetContext (void);
|
||||
// "Enabled" means the users can use all IMEs.
|
||||
// I.e., the focus is in the normal editors.
|
||||
PRBool IMEIsEnabledState (void);
|
||||
// "Editable" means the users can input characters. They may be not able to
|
||||
// use IMEs but they can use dead keys.
|
||||
// I.e., the forcus is in the normal editors or the password editors or
|
||||
// the |ime-mode: disabled;| editors.
|
||||
PRBool IMEIsEditableState(void);
|
||||
nsWindow* IMEComposingWindow(void);
|
||||
void IMECreateContext (void);
|
||||
PRBool IMEFilterEvent (GdkEventKey *aEvent);
|
||||
void IMESetCursorPosition(const nsTextEventReply& aReply);
|
||||
MozContainer* GetMozContainer() { return mContainer; }
|
||||
GdkWindow* GetGdkWindow() { return mGdkWindow; }
|
||||
PRBool IsDestroyed() { return mIsDestroyed; }
|
||||
|
||||
/*
|
||||
* |mIMEData| has all IME data for the window and its children widgets.
|
||||
* Only stand-alone windows and child windows embedded in non-Mozilla GTK
|
||||
* containers own IME contexts.
|
||||
* But this is referred from all children after the widget gets focus.
|
||||
* The children refers to its owning window's object.
|
||||
*/
|
||||
struct nsIMEData {
|
||||
// Actual context. This is used for handling the user's input.
|
||||
GtkIMContext *mContext;
|
||||
// mSimpleContext is used for the password field and
|
||||
// the |ime-mode: disabled;| editors. These editors disable IME.
|
||||
// But dead keys should work. Fortunately, the simple IM context of
|
||||
// GTK2 support only them.
|
||||
GtkIMContext *mSimpleContext;
|
||||
// mDummyContext is a dummy context and will be used in IMESetFocus()
|
||||
// when mEnabled is false. This mDummyContext IM state is always
|
||||
// "off", so it works to switch conversion mode to OFF on IM status
|
||||
// window.
|
||||
GtkIMContext *mDummyContext;
|
||||
// This mComposingWindow is set in IMEComposeStart(), when user starts
|
||||
// composition, then unset in IMEComposeEnd() when user ends the
|
||||
// composition. We will keep the widget where the actual composition is
|
||||
// started. During the composition, we may get some events like
|
||||
// ResetInputStateInternal() and CancelIMECompositionInternal() by
|
||||
// changing input focus, we will use the original widget of
|
||||
// mComposingWindow to commit or reset the composition.
|
||||
nsWindow *mComposingWindow;
|
||||
// Owner of this struct.
|
||||
// The owner window must release the contexts at destroying.
|
||||
nsWindow *mOwner;
|
||||
// The reference counter. When this will be zero by the decrement,
|
||||
// the decrementer must free the instance.
|
||||
PRUint32 mRefCount;
|
||||
// IME enabled state in this window.
|
||||
PRUint32 mEnabled;
|
||||
nsIMEData(nsWindow* aOwner) {
|
||||
mContext = nsnull;
|
||||
mSimpleContext = nsnull;
|
||||
mDummyContext = nsnull;
|
||||
mComposingWindow = nsnull;
|
||||
mOwner = aOwner;
|
||||
mRefCount = 1;
|
||||
mEnabled = nsIWidget::IME_STATUS_ENABLED;
|
||||
}
|
||||
};
|
||||
nsIMEData *mIMEData;
|
||||
// If this dispatched the keydown event actually, this returns TRUE,
|
||||
// otherwise, FALSE.
|
||||
PRBool DispatchKeyDownEvent(GdkEventKey *aEvent,
|
||||
PRBool *aIsCancelled);
|
||||
|
||||
NS_IMETHOD ResetInputState();
|
||||
NS_IMETHOD SetIMEOpenState(PRBool aState);
|
||||
NS_IMETHOD GetIMEOpenState(PRBool* aState);
|
||||
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
|
||||
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
|
||||
NS_IMETHOD CancelIMEComposition();
|
||||
NS_IMETHOD OnIMEFocusChange(PRBool aFocus);
|
||||
NS_IMETHOD GetToggledKeyState(PRUint32 aKeyCode, PRBool* aLEDState);
|
||||
|
||||
#endif
|
||||
|
||||
void ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight);
|
||||
void ApplyTransparencyBitmap();
|
||||
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
||||
@ -568,6 +498,20 @@ private:
|
||||
*flag &= ~mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* |mIMModule| takes all IME related stuff.
|
||||
*
|
||||
* This is owned by the top-level nsWindow or the topmost child
|
||||
* nsWindow embedded in a non-Gecko widget.
|
||||
*
|
||||
* The instance is created when the top level widget is created. And when
|
||||
* the widget is destroyed, it's released. All child windows refer its
|
||||
* ancestor widget's instance. So, one set of IM contexts is created for
|
||||
* all windows in a hierarchy. If the children are released after the top
|
||||
* level window is released, the children still have a valid pointer,
|
||||
* however, IME doesn't work at that time.
|
||||
*/
|
||||
nsRefPtr<nsGtkIMModule> mIMModule;
|
||||
};
|
||||
|
||||
class nsChildWindow : public nsWindow {
|
||||
|
@ -65,7 +65,7 @@ ifdef MOZ_ENABLE_GTK2
|
||||
CFLAGS += $(MOZ_GTK2_CFLAGS)
|
||||
endif
|
||||
|
||||
DEFINES += -D_IMPL_GTKXTBIN_API -DUSE_XIM
|
||||
DEFINES += -D_IMPL_GTKXTBIN_API
|
||||
|
||||
ifeq ($(OS_ARCH), OpenVMS)
|
||||
DEFINES += -DGENERIC_MOTIF_REDEFINES
|
||||
|
Loading…
Reference in New Issue
Block a user