зеркало из https://github.com/mozilla/pjs.git
Bug 532130 [IMM32] Support IMR_DOCUMENTFEED of WM_IME_REQUEST r=VYV03354
This commit is contained in:
Родитель
625b704880
Коммит
813f17b52c
|
@ -605,6 +605,11 @@ nsIMM32Handler::OnIMERequest(nsWindow* aWindow,
|
||||||
("IMM32: OnIMERequest, hWnd=%08x, IMR_QUERYCHARPOSITION\n",
|
("IMM32: OnIMERequest, hWnd=%08x, IMR_QUERYCHARPOSITION\n",
|
||||||
aWindow->GetWindowHandle()));
|
aWindow->GetWindowHandle()));
|
||||||
return HandleQueryCharPosition(aWindow, lParam, oResult);
|
return HandleQueryCharPosition(aWindow, lParam, oResult);
|
||||||
|
case IMR_DOCUMENTFEED:
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: OnIMERequest, hWnd=%08x, IMR_DOCUMENTFEED\n",
|
||||||
|
aWindow->GetWindowHandle()));
|
||||||
|
return HandleDocumentFeed(aWindow, lParam, oResult);
|
||||||
default:
|
default:
|
||||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
("IMM32: OnIMERequest, hWnd=%08x, wParam=%08x\n",
|
("IMM32: OnIMERequest, hWnd=%08x, wParam=%08x\n",
|
||||||
|
@ -922,6 +927,24 @@ nsIMM32Handler::HandleEndComposition(nsWindow* aWindow)
|
||||||
mIsComposing = PR_FALSE;
|
mIsComposing = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DumpReconvertString(RECONVERTSTRING* aReconv)
|
||||||
|
{
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
(" dwSize=%ld, dwVersion=%ld, dwStrLen=%ld, dwStrOffset=%ld\n",
|
||||||
|
aReconv->dwSize, aReconv->dwVersion,
|
||||||
|
aReconv->dwStrLen, aReconv->dwStrOffset));
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
(" dwCompStrLen=%ld, dwCompStrOffset=%ld, dwTargetStrLen=%ld, dwTargetStrOffset=%ld\n",
|
||||||
|
aReconv->dwCompStrLen, aReconv->dwCompStrOffset,
|
||||||
|
aReconv->dwTargetStrLen, aReconv->dwTargetStrOffset));
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
(" result str=\"%s\"\n",
|
||||||
|
NS_ConvertUTF16toUTF8(
|
||||||
|
nsAutoString((PRUnichar*)((char*)(aReconv) + aReconv->dwStrOffset),
|
||||||
|
aReconv->dwStrLen)).get()));
|
||||||
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsIMM32Handler::HandleReconvert(nsWindow* aWindow,
|
nsIMM32Handler::HandleReconvert(nsWindow* aWindow,
|
||||||
LPARAM lParam,
|
LPARAM lParam,
|
||||||
|
@ -940,25 +963,23 @@ nsIMM32Handler::HandleReconvert(nsWindow* aWindow,
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRUint32 len = selection.mReply.mString.Length();
|
||||||
|
PRUint32 needSize = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR);
|
||||||
|
|
||||||
if (!pReconv) {
|
if (!pReconv) {
|
||||||
// Return need size to reconvert.
|
// Return need size to reconvert.
|
||||||
if (selection.mReply.mString.IsEmpty()) {
|
if (len == 0) {
|
||||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
("IMM32: HandleReconvert, There are not selected text\n"));
|
("IMM32: HandleReconvert, There are not selected text\n"));
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
PRUint32 len = selection.mReply.mString.Length();
|
*oResult = needSize;
|
||||||
*oResult = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR);
|
|
||||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
("IMM32: HandleReconvert, SUCCEEDED result=%ld\n",
|
("IMM32: HandleReconvert, SUCCEEDED result=%ld\n",
|
||||||
*oResult));
|
*oResult));
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill reconvert struct
|
|
||||||
PRUint32 len = selection.mReply.mString.Length();
|
|
||||||
PRUint32 needSize = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR);
|
|
||||||
|
|
||||||
if (pReconv->dwSize < needSize) {
|
if (pReconv->dwSize < needSize) {
|
||||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
("IMM32: HandleReconvert, FAILED pReconv->dwSize=%ld, needSize=%ld\n",
|
("IMM32: HandleReconvert, FAILED pReconv->dwSize=%ld, needSize=%ld\n",
|
||||||
|
@ -968,9 +989,7 @@ nsIMM32Handler::HandleReconvert(nsWindow* aWindow,
|
||||||
|
|
||||||
*oResult = needSize;
|
*oResult = needSize;
|
||||||
|
|
||||||
DWORD tmpSize = pReconv->dwSize;
|
// Fill reconvert struct
|
||||||
::ZeroMemory(pReconv, tmpSize);
|
|
||||||
pReconv->dwSize = tmpSize;
|
|
||||||
pReconv->dwVersion = 0;
|
pReconv->dwVersion = 0;
|
||||||
pReconv->dwStrLen = len;
|
pReconv->dwStrLen = len;
|
||||||
pReconv->dwStrOffset = sizeof(RECONVERTSTRING);
|
pReconv->dwStrOffset = sizeof(RECONVERTSTRING);
|
||||||
|
@ -979,12 +998,13 @@ nsIMM32Handler::HandleReconvert(nsWindow* aWindow,
|
||||||
pReconv->dwTargetStrLen = len;
|
pReconv->dwTargetStrLen = len;
|
||||||
pReconv->dwTargetStrOffset = 0;
|
pReconv->dwTargetStrOffset = 0;
|
||||||
|
|
||||||
::CopyMemory((LPVOID) (lParam + sizeof(RECONVERTSTRING)),
|
::CopyMemory(reinterpret_cast<LPVOID>(lParam + sizeof(RECONVERTSTRING)),
|
||||||
selection.mReply.mString.get(), len * sizeof(WCHAR));
|
selection.mReply.mString.get(), len * sizeof(WCHAR));
|
||||||
|
|
||||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
("IMM32: HandleReconvert, SUCCEEDED str=\"%s\"\n",
|
("IMM32: HandleReconvert, SUCCEEDED result=%ld\n",
|
||||||
NS_ConvertUTF16toUTF8(selection.mReply.mString).get()));
|
*oResult));
|
||||||
|
DumpReconvertString(pReconv);
|
||||||
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1046,6 +1066,132 @@ nsIMM32Handler::HandleQueryCharPosition(nsWindow* aWindow,
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsIMM32Handler::HandleDocumentFeed(nsWindow* aWindow,
|
||||||
|
LPARAM lParam,
|
||||||
|
LRESULT *oResult)
|
||||||
|
{
|
||||||
|
*oResult = 0;
|
||||||
|
RECONVERTSTRING* pReconv = reinterpret_cast<RECONVERTSTRING*>(lParam);
|
||||||
|
|
||||||
|
nsIntPoint point(0, 0);
|
||||||
|
|
||||||
|
PRBool hasCompositionString =
|
||||||
|
mIsComposing && ShouldDrawCompositionStringOurselves();
|
||||||
|
|
||||||
|
PRInt32 targetOffset, targetLength;
|
||||||
|
if (!hasCompositionString) {
|
||||||
|
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT, aWindow);
|
||||||
|
aWindow->InitEvent(selection, &point);
|
||||||
|
aWindow->DispatchWindowEvent(&selection);
|
||||||
|
if (!selection.mSucceeded) {
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, FAILED (NS_QUERY_SELECTED_TEXT)\n"));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
targetOffset = PRInt32(selection.mReply.mOffset);
|
||||||
|
targetLength = PRInt32(selection.mReply.mString.Length());
|
||||||
|
} else {
|
||||||
|
targetOffset = PRInt32(mCompositionStart);
|
||||||
|
targetLength = PRInt32(mCompositionString.Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX nsString::Find and nsString::RFind take PRInt32 for offset, so,
|
||||||
|
// we cannot support this message when the current offset is larger than
|
||||||
|
// PR_INT32_MAX.
|
||||||
|
if (targetOffset < 0 || targetLength < 0 ||
|
||||||
|
targetOffset + targetLength < 0) {
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, FAILED (The selection is out of range)\n"));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all contents of the focused editor.
|
||||||
|
nsQueryContentEvent textContent(PR_TRUE, NS_QUERY_TEXT_CONTENT, aWindow);
|
||||||
|
textContent.InitForQueryTextContent(0, PR_UINT32_MAX);
|
||||||
|
aWindow->InitEvent(textContent, &point);
|
||||||
|
aWindow->DispatchWindowEvent(&textContent);
|
||||||
|
if (!textContent.mSucceeded) {
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, FAILED (NS_QUERY_TEXT_CONTENT)\n"));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString str(textContent.mReply.mString);
|
||||||
|
if (targetOffset > PRInt32(str.Length())) {
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, FAILED (The caret offset is invalid)\n"));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the focused paragraph, we decide that it starts from the previous CRLF
|
||||||
|
// (or start of the editor) to the next one (or the end of the editor).
|
||||||
|
PRInt32 paragraphStart = str.RFind("\n", PR_FALSE, targetOffset, -1) + 1;
|
||||||
|
PRInt32 paragraphEnd =
|
||||||
|
str.Find("\r", PR_FALSE, targetOffset + targetLength, -1);
|
||||||
|
if (paragraphEnd < 0) {
|
||||||
|
paragraphEnd = str.Length();
|
||||||
|
}
|
||||||
|
nsDependentSubstring paragraph(str, paragraphStart,
|
||||||
|
paragraphEnd - paragraphStart);
|
||||||
|
|
||||||
|
PRUint32 len = paragraph.Length();
|
||||||
|
PRUint32 needSize = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (!pReconv) {
|
||||||
|
*oResult = needSize;
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, SUCCEEDED result=%ld\n",
|
||||||
|
*oResult));
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pReconv->dwSize < needSize) {
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, FAILED pReconv->dwSize=%ld, needSize=%ld\n",
|
||||||
|
pReconv->dwSize, needSize));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill reconvert struct
|
||||||
|
pReconv->dwVersion = 0;
|
||||||
|
pReconv->dwStrLen = len;
|
||||||
|
pReconv->dwStrOffset = sizeof(RECONVERTSTRING);
|
||||||
|
if (hasCompositionString) {
|
||||||
|
pReconv->dwCompStrLen = targetLength;
|
||||||
|
pReconv->dwCompStrOffset =
|
||||||
|
(targetOffset - paragraphStart) * sizeof(WCHAR);
|
||||||
|
// Set composition target clause information
|
||||||
|
PRUint32 offset, length;
|
||||||
|
if (!GetTargetClauseRange(&offset, &length)) {
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, FAILED, by GetTargetClauseRange\n"));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
pReconv->dwTargetStrLen = offset - mCompositionStart;
|
||||||
|
pReconv->dwTargetStrOffset = length;
|
||||||
|
} else {
|
||||||
|
pReconv->dwTargetStrLen = targetLength;
|
||||||
|
pReconv->dwTargetStrOffset =
|
||||||
|
(targetOffset - paragraphStart) * sizeof(WCHAR);
|
||||||
|
// There is no composition string, so, the length is zero but we should
|
||||||
|
// set the cursor offset to the composition str offset.
|
||||||
|
pReconv->dwCompStrLen = 0;
|
||||||
|
pReconv->dwCompStrOffset = pReconv->dwTargetStrOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
*oResult = needSize;
|
||||||
|
::CopyMemory(reinterpret_cast<LPVOID>(lParam + sizeof(RECONVERTSTRING)),
|
||||||
|
paragraph.BeginReading(), len * sizeof(WCHAR));
|
||||||
|
|
||||||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
|
("IMM32: HandleDocumentFeed, SUCCEEDED result=%ld\n",
|
||||||
|
*oResult));
|
||||||
|
DumpReconvertString(pReconv);
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static PRUint32
|
static PRUint32
|
||||||
PlatformToNSAttr(PRUint8 aAttr)
|
PlatformToNSAttr(PRUint8 aAttr)
|
||||||
{
|
{
|
||||||
|
@ -1227,6 +1373,37 @@ nsIMM32Handler::GetCompositionString(const nsIMEContext &aIMEContext,
|
||||||
NS_ConvertUTF16toUTF8(mCompositionString).get()));
|
NS_ConvertUTF16toUTF8(mCompositionString).get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsIMM32Handler::GetTargetClauseRange(PRUint32 *aOffset, PRUint32 *aLength)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(aOffset, PR_FALSE);
|
||||||
|
NS_ENSURE_TRUE(mIsComposing, PR_FALSE);
|
||||||
|
NS_ENSURE_TRUE(ShouldDrawCompositionStringOurselves(), PR_FALSE);
|
||||||
|
|
||||||
|
*aOffset = mCompositionStart;
|
||||||
|
for (PRUint32 i = 0; i < mAttributeArray.Length(); i++) {
|
||||||
|
if (mAttributeArray[i] == ATTR_TARGET_NOTCONVERTED ||
|
||||||
|
mAttributeArray[i] == ATTR_TARGET_CONVERTED) {
|
||||||
|
*aOffset = mCompositionStart + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aLength) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aLength = mCompositionString.Length() - (*aOffset - mCompositionStart);
|
||||||
|
for (PRUint32 i = *aOffset; i < mAttributeArray.Length(); i++) {
|
||||||
|
if (mAttributeArray[i] != ATTR_TARGET_NOTCONVERTED &&
|
||||||
|
mAttributeArray[i] != ATTR_TARGET_CONVERTED) {
|
||||||
|
*aLength = i - (*aOffset - mCompositionStart);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsIMM32Handler::ConvertToANSIString(const nsAFlatString& aStr, UINT aCodePage,
|
nsIMM32Handler::ConvertToANSIString(const nsAFlatString& aStr, UINT aCodePage,
|
||||||
nsACString& aANSIStr)
|
nsACString& aANSIStr)
|
||||||
|
@ -1372,15 +1549,14 @@ nsIMM32Handler::SetIMERelatedWindowsPos(nsWindow* aWindow,
|
||||||
if (mIsComposing && !mCompositionString.IsEmpty()) {
|
if (mIsComposing && !mCompositionString.IsEmpty()) {
|
||||||
// If there are no targetted selection, we should use it's first character
|
// If there are no targetted selection, we should use it's first character
|
||||||
// rect instead.
|
// rect instead.
|
||||||
PRUint32 offset = 0;
|
PRUint32 offset;
|
||||||
for (PRUint32 i = 0; i < mAttributeArray.Length(); i++) {
|
if (!GetTargetClauseRange(&offset)) {
|
||||||
if (mAttributeArray[i] == ATTR_TARGET_NOTCONVERTED ||
|
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||||
mAttributeArray[i] == ATTR_TARGET_CONVERTED) {
|
("IMM32: SetIMERelatedWindowsPos, FAILED, by GetTargetClauseRange\n"));
|
||||||
offset = i;
|
return PR_FALSE;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
ret = GetCharacterRectOfSelectedTextAt(aWindow,
|
||||||
ret = GetCharacterRectOfSelectedTextAt(aWindow, offset, r);
|
offset - mCompositionStart, r);
|
||||||
NS_ENSURE_TRUE(ret, PR_FALSE);
|
NS_ENSURE_TRUE(ret, PR_FALSE);
|
||||||
} else {
|
} else {
|
||||||
// If there are no composition string, we should use a first character
|
// If there are no composition string, we should use a first character
|
||||||
|
|
|
@ -164,6 +164,7 @@ protected:
|
||||||
PRBool HandleReconvert(nsWindow* aWindow, LPARAM lParam, LRESULT *oResult);
|
PRBool HandleReconvert(nsWindow* aWindow, LPARAM lParam, LRESULT *oResult);
|
||||||
PRBool HandleQueryCharPosition(nsWindow* aWindow, LPARAM lParam,
|
PRBool HandleQueryCharPosition(nsWindow* aWindow, LPARAM lParam,
|
||||||
LRESULT *oResult);
|
LRESULT *oResult);
|
||||||
|
PRBool HandleDocumentFeed(nsWindow* aWindow, LPARAM lParam, LRESULT *oResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResolveIMECaretPos
|
* ResolveIMECaretPos
|
||||||
|
@ -196,6 +197,19 @@ protected:
|
||||||
nsIntRect &aCharRect);
|
nsIntRect &aCharRect);
|
||||||
PRBool GetCaretRect(nsWindow* aWindow, nsIntRect &aCaretRect);
|
PRBool GetCaretRect(nsWindow* aWindow, nsIntRect &aCaretRect);
|
||||||
void GetCompositionString(const nsIMEContext &aIMEContext, DWORD aIndex);
|
void GetCompositionString(const nsIMEContext &aIMEContext, DWORD aIndex);
|
||||||
|
/**
|
||||||
|
* Get the current target clause of composition string.
|
||||||
|
* If there are one or more characters whose attribute is ATTR_TARGET_*,
|
||||||
|
* this returns the first character's offset and its length.
|
||||||
|
* Otherwise, e.g., the all characters are ATTR_INPUT, this returns
|
||||||
|
* the composition string range because the all is the current target.
|
||||||
|
*
|
||||||
|
* aLength can be null (default), but aOffset must not be null.
|
||||||
|
*
|
||||||
|
* The aOffset value is offset in the contents. So, when you need offset
|
||||||
|
* in the composition string, you need to subtract mCompositionStart from it.
|
||||||
|
*/
|
||||||
|
PRBool GetTargetClauseRange(PRUint32 *aOffset, PRUint32 *aLength = nsnull);
|
||||||
void DispatchTextEvent(nsWindow* aWindow, const nsIMEContext &aIMEContext,
|
void DispatchTextEvent(nsWindow* aWindow, const nsIMEContext &aIMEContext,
|
||||||
PRBool aCheckAttr = PR_TRUE);
|
PRBool aCheckAttr = PR_TRUE);
|
||||||
void SetTextRangeList(nsTArray<nsTextRange> &aTextRangeList);
|
void SetTextRangeList(nsTArray<nsTextRange> &aTextRangeList);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче