зеркало из https://github.com/mozilla/gecko-dev.git
53989 XIM: over-the-spot hangs with VJE3.0 and ATOK X
(checked in the patch of katakai@japan.sun.com) r/sr=blizzard
This commit is contained in:
Родитель
906a287308
Коммит
bca2539c53
|
@ -31,7 +31,6 @@
|
||||||
#include "nsIPref.h"
|
#include "nsIPref.h"
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#include "nsWidget.h"
|
|
||||||
#include "nsWindow.h"
|
#include "nsWindow.h"
|
||||||
|
|
||||||
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
||||||
|
@ -817,14 +816,14 @@ nsIMEGtkIC::preedit_start_cbproc(XIC xic, XPointer client_data,
|
||||||
{
|
{
|
||||||
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
||||||
if (!thisXIC) return 0;
|
if (!thisXIC) return 0;
|
||||||
nsWidget *widget = thisXIC->mFocusWidget;
|
nsWindow *fwin = thisXIC->mFocusWindow;
|
||||||
if (!widget) return 0;
|
if (!fwin) return 0;
|
||||||
|
|
||||||
if (!thisXIC->mPreedit) {
|
if (!thisXIC->mPreedit) {
|
||||||
thisXIC->mPreedit = new nsIMEPreedit();
|
thisXIC->mPreedit = new nsIMEPreedit();
|
||||||
}
|
}
|
||||||
thisXIC->mPreedit->Reset();
|
thisXIC->mPreedit->Reset();
|
||||||
widget->ime_preedit_start();
|
fwin->ime_preedit_start();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,8 +833,8 @@ nsIMEGtkIC::preedit_draw_cbproc(XIC xic, XPointer client_data,
|
||||||
{
|
{
|
||||||
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
||||||
if (!thisXIC) return 0;
|
if (!thisXIC) return 0;
|
||||||
nsWidget *widget = thisXIC->mFocusWidget;
|
nsWindow *fwin = thisXIC->mFocusWindow;
|
||||||
if (!widget) return 0;
|
if (!fwin) return 0;
|
||||||
|
|
||||||
XIMPreeditDrawCallbackStruct *call_data =
|
XIMPreeditDrawCallbackStruct *call_data =
|
||||||
(XIMPreeditDrawCallbackStruct *) call_data_p;
|
(XIMPreeditDrawCallbackStruct *) call_data_p;
|
||||||
|
@ -847,7 +846,7 @@ nsIMEGtkIC::preedit_draw_cbproc(XIC xic, XPointer client_data,
|
||||||
thisXIC->mPreedit->SetPreeditString(text,
|
thisXIC->mPreedit->SetPreeditString(text,
|
||||||
call_data->chg_first,
|
call_data->chg_first,
|
||||||
call_data->chg_length);
|
call_data->chg_length);
|
||||||
widget->ime_preedit_draw();
|
fwin->ime_preedit_draw(thisXIC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,10 +863,10 @@ nsIMEGtkIC::preedit_done_cbproc(XIC xic, XPointer client_data,
|
||||||
{
|
{
|
||||||
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
||||||
if (!thisXIC) return 0;
|
if (!thisXIC) return 0;
|
||||||
nsWidget *widget = thisXIC->mFocusWidget;
|
nsWindow *fwin = thisXIC->mFocusWindow;
|
||||||
if (!widget) return 0;
|
if (!fwin) return 0;
|
||||||
|
|
||||||
widget->ime_preedit_done();
|
fwin->ime_preedit_done();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,8 +876,8 @@ nsIMEGtkIC::status_start_cbproc(XIC xic, XPointer client_data,
|
||||||
{
|
{
|
||||||
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
||||||
if (!thisXIC) return 0;
|
if (!thisXIC) return 0;
|
||||||
nsWidget *widget = thisXIC->mFocusWidget;
|
nsWindow *fwin = thisXIC->mFocusWindow;
|
||||||
if (!widget) return 0;
|
if (!fwin) return 0;
|
||||||
if (!gStatus) return 0;
|
if (!gStatus) return 0;
|
||||||
|
|
||||||
// focus_window is changed
|
// focus_window is changed
|
||||||
|
@ -893,8 +892,8 @@ nsIMEGtkIC::status_draw_cbproc(XIC xic, XPointer client_data,
|
||||||
{
|
{
|
||||||
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
|
||||||
if (!thisXIC) return 0;
|
if (!thisXIC) return 0;
|
||||||
nsWidget *widget = thisXIC->mFocusWidget;
|
nsWindow *fwin = thisXIC->mFocusWindow;
|
||||||
if (!widget) return 0;
|
if (!fwin) return 0;
|
||||||
|
|
||||||
if (!gStatus) return 0;
|
if (!gStatus) return 0;
|
||||||
|
|
||||||
|
@ -939,10 +938,10 @@ nsIMEGtkIC::status_done_cbproc(XIC xic, XPointer client_data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWidget *
|
nsWindow *
|
||||||
nsIMEGtkIC::GetFocusWidget()
|
nsIMEGtkIC::GetFocusWindow()
|
||||||
{
|
{
|
||||||
return mFocusWidget;
|
return mFocusWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround for kinput2/over-the-spot/ic-per-shell
|
// workaround for kinput2/over-the-spot/ic-per-shell
|
||||||
|
@ -965,10 +964,10 @@ nsIMEGtkIC::GetFocusWidget()
|
||||||
// *OverTheSpotConversion.modeLocation: bottomleft
|
// *OverTheSpotConversion.modeLocation: bottomleft
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIMEGtkIC::SetFocusWidget(nsWidget * aFocusWidget)
|
nsIMEGtkIC::SetFocusWindow(nsWindow * aFocusWindow)
|
||||||
{
|
{
|
||||||
mFocusWidget = aFocusWidget;
|
mFocusWindow = aFocusWindow;
|
||||||
GdkWindow *gdkWindow = (GdkWindow*)aFocusWidget->GetNativeData(NS_NATIVE_WINDOW);
|
GdkWindow *gdkWindow = (GdkWindow*)aFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
|
||||||
if (!gdkWindow) return;
|
if (!gdkWindow) return;
|
||||||
|
|
||||||
gdk_im_begin((GdkIC *) mIC, gdkWindow);
|
gdk_im_begin((GdkIC *) mIC, gdkWindow);
|
||||||
|
@ -987,20 +986,20 @@ nsIMEGtkIC::SetFocusWidget(nsWidget * aFocusWidget)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIMEGtkIC::UnsetFocusWidget()
|
nsIMEGtkIC::UnsetFocusWindow()
|
||||||
{
|
{
|
||||||
gdk_im_end();
|
gdk_im_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIMEGtkIC *nsIMEGtkIC::GetXIC(nsWidget * aFocusWidget, GdkFont *aFontSet)
|
nsIMEGtkIC *nsIMEGtkIC::GetXIC(nsWindow * aFocusWindow, GdkFont *aFontSet)
|
||||||
{
|
{
|
||||||
return nsIMEGtkIC::GetXIC(aFocusWidget, aFontSet, 0);
|
return nsIMEGtkIC::GetXIC(aFocusWindow, aFontSet, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIMEGtkIC *nsIMEGtkIC::GetXIC(nsWidget * aFocusWidget,
|
nsIMEGtkIC *nsIMEGtkIC::GetXIC(nsWindow * aFocusWindow,
|
||||||
GdkFont *aFontSet, GdkFont *aStatusFontSet)
|
GdkFont *aFontSet, GdkFont *aStatusFontSet)
|
||||||
{
|
{
|
||||||
nsIMEGtkIC *newic = new nsIMEGtkIC(aFocusWidget, aFontSet, aStatusFontSet);
|
nsIMEGtkIC *newic = new nsIMEGtkIC(aFocusWindow, aFontSet, aStatusFontSet);
|
||||||
if (!newic->mIC || !newic->mIC->xic) {
|
if (!newic->mIC || !newic->mIC->xic) {
|
||||||
delete newic;
|
delete newic;
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
@ -1032,7 +1031,7 @@ nsIMEGtkIC::~nsIMEGtkIC()
|
||||||
mIC = 0;
|
mIC = 0;
|
||||||
mIC_backup = 0;
|
mIC_backup = 0;
|
||||||
mPreedit = 0;
|
mPreedit = 0;
|
||||||
mFocusWidget = 0;
|
mFocusWindow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// xim.input_policy:
|
// xim.input_policy:
|
||||||
|
@ -1393,20 +1392,20 @@ nsIMEGtkIC::SetPreeditArea(int aX, int aY, int aW, int aH) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIMEGtkIC::nsIMEGtkIC(nsWidget *aFocusWidget, GdkFont *aFontSet)
|
nsIMEGtkIC::nsIMEGtkIC(nsWindow *aFocusWindow, GdkFont *aFontSet)
|
||||||
{
|
{
|
||||||
::nsIMEGtkIC(aFocusWidget, aFontSet, 0);
|
::nsIMEGtkIC(aFocusWindow, aFontSet, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIMEGtkIC::nsIMEGtkIC(nsWidget *aFocusWidget, GdkFont *aFontSet,
|
nsIMEGtkIC::nsIMEGtkIC(nsWindow *aFocusWindow, GdkFont *aFontSet,
|
||||||
GdkFont *aStatusFontSet)
|
GdkFont *aStatusFontSet)
|
||||||
{
|
{
|
||||||
mFocusWidget = 0;
|
mFocusWindow = 0;
|
||||||
mIC = 0;
|
mIC = 0;
|
||||||
mIC_backup = 0;
|
mIC_backup = 0;
|
||||||
mPreedit = 0;
|
mPreedit = 0;
|
||||||
|
|
||||||
GdkWindow *gdkWindow = (GdkWindow *) aFocusWidget->GetNativeData(NS_NATIVE_WINDOW);
|
GdkWindow *gdkWindow = (GdkWindow *) aFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
|
||||||
if (!gdkWindow) {
|
if (!gdkWindow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ typedef struct {
|
||||||
XIMProc1 callback;
|
XIMProc1 callback;
|
||||||
} XIMCallback1;
|
} XIMCallback1;
|
||||||
|
|
||||||
class nsWidget;
|
class nsWindow;
|
||||||
|
|
||||||
enum nsIMEPolicy {
|
enum nsIMEPolicy {
|
||||||
NSIME_UNKNOWN=0,
|
NSIME_UNKNOWN=0,
|
||||||
|
@ -130,10 +130,10 @@ class nsIMEGtkIC {
|
||||||
static GdkIMStyle gInputStyle;
|
static GdkIMStyle gInputStyle;
|
||||||
static nsIMEPolicy gInputPolicy;
|
static nsIMEPolicy gInputPolicy;
|
||||||
static nsIMEStatus *gStatus;
|
static nsIMEStatus *gStatus;
|
||||||
nsWidget *mClientWidget;
|
nsWindow *mClientWindow;
|
||||||
nsWidget *mFocusWidget;
|
nsWindow *mFocusWindow;
|
||||||
nsIMEGtkIC(nsWidget*, GdkFont*, GdkFont*);
|
nsIMEGtkIC(nsWindow*, GdkFont*, GdkFont*);
|
||||||
nsIMEGtkIC(nsWidget*, GdkFont*);
|
nsIMEGtkIC(nsWindow*, GdkFont*);
|
||||||
GdkICPrivate *mIC;
|
GdkICPrivate *mIC;
|
||||||
GdkICPrivate *mIC_backup;
|
GdkICPrivate *mIC_backup;
|
||||||
nsIMEPreedit *mPreedit;
|
nsIMEPreedit *mPreedit;
|
||||||
|
@ -141,11 +141,11 @@ class nsIMEGtkIC {
|
||||||
public:
|
public:
|
||||||
nsIMEPreedit *GetPreedit() {return mPreedit;}
|
nsIMEPreedit *GetPreedit() {return mPreedit;}
|
||||||
~nsIMEGtkIC();
|
~nsIMEGtkIC();
|
||||||
static nsIMEGtkIC *GetXIC(nsWidget*, GdkFont*, GdkFont*);
|
static nsIMEGtkIC *GetXIC(nsWindow*, GdkFont*, GdkFont*);
|
||||||
static nsIMEGtkIC *GetXIC(nsWidget*, GdkFont*);
|
static nsIMEGtkIC *GetXIC(nsWindow*, GdkFont*);
|
||||||
void SetFocusWidget(nsWidget * aFocusWidget);
|
void SetFocusWindow(nsWindow * aFocusWindow);
|
||||||
nsWidget* GetFocusWidget();
|
nsWindow* GetFocusWindow();
|
||||||
static void UnsetFocusWidget();
|
static void UnsetFocusWindow();
|
||||||
static GdkIMStyle GetInputStyle();
|
static GdkIMStyle GetInputStyle();
|
||||||
static nsIMEPolicy GetInputPolicy();
|
static nsIMEPolicy GetInputPolicy();
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include "nsGtkUtils.h" // for nsGtkUtils::gdk_keyboard_get_modifiers()
|
#include "nsGtkUtils.h" // for nsGtkUtils::gdk_keyboard_get_modifiers()
|
||||||
|
|
||||||
#include "nsIPref.h"
|
#include "nsIPref.h"
|
||||||
#include "nsGtkIMEHelper.h"
|
|
||||||
|
|
||||||
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
|
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
|
||||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||||
|
@ -67,18 +66,11 @@ private:
|
||||||
*mLast; // valid only for head of list
|
*mLast; // valid only for head of list
|
||||||
};
|
};
|
||||||
|
|
||||||
static nsWidget *GetShellWidget(GdkWindow *gdkWindow);
|
|
||||||
|
|
||||||
PRUint32 nsWidget::sWidgetCount = 0;
|
PRUint32 nsWidget::sWidgetCount = 0;
|
||||||
|
|
||||||
// this is the nsWindow with the focus
|
// this is the nsWindow with the focus
|
||||||
nsWidget *nsWidget::sFocusWindow = 0;
|
nsWidget *nsWidget::sFocusWindow = 0;
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
GdkFont *nsWidget::gPreeditFontset = nsnull;
|
|
||||||
GdkFont *nsWidget::gStatusFontset = nsnull;
|
|
||||||
GdkIMStyle nsWidget::gInputStyle = (GdkIMStyle)nsnull;
|
|
||||||
#endif // USE_XIM
|
|
||||||
// this is the last time that an event happened. we keep this
|
// this is the last time that an event happened. we keep this
|
||||||
// around so that we can synth drag events properly
|
// around so that we can synth drag events properly
|
||||||
guint32 nsWidget::sLastEventTime = 0;
|
guint32 nsWidget::sLastEventTime = 0;
|
||||||
|
@ -118,89 +110,6 @@ void nsWidget::GetLastEventTime(guint32 *aTime)
|
||||||
*aTime = sLastEventTime;
|
*aTime = sLastEventTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
nsresult nsWidget::KillICSpotTimer ()
|
|
||||||
{
|
|
||||||
if(mICSpotTimer)
|
|
||||||
{
|
|
||||||
mICSpotTimer->Cancel();
|
|
||||||
mICSpotTimer = nsnull;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
nsresult nsWidget::PrimeICSpotTimer ()
|
|
||||||
{
|
|
||||||
KillICSpotTimer();
|
|
||||||
nsresult err;
|
|
||||||
mICSpotTimer = do_CreateInstance("@mozilla.org/timer;1", &err);
|
|
||||||
if (NS_FAILED(err))
|
|
||||||
return err;
|
|
||||||
mICSpotTimer->Init(ICSpotCallback, this, 1000);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
void nsWidget::ICSpotCallback(nsITimer * aTimer, void * aClosure)
|
|
||||||
{
|
|
||||||
nsWidget *widget= NS_REINTERPRET_CAST(nsWidget*, aClosure);
|
|
||||||
if( ! widget) return;
|
|
||||||
nsresult res = widget->UpdateICSpot();
|
|
||||||
if(NS_SUCCEEDED(res))
|
|
||||||
{
|
|
||||||
widget->PrimeICSpotTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsresult nsWidget::UpdateICSpot()
|
|
||||||
{
|
|
||||||
// set spot location
|
|
||||||
nsCompositionEvent compEvent;
|
|
||||||
compEvent.widget = (nsWidget*)this;
|
|
||||||
compEvent.point.x = 0;
|
|
||||||
compEvent.point.y = 0;
|
|
||||||
compEvent.time = 0;
|
|
||||||
compEvent.message = NS_COMPOSITION_QUERY;
|
|
||||||
compEvent.eventStructType = NS_COMPOSITION_QUERY;
|
|
||||||
compEvent.compositionMessage = NS_COMPOSITION_QUERY;
|
|
||||||
static gint oldx =0;
|
|
||||||
static gint oldy =0;
|
|
||||||
static gint oldw =0;
|
|
||||||
static gint oldh =0;
|
|
||||||
compEvent.theReply.mCursorPosition.x=-1;
|
|
||||||
compEvent.theReply.mCursorPosition.y=-1;
|
|
||||||
this->OnComposition(compEvent);
|
|
||||||
// set SpotLocation
|
|
||||||
if((compEvent.theReply.mCursorPosition.x < 0) &&
|
|
||||||
(compEvent.theReply.mCursorPosition.y < 0))
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// In over-the-spot style, pre-edit can not be drawn properly when
|
|
||||||
// IMESetFocusWidget() is called at height=1 and width=1
|
|
||||||
// After resizing, we need to call SetPreeditArea() again
|
|
||||||
if((oldw != mBounds.width) || (oldh != mBounds.height)) {
|
|
||||||
GdkWindow *gdkWindow = (GdkWindow*)this->GetNativeData(NS_NATIVE_WINDOW);
|
|
||||||
if (mXIC && gdkWindow) {
|
|
||||||
mXIC->SetPreeditArea(0, 0,
|
|
||||||
(int)((GdkWindowPrivate*)gdkWindow)->width,
|
|
||||||
(int)((GdkWindowPrivate*)gdkWindow)->height);
|
|
||||||
}
|
|
||||||
oldw = mBounds.width;
|
|
||||||
oldh = mBounds.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((compEvent.theReply.mCursorPosition.x != oldx)||
|
|
||||||
(compEvent.theReply.mCursorPosition.y != oldy))
|
|
||||||
{
|
|
||||||
nsPoint spot;
|
|
||||||
spot.x = compEvent.theReply.mCursorPosition.x;
|
|
||||||
spot.y = compEvent.theReply.mCursorPosition.y +
|
|
||||||
compEvent.theReply.mCursorPosition.height;
|
|
||||||
SetXICBaseFontSize( compEvent.theReply.mCursorPosition.height - 1);
|
|
||||||
SetXICSpotLocation(spot);
|
|
||||||
oldx = compEvent.theReply.mCursorPosition.x;
|
|
||||||
oldy = compEvent.theReply.mCursorPosition.y;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRollupListener> nsWidget::gRollupListener;
|
nsCOMPtr<nsIRollupListener> nsWidget::gRollupListener;
|
||||||
nsWeakPtr nsWidget::gRollupWidget;
|
nsWeakPtr nsWidget::gRollupWidget;
|
||||||
PRBool nsWidget::gRollupConsumeRollupEvent = PR_FALSE;
|
PRBool nsWidget::gRollupConsumeRollupEvent = PR_FALSE;
|
||||||
|
@ -268,20 +177,6 @@ nsWidget::nsWidget()
|
||||||
|
|
||||||
sWidgetCount++;
|
sWidgetCount++;
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
mIMEEnable = PR_TRUE;
|
|
||||||
mXIC = 0;
|
|
||||||
|
|
||||||
mIMEShellWidget = 0;
|
|
||||||
mIMECallComposeStart = PR_FALSE;
|
|
||||||
mIMECallComposeEnd = PR_TRUE;
|
|
||||||
mIMEIsBeingActivate = PR_FALSE;
|
|
||||||
|
|
||||||
mICSpotTimer = nsnull;
|
|
||||||
#endif // USE_XIM
|
|
||||||
mIMECompositionUniString = nsnull;
|
|
||||||
mIMECompositionUniStringSize = 0;
|
|
||||||
|
|
||||||
mListenForResizes = PR_FALSE;
|
mListenForResizes = PR_FALSE;
|
||||||
mHasFocus = PR_FALSE;
|
mHasFocus = PR_FALSE;
|
||||||
if (mGDKHandlerInstalled == PR_FALSE) {
|
if (mGDKHandlerInstalled == PR_FALSE) {
|
||||||
|
@ -320,11 +215,6 @@ nsWidget::nsWidget()
|
||||||
|
|
||||||
nsWidget::~nsWidget()
|
nsWidget::~nsWidget()
|
||||||
{
|
{
|
||||||
#ifdef USE_XIM
|
|
||||||
mXIC = 0;
|
|
||||||
KillICSpotTimer();
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
#ifdef NOISY_DESTROY
|
#ifdef NOISY_DESTROY
|
||||||
IndentByDepth(stdout);
|
IndentByDepth(stdout);
|
||||||
printf("nsWidget::~nsWidget:%p\n", this);
|
printf("nsWidget::~nsWidget:%p\n", this);
|
||||||
|
@ -336,10 +226,6 @@ nsWidget::~nsWidget()
|
||||||
// to be called once
|
// to be called once
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
if (mIMECompositionUniString) {
|
|
||||||
delete[] mIMECompositionUniString;
|
|
||||||
mIMECompositionUniString = nsnull;
|
|
||||||
}
|
|
||||||
NS_ASSERTION(!ModalWidgetList::Find(this), "destroying widget without first clearing modality.");
|
NS_ASSERTION(!ModalWidgetList::Find(this), "destroying widget without first clearing modality.");
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
if (mIsToplevel) {
|
if (mIsToplevel) {
|
||||||
|
@ -727,10 +613,6 @@ nsWidget::LoseFocus(void)
|
||||||
if (mHasFocus == PR_FALSE)
|
if (mHasFocus == PR_FALSE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
IMEUnsetFocusWidget();
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
sFocusWindow = 0;
|
sFocusWindow = 0;
|
||||||
mHasFocus = PR_FALSE;
|
mHasFocus = PR_FALSE;
|
||||||
|
|
||||||
|
@ -2521,137 +2403,11 @@ void nsWidget::SetBackgroundColorNative(GdkColor *aColorNor,
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
void
|
|
||||||
nsWidget::GetXIC()
|
|
||||||
{
|
|
||||||
if (gInputStyle == nsnull) {
|
|
||||||
gInputStyle = nsIMEGtkIC::GetInputStyle();
|
|
||||||
}
|
|
||||||
if (gPreeditFontset == nsnull) {
|
|
||||||
gPreeditFontset = gdk_fontset_load("-*-*-medium-r-*-*-16-*-*-*-*-*-*-*");
|
|
||||||
mXICFontSize = 16; // default
|
|
||||||
}
|
|
||||||
if (gStatusFontset == nsnull) {
|
|
||||||
gStatusFontset = gdk_fontset_load("-*-*-medium-r-*-*-16-*-*-*-*-*-*-*");
|
|
||||||
}
|
|
||||||
IMEGetShellWidget();
|
|
||||||
if (!gInputStyle || !gPreeditFontset || !gStatusFontset || !mIMEShellWidget) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIMEShellWidget->mXIC){
|
|
||||||
mXIC = mIMEShellWidget->mXIC;
|
|
||||||
} else {
|
|
||||||
mXIC = nsIMEGtkIC::GetXIC(mIMEShellWidget, gPreeditFontset,
|
|
||||||
gStatusFontset);
|
|
||||||
if (mXIC) {
|
|
||||||
// fix me! need to know how to get spot location
|
|
||||||
mXIC->SetPreeditSpotLocation(0, 14);
|
|
||||||
mIMEShellWidget->mXIC = mXIC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsWidget::ResetInputState()
|
NS_IMETHODIMP nsWidget::ResetInputState()
|
||||||
{
|
{
|
||||||
#ifdef USE_XIM
|
|
||||||
if (mIMEEnable == PR_FALSE) return NS_OK;
|
|
||||||
|
|
||||||
if (mXIC) {
|
|
||||||
IMEGetShellWidget();
|
|
||||||
if (!mIMEShellWidget) return NS_OK;
|
|
||||||
|
|
||||||
// while being called for NS_ACTIVE and NS_DEACTIVATE,
|
|
||||||
// ignore ResetInputState() call
|
|
||||||
if (mIMEShellWidget->mIMEIsBeingActivate == PR_TRUE) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 uniCharSize =
|
|
||||||
mXIC->ResetIC(&(mIMECompositionUniString),
|
|
||||||
&(mIMECompositionUniStringSize));
|
|
||||||
|
|
||||||
if (uniCharSize) {
|
|
||||||
mIMECompositionUniString[uniCharSize] = 0;
|
|
||||||
|
|
||||||
IMEComposeStart(nsnull);
|
|
||||||
IMEComposeText(nsnull,
|
|
||||||
mIMECompositionUniString,
|
|
||||||
uniCharSize,
|
|
||||||
nsnull);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call IMEComposeEnd() to reset the state of field
|
|
||||||
IMEComposeEnd(nsnull);
|
|
||||||
if (gInputStyle & GDK_IM_PREEDIT_POSITION) {
|
|
||||||
UpdateICSpot();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
void
|
|
||||||
nsWidget::GetXYFromPosition(unsigned long *aX,
|
|
||||||
unsigned long *aY)
|
|
||||||
{
|
|
||||||
if (mIMEEnable == PR_FALSE) return;
|
|
||||||
if (nsnull == mXIC) return;
|
|
||||||
if (mXIC) {
|
|
||||||
GdkFont *gfontset = mXIC->GetPreeditFont();
|
|
||||||
if (gfontset) {
|
|
||||||
// this is currently not working well
|
|
||||||
// We change from += ascent to -= descent because we change the nsCaret
|
|
||||||
// code to return the nsPoint from the top of the cursor to the bottom
|
|
||||||
// of the cursor
|
|
||||||
*aY -= gfontset->descent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::SetXICBaseFontSize(int height)
|
|
||||||
{
|
|
||||||
if (mIMEEnable == PR_FALSE) return;
|
|
||||||
if (nsnull == mXIC) return;
|
|
||||||
if (mXIC) {
|
|
||||||
if (height == mXICFontSize) return;
|
|
||||||
if (height%2) {
|
|
||||||
height-=1;
|
|
||||||
}
|
|
||||||
if (height<2) return;
|
|
||||||
if (gPreeditFontset) {
|
|
||||||
gdk_font_unref(gPreeditFontset);
|
|
||||||
}
|
|
||||||
char xlfdbase[128];
|
|
||||||
sprintf(xlfdbase, "-*-*-medium-r-*-*-%d-*-*-*-*-*-*-*", height);
|
|
||||||
gPreeditFontset = gdk_fontset_load(xlfdbase);
|
|
||||||
if (gPreeditFontset) {
|
|
||||||
mXIC->SetPreeditFont(gPreeditFontset);
|
|
||||||
}
|
|
||||||
mXICFontSize = height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsWidget::SetXICSpotLocation(nsPoint aPoint)
|
|
||||||
{
|
|
||||||
if (mIMEEnable == PR_FALSE) return;
|
|
||||||
if (nsnull == mXIC) return;
|
|
||||||
if (mXIC) {
|
|
||||||
unsigned long x, y;
|
|
||||||
x = aPoint.x, y = aPoint.y;
|
|
||||||
GetXYFromPosition(&x, &y);
|
|
||||||
mXIC->SetPreeditSpotLocation(x, y);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
/********************** class ModalWidgetList ***********************/
|
/********************** class ModalWidgetList ***********************/
|
||||||
/* This silly little thing is a linked list of widgets that have been
|
/* This silly little thing is a linked list of widgets that have been
|
||||||
declared modal, in the order of their declaration. We do this only
|
declared modal, in the order of their declaration. We do this only
|
||||||
|
@ -2904,267 +2660,10 @@ static gint debugHandleWindowClose(GtkWidget *window, void *data)
|
||||||
|
|
||||||
#endif /* NS_DEBUG */
|
#endif /* NS_DEBUG */
|
||||||
|
|
||||||
#ifdef USE_XIM
|
void nsWidget::IMECommitEvent(GdkEventKey *aEvent) {
|
||||||
void
|
NS_ASSERTION(0, "nsWidget::IMECommitEvent() shouldn't be called!\n");
|
||||||
nsWidget::ime_preedit_start() {
|
|
||||||
IMEComposeStart(nsnull);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::ime_preedit_draw() {
|
|
||||||
IMEComposeStart(nsnull);
|
|
||||||
nsIMEPreedit *preedit = mXIC->GetPreedit();
|
|
||||||
IMEComposeText(nsnull,
|
|
||||||
preedit->GetPreeditString(),
|
|
||||||
preedit->GetPreeditLength(),
|
|
||||||
preedit->GetPreeditFeedback());
|
|
||||||
if (mXIC->IsPreeditComposing() == PR_FALSE) {
|
|
||||||
IMEComposeEnd(nsnull);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::ime_preedit_done() {
|
|
||||||
IMEComposeEnd(nsnull);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMEUnsetFocusWidget()
|
|
||||||
{
|
|
||||||
KillICSpotTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMESetFocusWidget()
|
|
||||||
{
|
|
||||||
if (!mXIC) {
|
|
||||||
GetXIC();
|
|
||||||
}
|
|
||||||
|
|
||||||
IMEGetShellWidget();
|
|
||||||
if (!mIMEShellWidget) return;
|
|
||||||
|
|
||||||
if (mXIC) {
|
|
||||||
if (mXIC->IsPreeditComposing() == PR_FALSE) {
|
|
||||||
IMEComposeEnd(nsnull);
|
|
||||||
}
|
|
||||||
mXIC->SetFocusWidget(this);
|
|
||||||
if (gInputStyle & GDK_IM_PREEDIT_POSITION) {
|
|
||||||
UpdateICSpot();
|
|
||||||
PrimeICSpotTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMEBeingActivate(PRBool aActive)
|
|
||||||
{
|
|
||||||
IMEGetShellWidget();
|
|
||||||
if (!mIMEShellWidget) return;
|
|
||||||
mIMEShellWidget->mIMEIsBeingActivate = aActive;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMEComposeStart(guint aTime)
|
|
||||||
{
|
|
||||||
#ifdef USE_XIM
|
|
||||||
if (mIMECallComposeStart == PR_TRUE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
nsCompositionEvent compEvent;
|
|
||||||
compEvent.widget = (nsWidget *) this;
|
|
||||||
compEvent.point.x = compEvent.point.y = 0;
|
|
||||||
compEvent.time = aTime;
|
|
||||||
compEvent.message = compEvent.eventStructType
|
|
||||||
= compEvent.compositionMessage = NS_COMPOSITION_START;
|
|
||||||
|
|
||||||
OnComposition(compEvent);
|
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
mIMECallComposeStart = PR_TRUE;
|
|
||||||
mIMECallComposeEnd = PR_FALSE;
|
|
||||||
#endif // USE_XIM
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMECommitEvent(GdkEventKey *aEvent) {
|
|
||||||
PRInt32 srcLen = aEvent->length;
|
|
||||||
|
|
||||||
if (srcLen && aEvent->string && aEvent->string[0] &&
|
|
||||||
nsGtkIMEHelper::GetSingleton()) {
|
|
||||||
|
|
||||||
PRInt32 uniCharSize;
|
|
||||||
uniCharSize = nsGtkIMEHelper::GetSingleton()->MultiByteToUnicode(
|
|
||||||
aEvent->string,
|
|
||||||
srcLen,
|
|
||||||
&(mIMECompositionUniString),
|
|
||||||
&(mIMECompositionUniStringSize));
|
|
||||||
|
|
||||||
if (uniCharSize) {
|
|
||||||
mIMECompositionUniString[uniCharSize] = 0;
|
|
||||||
if(sFocusWindow == 0 && mXIC != 0) {
|
|
||||||
// Commit event happens when Mozilla window does not have
|
|
||||||
// input focus but Lookup window (candidate) window has the focus
|
|
||||||
// At the case, we have to call IME events with focused widget
|
|
||||||
nsWidget *widget = mXIC->GetFocusWidget();
|
|
||||||
if (widget) {
|
|
||||||
widget->IMEComposeStart(aEvent->time);
|
|
||||||
widget->IMEComposeText(aEvent,
|
|
||||||
mIMECompositionUniString,
|
|
||||||
uniCharSize,
|
|
||||||
nsnull);
|
|
||||||
widget->IMEComposeEnd(aEvent->time);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
IMEComposeStart(aEvent->time);
|
|
||||||
IMEComposeText(aEvent,
|
|
||||||
mIMECompositionUniString,
|
|
||||||
uniCharSize,
|
|
||||||
nsnull);
|
|
||||||
IMEComposeEnd(aEvent->time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
if (gInputStyle & GDK_IM_PREEDIT_POSITION) {
|
|
||||||
// update spot location
|
|
||||||
IMEGetShellWidget();
|
|
||||||
if (!mIMEShellWidget) return;
|
|
||||||
nsIMEGtkIC *XIC_tmp = mXIC ? mXIC : mIMEShellWidget->mXIC;
|
|
||||||
if (XIC_tmp) {
|
|
||||||
nsWidget *widget = XIC_tmp->GetFocusWidget();
|
|
||||||
if (widget) {
|
|
||||||
widget->UpdateICSpot();
|
|
||||||
widget->PrimeICSpotTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMEComposeText(GdkEventKey *aEvent,
|
|
||||||
const PRUnichar *aText, const PRInt32 aLen,
|
|
||||||
const char *aFeedback) {
|
|
||||||
nsTextEvent textEvent;
|
|
||||||
if (aEvent) {
|
|
||||||
textEvent.isShift = (aEvent->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
|
|
||||||
textEvent.isControl = (aEvent->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
|
|
||||||
textEvent.isAlt = (aEvent->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
|
|
||||||
// XXX
|
|
||||||
textEvent.isMeta = PR_FALSE; //(aEvent->state & GDK_MOD2_MASK) ? PR_TRUE : PR_FALSE;
|
|
||||||
textEvent.time = aEvent->time;
|
|
||||||
} else {
|
|
||||||
textEvent.time = 0;
|
|
||||||
textEvent.isShift = textEvent.isControl =
|
|
||||||
textEvent.isAlt = textEvent.isMeta = PR_FALSE;
|
|
||||||
}
|
|
||||||
textEvent.message = textEvent.eventStructType = NS_TEXT_EVENT;
|
|
||||||
textEvent.widget = (nsWidget *)this;
|
|
||||||
textEvent.point.x = textEvent.point.y = 0;
|
|
||||||
|
|
||||||
if (aLen == 0) {
|
|
||||||
textEvent.theText = nsnull;
|
|
||||||
textEvent.rangeCount = 0;
|
|
||||||
textEvent.rangeArray = nsnull;
|
|
||||||
} else {
|
|
||||||
textEvent.theText = (PRUnichar*)aText;
|
|
||||||
textEvent.rangeCount = 0;
|
|
||||||
textEvent.rangeArray = nsnull;
|
|
||||||
#ifdef USE_XIM
|
|
||||||
if (aFeedback) {
|
|
||||||
nsIMEPreedit::IMSetTextRange(aLen,
|
|
||||||
aFeedback,
|
|
||||||
&(textEvent.rangeCount),
|
|
||||||
&(textEvent.rangeArray));
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
}
|
|
||||||
OnText(textEvent);
|
|
||||||
#ifdef USE_XIM
|
|
||||||
if (textEvent.rangeArray) {
|
|
||||||
delete[] textEvent.rangeArray;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMEComposeEnd(guint aTime)
|
|
||||||
{
|
|
||||||
#ifdef USE_XIM
|
|
||||||
if (mIMECallComposeEnd == PR_TRUE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
nsCompositionEvent compEvent;
|
|
||||||
compEvent.widget = (nsWidget *) this;
|
|
||||||
compEvent.point.x = compEvent.point.y = 0;
|
|
||||||
compEvent.time = aTime;
|
|
||||||
compEvent.message = compEvent.eventStructType
|
|
||||||
= compEvent.compositionMessage = NS_COMPOSITION_END;
|
|
||||||
OnComposition(compEvent);
|
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
mIMECallComposeStart = PR_FALSE;
|
|
||||||
mIMECallComposeEnd = PR_TRUE;
|
|
||||||
#endif // USE_XIM
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
void
|
|
||||||
nsWidget::IMEGetShellWidget(void)
|
|
||||||
{
|
|
||||||
if (!mIMEShellWidget) {
|
|
||||||
mIMEShellWidget = GetShellWidget((GdkWindow*)
|
|
||||||
GetNativeData(NS_NATIVE_WINDOW));
|
|
||||||
NS_ASSERTION(mIMEShellWidget, "GetShellWidget() fails");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: need to find more efficient way for finding the shell widget
|
|
||||||
static nsWidget *
|
|
||||||
GetShellWidget(GdkWindow *gdkWindow)
|
|
||||||
{
|
|
||||||
GdkWindow *parent = gdk_window_get_parent(gdkWindow);
|
|
||||||
nsWidget *root_win = nsnull;
|
|
||||||
gpointer data;
|
|
||||||
|
|
||||||
while (parent) {
|
|
||||||
gdk_window_get_user_data(parent, &data);
|
|
||||||
if (GTK_IS_OBJECT(data)) {
|
|
||||||
root_win = (nsWidget *) gtk_object_get_data(GTK_OBJECT(data), "nsWindow");
|
|
||||||
if(root_win && root_win->mIsToplevel == PR_TRUE){
|
|
||||||
return root_win;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent = gdk_window_get_parent(parent);
|
|
||||||
}
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsWidget::IMEDestroyIC()
|
|
||||||
{
|
|
||||||
if (!mXIC) return;
|
|
||||||
if (mIsToplevel == PR_TRUE) {
|
|
||||||
delete mXIC;
|
|
||||||
} else {
|
|
||||||
// see discussion in bug 53989
|
|
||||||
nsWidget *widget = mXIC->GetFocusWidget();
|
|
||||||
if (widget && widget == this && mIMEShellWidget) {
|
|
||||||
mXIC->SetFocusWidget(mIMEShellWidget);
|
|
||||||
mXIC->UnsetFocusWidget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mXIC = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
void nsWidget::DispatchSetFocusEvent(void)
|
void nsWidget::DispatchSetFocusEvent(void)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(0, "nsWidget::DispatchSetFocusEvent shouldn't be called!\n");
|
NS_ASSERTION(0, "nsWidget::DispatchSetFocusEvent shouldn't be called!\n");
|
||||||
|
|
|
@ -36,10 +36,6 @@
|
||||||
class nsILookAndFeel;
|
class nsILookAndFeel;
|
||||||
class nsIAppShell;
|
class nsIAppShell;
|
||||||
class nsIToolkit;
|
class nsIToolkit;
|
||||||
#ifdef USE_XIM
|
|
||||||
class nsIMEGtkIC;
|
|
||||||
class nsIMEPreedit;
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
@ -49,6 +45,7 @@ class nsIMEPreedit;
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsITimerCallback.h"
|
#include "nsITimerCallback.h"
|
||||||
|
|
||||||
|
|
||||||
#define NSRECT_TO_GDKRECT(ns,gdk) \
|
#define NSRECT_TO_GDKRECT(ns,gdk) \
|
||||||
PR_BEGIN_MACRO \
|
PR_BEGIN_MACRO \
|
||||||
gdk.x = ns.x; \
|
gdk.x = ns.x; \
|
||||||
|
@ -309,52 +306,8 @@ protected:
|
||||||
PRBool HandlePopup(PRInt32 inMouseX, PRInt32 inMouseY, PRBool isWheel);
|
PRBool HandlePopup(PRInt32 inMouseX, PRInt32 inMouseY, PRBool isWheel);
|
||||||
PRBool IsMouseInWindow ( GdkWindow* inWindow, PRInt32 inMouseX, PRInt32 inMouseY ) ;
|
PRBool IsMouseInWindow ( GdkWindow* inWindow, PRInt32 inMouseX, PRInt32 inMouseY ) ;
|
||||||
|
|
||||||
#ifdef USE_XIM
|
|
||||||
protected:
|
|
||||||
PRBool mIMEEnable;
|
|
||||||
void GetXIC();
|
|
||||||
static GdkFont *gPreeditFontset;
|
|
||||||
static GdkFont *gStatusFontset;
|
|
||||||
static GdkIMStyle gInputStyle;
|
|
||||||
nsIMEGtkIC *mXIC;
|
|
||||||
PRBool mIMECallComposeStart;
|
|
||||||
PRBool mIMECallComposeEnd;
|
|
||||||
PRBool mIMEIsBeingActivate;
|
|
||||||
nsWidget* mIMEShellWidget;
|
|
||||||
void SetXICSpotLocation(nsPoint aPoint);
|
|
||||||
void SetXICBaseFontSize(int height);
|
|
||||||
|
|
||||||
void GetXYFromPosition(unsigned long *aX, unsigned long *aY);
|
|
||||||
nsCOMPtr<nsITimer> mICSpotTimer;
|
|
||||||
static void ICSpotCallback(nsITimer* aTimer, void* aClosure);
|
|
||||||
nsresult KillICSpotTimer();
|
|
||||||
nsresult PrimeICSpotTimer();
|
|
||||||
nsresult UpdateICSpot();
|
|
||||||
int mXICFontSize;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ime_preedit_start();
|
virtual void IMECommitEvent(GdkEventKey *aEvent);
|
||||||
void ime_preedit_draw();
|
|
||||||
void ime_preedit_done();
|
|
||||||
void ime_status_draw();
|
|
||||||
|
|
||||||
void IMEUnsetFocusWidget();
|
|
||||||
void IMESetFocusWidget();
|
|
||||||
void IMEGetShellWidget();
|
|
||||||
void IMEDestroyIC();
|
|
||||||
void IMEBeingActivate(PRBool aActive);
|
|
||||||
#endif // USE_XIM
|
|
||||||
protected:
|
|
||||||
void IMEComposeStart(guint aTime);
|
|
||||||
void IMEComposeText(GdkEventKey*,
|
|
||||||
const PRUnichar *aText,
|
|
||||||
const PRInt32 aLen,
|
|
||||||
const char *aFeedback);
|
|
||||||
void IMEComposeEnd(guint aTime);
|
|
||||||
PRUnichar* mIMECompositionUniString;
|
|
||||||
PRInt32 mIMECompositionUniStringSize;
|
|
||||||
public:
|
|
||||||
void IMECommitEvent(GdkEventKey *aEvent);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@
|
||||||
#include "nsIDragService.h"
|
#include "nsIDragService.h"
|
||||||
#include "nsIDragSessionGTK.h"
|
#include "nsIDragSessionGTK.h"
|
||||||
|
|
||||||
|
#include "nsGtkIMEHelper.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef NEED_USLEEP_PROTOTYPE
|
#ifdef NEED_USLEEP_PROTOTYPE
|
||||||
|
@ -118,6 +120,20 @@ nsWindow *nsWindow::mLastLeaveWindow = NULL;
|
||||||
PRBool gJustGotDeactivate = PR_FALSE;
|
PRBool gJustGotDeactivate = PR_FALSE;
|
||||||
PRBool gJustGotActivate = PR_FALSE;
|
PRBool gJustGotActivate = PR_FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
|
||||||
|
struct nsXICLookupEntry {
|
||||||
|
PLDHashEntryHdr mKeyHash;
|
||||||
|
nsWindow* mShellWindow;
|
||||||
|
nsIMEGtkIC* mXIC;
|
||||||
|
};
|
||||||
|
|
||||||
|
PLDHashTable nsWindow::gXICLookupTable;
|
||||||
|
GdkFont *nsWindow::gPreeditFontset = nsnull;
|
||||||
|
GdkFont *nsWindow::gStatusFontset = nsnull;
|
||||||
|
GdkIMStyle nsWindow::gInputStyle = (GdkIMStyle)nsnull;
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
static void printDepth(int depth) {
|
static void printDepth(int depth) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i < depth; i++)
|
for (i=0; i < depth; i++)
|
||||||
|
@ -166,6 +182,23 @@ nsWindow::nsWindow()
|
||||||
mDragMotionY = 0;
|
mDragMotionY = 0;
|
||||||
mDragMotionTime = 0;
|
mDragMotionTime = 0;
|
||||||
|
|
||||||
|
// for commit character
|
||||||
|
mIMECompositionUniString = nsnull;
|
||||||
|
mIMECompositionUniStringSize = 0;
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
mIMEEnable = PR_TRUE; //currently will not be used
|
||||||
|
mIMEShellWindow = 0;
|
||||||
|
mIMECallComposeStart = PR_FALSE;
|
||||||
|
mIMECallComposeEnd = PR_TRUE;
|
||||||
|
mIMEIsBeingActivate = PR_FALSE;
|
||||||
|
mICSpotTimer = nsnull;
|
||||||
|
if (gXICLookupTable.ops == NULL) {
|
||||||
|
PL_DHashTableInit(&gXICLookupTable, PL_DHashGetStubOps(), nsnull,
|
||||||
|
sizeof(nsXICLookupEntry), PL_DHASH_MIN_SIZE);
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
// check to see if we should set our raise pref
|
// check to see if we should set our raise pref
|
||||||
if (!gRaisePrefInitialized) {
|
if (!gRaisePrefInitialized) {
|
||||||
gRaisePrefInitialized = PR_TRUE;
|
gRaisePrefInitialized = PR_TRUE;
|
||||||
|
@ -188,6 +221,15 @@ nsWindow::nsWindow()
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
nsWindow::~nsWindow()
|
nsWindow::~nsWindow()
|
||||||
{
|
{
|
||||||
|
#ifdef USE_XIM
|
||||||
|
KillICSpotTimer();
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
|
if (mIMECompositionUniString) {
|
||||||
|
delete[] mIMECompositionUniString;
|
||||||
|
mIMECompositionUniString = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure to unset any drag motion timers here.
|
// make sure to unset any drag motion timers here.
|
||||||
ResetDragMotionTimer(0, 0, 0, 0, 0);
|
ResetDragMotionTimer(0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
@ -310,14 +352,14 @@ NS_IMETHODIMP nsWindow::WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect)
|
||||||
void
|
void
|
||||||
nsWindow::DestroyNative(void)
|
nsWindow::DestroyNative(void)
|
||||||
{
|
{
|
||||||
#ifdef USE_XIM
|
|
||||||
IMEDestroyIC();
|
|
||||||
#endif // USE_XIM
|
|
||||||
|
|
||||||
// destroy all of the children that are nsWindow() classes
|
// destroy all of the children that are nsWindow() classes
|
||||||
// preempting the gdk destroy system.
|
// preempting the gdk destroy system.
|
||||||
DestroyNativeChildren();
|
DestroyNativeChildren();
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
IMEDestroyIC();
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
if (mSuperWin) {
|
if (mSuperWin) {
|
||||||
// remove the key from the hash table for the shell_window
|
// remove the key from the hash table for the shell_window
|
||||||
g_hash_table_remove(mWindowLookupTable, mSuperWin->shell_window);
|
g_hash_table_remove(mWindowLookupTable, mSuperWin->shell_window);
|
||||||
|
@ -1157,7 +1199,7 @@ nsWindow::SetFocus(PRBool aRaise)
|
||||||
mHasFocus = PR_TRUE;
|
mHasFocus = PR_TRUE;
|
||||||
|
|
||||||
#ifdef USE_XIM
|
#ifdef USE_XIM
|
||||||
if (sFocusWindow) sFocusWindow->IMESetFocusWidget();
|
IMESetFocusWindow();
|
||||||
#endif // USE_XIM
|
#endif // USE_XIM
|
||||||
|
|
||||||
DispatchSetFocusEvent();
|
DispatchSetFocusEvent();
|
||||||
|
@ -1172,6 +1214,22 @@ nsWindow::SetFocus(PRBool aRaise)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virtual */ void
|
||||||
|
nsWindow::LoseFocus(void)
|
||||||
|
{
|
||||||
|
// doesn't do anything. needed for nsWindow housekeeping, really.
|
||||||
|
if (mHasFocus == PR_FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
IMEUnsetFocusWindow();
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
|
sFocusWindow = 0;
|
||||||
|
mHasFocus = PR_FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void nsWindow::DispatchSetFocusEvent(void)
|
void nsWindow::DispatchSetFocusEvent(void)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_FOCUS
|
#ifdef DEBUG_FOCUS
|
||||||
|
@ -3487,3 +3545,481 @@ PRBool ChildWindow::IsChild() const
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
nsresult nsWindow::KillICSpotTimer ()
|
||||||
|
{
|
||||||
|
if(mICSpotTimer)
|
||||||
|
{
|
||||||
|
mICSpotTimer->Cancel();
|
||||||
|
mICSpotTimer = nsnull;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsWindow::PrimeICSpotTimer ()
|
||||||
|
{
|
||||||
|
KillICSpotTimer();
|
||||||
|
nsresult err;
|
||||||
|
mICSpotTimer = do_CreateInstance("@mozilla.org/timer;1", &err);
|
||||||
|
if (NS_FAILED(err))
|
||||||
|
return err;
|
||||||
|
mICSpotTimer->Init(ICSpotCallback, this, 1000);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsWindow::ICSpotCallback(nsITimer * aTimer, void * aClosure)
|
||||||
|
{
|
||||||
|
nsWindow *window= NS_REINTERPRET_CAST(nsWindow*, aClosure);
|
||||||
|
if( ! window) return;
|
||||||
|
nsresult res = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsIMEGtkIC *xic = window->IMEGetInputContext(PR_FALSE);
|
||||||
|
if (xic) {
|
||||||
|
res = window->UpdateICSpot(xic);
|
||||||
|
}
|
||||||
|
if(NS_SUCCEEDED(res))
|
||||||
|
{
|
||||||
|
window->PrimeICSpotTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsWindow::UpdateICSpot(nsIMEGtkIC *aXIC)
|
||||||
|
{
|
||||||
|
// set spot location
|
||||||
|
nsCompositionEvent compEvent;
|
||||||
|
compEvent.widget = NS_STATIC_CAST(nsWidget *, this);
|
||||||
|
compEvent.point.x = 0;
|
||||||
|
compEvent.point.y = 0;
|
||||||
|
compEvent.time = 0;
|
||||||
|
compEvent.message = NS_COMPOSITION_QUERY;
|
||||||
|
compEvent.eventStructType = NS_COMPOSITION_QUERY;
|
||||||
|
compEvent.compositionMessage = NS_COMPOSITION_QUERY;
|
||||||
|
static gint oldx =0;
|
||||||
|
static gint oldy =0;
|
||||||
|
static gint oldw =0;
|
||||||
|
static gint oldh =0;
|
||||||
|
compEvent.theReply.mCursorPosition.x=-1;
|
||||||
|
compEvent.theReply.mCursorPosition.y=-1;
|
||||||
|
this->OnComposition(compEvent);
|
||||||
|
// set SpotLocation
|
||||||
|
if((compEvent.theReply.mCursorPosition.x < 0) &&
|
||||||
|
(compEvent.theReply.mCursorPosition.y < 0))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// In over-the-spot style, pre-edit can not be drawn properly when
|
||||||
|
// IMESetFocusWindow() is called at height=1 and width=1
|
||||||
|
// After resizing, we need to call SetPreeditArea() again
|
||||||
|
if((oldw != mBounds.width) || (oldh != mBounds.height)) {
|
||||||
|
GdkWindow *gdkWindow = (GdkWindow*)this->GetNativeData(NS_NATIVE_WINDOW);
|
||||||
|
if (gdkWindow) {
|
||||||
|
aXIC->SetPreeditArea(0, 0,
|
||||||
|
(int)((GdkWindowPrivate*)gdkWindow)->width,
|
||||||
|
(int)((GdkWindowPrivate*)gdkWindow)->height);
|
||||||
|
}
|
||||||
|
oldw = mBounds.width;
|
||||||
|
oldh = mBounds.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((compEvent.theReply.mCursorPosition.x != oldx)||
|
||||||
|
(compEvent.theReply.mCursorPosition.y != oldy))
|
||||||
|
{
|
||||||
|
nsPoint spot;
|
||||||
|
spot.x = compEvent.theReply.mCursorPosition.x;
|
||||||
|
spot.y = compEvent.theReply.mCursorPosition.y +
|
||||||
|
compEvent.theReply.mCursorPosition.height;
|
||||||
|
SetXICBaseFontSize(aXIC, compEvent.theReply.mCursorPosition.height - 1);
|
||||||
|
SetXICSpotLocation(aXIC, spot);
|
||||||
|
oldx = compEvent.theReply.mCursorPosition.x;
|
||||||
|
oldy = compEvent.theReply.mCursorPosition.y;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::GetXYFromPosition(nsIMEGtkIC* aXIC,
|
||||||
|
unsigned long *aX,
|
||||||
|
unsigned long *aY)
|
||||||
|
{
|
||||||
|
GdkFont *gfontset = aXIC->GetPreeditFont();
|
||||||
|
if (gfontset) {
|
||||||
|
// this is currently not working well
|
||||||
|
// We change from += ascent to -= descent because we change the nsCaret
|
||||||
|
// code to return the nsPoint from the top of the cursor to the bottom
|
||||||
|
// of the cursor
|
||||||
|
*aY -= gfontset->descent;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::SetXICBaseFontSize(nsIMEGtkIC* aXIC, int height)
|
||||||
|
{
|
||||||
|
if (height == mXICFontSize) return;
|
||||||
|
if (height%2) {
|
||||||
|
height-=1;
|
||||||
|
}
|
||||||
|
if (height<2) return;
|
||||||
|
if (gPreeditFontset) {
|
||||||
|
gdk_font_unref(gPreeditFontset);
|
||||||
|
}
|
||||||
|
char xlfdbase[128];
|
||||||
|
sprintf(xlfdbase, "-*-*-medium-r-*-*-%d-*-*-*-*-*-*-*", height);
|
||||||
|
gPreeditFontset = gdk_fontset_load(xlfdbase);
|
||||||
|
if (gPreeditFontset) {
|
||||||
|
aXIC->SetPreeditFont(gPreeditFontset);
|
||||||
|
}
|
||||||
|
mXICFontSize = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::SetXICSpotLocation(nsIMEGtkIC* aXIC, nsPoint aPoint)
|
||||||
|
{
|
||||||
|
unsigned long x, y;
|
||||||
|
x = aPoint.x, y = aPoint.y;
|
||||||
|
GetXYFromPosition(aXIC, &x, &y);
|
||||||
|
aXIC->SetPreeditSpotLocation(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::ime_preedit_start() {
|
||||||
|
IMEComposeStart(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::ime_preedit_draw(nsIMEGtkIC *aXIC) {
|
||||||
|
IMEComposeStart(nsnull);
|
||||||
|
nsIMEPreedit *preedit = aXIC->GetPreedit();
|
||||||
|
IMEComposeText(nsnull,
|
||||||
|
preedit->GetPreeditString(),
|
||||||
|
preedit->GetPreeditLength(),
|
||||||
|
preedit->GetPreeditFeedback());
|
||||||
|
if (aXIC->IsPreeditComposing() == PR_FALSE) {
|
||||||
|
IMEComposeEnd(nsnull);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::ime_preedit_done() {
|
||||||
|
IMEComposeEnd(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEUnsetFocusWindow()
|
||||||
|
{
|
||||||
|
KillICSpotTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMESetFocusWindow()
|
||||||
|
{
|
||||||
|
// there is only one place to get ShellWindow
|
||||||
|
IMEGetShellWindow();
|
||||||
|
|
||||||
|
nsIMEGtkIC *xic = IMEGetInputContext(PR_TRUE);
|
||||||
|
|
||||||
|
if (xic) {
|
||||||
|
if (xic->IsPreeditComposing() == PR_FALSE) {
|
||||||
|
IMEComposeEnd(nsnull);
|
||||||
|
}
|
||||||
|
xic->SetFocusWindow(this);
|
||||||
|
if (gInputStyle & GDK_IM_PREEDIT_POSITION) {
|
||||||
|
UpdateICSpot(xic);
|
||||||
|
PrimeICSpotTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEBeingActivate(PRBool aActive)
|
||||||
|
{
|
||||||
|
// mIMEShellWindow has been retrieved in IMESetFocusWindow()
|
||||||
|
if (mIMEShellWindow) {
|
||||||
|
mIMEShellWindow->mIMEIsBeingActivate = aActive;
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(0, "mIMEShellWindow should exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEGetShellWindow(void)
|
||||||
|
{
|
||||||
|
if (!mIMEShellWindow) {
|
||||||
|
nsWindow *mozAreaWindow = nsnull;
|
||||||
|
GtkWidget *top_mozarea = GetMozArea();
|
||||||
|
if (top_mozarea) {
|
||||||
|
mozAreaWindow = NS_STATIC_CAST(nsWindow *,
|
||||||
|
gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow"));
|
||||||
|
}
|
||||||
|
mIMEShellWindow = mozAreaWindow;
|
||||||
|
NS_ASSERTION(mIMEShellWindow, "IMEGetShellWindow() fails");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIMEGtkIC*
|
||||||
|
nsWindow::IMEGetInputContext(PRBool aCreate)
|
||||||
|
{
|
||||||
|
PLDHashEntryHdr* hash_entry;
|
||||||
|
nsXICLookupEntry* entry;
|
||||||
|
|
||||||
|
if (!mIMEShellWindow) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_entry = PL_DHashTableOperate(&gXICLookupTable, mIMEShellWindow, PL_DHASH_LOOKUP);
|
||||||
|
|
||||||
|
if (hash_entry) {
|
||||||
|
entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry);
|
||||||
|
if (entry->mXIC) {
|
||||||
|
return entry->mXIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new XIC
|
||||||
|
if (aCreate) {
|
||||||
|
if (gInputStyle == nsnull) {
|
||||||
|
gInputStyle = nsIMEGtkIC::GetInputStyle();
|
||||||
|
}
|
||||||
|
if (gPreeditFontset == nsnull) {
|
||||||
|
gPreeditFontset = gdk_fontset_load("-*-*-medium-r-*-*-16-*-*-*-*-*-*-*");
|
||||||
|
mXICFontSize = 16; // default
|
||||||
|
}
|
||||||
|
if (gStatusFontset == nsnull) {
|
||||||
|
gStatusFontset = gdk_fontset_load("-*-*-medium-r-*-*-16-*-*-*-*-*-*-*");
|
||||||
|
}
|
||||||
|
if (!gInputStyle || !gPreeditFontset || !gStatusFontset) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
nsIMEGtkIC *xic = nsIMEGtkIC::GetXIC(mIMEShellWindow, gPreeditFontset,
|
||||||
|
gStatusFontset);
|
||||||
|
if (xic) {
|
||||||
|
xic->SetPreeditSpotLocation(0, 14);
|
||||||
|
hash_entry = PL_DHashTableOperate(&gXICLookupTable,
|
||||||
|
mIMEShellWindow,
|
||||||
|
PL_DHASH_ADD);
|
||||||
|
if (hash_entry) {
|
||||||
|
entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry);
|
||||||
|
entry->mShellWindow = mIMEShellWindow;
|
||||||
|
entry->mXIC = xic;
|
||||||
|
}
|
||||||
|
mIMEShellWindow->mIMEShellWindow = mIMEShellWindow;
|
||||||
|
return xic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEDestroyIC()
|
||||||
|
{
|
||||||
|
// do not call IMEGetShellWindow() here
|
||||||
|
// user mIMEShellWindow to retrieve XIC
|
||||||
|
nsIMEGtkIC *xic = IMEGetInputContext(PR_FALSE);
|
||||||
|
|
||||||
|
// xic=null means mIMEShellWindow is destroyed before
|
||||||
|
// or xic is never created for this widget
|
||||||
|
if (!xic) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIMEShellWindow == this) {
|
||||||
|
// shell widget is being destroyed
|
||||||
|
// remove XIC from hashtable by mIMEShellWindow key
|
||||||
|
PL_DHashTableOperate(&gXICLookupTable, mIMEShellWindow, PL_DHASH_REMOVE);
|
||||||
|
delete xic;
|
||||||
|
} else {
|
||||||
|
// xic and mIMEShellWindow are valid
|
||||||
|
// see discussion in bug 53989
|
||||||
|
nsWindow *fwin = xic->GetFocusWindow();
|
||||||
|
if (fwin && fwin == this) {
|
||||||
|
xic->SetFocusWindow(mIMEShellWindow);
|
||||||
|
xic->UnsetFocusWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEComposeStart(guint aTime)
|
||||||
|
{
|
||||||
|
#ifdef USE_XIM
|
||||||
|
if (mIMECallComposeStart == PR_TRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
nsCompositionEvent compEvent;
|
||||||
|
compEvent.widget = NS_STATIC_CAST(nsWidget *, this);
|
||||||
|
compEvent.point.x = compEvent.point.y = 0;
|
||||||
|
compEvent.time = aTime;
|
||||||
|
compEvent.message = compEvent.eventStructType
|
||||||
|
= compEvent.compositionMessage = NS_COMPOSITION_START;
|
||||||
|
|
||||||
|
OnComposition(compEvent);
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
mIMECallComposeStart = PR_TRUE;
|
||||||
|
mIMECallComposeEnd = PR_FALSE;
|
||||||
|
#endif // USE_XIM
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMECommitEvent(GdkEventKey *aEvent) {
|
||||||
|
PRInt32 srcLen = aEvent->length;
|
||||||
|
|
||||||
|
if (srcLen && aEvent->string && aEvent->string[0] &&
|
||||||
|
nsGtkIMEHelper::GetSingleton()) {
|
||||||
|
|
||||||
|
PRInt32 uniCharSize;
|
||||||
|
uniCharSize = nsGtkIMEHelper::GetSingleton()->MultiByteToUnicode(
|
||||||
|
aEvent->string,
|
||||||
|
srcLen,
|
||||||
|
&(mIMECompositionUniString),
|
||||||
|
&(mIMECompositionUniStringSize));
|
||||||
|
|
||||||
|
if (uniCharSize) {
|
||||||
|
#ifdef USE_XIM
|
||||||
|
nsIMEGtkIC *xic = IMEGetInputContext(PR_FALSE);
|
||||||
|
mIMECompositionUniString[uniCharSize] = 0;
|
||||||
|
if(sFocusWindow == 0 && xic != 0) {
|
||||||
|
// Commit event happens when Mozilla window does not have
|
||||||
|
// input focus but Lookup window (candidate) window has the focus
|
||||||
|
// At the case, we have to call IME events with focused widget
|
||||||
|
nsWindow *window = xic->GetFocusWindow();
|
||||||
|
if (window) {
|
||||||
|
window->IMEComposeStart(aEvent->time);
|
||||||
|
window->IMEComposeText(aEvent,
|
||||||
|
mIMECompositionUniString,
|
||||||
|
uniCharSize,
|
||||||
|
nsnull);
|
||||||
|
window->IMEComposeEnd(aEvent->time);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif // USE_XIM
|
||||||
|
{
|
||||||
|
IMEComposeStart(aEvent->time);
|
||||||
|
IMEComposeText(aEvent,
|
||||||
|
mIMECompositionUniString,
|
||||||
|
uniCharSize,
|
||||||
|
nsnull);
|
||||||
|
IMEComposeEnd(aEvent->time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
if (gInputStyle & GDK_IM_PREEDIT_POSITION) {
|
||||||
|
// update spot location
|
||||||
|
nsIMEGtkIC *xic = IMEGetInputContext(PR_FALSE);
|
||||||
|
if (xic) {
|
||||||
|
nsWindow *window = xic->GetFocusWindow();
|
||||||
|
if (window) {
|
||||||
|
window->UpdateICSpot(xic);
|
||||||
|
window->PrimeICSpotTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEComposeText(GdkEventKey *aEvent,
|
||||||
|
const PRUnichar *aText, const PRInt32 aLen,
|
||||||
|
const char *aFeedback) {
|
||||||
|
nsTextEvent textEvent;
|
||||||
|
if (aEvent) {
|
||||||
|
textEvent.isShift = (aEvent->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
|
||||||
|
textEvent.isControl = (aEvent->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
|
||||||
|
textEvent.isAlt = (aEvent->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
|
||||||
|
// XXX
|
||||||
|
textEvent.isMeta = PR_FALSE; //(aEvent->state & GDK_MOD2_MASK) ? PR_TRUE : PR_FALSE;
|
||||||
|
textEvent.time = aEvent->time;
|
||||||
|
} else {
|
||||||
|
textEvent.time = 0;
|
||||||
|
textEvent.isShift = textEvent.isControl =
|
||||||
|
textEvent.isAlt = textEvent.isMeta = PR_FALSE;
|
||||||
|
}
|
||||||
|
textEvent.message = textEvent.eventStructType = NS_TEXT_EVENT;
|
||||||
|
textEvent.widget = NS_STATIC_CAST(nsWidget *, this);
|
||||||
|
textEvent.point.x = textEvent.point.y = 0;
|
||||||
|
|
||||||
|
if (aLen == 0) {
|
||||||
|
textEvent.theText = nsnull;
|
||||||
|
textEvent.rangeCount = 0;
|
||||||
|
textEvent.rangeArray = nsnull;
|
||||||
|
} else {
|
||||||
|
textEvent.theText = (PRUnichar*)aText;
|
||||||
|
textEvent.rangeCount = 0;
|
||||||
|
textEvent.rangeArray = nsnull;
|
||||||
|
#ifdef USE_XIM
|
||||||
|
if (aFeedback) {
|
||||||
|
nsIMEPreedit::IMSetTextRange(aLen,
|
||||||
|
aFeedback,
|
||||||
|
&(textEvent.rangeCount),
|
||||||
|
&(textEvent.rangeArray));
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
}
|
||||||
|
OnText(textEvent);
|
||||||
|
#ifdef USE_XIM
|
||||||
|
if (textEvent.rangeArray) {
|
||||||
|
delete[] textEvent.rangeArray;
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::IMEComposeEnd(guint aTime)
|
||||||
|
{
|
||||||
|
#ifdef USE_XIM
|
||||||
|
if (mIMECallComposeEnd == PR_TRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
|
nsCompositionEvent compEvent;
|
||||||
|
compEvent.widget = NS_STATIC_CAST(nsWidget*, this);
|
||||||
|
compEvent.point.x = compEvent.point.y = 0;
|
||||||
|
compEvent.time = aTime;
|
||||||
|
compEvent.message = compEvent.eventStructType
|
||||||
|
= compEvent.compositionMessage = NS_COMPOSITION_END;
|
||||||
|
OnComposition(compEvent);
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
mIMECallComposeStart = PR_FALSE;
|
||||||
|
mIMECallComposeEnd = PR_TRUE;
|
||||||
|
#endif // USE_XIM
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsWindow::ResetInputState()
|
||||||
|
{
|
||||||
|
#ifdef USE_XIM
|
||||||
|
nsIMEGtkIC *xic = IMEGetInputContext(PR_FALSE);
|
||||||
|
if (xic) {
|
||||||
|
// while being called for NS_ACTIVE and NS_DEACTIVATE,
|
||||||
|
// ignore ResetInputState() call
|
||||||
|
if (mIMEShellWindow->mIMEIsBeingActivate == PR_TRUE) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt32 uniCharSize =
|
||||||
|
xic->ResetIC(&(mIMECompositionUniString),
|
||||||
|
&(mIMECompositionUniStringSize));
|
||||||
|
|
||||||
|
if (uniCharSize) {
|
||||||
|
mIMECompositionUniString[uniCharSize] = 0;
|
||||||
|
|
||||||
|
IMEComposeStart(nsnull);
|
||||||
|
IMEComposeText(nsnull,
|
||||||
|
mIMECompositionUniString,
|
||||||
|
uniCharSize,
|
||||||
|
nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call IMEComposeEnd() to reset the state of field
|
||||||
|
IMEComposeEnd(nsnull);
|
||||||
|
if (gInputStyle & GDK_IM_PREEDIT_POSITION) {
|
||||||
|
UpdateICSpot(xic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_XIM
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,12 @@
|
||||||
#include "gtkmozarea.h"
|
#include "gtkmozarea.h"
|
||||||
#include "gdksuperwin.h"
|
#include "gdksuperwin.h"
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
#include "pldhash.h"
|
||||||
|
class nsIMEGtkIC;
|
||||||
|
class nsIMEPreedit;
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
class nsFont;
|
class nsFont;
|
||||||
class nsIAppShell;
|
class nsIAppShell;
|
||||||
|
|
||||||
|
@ -89,6 +95,11 @@ public:
|
||||||
NS_IMETHOD GetAttention(void);
|
NS_IMETHOD GetAttention(void);
|
||||||
NS_IMETHOD Destroy();
|
NS_IMETHOD Destroy();
|
||||||
|
|
||||||
|
virtual void LoseFocus(void);
|
||||||
|
|
||||||
|
// nsIKBStateControl
|
||||||
|
NS_IMETHOD ResetInputState();
|
||||||
|
|
||||||
void QueueDraw();
|
void QueueDraw();
|
||||||
void UnqueueDraw();
|
void UnqueueDraw();
|
||||||
void DoPaint(PRInt32 x, PRInt32 y, PRInt32 width, PRInt32 height,
|
void DoPaint(PRInt32 x, PRInt32 y, PRInt32 width, PRInt32 height,
|
||||||
|
@ -309,7 +320,56 @@ protected:
|
||||||
static void dumpWindowChildren(Window aWindow, unsigned int depth);
|
static void dumpWindowChildren(Window aWindow, unsigned int depth);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_XIM
|
||||||
|
protected:
|
||||||
|
nsIMEGtkIC* IMEGetInputContext(PRBool aCreate);
|
||||||
|
PRBool mIMEEnable;
|
||||||
|
static GdkFont *gPreeditFontset;
|
||||||
|
static GdkFont *gStatusFontset;
|
||||||
|
static GdkIMStyle gInputStyle;
|
||||||
|
static PLDHashTable gXICLookupTable;
|
||||||
|
PRBool mIMECallComposeStart;
|
||||||
|
PRBool mIMECallComposeEnd;
|
||||||
|
PRBool mIMEIsBeingActivate;
|
||||||
|
nsWindow* mIMEShellWindow;
|
||||||
|
void SetXICSpotLocation(nsIMEGtkIC* aXIC, nsPoint aPoint);
|
||||||
|
void SetXICBaseFontSize(nsIMEGtkIC* aXIC, int height);
|
||||||
|
void GetXYFromPosition(nsIMEGtkIC* aXIC, unsigned long *aX, unsigned long *aY);
|
||||||
|
nsCOMPtr<nsITimer> mICSpotTimer;
|
||||||
|
static void ICSpotCallback(nsITimer* aTimer, void* aClosure);
|
||||||
|
nsresult KillICSpotTimer();
|
||||||
|
nsresult PrimeICSpotTimer();
|
||||||
|
nsresult UpdateICSpot(nsIMEGtkIC* aXIC);
|
||||||
|
int mXICFontSize;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void ime_preedit_start();
|
||||||
|
void ime_preedit_draw(nsIMEGtkIC* aXIC);
|
||||||
|
void ime_preedit_done();
|
||||||
|
void ime_status_draw();
|
||||||
|
|
||||||
|
void IMEUnsetFocusWindow();
|
||||||
|
void IMESetFocusWindow();
|
||||||
|
void IMEGetShellWindow();
|
||||||
|
void IMEDestroyIC();
|
||||||
|
void IMEBeingActivate(PRBool aActive);
|
||||||
|
#endif // USE_XIM
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void IMEComposeStart(guint aTime);
|
||||||
|
void IMEComposeText(GdkEventKey*,
|
||||||
|
const PRUnichar *aText,
|
||||||
|
const PRInt32 aLen,
|
||||||
|
const char *aFeedback);
|
||||||
|
void IMEComposeEnd(guint aTime);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void IMECommitEvent(GdkEventKey *aEvent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PRUnichar* mIMECompositionUniString;
|
||||||
|
PRInt32 mIMECompositionUniStringSize;
|
||||||
|
|
||||||
nsresult SetMiniIcon(GdkPixmap *window_pixmap,
|
nsresult SetMiniIcon(GdkPixmap *window_pixmap,
|
||||||
GdkBitmap *window_mask);
|
GdkBitmap *window_mask);
|
||||||
nsresult SetIcon(GdkPixmap *window_pixmap,
|
nsresult SetIcon(GdkPixmap *window_pixmap,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче