From 309c493895481a0b43fac1337cf2fd2462ae0dc8 Mon Sep 17 00:00:00 2001 From: "shanjian%netscape.com" Date: Fri, 4 Aug 2000 21:43:29 +0000 Subject: [PATCH] #14022 IME98 Reconversion does not work in HTML Editor r = jfrancis a = ftang fix proposed by m_kato@ga2.so-net.ne.jp New events are added to support reconversion. As a result, many files are affected. They are: editor: nsEditor.h nsEditor.cpp nsEditorEventListeners.cpp nsEditorEventListeners.h nsHTMLEditor.h nsHTMLEditor.cpp nsIEditorIMESupport.h dom and layout: nsIPrivateCompositionEvent.h nsDOMEvent.h nsDOMEvnet.cpp nsEventListenerManager.cpp nsIDOMCompositionListener.h widget: nsGUIEvent.h nsWindow.h nsWindow.cpp git-svn-id: svn://10.0.0.236/trunk@75606 18797224-902f-48f8-a5cc-f745e15eee43 --- .../public/nsIPrivateCompositionEvent.h | 1 + mozilla/content/events/src/nsDOMEvent.cpp | 8 + mozilla/content/events/src/nsDOMEvent.h | 1 + .../events/src/nsEventListenerManager.cpp | 8 +- .../coreEvents/nsIDOMCompositionListener.h | 2 +- mozilla/editor/base/nsEditor.cpp | 6 + mozilla/editor/base/nsEditor.h | 1 + .../editor/base/nsEditorEventListeners.cpp | 18 ++ mozilla/editor/base/nsEditorEventListeners.h | 1 + mozilla/editor/base/nsHTMLEditor.cpp | 35 +++ mozilla/editor/base/nsHTMLEditor.h | 1 + mozilla/editor/libeditor/base/nsEditor.cpp | 6 + mozilla/editor/libeditor/base/nsEditor.h | 1 + .../editor/libeditor/html/nsHTMLEditor.cpp | 35 +++ mozilla/editor/libeditor/html/nsHTMLEditor.h | 1 + .../libeditor/text/nsEditorEventListeners.cpp | 18 ++ .../libeditor/text/nsEditorEventListeners.h | 1 + mozilla/editor/public/nsIEditorIMESupport.h | 6 + .../public/nsIPrivateCompositionEvent.h | 1 + mozilla/layout/events/src/nsDOMEvent.cpp | 8 + mozilla/layout/events/src/nsDOMEvent.h | 1 + .../events/src/nsEventListenerManager.cpp | 8 +- mozilla/widget/public/nsGUIEvent.h | 9 + mozilla/widget/src/windows/nsWindow.cpp | 247 +++++++++++++++++- mozilla/widget/src/windows/nsWindow.h | 10 +- 25 files changed, 415 insertions(+), 19 deletions(-) diff --git a/mozilla/content/events/public/nsIPrivateCompositionEvent.h b/mozilla/content/events/public/nsIPrivateCompositionEvent.h index 79a3ffa5268..df72b663ded 100644 --- a/mozilla/content/events/public/nsIPrivateCompositionEvent.h +++ b/mozilla/content/events/public/nsIPrivateCompositionEvent.h @@ -37,6 +37,7 @@ public: static const nsIID& GetIID() { static nsIID iid = NS_IPRIVATECOMPOSITIONEVENT_IID; return iid; } NS_IMETHOD GetCompositionReply(struct nsTextEventReply** aReply) = 0; + NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply) = 0; }; #endif // nsIPrivateCompositionEvent_h__ diff --git a/mozilla/content/events/src/nsDOMEvent.cpp b/mozilla/content/events/src/nsDOMEvent.cpp index 8170e2487b2..8776982f0cb 100644 --- a/mozilla/content/events/src/nsDOMEvent.cpp +++ b/mozilla/content/events/src/nsDOMEvent.cpp @@ -399,6 +399,14 @@ NS_METHOD nsDOMEvent::GetCompositionReply(nsTextEventReply** aReply) } +NS_METHOD +nsDOMEvent::GetReconversionReply(nsReconversionEventReply** aReply) +{ + *aReply = &(((nsReconversionEvent*)mEvent)->theReply); + return NS_OK; +} + + NS_METHOD nsDOMEvent::GetScreenX(PRInt32* aScreenX) { if (!mEvent || diff --git a/mozilla/content/events/src/nsDOMEvent.h b/mozilla/content/events/src/nsDOMEvent.h index c4d6209c475..18361a20638 100644 --- a/mozilla/content/events/src/nsDOMEvent.h +++ b/mozilla/content/events/src/nsDOMEvent.h @@ -159,6 +159,7 @@ public: // nsIPrivateCompositionEvent interface NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply); + NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply); protected: diff --git a/mozilla/content/events/src/nsEventListenerManager.cpp b/mozilla/content/events/src/nsEventListenerManager.cpp index 22e12537be1..362085205b9 100644 --- a/mozilla/content/events/src/nsEventListenerManager.cpp +++ b/mozilla/content/events/src/nsEventListenerManager.cpp @@ -970,6 +970,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_COMPOSITION_START: case NS_COMPOSITION_END: case NS_COMPOSITION_QUERY: + case NS_RECONVERSION_QUERY: #if DEBUG_TAGUE printf("DOM: got composition event\n"); #endif @@ -988,12 +989,15 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, if (aEvent->message==NS_COMPOSITION_START) { ret = mCompositionListener->HandleStartComposition(*aDOMEvent); } - if (aEvent->message==NS_COMPOSITION_END) { + else if (aEvent->message==NS_COMPOSITION_END) { ret = mCompositionListener->HandleEndComposition(*aDOMEvent); } - if (aEvent->message==NS_COMPOSITION_QUERY) { + else if (aEvent->message==NS_COMPOSITION_QUERY) { ret = mCompositionListener->HandleQueryComposition(*aDOMEvent); } + else if (aEvent->message==NS_RECONVERSION_QUERY) { + ret = mCompositionListener->HandleQueryReconversion(*aDOMEvent); + } } NS_RELEASE(mCompositionListener); } diff --git a/mozilla/dom/public/coreEvents/nsIDOMCompositionListener.h b/mozilla/dom/public/coreEvents/nsIDOMCompositionListener.h index 15a98db224e..94d936cfa17 100644 --- a/mozilla/dom/public/coreEvents/nsIDOMCompositionListener.h +++ b/mozilla/dom/public/coreEvents/nsIDOMCompositionListener.h @@ -44,6 +44,6 @@ public: virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent) = 0; virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0; virtual nsresult HandleQueryComposition(nsIDOMEvent* aCompositionEvent) = 0; - + virtual nsresult HandleQueryReconversion(nsIDOMEvent* aCompositionEvent) = 0; }; #endif // nsIDOMCompositionListener_h__ diff --git a/mozilla/editor/base/nsEditor.cpp b/mozilla/editor/base/nsEditor.cpp index d99b300916a..4b6bfe2ef66 100644 --- a/mozilla/editor/base/nsEditor.cpp +++ b/mozilla/editor/base/nsEditor.cpp @@ -2477,6 +2477,12 @@ nsEditor::ForceCompositionEnd() return NS_OK; } +NS_IMETHODIMP +nsEditor::GetReconversionString(nsReconversionEventReply* aReply) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + #ifdef XP_MAC #pragma mark - #pragma mark public nsEditor methods diff --git a/mozilla/editor/base/nsEditor.h b/mozilla/editor/base/nsEditor.h index 35626fac2a7..ca3c148c34e 100644 --- a/mozilla/editor/base/nsEditor.h +++ b/mozilla/editor/base/nsEditor.h @@ -304,6 +304,7 @@ public: NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); NS_IMETHOD EndComposition(void); NS_IMETHOD ForceCompositionEnd(void); + NS_IMETHOD GetReconversionString(nsReconversionEventReply *aReply); public: diff --git a/mozilla/editor/base/nsEditorEventListeners.cpp b/mozilla/editor/base/nsEditorEventListeners.cpp index 212ec6dd985..42c93eb3650 100644 --- a/mozilla/editor/base/nsEditorEventListeners.cpp +++ b/mozilla/editor/base/nsEditorEventListeners.cpp @@ -807,6 +807,24 @@ nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionE } +nsresult +nsTextEditorCompositionListener::HandleQueryReconversion(nsIDOMEvent* aReconversionEvent) +{ +#ifdef DEBUG_IME + printf("nsTextEditorCompositionListener::HandleQueryReconversion\n"); +#endif + nsCOMPtr pCompositionEvent = do_QueryInterface(aReconversionEvent); + nsReconversionEventReply* eventReply; + + if (!pCompositionEvent) + return NS_ERROR_FAILURE; + + nsresult rv = pCompositionEvent->GetReconversionReply(&eventReply); + if (NS_FAILED(rv)) + return rv; + + return mEditor->GetReconversionString(eventReply); +} /* * Factory functions diff --git a/mozilla/editor/base/nsEditorEventListeners.h b/mozilla/editor/base/nsEditorEventListeners.h index 1379e0c6b6e..39db78bdd2a 100644 --- a/mozilla/editor/base/nsEditorEventListeners.h +++ b/mozilla/editor/base/nsEditorEventListeners.h @@ -132,6 +132,7 @@ public: virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent); virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent); virtual nsresult HandleQueryComposition(nsIDOMEvent* aCompositionEvent); + virtual nsresult HandleQueryReconversion(nsIDOMEvent* aReconvertionEvent); /*END implementations of textevent handler interface*/ protected: diff --git a/mozilla/editor/base/nsHTMLEditor.cpp b/mozilla/editor/base/nsHTMLEditor.cpp index 4451921492e..aab0fa6e24a 100644 --- a/mozilla/editor/base/nsHTMLEditor.cpp +++ b/mozilla/editor/base/nsHTMLEditor.cpp @@ -5750,6 +5750,41 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat return result; } +NS_IMETHODIMP +nsHTMLEditor::GetReconversionString(nsReconversionEventReply* aReply) +{ + nsresult res; + + nsCOMPtr selection; + res = GetSelection(getter_AddRefs(selection)); + if (NS_FAILED(res) || !selection) + return (res == NS_OK) ? NS_ERROR_FAILURE : res; + + // get the first range in the selection. Since it is + // unclear what to do if reconversion happens with a + // multirange selection, we will ignore any additional ranges. + + nsCOMPtr range; + res = selection->GetRangeAt(0, getter_AddRefs(range)); + if (NS_FAILED(res) || !range) + return (res == NS_OK) ? NS_ERROR_FAILURE : res; + + nsAutoString textValue; + res = range->ToString(textValue); + if (NS_FAILED(res)) + return res; + + aReply->mReconversionString = (PRUnichar*) nsMemory::Clone(textValue.GetUnicode(), + (textValue.Length() + 1) * sizeof(PRUnichar)); + if (!aReply->mReconversionString) + return NS_ERROR_OUT_OF_MEMORY; + + // delete the selection + res = DeleteSelection(eNone); + + return res; +} + #ifdef XP_MAC #pragma mark - #pragma mark StyleSheet utils diff --git a/mozilla/editor/base/nsHTMLEditor.h b/mozilla/editor/base/nsHTMLEditor.h index 83d1fb45310..b7fc9bffa05 100644 --- a/mozilla/editor/base/nsHTMLEditor.h +++ b/mozilla/editor/base/nsHTMLEditor.h @@ -155,6 +155,7 @@ public: /* ------------ nsIEditorIMESupport overrides -------------- */ NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); + NS_IMETHOD GetReconversionString(nsReconversionEventReply* aReply); /* ------------ nsIEditorStyleSheets methods -------------- */ diff --git a/mozilla/editor/libeditor/base/nsEditor.cpp b/mozilla/editor/libeditor/base/nsEditor.cpp index d99b300916a..4b6bfe2ef66 100644 --- a/mozilla/editor/libeditor/base/nsEditor.cpp +++ b/mozilla/editor/libeditor/base/nsEditor.cpp @@ -2477,6 +2477,12 @@ nsEditor::ForceCompositionEnd() return NS_OK; } +NS_IMETHODIMP +nsEditor::GetReconversionString(nsReconversionEventReply* aReply) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + #ifdef XP_MAC #pragma mark - #pragma mark public nsEditor methods diff --git a/mozilla/editor/libeditor/base/nsEditor.h b/mozilla/editor/libeditor/base/nsEditor.h index 35626fac2a7..ca3c148c34e 100644 --- a/mozilla/editor/libeditor/base/nsEditor.h +++ b/mozilla/editor/libeditor/base/nsEditor.h @@ -304,6 +304,7 @@ public: NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); NS_IMETHOD EndComposition(void); NS_IMETHOD ForceCompositionEnd(void); + NS_IMETHOD GetReconversionString(nsReconversionEventReply *aReply); public: diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index 4451921492e..aab0fa6e24a 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -5750,6 +5750,41 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat return result; } +NS_IMETHODIMP +nsHTMLEditor::GetReconversionString(nsReconversionEventReply* aReply) +{ + nsresult res; + + nsCOMPtr selection; + res = GetSelection(getter_AddRefs(selection)); + if (NS_FAILED(res) || !selection) + return (res == NS_OK) ? NS_ERROR_FAILURE : res; + + // get the first range in the selection. Since it is + // unclear what to do if reconversion happens with a + // multirange selection, we will ignore any additional ranges. + + nsCOMPtr range; + res = selection->GetRangeAt(0, getter_AddRefs(range)); + if (NS_FAILED(res) || !range) + return (res == NS_OK) ? NS_ERROR_FAILURE : res; + + nsAutoString textValue; + res = range->ToString(textValue); + if (NS_FAILED(res)) + return res; + + aReply->mReconversionString = (PRUnichar*) nsMemory::Clone(textValue.GetUnicode(), + (textValue.Length() + 1) * sizeof(PRUnichar)); + if (!aReply->mReconversionString) + return NS_ERROR_OUT_OF_MEMORY; + + // delete the selection + res = DeleteSelection(eNone); + + return res; +} + #ifdef XP_MAC #pragma mark - #pragma mark StyleSheet utils diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 83d1fb45310..b7fc9bffa05 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -155,6 +155,7 @@ public: /* ------------ nsIEditorIMESupport overrides -------------- */ NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); + NS_IMETHOD GetReconversionString(nsReconversionEventReply* aReply); /* ------------ nsIEditorStyleSheets methods -------------- */ diff --git a/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp b/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp index 212ec6dd985..42c93eb3650 100644 --- a/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp +++ b/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp @@ -807,6 +807,24 @@ nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionE } +nsresult +nsTextEditorCompositionListener::HandleQueryReconversion(nsIDOMEvent* aReconversionEvent) +{ +#ifdef DEBUG_IME + printf("nsTextEditorCompositionListener::HandleQueryReconversion\n"); +#endif + nsCOMPtr pCompositionEvent = do_QueryInterface(aReconversionEvent); + nsReconversionEventReply* eventReply; + + if (!pCompositionEvent) + return NS_ERROR_FAILURE; + + nsresult rv = pCompositionEvent->GetReconversionReply(&eventReply); + if (NS_FAILED(rv)) + return rv; + + return mEditor->GetReconversionString(eventReply); +} /* * Factory functions diff --git a/mozilla/editor/libeditor/text/nsEditorEventListeners.h b/mozilla/editor/libeditor/text/nsEditorEventListeners.h index 1379e0c6b6e..39db78bdd2a 100644 --- a/mozilla/editor/libeditor/text/nsEditorEventListeners.h +++ b/mozilla/editor/libeditor/text/nsEditorEventListeners.h @@ -132,6 +132,7 @@ public: virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent); virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent); virtual nsresult HandleQueryComposition(nsIDOMEvent* aCompositionEvent); + virtual nsresult HandleQueryReconversion(nsIDOMEvent* aReconvertionEvent); /*END implementations of textevent handler interface*/ protected: diff --git a/mozilla/editor/public/nsIEditorIMESupport.h b/mozilla/editor/public/nsIEditorIMESupport.h index cca58a500cb..51ace9367fe 100644 --- a/mozilla/editor/public/nsIEditorIMESupport.h +++ b/mozilla/editor/public/nsIEditorIMESupport.h @@ -32,6 +32,7 @@ class nsIPrivateTextRangeList; struct nsTextEventReply; +struct nsReconversionEventReply; class nsIEditorIMESupport : public nsISupports { @@ -67,6 +68,11 @@ public: * ForceCompositionEnd() force the composition end */ NS_IMETHOD ForceCompositionEnd() = 0; + + /** + * GetReconvertionString() Get the reconvertion string + */ + NS_IMETHOD GetReconversionString(nsReconversionEventReply *aReply) = 0; }; diff --git a/mozilla/layout/events/public/nsIPrivateCompositionEvent.h b/mozilla/layout/events/public/nsIPrivateCompositionEvent.h index 79a3ffa5268..df72b663ded 100644 --- a/mozilla/layout/events/public/nsIPrivateCompositionEvent.h +++ b/mozilla/layout/events/public/nsIPrivateCompositionEvent.h @@ -37,6 +37,7 @@ public: static const nsIID& GetIID() { static nsIID iid = NS_IPRIVATECOMPOSITIONEVENT_IID; return iid; } NS_IMETHOD GetCompositionReply(struct nsTextEventReply** aReply) = 0; + NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply) = 0; }; #endif // nsIPrivateCompositionEvent_h__ diff --git a/mozilla/layout/events/src/nsDOMEvent.cpp b/mozilla/layout/events/src/nsDOMEvent.cpp index 8170e2487b2..8776982f0cb 100644 --- a/mozilla/layout/events/src/nsDOMEvent.cpp +++ b/mozilla/layout/events/src/nsDOMEvent.cpp @@ -399,6 +399,14 @@ NS_METHOD nsDOMEvent::GetCompositionReply(nsTextEventReply** aReply) } +NS_METHOD +nsDOMEvent::GetReconversionReply(nsReconversionEventReply** aReply) +{ + *aReply = &(((nsReconversionEvent*)mEvent)->theReply); + return NS_OK; +} + + NS_METHOD nsDOMEvent::GetScreenX(PRInt32* aScreenX) { if (!mEvent || diff --git a/mozilla/layout/events/src/nsDOMEvent.h b/mozilla/layout/events/src/nsDOMEvent.h index c4d6209c475..18361a20638 100644 --- a/mozilla/layout/events/src/nsDOMEvent.h +++ b/mozilla/layout/events/src/nsDOMEvent.h @@ -159,6 +159,7 @@ public: // nsIPrivateCompositionEvent interface NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply); + NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply); protected: diff --git a/mozilla/layout/events/src/nsEventListenerManager.cpp b/mozilla/layout/events/src/nsEventListenerManager.cpp index 22e12537be1..362085205b9 100644 --- a/mozilla/layout/events/src/nsEventListenerManager.cpp +++ b/mozilla/layout/events/src/nsEventListenerManager.cpp @@ -970,6 +970,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_COMPOSITION_START: case NS_COMPOSITION_END: case NS_COMPOSITION_QUERY: + case NS_RECONVERSION_QUERY: #if DEBUG_TAGUE printf("DOM: got composition event\n"); #endif @@ -988,12 +989,15 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, if (aEvent->message==NS_COMPOSITION_START) { ret = mCompositionListener->HandleStartComposition(*aDOMEvent); } - if (aEvent->message==NS_COMPOSITION_END) { + else if (aEvent->message==NS_COMPOSITION_END) { ret = mCompositionListener->HandleEndComposition(*aDOMEvent); } - if (aEvent->message==NS_COMPOSITION_QUERY) { + else if (aEvent->message==NS_COMPOSITION_QUERY) { ret = mCompositionListener->HandleQueryComposition(*aDOMEvent); } + else if (aEvent->message==NS_RECONVERSION_QUERY) { + ret = mCompositionListener->HandleQueryReconversion(*aDOMEvent); + } } NS_RELEASE(mCompositionListener); } diff --git a/mozilla/widget/public/nsGUIEvent.h b/mozilla/widget/public/nsGUIEvent.h index ce45d672f70..ce8a6820b50 100644 --- a/mozilla/widget/public/nsGUIEvent.h +++ b/mozilla/widget/public/nsGUIEvent.h @@ -234,6 +234,14 @@ struct nsMouseScrollEvent : public nsInputEvent { PRInt32 deltaLines; }; +struct nsReconversionEventReply { + PRUnichar *mReconversionString; +}; + +struct nsReconversionEvent : public nsInputEvent { + nsReconversionEventReply theReply; +}; + /** * Tooltip event */ @@ -288,6 +296,7 @@ enum nsDragDropEventStatus { #define NS_MOUSE_SCROLL_EVENT 16 #define NS_COMPOSITION_QUERY 17 #define NS_SCROLLPORT_EVENT 18 +#define NS_RECONVERSION_QUERY 19 /** * GUI MESSAGES diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index 59bd3da00bf..84e08556af7 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -115,6 +115,9 @@ OleRegisterMgr::~OleRegisterMgr() //////////////////////////////////////////////////// BOOL nsWindow::sIsRegistered = FALSE; UINT nsWindow::uMSH_MOUSEWHEEL = 0; +UINT nsWindow::uWM_MSIME_RECONVERT = 0; // reconvert messge for MSIME +UINT nsWindow::uWM_MSIME_MOUSE = 0; // mouse messge for MSIME +UINT nsWindow::uWM_ATOK_RECONVERT = 0; // reconvert messge for ATOK nsWindow* nsWindow::gCurrentWindow = nsnull; //////////////////////////////////////////////////// @@ -253,6 +256,41 @@ extern HINSTANCE g_hinst; #endif /* MOZ_AIMM */ +// +// for reconversion define +// + +// VC++5.0 header doesn't have reconvertion structure and message. +#ifndef WM_IME_REQUEST +typedef struct tagRECONVERTSTRING { + DWORD dwSize; + DWORD dwVersion; + DWORD dwStrLen; + DWORD dwStrOffset; + DWORD dwCompStrLen; + DWORD dwCompStrOffset; + DWORD dwTargetStrLen; + DWORD dwTargetStrOffset; +} RECONVERTSTRING, FAR * LPRECONVERTSTRING; + +#define IMR_RECONVERTSTRING 0x0004 +#define WM_IME_REQUEST 0x0288 +#endif + +// from http://msdn.microsoft.com/library/specs/msime.h +#define RWM_RECONVERT TEXT("MSIMEReconvert") +#define RWM_MOUSE TEXT("MSIMEMouseOperation") + +#define IMEMOUSE_NONE 0x00 // no mouse button was pushed +#define IMEMOUSE_LDOWN 0x01 +#define IMEMOUSE_RDOWN 0x02 +#define IMEMOUSE_MDOWN 0x04 +#define IMEMOUSE_WUP 0x10 // wheel up +#define IMEMOUSE_WDOWN 0x20 // wheel down + +// from http://www.justsystem.co.jp/tech/atok/api12_04.html#4_11 +#define MSGNAME_ATOK_RECONVERT TEXT("Atok Message for ReconvertString") + static PRBool LangIDToCP(WORD aLangID, UINT& oCP) { @@ -343,15 +381,27 @@ nsWindow::nsWindow() : nsBaseWidget() mIMECompClauseString = NULL; mIMECompClauseStringSize = 0; mIMECompClauseStringLength = 0; + mIMEReconvertUnicode = NULL; + static BOOL gbInitGlobalValue = FALSE; + if(! gbInitGlobalValue) { + gbInitGlobalValue = TRUE; + gKeyboardLayout = GetKeyboardLayout(0); + LangIDToCP((WORD)(0x0FFFFL & (DWORD)gKeyboardLayout), gCurrentKeyboardCP); - static BOOL gbInitHKL = FALSE; - if(! gbInitHKL) - { - gbInitHKL = TRUE; - gKeyboardLayout = GetKeyboardLayout(0); - LangIDToCP((WORD)(0x0FFFFL & (DWORD)gKeyboardLayout), gCurrentKeyboardCP); - } + // + // Reconvert message for Windows 95 / NT 4.0 + // + + // MS-IME98/2000 + nsWindow::uWM_MSIME_RECONVERT = ::RegisterWindowMessage(RWM_RECONVERT); + + // ATOK12/13 + nsWindow::uWM_ATOK_RECONVERT = ::RegisterWindowMessage(MSGNAME_ATOK_RECONVERT); + + // mouse message of MSIME98/2000 + nsWindow::uWM_MSIME_MOUSE = ::RegisterWindowMessage(RWM_MOUSE); + } mNativeDragTarget = nsnull; mIsTopWidgetWindow = PR_FALSE; @@ -401,6 +451,8 @@ nsWindow::~nsWindow() delete [] mIMEAttributeString; if (mIMECompClauseString!=NULL) delete [] mIMECompClauseString; + if (mIMEReconvertUnicode) + nsMemory::Free(mIMEReconvertUnicode); NS_IF_RELEASE(mNativeDragTarget); } @@ -2821,6 +2873,13 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT //SetFocus(); // this is bad //RelayMouseEvent(msg,wParam, lParam); { +#if IME_MOUSE_EVENT_SUPPORT + // check whether IME window do mouse operation + if (mIMEIsComposing && nsWindow::uWM_MSIME_MOUSE) { + if (HandleMouseActionOfIME(IMEMOUSE_LDOWN)) + break; + } +#endif result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_DOWN); } break; @@ -2835,6 +2894,13 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT case WM_MBUTTONDOWN: { +#if IME_MOUSE_EVENT_SUPPORT + // check whether IME window do mouse operation + if (mIMEIsComposing && nsWindow::uWM_MSIME_MOUSE) { + if (HandleMouseActionOfIME(IMEMOUSE_MDOWN)) + break; + } +#endif result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN); } break; @@ -2848,6 +2914,13 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT case WM_RBUTTONDOWN: { +#if IME_MOUSE_EVENT_SUPPORT + // check whether IME window do mouse operation + if (mIMEIsComposing && nsWindow::uWM_MSIME_MOUSE) { + if (HandleMouseActionOfIME(IMEMOUSE_RDOWN)) + break; + } +#endif result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN); } break; @@ -3064,12 +3137,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT result = OnIMENotify(wParam, lParam, aRetValue); break; -#if 0 // This is a Window 98/2000 only message case WM_IME_REQUEST: result = OnIMERequest(wParam, lParam, aRetValue); break; -#endif case WM_IME_SELECT: result = OnIMESelect(wParam, (WORD)(lParam & 0x0FFFF)); @@ -3206,6 +3277,18 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT } NS_RELEASE(scrollEvent.widget); } // WM_MOUSEWHEEL || uMSH_MOUSEWHEEL + + // + // reconvertion meesage for Windows 95 / NT 4.0 + // + // See the following URL + // http://msdn.microsoft.com/library/specs/msimeif_perimeinterfaces.htm#WM_MSIME_RECONVERT + // http://www.justsystem.co.jp/tech/atok/api12_04.html#4_11 + + else if ((msg == nsWindow::uWM_ATOK_RECONVERT) || (msg == nsWindow::uWM_MSIME_RECONVERT)) { + result = OnIMERequest(wParam, lParam, aRetValue, PR_TRUE); + } + } break; } @@ -4599,15 +4682,118 @@ BOOL nsWindow::OnIMENotify(WPARAM aIMN, LPARAM aData, LRESULT *oResult) return PR_FALSE; } //========================================================================== -BOOL nsWindow::OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult) +BOOL nsWindow::OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult, PRBool aUseUnicode) { -#ifdef DEBUG_IME2 +#ifdef DEBUG_IME printf("OnIMERequest\n"); #endif - // not implement yet - return PR_FALSE; + PRBool result = PR_FALSE; + + switch(aIMR) { + case IMR_RECONVERTSTRING: + result = OnIMEReconvert(aData, oResult, aUseUnicode); + break; + } + + return result; } + +//========================================================================== +PRBool nsWindow::OnIMEReconvert(LPARAM aData, LRESULT *oResult, PRBool aUseUnicode) +{ +#ifdef DEBUG_IME + printf("OnIMEReconvert\n"); +#endif + + PRBool result = PR_FALSE; + RECONVERTSTRING* pReconv = (RECONVERTSTRING*) aData; + int len = 0; + + if(!pReconv) { + + // + // When reconvert, it must return need size to reconvert. + // + if(mIMEReconvertUnicode) { + nsMemory::Free(mIMEReconvertUnicode); + mIMEReconvertUnicode = NULL; + } + + // Get reconversion string + nsReconversionEvent event; + nsPoint point; + + point.x = 0; + point.y = 0; + InitEvent(event, NS_RECONVERSION_QUERY, &point); + event.theReply.mReconversionString = NULL; + DispatchWindowEvent(&event); + + mIMEReconvertUnicode = event.theReply.mReconversionString; + NS_RELEASE(event.widget); + + // Return need size + + if(mIMEReconvertUnicode) { + if (aUseUnicode) { + len = nsCRT::strlen(mIMEReconvertUnicode); + *oResult = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); + } else { + len = ::WideCharToMultiByte(gCurrentKeyboardCP, 0, + mIMEReconvertUnicode, + nsCRT::strlen(mIMEReconvertUnicode), + NULL, 0, NULL, NULL); + *oResult = sizeof(RECONVERTSTRING) + len; + } + + result = PR_TRUE; + } + } else { + + // + // Fill reconvert struct + // + + if (aUseUnicode) { + len = nsCRT::strlen(mIMEReconvertUnicode); + *oResult = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); + } else { + len = ::WideCharToMultiByte(gCurrentKeyboardCP, 0, + mIMEReconvertUnicode, + nsCRT::strlen(mIMEReconvertUnicode), + NULL, 0, NULL, NULL); + *oResult = sizeof(RECONVERTSTRING) + len; + } + + ::ZeroMemory(pReconv, sizeof(RECONVERTSTRING)); + pReconv->dwSize = sizeof(RECONVERTSTRING); + pReconv->dwVersion = 0; + pReconv->dwStrLen = len; + pReconv->dwStrOffset = sizeof(RECONVERTSTRING); + pReconv->dwCompStrLen = len; + pReconv->dwCompStrOffset = 0; + pReconv->dwTargetStrLen = len; + pReconv->dwTargetStrOffset = 0; + + if (aUseUnicode) { + ::CopyMemory((LPVOID) (aData + sizeof(RECONVERTSTRING)), + mIMEReconvertUnicode, len * sizeof(WCHAR)); + } else { + ::WideCharToMultiByte(gCurrentKeyboardCP, 0, + mIMEReconvertUnicode, + nsCRT::strlen(mIMEReconvertUnicode), + (LPSTR) (aData + sizeof(RECONVERTSTRING)), + len, + NULL, NULL); + } + + result = PR_TRUE; + } + + return result; +} + //========================================================================== BOOL nsWindow::OnIMESelect(BOOL aSelected, WORD aLangID) { @@ -4679,6 +4865,41 @@ NS_IMETHODIMP nsWindow::ResetInputState() //} return NS_OK; } + + +#if IME_MOUSE_EVENT_SUPPORT +// Mouse operation of IME +PRBool +nsWindow::HandleMouseActionOfIME(int aAction) +{ + PRBool IsHandle = PR_FALSE; + + HWND hIMEWnd = ::ImmGetDefaultIMEWnd(mWnd); + if (hIMEWnd) { + HIMC hIMC = ::ImmGetContext(mWnd); + if (hIMC) { + int positioning = 0; + int offset = 0; + + // get location of each compositon charactors + + // calcurate positioning and offset + + // send MS_MSIME_MOUSE message to default IME window. + if (::SendMessge(hIMEWnd, nsWindow::uWM_MSIME_MOUSE, MAKELONG(MAKEWORD(aAction, positioning), offset), (LPARAM) hIMC) == 1) { + IsHandle = PR_TRUE; + } else { + break; + } + } + ::ImmReleaseContext(mWnd, hIMC); + } + + return IsHandle; +} +#endif + + NS_IMETHODIMP nsWindow::PasswordFieldInit() { #ifdef DEBUG_KBSTATE diff --git a/mozilla/widget/src/windows/nsWindow.h b/mozilla/widget/src/windows/nsWindow.h index 52be7f3090b..09ce4606189 100644 --- a/mozilla/widget/src/windows/nsWindow.h +++ b/mozilla/widget/src/windows/nsWindow.h @@ -214,10 +214,11 @@ protected: BOOL OnIMECompositionFull(); BOOL OnIMEEndComposition(); BOOL OnIMENotify(WPARAM aIMN, LPARAM aData, LRESULT *oResult); - BOOL OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult); + BOOL OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult, PRBool aUseUnicode = PR_FALSE); BOOL OnIMESelect(BOOL aSelected, WORD aLangID); BOOL OnIMESetContext(BOOL aActive, LPARAM& aISC); BOOL OnIMEStartComposition(); + BOOL OnIMEReconvert(LPARAM aData, LRESULT *oResult, PRBool aUseUnicode); ULONG IsSpecialChar(UINT aVirtualKeyCode, WORD *aAsciiKey); virtual PRBool DispatchKeyEvent(PRUint32 aEventType, WORD aCharCode, UINT aVirtualCharCode); @@ -295,6 +296,8 @@ protected: PRInt32 mIMECompClauseStringSize; long mIMECursorPosition; + PRUnichar* mIMEReconvertUnicode; // reconvert string + static UINT gCurrentKeyboardCP; static HKL gKeyboardLayout; @@ -320,6 +323,11 @@ protected: HDWP mDeferredPositioner; static UINT uMSH_MOUSEWHEEL; + + // IME special message + static UINT uWM_MSIME_RECONVERT; // reconvert messge for MSIME + static UINT uWM_MSIME_MOUSE; // mouse messge for MSIME + static UINT uWM_ATOK_RECONVERT; // reconvert messge for ATOK }; //