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:
tajima%eng.sun.com 2001-05-15 03:08:08 +00:00
Родитель 906a287308
Коммит bca2539c53
6 изменённых файлов: 645 добавлений и 598 удалений

Просмотреть файл

@ -31,7 +31,6 @@
#include "nsIPref.h"
#include <X11/Xatom.h>
#include "nsWidget.h"
#include "nsWindow.h"
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;
if (!thisXIC) return 0;
nsWidget *widget = thisXIC->mFocusWidget;
if (!widget) return 0;
nsWindow *fwin = thisXIC->mFocusWindow;
if (!fwin) return 0;
if (!thisXIC->mPreedit) {
thisXIC->mPreedit = new nsIMEPreedit();
}
thisXIC->mPreedit->Reset();
widget->ime_preedit_start();
fwin->ime_preedit_start();
return 0;
}
@ -834,8 +833,8 @@ nsIMEGtkIC::preedit_draw_cbproc(XIC xic, XPointer client_data,
{
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
if (!thisXIC) return 0;
nsWidget *widget = thisXIC->mFocusWidget;
if (!widget) return 0;
nsWindow *fwin = thisXIC->mFocusWindow;
if (!fwin) return 0;
XIMPreeditDrawCallbackStruct *call_data =
(XIMPreeditDrawCallbackStruct *) call_data_p;
@ -847,7 +846,7 @@ nsIMEGtkIC::preedit_draw_cbproc(XIC xic, XPointer client_data,
thisXIC->mPreedit->SetPreeditString(text,
call_data->chg_first,
call_data->chg_length);
widget->ime_preedit_draw();
fwin->ime_preedit_draw(thisXIC);
return 0;
}
@ -864,10 +863,10 @@ nsIMEGtkIC::preedit_done_cbproc(XIC xic, XPointer client_data,
{
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
if (!thisXIC) return 0;
nsWidget *widget = thisXIC->mFocusWidget;
if (!widget) return 0;
nsWindow *fwin = thisXIC->mFocusWindow;
if (!fwin) return 0;
widget->ime_preedit_done();
fwin->ime_preedit_done();
return 0;
}
@ -877,8 +876,8 @@ nsIMEGtkIC::status_start_cbproc(XIC xic, XPointer client_data,
{
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
if (!thisXIC) return 0;
nsWidget *widget = thisXIC->mFocusWidget;
if (!widget) return 0;
nsWindow *fwin = thisXIC->mFocusWindow;
if (!fwin) return 0;
if (!gStatus) return 0;
// focus_window is changed
@ -893,8 +892,8 @@ nsIMEGtkIC::status_draw_cbproc(XIC xic, XPointer client_data,
{
nsIMEGtkIC *thisXIC = (nsIMEGtkIC*)client_data;
if (!thisXIC) return 0;
nsWidget *widget = thisXIC->mFocusWidget;
if (!widget) return 0;
nsWindow *fwin = thisXIC->mFocusWindow;
if (!fwin) return 0;
if (!gStatus) return 0;
@ -939,10 +938,10 @@ nsIMEGtkIC::status_done_cbproc(XIC xic, XPointer client_data,
return 0;
}
nsWidget *
nsIMEGtkIC::GetFocusWidget()
nsWindow *
nsIMEGtkIC::GetFocusWindow()
{
return mFocusWidget;
return mFocusWindow;
}
// workaround for kinput2/over-the-spot/ic-per-shell
@ -965,10 +964,10 @@ nsIMEGtkIC::GetFocusWidget()
// *OverTheSpotConversion.modeLocation: bottomleft
void
nsIMEGtkIC::SetFocusWidget(nsWidget * aFocusWidget)
nsIMEGtkIC::SetFocusWindow(nsWindow * aFocusWindow)
{
mFocusWidget = aFocusWidget;
GdkWindow *gdkWindow = (GdkWindow*)aFocusWidget->GetNativeData(NS_NATIVE_WINDOW);
mFocusWindow = aFocusWindow;
GdkWindow *gdkWindow = (GdkWindow*)aFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
if (!gdkWindow) return;
gdk_im_begin((GdkIC *) mIC, gdkWindow);
@ -987,20 +986,20 @@ nsIMEGtkIC::SetFocusWidget(nsWidget * aFocusWidget)
}
void
nsIMEGtkIC::UnsetFocusWidget()
nsIMEGtkIC::UnsetFocusWindow()
{
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)
{
nsIMEGtkIC *newic = new nsIMEGtkIC(aFocusWidget, aFontSet, aStatusFontSet);
nsIMEGtkIC *newic = new nsIMEGtkIC(aFocusWindow, aFontSet, aStatusFontSet);
if (!newic->mIC || !newic->mIC->xic) {
delete newic;
return nsnull;
@ -1032,7 +1031,7 @@ nsIMEGtkIC::~nsIMEGtkIC()
mIC = 0;
mIC_backup = 0;
mPreedit = 0;
mFocusWidget = 0;
mFocusWindow = 0;
}
// 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)
{
mFocusWidget = 0;
mFocusWindow = 0;
mIC = 0;
mIC_backup = 0;
mPreedit = 0;
GdkWindow *gdkWindow = (GdkWindow *) aFocusWidget->GetNativeData(NS_NATIVE_WINDOW);
GdkWindow *gdkWindow = (GdkWindow *) aFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
if (!gdkWindow) {
return;
}

Просмотреть файл

@ -110,7 +110,7 @@ typedef struct {
XIMProc1 callback;
} XIMCallback1;
class nsWidget;
class nsWindow;
enum nsIMEPolicy {
NSIME_UNKNOWN=0,
@ -130,10 +130,10 @@ class nsIMEGtkIC {
static GdkIMStyle gInputStyle;
static nsIMEPolicy gInputPolicy;
static nsIMEStatus *gStatus;
nsWidget *mClientWidget;
nsWidget *mFocusWidget;
nsIMEGtkIC(nsWidget*, GdkFont*, GdkFont*);
nsIMEGtkIC(nsWidget*, GdkFont*);
nsWindow *mClientWindow;
nsWindow *mFocusWindow;
nsIMEGtkIC(nsWindow*, GdkFont*, GdkFont*);
nsIMEGtkIC(nsWindow*, GdkFont*);
GdkICPrivate *mIC;
GdkICPrivate *mIC_backup;
nsIMEPreedit *mPreedit;
@ -141,11 +141,11 @@ class nsIMEGtkIC {
public:
nsIMEPreedit *GetPreedit() {return mPreedit;}
~nsIMEGtkIC();
static nsIMEGtkIC *GetXIC(nsWidget*, GdkFont*, GdkFont*);
static nsIMEGtkIC *GetXIC(nsWidget*, GdkFont*);
void SetFocusWidget(nsWidget * aFocusWidget);
nsWidget* GetFocusWidget();
static void UnsetFocusWidget();
static nsIMEGtkIC *GetXIC(nsWindow*, GdkFont*, GdkFont*);
static nsIMEGtkIC *GetXIC(nsWindow*, GdkFont*);
void SetFocusWindow(nsWindow * aFocusWindow);
nsWindow* GetFocusWindow();
static void UnsetFocusWindow();
static GdkIMStyle GetInputStyle();
static nsIMEPolicy GetInputPolicy();

Просмотреть файл

@ -42,7 +42,6 @@
#include "nsGtkUtils.h" // for nsGtkUtils::gdk_keyboard_get_modifiers()
#include "nsIPref.h"
#include "nsGtkIMEHelper.h"
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
@ -67,18 +66,11 @@ private:
*mLast; // valid only for head of list
};
static nsWidget *GetShellWidget(GdkWindow *gdkWindow);
PRUint32 nsWidget::sWidgetCount = 0;
// this is the nsWindow with the focus
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
// around so that we can synth drag events properly
guint32 nsWidget::sLastEventTime = 0;
@ -118,89 +110,6 @@ void nsWidget::GetLastEventTime(guint32 *aTime)
*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;
nsWeakPtr nsWidget::gRollupWidget;
PRBool nsWidget::gRollupConsumeRollupEvent = PR_FALSE;
@ -268,20 +177,6 @@ nsWidget::nsWidget()
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;
mHasFocus = PR_FALSE;
if (mGDKHandlerInstalled == PR_FALSE) {
@ -320,11 +215,6 @@ nsWidget::nsWidget()
nsWidget::~nsWidget()
{
#ifdef USE_XIM
mXIC = 0;
KillICSpotTimer();
#endif // USE_XIM
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWidget::~nsWidget:%p\n", this);
@ -336,10 +226,6 @@ nsWidget::~nsWidget()
// to be called once
Destroy();
if (mIMECompositionUniString) {
delete[] mIMECompositionUniString;
mIMECompositionUniString = nsnull;
}
NS_ASSERTION(!ModalWidgetList::Find(this), "destroying widget without first clearing modality.");
#ifdef NS_DEBUG
if (mIsToplevel) {
@ -727,10 +613,6 @@ nsWidget::LoseFocus(void)
if (mHasFocus == PR_FALSE)
return;
#ifdef USE_XIM
IMEUnsetFocusWidget();
#endif // USE_XIM
sFocusWindow = 0;
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()
{
#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;
}
#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 ***********************/
/* 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
@ -2904,267 +2660,10 @@ static gint debugHandleWindowClose(GtkWidget *window, void *data)
#endif /* NS_DEBUG */
#ifdef USE_XIM
void
nsWidget::ime_preedit_start() {
IMEComposeStart(nsnull);
void nsWidget::IMECommitEvent(GdkEventKey *aEvent) {
NS_ASSERTION(0, "nsWidget::IMECommitEvent() shouldn't be called!\n");
}
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)
{
NS_ASSERTION(0, "nsWidget::DispatchSetFocusEvent shouldn't be called!\n");

Просмотреть файл

@ -36,10 +36,6 @@
class nsILookAndFeel;
class nsIAppShell;
class nsIToolkit;
#ifdef USE_XIM
class nsIMEGtkIC;
class nsIMEPreedit;
#endif // USE_XIM
#include <gtk/gtk.h>
@ -49,6 +45,7 @@ class nsIMEPreedit;
#include "nsITimer.h"
#include "nsITimerCallback.h"
#define NSRECT_TO_GDKRECT(ns,gdk) \
PR_BEGIN_MACRO \
gdk.x = ns.x; \
@ -309,52 +306,8 @@ protected:
PRBool HandlePopup(PRInt32 inMouseX, PRInt32 inMouseY, PRBool isWheel);
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:
void ime_preedit_start();
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);
virtual void IMECommitEvent(GdkEventKey *aEvent);
protected:

Просмотреть файл

@ -59,6 +59,8 @@
#include "nsIDragService.h"
#include "nsIDragSessionGTK.h"
#include "nsGtkIMEHelper.h"
#include <unistd.h>
#ifdef NEED_USLEEP_PROTOTYPE
@ -118,6 +120,20 @@ nsWindow *nsWindow::mLastLeaveWindow = NULL;
PRBool gJustGotDeactivate = 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) {
int i;
for (i=0; i < depth; i++)
@ -166,6 +182,23 @@ nsWindow::nsWindow()
mDragMotionY = 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
if (!gRaisePrefInitialized) {
gRaisePrefInitialized = PR_TRUE;
@ -188,6 +221,15 @@ 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.
ResetDragMotionTimer(0, 0, 0, 0, 0);
@ -310,14 +352,14 @@ NS_IMETHODIMP nsWindow::WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect)
void
nsWindow::DestroyNative(void)
{
#ifdef USE_XIM
IMEDestroyIC();
#endif // USE_XIM
// destroy all of the children that are nsWindow() classes
// preempting the gdk destroy system.
DestroyNativeChildren();
#ifdef USE_XIM
IMEDestroyIC();
#endif // USE_XIM
if (mSuperWin) {
// remove the key from the hash table for the shell_window
g_hash_table_remove(mWindowLookupTable, mSuperWin->shell_window);
@ -1157,7 +1199,7 @@ nsWindow::SetFocus(PRBool aRaise)
mHasFocus = PR_TRUE;
#ifdef USE_XIM
if (sFocusWindow) sFocusWindow->IMESetFocusWidget();
IMESetFocusWindow();
#endif // USE_XIM
DispatchSetFocusEvent();
@ -1172,6 +1214,22 @@ nsWindow::SetFocus(PRBool aRaise)
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)
{
#ifdef DEBUG_FOCUS
@ -3487,3 +3545,481 @@ PRBool ChildWindow::IsChild() const
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 "gdksuperwin.h"
#ifdef USE_XIM
#include "pldhash.h"
class nsIMEGtkIC;
class nsIMEPreedit;
#endif // USE_XIM
class nsFont;
class nsIAppShell;
@ -89,6 +95,11 @@ public:
NS_IMETHOD GetAttention(void);
NS_IMETHOD Destroy();
virtual void LoseFocus(void);
// nsIKBStateControl
NS_IMETHOD ResetInputState();
void QueueDraw();
void UnqueueDraw();
void DoPaint(PRInt32 x, PRInt32 y, PRInt32 width, PRInt32 height,
@ -309,7 +320,56 @@ protected:
static void dumpWindowChildren(Window aWindow, unsigned int depth);
#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:
PRUnichar* mIMECompositionUniString;
PRInt32 mIMECompositionUniStringSize;
nsresult SetMiniIcon(GdkPixmap *window_pixmap,
GdkBitmap *window_mask);
nsresult SetIcon(GdkPixmap *window_pixmap,