Add a way for IME to query the caret position. Bug 278061, patch by
Masayuki Nakano (Mozilla Japan) <masayuki@d-toybox.com>, r=smontagu,glazou, sr=bzbarsky git-svn-id: svn://10.0.0.236/trunk@168653 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
dc91459b0d
commit
7572605e3c
@ -41,18 +41,19 @@
|
||||
#include "nsEvent.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
// {ECF6BEF1-5F0C-11d3-9EB3-0060089FE59B}
|
||||
// {889792DC-22D8-4d1a-AC3D-58AD7DEBA17B}
|
||||
#define NS_IPRIVATECOMPOSITIONEVENT_IID \
|
||||
{ 0xecf6bef1, 0x5f0c, 0x11d3, \
|
||||
{ 0x9e, 0xb3, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b }}
|
||||
{ 0x889792dc, 0x22d8, 0x4d1a, \
|
||||
{ 0xac, 0x3d, 0x58, 0xad, 0x7d, 0xeb, 0xa1, 0x7b }}
|
||||
|
||||
class nsIPrivateCompositionEvent : public nsISupports {
|
||||
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPRIVATECOMPOSITIONEVENT_IID)
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPRIVATECOMPOSITIONEVENT_IID)
|
||||
|
||||
NS_IMETHOD GetCompositionReply(struct nsTextEventReply** aReply) = 0;
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply) = 0;
|
||||
NS_IMETHOD GetCompositionReply(struct nsTextEventReply** aReply) = 0;
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply) = 0;
|
||||
NS_IMETHOD GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply) = 0;
|
||||
};
|
||||
|
||||
#endif // nsIPrivateCompositionEvent_h__
|
||||
|
||||
@ -468,6 +468,18 @@ nsDOMUIEvent::GetReconversionReply(nsReconversionEventReply** aReply)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsDOMUIEvent::GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply)
|
||||
{
|
||||
if (mEvent->eventStructType == NS_QUERYCARETRECT_EVENT)
|
||||
{
|
||||
*aReply = &(NS_STATIC_CAST(nsQueryCaretRectEvent*, mEvent)->theReply);
|
||||
return NS_OK;
|
||||
}
|
||||
aReply = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsGUIEvent *aEvent)
|
||||
|
||||
@ -64,6 +64,7 @@ public:
|
||||
// nsIPrivateCompositionEvent interface
|
||||
NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply);
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply);
|
||||
NS_IMETHOD GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply);
|
||||
|
||||
// Forward to nsDOMEvent
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
@ -206,7 +206,9 @@ static const EventDispatchData sCompositionEvents[] = {
|
||||
{ NS_COMPOSITION_QUERY, HANDLER(&nsIDOMCompositionListener::HandleQueryComposition),
|
||||
NS_EVENT_BITS_COMPOSITION_QUERY },
|
||||
{ NS_RECONVERSION_QUERY, HANDLER(&nsIDOMCompositionListener::HandleQueryReconversion),
|
||||
NS_EVENT_BITS_COMPOSITION_RECONVERSION }
|
||||
NS_EVENT_BITS_COMPOSITION_RECONVERSION },
|
||||
{ NS_QUERYCARETRECT, HANDLER(&nsIDOMCompositionListener::HandleQueryCaretRect),
|
||||
NS_EVENT_BITS_COMPOSITION_QUERYCARETRECT }
|
||||
};
|
||||
|
||||
static const EventDispatchData sTextEvents[] = {
|
||||
@ -1642,6 +1644,7 @@ nsEventListenerManager::CreateEvent(nsPresContext* aPresContext,
|
||||
case NS_GUI_EVENT:
|
||||
case NS_COMPOSITION_EVENT:
|
||||
case NS_RECONVERSION_EVENT:
|
||||
case NS_QUERYCARETRECT_EVENT:
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext, NS_STATIC_CAST(nsGUIEvent*,aEvent));
|
||||
case NS_KEY_EVENT:
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, NS_STATIC_CAST(nsKeyEvent*,aEvent));
|
||||
|
||||
@ -273,11 +273,12 @@ protected:
|
||||
#define NS_EVENT_BITS_TEXT_TEXT 0x01
|
||||
|
||||
//nsIDOMCompositionListener
|
||||
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
|
||||
#define NS_EVENT_BITS_COMPOSITION_START 0x01
|
||||
#define NS_EVENT_BITS_COMPOSITION_END 0x02
|
||||
#define NS_EVENT_BITS_COMPOSITION_QUERY 0x04
|
||||
#define NS_EVENT_BITS_COMPOSITION_RECONVERSION 0x08
|
||||
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
|
||||
#define NS_EVENT_BITS_COMPOSITION_START 0x01
|
||||
#define NS_EVENT_BITS_COMPOSITION_END 0x02
|
||||
#define NS_EVENT_BITS_COMPOSITION_QUERY 0x04
|
||||
#define NS_EVENT_BITS_COMPOSITION_RECONVERSION 0x08
|
||||
#define NS_EVENT_BITS_COMPOSITION_QUERYCARETRECT 0x10
|
||||
|
||||
//nsIDOMFocusListener
|
||||
#define NS_EVENT_BITS_FOCUS_NONE 0x00
|
||||
|
||||
@ -60,5 +60,6 @@ public:
|
||||
NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
};
|
||||
#endif // nsIDOMCompositionListener_h__
|
||||
|
||||
@ -42,65 +42,75 @@
|
||||
class nsIPrivateTextRangeList;
|
||||
struct nsTextEventReply;
|
||||
struct nsReconversionEventReply;
|
||||
struct nsQueryCaretRectEventReply;
|
||||
%}
|
||||
|
||||
[ptr] native nsIPrivateTextRangeListPtr(nsIPrivateTextRangeList);
|
||||
[ptr] native nsTextEventReplyPtr(nsTextEventReply);
|
||||
[ptr] native nsReconversionEventReplyPtr(nsReconversionEventReply);
|
||||
[ptr] native nsQueryCaretRectEventReplyPtr(nsQueryCaretRectEventReply);
|
||||
|
||||
|
||||
[scriptable, uuid(fe489b4d-d2f6-4215-ab33-6afd66388416)]
|
||||
[scriptable, uuid(205b3e49-aa58-499e-880b-aacab9dede01)]
|
||||
|
||||
interface nsIEditorIMESupport : nsISupports
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* BeginComposition(nsTextEventReply* aReply) Handles the start of inline input composition.
|
||||
* beginComposition(nsTextEventReply* aReply) Handles the start of inline input composition.
|
||||
*/
|
||||
|
||||
[noscript] void BeginComposition(in nsTextEventReplyPtr aReply);
|
||||
[noscript] void beginComposition(in nsTextEventReplyPtr aReply);
|
||||
|
||||
/**
|
||||
* SetCompositionString() Sets the inline input composition string.
|
||||
* BeginComposition must be called prior to this.
|
||||
* setCompositionString() Sets the inline input composition string.
|
||||
* beginComposition must be called prior to this.
|
||||
*/
|
||||
|
||||
[noscript] void SetCompositionString(in DOMString aCompositionString, in nsIPrivateTextRangeListPtr aTextRange, in nsTextEventReplyPtr aReply);
|
||||
[noscript] void setCompositionString(in DOMString aCompositionString, in nsIPrivateTextRangeListPtr aTextRange, in nsTextEventReplyPtr aReply);
|
||||
|
||||
/**
|
||||
* EndComposition() Handles the end of inline input composition.
|
||||
* endComposition() Handles the end of inline input composition.
|
||||
*/
|
||||
|
||||
void EndComposition();
|
||||
void endComposition();
|
||||
|
||||
/**
|
||||
* QueryComposition() Get the composition position
|
||||
* queryComposition() Get the composition position
|
||||
*/
|
||||
[noscript] void QueryComposition(in nsTextEventReplyPtr aReply);
|
||||
|
||||
[noscript] void queryComposition(in nsTextEventReplyPtr aReply);
|
||||
|
||||
/**
|
||||
* ForceCompositionEnd() force the composition end
|
||||
* forceCompositionEnd() force the composition end
|
||||
*/
|
||||
|
||||
void ForceCompositionEnd();
|
||||
void forceCompositionEnd();
|
||||
|
||||
/**
|
||||
* GetReconvertionString() Get the reconvertion string
|
||||
* getReconversionString() Get the reconvertion string
|
||||
*/
|
||||
[noscript] void GetReconversionString(in nsReconversionEventReplyPtr aReply);
|
||||
|
||||
|
||||
[noscript] void getReconversionString(in nsReconversionEventReplyPtr aReply);
|
||||
|
||||
/**
|
||||
* Notify for IME when the editor got focus.
|
||||
*/
|
||||
|
||||
[noscript] void NotifyIMEOnFocus();
|
||||
|
||||
void notifyIMEOnFocus();
|
||||
|
||||
/**
|
||||
* Notify for IME when the editor lost focus.
|
||||
*/
|
||||
|
||||
[noscript] void NotifyIMEOnBlur();
|
||||
void notifyIMEOnBlur();
|
||||
|
||||
/**
|
||||
* getQueryCaretRect() Get the query caret rect
|
||||
*/
|
||||
|
||||
[noscript] void getQueryCaretRect(in nsQueryCaretRectEventReplyPtr aReply);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -2167,6 +2167,34 @@ nsEditor::GetReconversionString(nsReconversionEventReply* aReply)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditor::GetQueryCaretRect(nsQueryCaretRectEventReply* aReply)
|
||||
{
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsresult rv = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!mPresShellWeak)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsICaret> caretP;
|
||||
rv = ps->GetCaret(getter_AddRefs(caretP));
|
||||
|
||||
if (NS_FAILED(rv) || !caretP)
|
||||
return rv;
|
||||
|
||||
PRBool cursorIsCollapsed;
|
||||
rv = caretP->GetCaretCoordinates(nsICaret::eIMECoordinates, selection,
|
||||
&aReply->mCaretRect, &cursorIsCollapsed, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#pragma mark public nsEditor methods
|
||||
|
||||
@ -843,6 +843,24 @@ nsTextEditorCompositionListener::HandleQueryReconversion(nsIDOMEvent* aReconvers
|
||||
return mEditor->GetReconversionString(eventReply);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorCompositionListener::HandleQueryCaretRect(nsIDOMEvent* aQueryCaretRectEvent)
|
||||
{
|
||||
#ifdef DEBUG_IME
|
||||
printf("nsTextEditorCompositionListener::HandleQueryCaretRect\n");
|
||||
#endif
|
||||
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aQueryCaretRectEvent);
|
||||
if (!pCompositionEvent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsQueryCaretRectEventReply* eventReply;
|
||||
nsresult rv = pCompositionEvent->GetQueryCaretRectReply(&eventReply);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return mEditor->GetQueryCaretRect(eventReply);
|
||||
}
|
||||
|
||||
/*
|
||||
* Factory functions
|
||||
*/
|
||||
|
||||
@ -146,6 +146,7 @@ public:
|
||||
NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aReconvertionEvent);
|
||||
NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aQueryCaretRectEvent);
|
||||
/*END implementations of textevent handler interface*/
|
||||
|
||||
protected:
|
||||
|
||||
@ -929,7 +929,7 @@ function OutputFileWithPersistAPI(editorDoc, aDestinationLocation, aRelatedFiles
|
||||
var editor = GetCurrentEditor();
|
||||
try {
|
||||
var imeEditor = editor.QueryInterface(Components.interfaces.nsIEditorIMESupport);
|
||||
imeEditor.ForceCompositionEnd();
|
||||
imeEditor.forceCompositionEnd();
|
||||
} catch (e) {}
|
||||
|
||||
var isLocalFile = false;
|
||||
|
||||
@ -1211,6 +1211,13 @@ nsTypeAheadFind::HandleQueryReconversion(nsIDOMEvent* aCompositionEvent)
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTypeAheadFind::HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell,
|
||||
PRBool aIsRepeatingSameChar, PRBool aIsLinksOnly,
|
||||
|
||||
@ -115,6 +115,7 @@ public:
|
||||
NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent);
|
||||
|
||||
// ----- nsIScrollPositionListener --------------------
|
||||
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView,
|
||||
|
||||
@ -2174,6 +2174,12 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
|
||||
((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.width=NSTwipsToIntPixels(((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.width,t2p);
|
||||
((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.height=NSTwipsToIntPixels(((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.height,t2p);
|
||||
}
|
||||
if(aEvent->message==NS_QUERYCARETRECT) {
|
||||
((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.x=NSTwipsToIntPixels(((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.x,t2p);
|
||||
((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.y=NSTwipsToIntPixels(((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.y,t2p);
|
||||
((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.width=NSTwipsToIntPixels(((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.width,t2p);
|
||||
((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.height=NSTwipsToIntPixels(((nsQueryCaretRectEvent*)aEvent)->theReply.mCaretRect.height,t2p);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -79,5 +79,6 @@ struct nsMenuEvent;
|
||||
|
||||
struct nsTextEventReply;
|
||||
struct nsReconversionEventReply;
|
||||
struct nsQueryCaretRectEventReply;
|
||||
|
||||
#endif // nsEvent_h__
|
||||
|
||||
@ -91,6 +91,7 @@ class nsIURI;
|
||||
#define NS_POPUPBLOCKED_EVENT 25
|
||||
#define NS_BEFORE_PAGE_UNLOAD_EVENT 26
|
||||
#define NS_UI_EVENT 27
|
||||
#define NS_QUERYCARETRECT_EVENT 28
|
||||
|
||||
#define NS_EVENT_FLAG_NONE 0x0000
|
||||
#define NS_EVENT_FLAG_INIT 0x0001
|
||||
@ -317,6 +318,10 @@ class nsIURI;
|
||||
#define NS_UI_FOCUSIN (NS_UI_EVENT_START + 1)
|
||||
#define NS_UI_FOCUSOUT (NS_UI_EVENT_START + 2)
|
||||
|
||||
// query caret rect events
|
||||
#define NS_QUERYCARETRECT_START 2600
|
||||
#define NS_QUERYCARETRECT (NS_QUERYCARETRECT_START)
|
||||
|
||||
/**
|
||||
* Return status for event processors, nsEventStatus, is defined in
|
||||
* nsEvent.h.
|
||||
@ -728,6 +733,26 @@ struct nsReconversionEvent : public nsInputEvent
|
||||
nsReconversionEventReply theReply;
|
||||
};
|
||||
|
||||
struct nsQueryCaretRectEventReply {
|
||||
nsQueryCaretRectEventReply()
|
||||
{
|
||||
}
|
||||
|
||||
nsRect mCaretRect;
|
||||
};
|
||||
|
||||
struct nsQueryCaretRectEvent : public nsInputEvent
|
||||
{
|
||||
nsQueryCaretRectEvent(PRUint32 msg = 0,
|
||||
nsIWidget *w = nsnull,
|
||||
PRUint8 structType = NS_QUERYCARETRECT_EVENT)
|
||||
: nsInputEvent(msg, w, structType)
|
||||
{
|
||||
}
|
||||
|
||||
nsQueryCaretRectEventReply theReply;
|
||||
};
|
||||
|
||||
/**
|
||||
* MenuItem event
|
||||
*
|
||||
@ -887,6 +912,7 @@ enum nsDragDropEventStatus {
|
||||
((evnt)->message == NS_COMPOSITION_START) || \
|
||||
((evnt)->message == NS_COMPOSITION_END) || \
|
||||
((evnt)->message == NS_RECONVERSION_QUERY) || \
|
||||
((evnt)->message == NS_QUERYCARETRECT) || \
|
||||
((evnt)->message == NS_COMPOSITION_QUERY))
|
||||
|
||||
#define NS_IS_FOCUS_EVENT(evnt) \
|
||||
|
||||
@ -70,6 +70,7 @@
|
||||
#include "nsColor.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include <windows.h>
|
||||
|
||||
// unknwn.h is needed to build with WIN32_LEAN_AND_MEAN
|
||||
@ -245,6 +246,7 @@ long nsWindow::sIMECursorPosition = 0;
|
||||
PRUnichar* nsWindow::sIMEReconvertUnicode = NULL;
|
||||
|
||||
RECT* nsWindow::sIMECompCharPos = nsnull;
|
||||
PRInt32 nsWindow::sIMECaretHeight = 0;
|
||||
|
||||
BOOL nsWindow::sIsRegistered = FALSE;
|
||||
BOOL nsWindow::sIsPopupClassRegistered = FALSE;
|
||||
@ -489,7 +491,16 @@ typedef struct tagRECONVERTSTRING {
|
||||
DWORD dwTargetStrOffset;
|
||||
} RECONVERTSTRING, FAR * LPRECONVERTSTRING;
|
||||
|
||||
typedef struct tagIMECHARPOSITION {
|
||||
DWORD dwSize;
|
||||
DWORD dwCharPos;
|
||||
POINT pt;
|
||||
UINT cLineHeight;
|
||||
RECT rcDocument;
|
||||
} IMECHARPOSITION, *PIMECHARPOSITION;
|
||||
|
||||
#define IMR_RECONVERTSTRING 0x0004
|
||||
#define IMR_QUERYCHARPOSITION 0x0006
|
||||
#define WM_IME_REQUEST 0x0288
|
||||
#endif
|
||||
|
||||
@ -5786,7 +5797,6 @@ nsWindow::HandleTextEvent(HIMC hIMEContext,PRBool aCheckAttr)
|
||||
|
||||
nsTextEvent event(NS_TEXT_TEXT, this);
|
||||
nsPoint point(0, 0);
|
||||
CANDIDATEFORM candForm;
|
||||
|
||||
InitEvent(event, &point);
|
||||
|
||||
@ -5814,6 +5824,7 @@ nsWindow::HandleTextEvent(HIMC hIMEContext,PRBool aCheckAttr)
|
||||
//
|
||||
if (event.theReply.mCursorPosition.width || event.theReply.mCursorPosition.height)
|
||||
{
|
||||
CANDIDATEFORM candForm;
|
||||
candForm.dwIndex = 0;
|
||||
candForm.dwStyle = CFS_EXCLUDE;
|
||||
candForm.ptCurrentPos.x = event.theReply.mCursorPosition.x;
|
||||
@ -5829,6 +5840,13 @@ nsWindow::HandleTextEvent(HIMC hIMEContext,PRBool aCheckAttr)
|
||||
}
|
||||
|
||||
NS_IMM_SETCANDIDATEWINDOW(hIMEContext, &candForm);
|
||||
|
||||
COMPOSITIONFORM compForm;
|
||||
compForm.dwStyle = CFS_POINT;
|
||||
compForm.ptCurrentPos.x = event.theReply.mCursorPosition.x;
|
||||
compForm.ptCurrentPos.y = event.theReply.mCursorPosition.y;
|
||||
NS_IMM_SETCOMPOSITIONWINDOW(hIMEContext, &compForm);
|
||||
|
||||
// somehow the "Intellegent ABC IME" in Simplified Chinese
|
||||
// window listen to the caret position to decide where to put the
|
||||
// candidate window
|
||||
@ -5855,6 +5873,7 @@ nsWindow::HandleTextEvent(HIMC hIMEContext,PRBool aCheckAttr)
|
||||
sIMECompCharPos[sIMECursorPosition].top = event.theReply.mCursorPosition.y;
|
||||
sIMECompCharPos[sIMECursorPosition].bottom = event.theReply.mCursorPosition.YMost();
|
||||
}
|
||||
sIMECaretHeight = event.theReply.mCursorPosition.height;
|
||||
} else {
|
||||
// for some reason we don't know yet, theReply may contain invalid result
|
||||
// need more debugging in nsCaret to find out the reason
|
||||
@ -5899,6 +5918,12 @@ nsWindow::HandleStartComposition(HIMC hIMEContext)
|
||||
|
||||
NS_IMM_SETCANDIDATEWINDOW(hIMEContext, &candForm);
|
||||
|
||||
COMPOSITIONFORM compForm;
|
||||
compForm.dwStyle = CFS_POINT;
|
||||
compForm.ptCurrentPos.x = event.theReply.mCursorPosition.x + IME_X_OFFSET;
|
||||
compForm.ptCurrentPos.y = event.theReply.mCursorPosition.y + IME_Y_OFFSET;
|
||||
NS_IMM_SETCOMPOSITIONWINDOW(hIMEContext, &compForm);
|
||||
|
||||
sIMECompCharPos = (RECT*)PR_MALLOC(IME_MAX_CHAR_POS*sizeof(RECT));
|
||||
if (sIMECompCharPos) {
|
||||
memset(sIMECompCharPos, -1, sizeof(RECT)*IME_MAX_CHAR_POS);
|
||||
@ -5906,6 +5931,7 @@ nsWindow::HandleStartComposition(HIMC hIMEContext)
|
||||
sIMECompCharPos[0].top = event.theReply.mCursorPosition.y;
|
||||
sIMECompCharPos[0].bottom = event.theReply.mCursorPosition.YMost();
|
||||
}
|
||||
sIMECaretHeight = event.theReply.mCursorPosition.height;
|
||||
} else {
|
||||
// for some reason we don't know yet, theReply may contain invalid result
|
||||
// need more debugging in nsCaret to find out the reason
|
||||
@ -5939,6 +5965,7 @@ nsWindow::HandleEndComposition(void)
|
||||
NS_RELEASE(event.widget);
|
||||
PR_FREEIF(sIMECompCharPos);
|
||||
sIMECompCharPos = nsnull;
|
||||
sIMECaretHeight = 0;
|
||||
sIMEIsComposing = PR_FALSE;
|
||||
}
|
||||
|
||||
@ -6454,6 +6481,9 @@ BOOL nsWindow::OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult, PRBool
|
||||
case IMR_RECONVERTSTRING:
|
||||
result = OnIMEReconvert(aData, oResult, aUseUnicode);
|
||||
break;
|
||||
case IMR_QUERYCHARPOSITION:
|
||||
result = OnIMEQueryCharPosition(aData, oResult, aUseUnicode);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -6552,6 +6582,83 @@ PRBool nsWindow::OnIMEReconvert(LPARAM aData, LRESULT *oResult, PRBool aUseUnico
|
||||
return result;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
PRBool nsWindow::OnIMEQueryCharPosition(LPARAM aData, LRESULT *oResult, PRBool aUseUnicode)
|
||||
{
|
||||
#ifdef DEBUG_IME
|
||||
printf("OnIMEQueryCharPosition\n");
|
||||
#endif
|
||||
IMECHARPOSITION* pCharPosition = (IMECHARPOSITION*)aData;
|
||||
if (!pCharPosition ||
|
||||
pCharPosition->dwSize < sizeof(IMECHARPOSITION) ||
|
||||
::GetFocus() != mWnd) {
|
||||
*oResult = FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!sIMEIsComposing) { // Including |!sIMECompUnicode| and |!sIMECompUnicode->IsEmpty|.
|
||||
if (pCharPosition->dwCharPos != 0) {
|
||||
*oResult = FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsPoint point(0, 0);
|
||||
nsQueryCaretRectEvent event(NS_QUERYCARETRECT, this);
|
||||
InitEvent(event, &point);
|
||||
DispatchWindowEvent(&event);
|
||||
NS_RELEASE(event.widget);
|
||||
|
||||
nsRect screenRect, widgetRect(event.theReply.mCaretRect);
|
||||
WidgetToScreen(widgetRect, screenRect);
|
||||
pCharPosition->pt.x = screenRect.x;
|
||||
pCharPosition->pt.y = screenRect.y;
|
||||
|
||||
pCharPosition->cLineHeight = event.theReply.mCaretRect.height;
|
||||
|
||||
::GetWindowRect(mWnd, &pCharPosition->rcDocument);
|
||||
|
||||
*oResult = TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
long charPosition;
|
||||
if (aUseUnicode || pCharPosition->dwCharPos == 0) {
|
||||
if (pCharPosition->dwCharPos > sIMECompUnicode->Length()) {
|
||||
*oResult = FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
charPosition = pCharPosition->dwCharPos;
|
||||
} else {
|
||||
nsCAutoString strIMECompAnsi;
|
||||
NS_CopyUnicodeToNative(*sIMECompUnicode, strIMECompAnsi);
|
||||
if (pCharPosition->dwCharPos > strIMECompAnsi.Length()) {
|
||||
*oResult = FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
charPosition = ::MultiByteToWideChar(gCurrentKeyboardCP, MB_PRECOMPOSED,
|
||||
strIMECompAnsi.get(), pCharPosition->dwCharPos, NULL, 0);
|
||||
}
|
||||
// We only support insertion at the cursor position or at the leftmost position.
|
||||
// Because sIMECompCharPos may be broken by user converting the string.
|
||||
// But leftmost position and cursor position is always correctly.
|
||||
if ((charPosition != 0 && charPosition != sIMECursorPosition) ||
|
||||
charPosition > IME_MAX_CHAR_POS) {
|
||||
*oResult = FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
POINT pt;
|
||||
pt.x = sIMECompCharPos[charPosition].left;
|
||||
pt.y = sIMECompCharPos[charPosition].top;
|
||||
::ClientToScreen(mWnd, &pt);
|
||||
pCharPosition->pt = pt;
|
||||
|
||||
pCharPosition->cLineHeight = sIMECaretHeight;
|
||||
|
||||
::GetWindowRect(mWnd, &pCharPosition->rcDocument);
|
||||
|
||||
*oResult = TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
BOOL nsWindow::OnIMESelect(BOOL aSelected, WORD aLangID)
|
||||
{
|
||||
|
||||
@ -452,6 +452,7 @@ protected:
|
||||
BOOL OnIMESetContext(BOOL aActive, LPARAM& aISC);
|
||||
BOOL OnIMEStartComposition();
|
||||
BOOL OnIMEReconvert(LPARAM aData, LRESULT *oResult, PRBool aUseUnicode);
|
||||
BOOL OnIMEQueryCharPosition(LPARAM aData, LRESULT *oResult, PRBool aUseUnicode);
|
||||
|
||||
void GetCompositionString(HIMC aHIMC, DWORD aIndex, nsString* aStrUnicode, nsCString* aStrAnsi);
|
||||
|
||||
@ -508,6 +509,7 @@ protected:
|
||||
|
||||
// For describing composing frame
|
||||
static RECT* sIMECompCharPos;
|
||||
static PRInt32 sIMECaretHeight;
|
||||
|
||||
nsSize mLastSize;
|
||||
static nsWindow* gCurrentWindow;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user