michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim:expandtab:shiftwidth=4:tabstop=4: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef __nsGtkIMModule_h__ michael@0: #define __nsGtkIMModule_h__ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "nsString.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsTArray.h" michael@0: #include "nsIWidget.h" michael@0: #include "mozilla/EventForwards.h" michael@0: michael@0: class nsWindow; michael@0: michael@0: class nsGtkIMModule michael@0: { michael@0: protected: michael@0: typedef mozilla::widget::InputContext InputContext; michael@0: typedef mozilla::widget::InputContextAction InputContextAction; michael@0: michael@0: public: michael@0: nsrefcnt AddRef() michael@0: { michael@0: NS_PRECONDITION(int32_t(mRefCnt) >= 0, "mRefCnt is negative"); michael@0: ++mRefCnt; michael@0: NS_LOG_ADDREF(this, mRefCnt, "nsGtkIMModule", sizeof(*this)); michael@0: return mRefCnt; michael@0: } michael@0: nsrefcnt Release() michael@0: { michael@0: NS_PRECONDITION(mRefCnt != 0, "mRefCnt is alrady zero"); michael@0: --mRefCnt; michael@0: NS_LOG_RELEASE(this, mRefCnt, "nsGtkIMModule"); michael@0: if (mRefCnt == 0) { michael@0: mRefCnt = 1; /* stabilize */ michael@0: delete this; michael@0: return 0; michael@0: } michael@0: return mRefCnt; michael@0: } michael@0: michael@0: protected: michael@0: nsAutoRefCnt mRefCnt; michael@0: michael@0: public: michael@0: // aOwnerWindow is a pointer of the owner window. When aOwnerWindow is michael@0: // destroyed, the related IME contexts are released (i.e., IME cannot be michael@0: // used with the instance after that). michael@0: nsGtkIMModule(nsWindow* aOwnerWindow); michael@0: ~nsGtkIMModule(); michael@0: michael@0: // "Enabled" means the users can use all IMEs. michael@0: // I.e., the focus is in the normal editors. michael@0: bool IsEnabled(); michael@0: michael@0: // OnFocusWindow is a notification that aWindow is going to be focused. michael@0: void OnFocusWindow(nsWindow* aWindow); michael@0: // OnBlurWindow is a notification that aWindow is going to be unfocused. michael@0: void OnBlurWindow(nsWindow* aWindow); michael@0: // OnDestroyWindow is a notification that aWindow is going to be destroyed. michael@0: void OnDestroyWindow(nsWindow* aWindow); michael@0: // OnFocusChangeInGecko is a notification that an editor gets focus. michael@0: void OnFocusChangeInGecko(bool aFocus); michael@0: michael@0: // OnKeyEvent is called when aWindow gets a native key press event or a michael@0: // native key release event. If this returns TRUE, the key event was michael@0: // filtered by IME. Otherwise, this returns FALSE. michael@0: // NOTE: When the keypress event starts composition, this returns TRUE but michael@0: // this dispatches keydown event before compositionstart event. michael@0: bool OnKeyEvent(nsWindow* aWindow, GdkEventKey* aEvent, michael@0: bool aKeyDownEventWasSent = false); michael@0: michael@0: // IME related nsIWidget methods. michael@0: nsresult CommitIMEComposition(nsWindow* aCaller); michael@0: void SetInputContext(nsWindow* aCaller, michael@0: const InputContext* aContext, michael@0: const InputContextAction* aAction); michael@0: InputContext GetInputContext(); michael@0: nsresult CancelIMEComposition(nsWindow* aCaller); michael@0: void OnUpdateComposition(); michael@0: michael@0: // If a software keyboard has been opened, this returns TRUE. michael@0: // Otherwise, FALSE. michael@0: static bool IsVirtualKeyboardOpened(); michael@0: michael@0: protected: michael@0: // Owner of an instance of this class. This should be top level window. michael@0: // The owner window must release the contexts when it's destroyed because michael@0: // the IME contexts need the native window. If OnDestroyWindow() is called michael@0: // with the owner window, it'll release IME contexts. Otherwise, it'll michael@0: // just clean up any existing composition if it's related to the destroying michael@0: // child window. michael@0: nsWindow* mOwnerWindow; michael@0: michael@0: // A last focused window in this class's context. michael@0: nsWindow* mLastFocusedWindow; michael@0: michael@0: // Actual context. This is used for handling the user's input. michael@0: GtkIMContext *mContext; michael@0: michael@0: // mSimpleContext is used for the password field and michael@0: // the |ime-mode: disabled;| editors if sUseSimpleContext is true. michael@0: // These editors disable IME. But dead keys should work. Fortunately, michael@0: // the simple IM context of GTK2 support only them. michael@0: GtkIMContext *mSimpleContext; michael@0: michael@0: // mDummyContext is a dummy context and will be used in Focus() michael@0: // when the state of mEnabled means disabled. This context's IME state is michael@0: // always "closed", so it closes IME forcedly. michael@0: GtkIMContext *mDummyContext; michael@0: michael@0: // IME enabled state and other things defined in InputContext. michael@0: // Use following helper methods if you don't need the detail of the status. michael@0: InputContext mInputContext; michael@0: michael@0: // mCompositionStart is the start offset of the composition string in the michael@0: // current content. When