зеркало из https://github.com/mozilla/pjs.git
Added TSM Input Method support for the Macintosh.
This commit is contained in:
Родитель
a520986b65
Коммит
543ea9737d
Двоичные данные
widget/macbuild/widget.mcp
Двоичные данные
widget/macbuild/widget.mcp
Двоичный файл не отображается.
|
@ -26,6 +26,8 @@
|
|||
#include <ToolUtils.h>
|
||||
#include <DiskInit.h>
|
||||
#include <LowMem.h>
|
||||
#include <TextServices.h>
|
||||
#include <UnicodeConverter.h>
|
||||
|
||||
// from MacHeaders.c
|
||||
#ifndef topLeft
|
||||
|
@ -44,9 +46,27 @@ PRBool nsMacEventHandler::mInBackground = PR_FALSE;
|
|||
//-------------------------------------------------------------------------
|
||||
nsMacEventHandler::nsMacEventHandler(nsMacWindow* aTopLevelWidget)
|
||||
{
|
||||
OSErr err;
|
||||
InterfaceTypeList supportedServices;
|
||||
|
||||
mTopLevelWidget = aTopLevelWidget;
|
||||
mLastWidgetHit = nsnull;
|
||||
mLastWidgetPointed = nsnull;
|
||||
mLastWidgetPointed = nsnull;
|
||||
|
||||
//
|
||||
// create a TSMDocument for this window. We are allocating a TSM document for
|
||||
// each Mac window
|
||||
//
|
||||
supportedServices[0] = kTextService;
|
||||
err = ::NewTSMDocument(1,supportedServices,&mTSMDocument,(long)this);
|
||||
NS_ASSERTION(err==noErr,"nsMacEventHandler::nsMacEventHandler: NewTSMDocument failed.");
|
||||
printf("nsMacEventHandler::nsMacEventHandler: created TSMDocument[%p]\n",mTSMDocument);
|
||||
|
||||
mIMEIsComposing = PR_FALSE;
|
||||
mIMECompositionString = nsnull;
|
||||
mIMECompositionStringSize = 0;
|
||||
mIMECompositionStringLength = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,6 +77,9 @@ nsMacEventHandler::~nsMacEventHandler()
|
|||
|
||||
if (mLastWidgetHit)
|
||||
mLastWidgetHit->RemoveDeleteObserver(this);
|
||||
|
||||
if (mTSMDocument)
|
||||
(void)::DeleteTSMDocument(mTSMDocument);
|
||||
}
|
||||
|
||||
|
||||
|
@ -496,12 +519,20 @@ PRBool nsMacEventHandler::HandleKeyEvent(EventRecord& aOSEvent)
|
|||
//-------------------------------------------------------------------------
|
||||
PRBool nsMacEventHandler::HandleActivateEvent(EventRecord& aOSEvent)
|
||||
{
|
||||
OSErr err;
|
||||
nsCOMPtr<nsToolkit> toolkit ( dont_AddRef((nsToolkit*)mTopLevelWidget->GetToolkit()) );
|
||||
if (toolkit)
|
||||
{
|
||||
Boolean isActive = ((aOSEvent.modifiers & activeFlag) != 0);
|
||||
if (isActive)
|
||||
{
|
||||
//
|
||||
// Activate The TSMDocument associated with this handler
|
||||
//
|
||||
err = ::ActivateTSMDocument(mTSMDocument);
|
||||
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleActivateEvent: ActivateTSMDocument failed");
|
||||
printf("nsEventHandler::HandleActivateEvent: ActivateTSMDocument[%p]\n",mTSMDocument);
|
||||
|
||||
//¥TODO: retrieve the focused widget for that window
|
||||
nsWindow* focusedWidget = mTopLevelWidget;
|
||||
toolkit->SetFocus(focusedWidget);
|
||||
|
@ -525,6 +556,13 @@ PRBool nsMacEventHandler::HandleActivateEvent(EventRecord& aOSEvent)
|
|||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Deactivate the TSMDocument assoicated with this EventHandler
|
||||
//
|
||||
err = ::DeactivateTSMDocument(mTSMDocument);
|
||||
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleActivateEvent: DeactivateTSMDocument failed");
|
||||
printf("nsEventHandler::HandleActivateEvent: DeactivateTSMDocument[%p]\n",mTSMDocument);
|
||||
|
||||
//¥TODO: save the focused widget for that window
|
||||
toolkit->SetFocus(nsnull);
|
||||
|
||||
|
@ -843,3 +881,215 @@ void nsMacEventHandler::ConvertOSEventToMouseEvent(
|
|||
// nsMouseEvent
|
||||
aMouseEvent.clickCount = lastClickCount;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// HandlePositionToOffsetEvent
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
long nsMacEventHandler::HandlePositionToOffset(Point aPoint,short* regionClass)
|
||||
{
|
||||
*regionClass = kTSMOutsideOfBody;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// HandleOffsetToPosition Event
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
PRBool nsMacEventHandler::HandleOffsetToPosition(long offset,Point* thePoint)
|
||||
{
|
||||
(*thePoint).v = 0;
|
||||
(*thePoint).h = 0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// HandleUpdate Event
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
nsMacEventHandler::HandleUpdate(Handle textHandle,ScriptCode script,long fixedLength)
|
||||
{
|
||||
TextToUnicodeInfo textToUnicodeInfo;
|
||||
TextEncoding textEncodingFromScript;
|
||||
ByteCount text_size, source_read;
|
||||
PRBool rv;
|
||||
OSErr err;
|
||||
|
||||
HLock(textHandle);
|
||||
|
||||
//
|
||||
// if we aren't in composition mode alredy, signal the backing store w/ the mode change
|
||||
//
|
||||
if (!mIMEIsComposing) {
|
||||
mIMEIsComposing = PR_TRUE;
|
||||
HandleStartComposition();
|
||||
}
|
||||
|
||||
//
|
||||
// convert our script code (smKeyScript) to a TextEncoding
|
||||
//
|
||||
err = ::UpgradeScriptInfoToTextEncoding(script,kTextLanguageDontCare,kTextRegionDontCare,nsnull,
|
||||
&textEncodingFromScript);
|
||||
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleUpdate: UpgradeScriptInfoToTextEncoding failed.");
|
||||
if (err!=noErr) { ::HUnlock(textHandle); return PR_FALSE; }
|
||||
|
||||
err = ::CreateTextToUnicodeInfoByEncoding(textEncodingFromScript,&textToUnicodeInfo);
|
||||
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleUpdate: CreateUnicodeToTextInfoByEncoding failed.");
|
||||
if (err!=noErr) { ::HUnlock(textHandle); return PR_FALSE; }
|
||||
|
||||
|
||||
text_size = ::GetHandleSize(textHandle);
|
||||
if (mIMECompositionStringSize < (text_size+1)*3) {
|
||||
mIMECompositionStringSize = (text_size+1)*3;
|
||||
if (mIMECompositionString!=nsnull) delete [] mIMECompositionString;
|
||||
mIMECompositionString = new PRUnichar[(text_size+1)*3];
|
||||
}
|
||||
|
||||
//
|
||||
// convert the text from the Update event into Unicode
|
||||
//
|
||||
err = ::ConvertFromTextToUnicode(textToUnicodeInfo,
|
||||
text_size,*textHandle,
|
||||
kUnicodeLooseMappingsMask,
|
||||
0,NULL,NULL,NULL,
|
||||
mIMECompositionStringSize*sizeof(PRUnichar),&source_read,
|
||||
&mIMECompositionStringLength,mIMECompositionString);
|
||||
|
||||
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleUpdate: ConverFromTextToUnicode failed.");
|
||||
if (err!=noErr) { ::HUnlock(textHandle); ::DisposeTextToUnicodeInfo(&textToUnicodeInfo); return PR_FALSE; }
|
||||
|
||||
//
|
||||
// null terminate the string for the XP-stuff
|
||||
//
|
||||
mIMECompositionString[mIMECompositionStringLength/sizeof(PRUnichar)] = (PRUnichar)0;
|
||||
|
||||
rv = HandleTextEvent();
|
||||
|
||||
::HUnlock(textHandle);
|
||||
::DisposeTextToUnicodeInfo(&textToUnicodeInfo);
|
||||
|
||||
if (fixedLength==-1 || fixedLength==text_size) {
|
||||
HandleEndComposition();
|
||||
mIMEIsComposing = PR_FALSE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// HandleStartComposition
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
PRBool nsMacEventHandler::HandleStartComposition(void)
|
||||
{
|
||||
//
|
||||
// get the focused widget [tague: may need to rethink this later]
|
||||
//
|
||||
nsWindow* focusedWidget = mTopLevelWidget;
|
||||
nsCOMPtr<nsToolkit> toolkit ( dont_AddRef((nsToolkit*)mTopLevelWidget->GetToolkit()) );
|
||||
if (toolkit)
|
||||
focusedWidget = toolkit->GetFocus();
|
||||
|
||||
if (!focusedWidget) return PR_FALSE;
|
||||
|
||||
//
|
||||
// create the nsCompositionEvent
|
||||
//
|
||||
nsCompositionEvent compositionEvent;
|
||||
|
||||
compositionEvent.eventStructType = NS_COMPOSITION_START;
|
||||
compositionEvent.message = NS_COMPOSITION_START;
|
||||
compositionEvent.point.x = 0;
|
||||
compositionEvent.point.y = 0;
|
||||
compositionEvent.time = PR_IntervalNow();
|
||||
|
||||
//
|
||||
// nsGUIEvent parts
|
||||
//
|
||||
compositionEvent.widget = focusedWidget;
|
||||
compositionEvent.nativeMsg = (void*)nsnull; // no native message for this
|
||||
|
||||
return(focusedWidget->DispatchWindowEvent(compositionEvent));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// HandleEndComposition
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
PRBool nsMacEventHandler::HandleEndComposition(void)
|
||||
{
|
||||
//
|
||||
// get the focused widget [tague: may need to rethink this later]
|
||||
//
|
||||
nsWindow* focusedWidget = mTopLevelWidget;
|
||||
nsCOMPtr<nsToolkit> toolkit ( dont_AddRef((nsToolkit*)mTopLevelWidget->GetToolkit()) );
|
||||
if (toolkit)
|
||||
focusedWidget = toolkit->GetFocus();
|
||||
|
||||
if (!focusedWidget) return PR_FALSE;
|
||||
|
||||
//
|
||||
// create the nsCompositionEvent
|
||||
//
|
||||
nsCompositionEvent compositionEvent;
|
||||
|
||||
compositionEvent.eventStructType = NS_COMPOSITION_END;
|
||||
compositionEvent.message = NS_COMPOSITION_END;
|
||||
compositionEvent.point.x = 0;
|
||||
compositionEvent.point.y = 0;
|
||||
compositionEvent.time = PR_IntervalNow();
|
||||
|
||||
//
|
||||
// nsGUIEvent parts
|
||||
//
|
||||
compositionEvent.widget = focusedWidget;
|
||||
compositionEvent.nativeMsg = (void*)nsnull; // no native message for this
|
||||
|
||||
return(focusedWidget->DispatchWindowEvent(compositionEvent));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// HandleTextEvent
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
PRBool nsMacEventHandler::HandleTextEvent(void)
|
||||
{
|
||||
//
|
||||
// get the focused widget [tague: may need to rethink this later]
|
||||
//
|
||||
nsWindow* focusedWidget = mTopLevelWidget;
|
||||
nsCOMPtr<nsToolkit> toolkit ( dont_AddRef((nsToolkit*)mTopLevelWidget->GetToolkit()) );
|
||||
if (toolkit)
|
||||
focusedWidget = toolkit->GetFocus();
|
||||
|
||||
if (!focusedWidget) return PR_FALSE;
|
||||
|
||||
//
|
||||
// create the nsCompositionEvent
|
||||
//
|
||||
nsTextEvent textEvent;
|
||||
|
||||
textEvent.eventStructType = NS_TEXT_EVENT;
|
||||
textEvent.message = NS_TEXT_EVENT;
|
||||
textEvent.point.x = 0;
|
||||
textEvent.point.y = 0;
|
||||
textEvent.time = PR_IntervalNow();
|
||||
textEvent.theText = mIMECompositionString;
|
||||
|
||||
//
|
||||
// nsGUIEvent parts
|
||||
//
|
||||
textEvent.widget = focusedWidget;
|
||||
textEvent.nativeMsg = (void*)nsnull; // no native message for this
|
||||
|
||||
if (focusedWidget->DispatchWindowEvent(textEvent)==NS_OK)
|
||||
return PR_TRUE;
|
||||
else
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <Events.h>
|
||||
#include <MacWindows.h>
|
||||
#include <TextServices.h>
|
||||
#include "nsDeleteObserver.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
@ -42,6 +43,13 @@ public:
|
|||
virtual PRBool DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) ;
|
||||
//virtual PRBool TrackDrag ( Point aMouseGlobal, UInt32 aKeyModifiers ) ;
|
||||
|
||||
//
|
||||
// TSM Event Handlers
|
||||
//
|
||||
virtual long HandlePositionToOffset(Point aPoint,short* regionClass);
|
||||
virtual PRBool HandleOffsetToPosition(long offset,Point* position);
|
||||
virtual PRBool HandleUpdate(Handle textHandle,ScriptCode script,long fixedLength);
|
||||
|
||||
protected:
|
||||
virtual PRBool HandleKeyEvent(EventRecord& aOSEvent);
|
||||
virtual PRBool HandleActivateEvent(EventRecord& aOSEvent);
|
||||
|
@ -54,6 +62,9 @@ protected:
|
|||
EventRecord& aOSEvent,
|
||||
nsMouseEvent& aMouseEvent,
|
||||
PRUint32 aMessage);
|
||||
virtual PRBool HandleStartComposition(void);
|
||||
virtual PRBool HandleEndComposition(void);
|
||||
virtual PRBool HandleTextEvent(void);
|
||||
|
||||
public:
|
||||
virtual void NotifyDelete(void* aDeletedObject);
|
||||
|
@ -64,6 +75,11 @@ protected:
|
|||
PRBool mMouseInWidgetHit;
|
||||
nsWindow* mLastWidgetPointed;
|
||||
RgnHandle mUpdateRgn;
|
||||
TSMDocumentID mTSMDocument;
|
||||
PRBool mIMEIsComposing;
|
||||
PRUnichar *mIMECompositionString;
|
||||
size_t mIMECompositionStringSize;
|
||||
size_t mIMECompositionStringLength;
|
||||
static PRBool mInBackground;
|
||||
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "plevent.h"
|
||||
#include "prthread.h"
|
||||
#include "nsMacTSMMessagePump.h"
|
||||
|
||||
#include <MacWindows.h>
|
||||
#include <ToolUtils.h>
|
||||
|
@ -158,7 +159,7 @@ static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
|
|||
* @return NONE
|
||||
*/
|
||||
nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit, nsMacMessageSink* aSink)
|
||||
: mToolkit(aToolkit), mMessageSink(aSink), mEventQueue(NULL)
|
||||
: mToolkit(aToolkit), mMessageSink(aSink), mEventQueue(NULL), mTSMMessagePump(NULL)
|
||||
{
|
||||
mRunning = PR_FALSE;
|
||||
mMouseRgn = ::NewRgn();
|
||||
|
@ -171,6 +172,13 @@ nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit, nsMacMessageSink* aSink)
|
|||
serviceManager->ReleaseService(kEventQueueServiceCID, eventService);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// create the TSM Message Pump
|
||||
//
|
||||
mTSMMessagePump = new nsMacTSMMessagePump();
|
||||
NS_ASSERTION(mTSMMessagePump!=NULL,"nsMacMessagePump::nsMacMessagePump: Unable to create TSM Message Pump.");
|
||||
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
@ -186,6 +194,12 @@ nsMacMessagePump::~nsMacMessagePump()
|
|||
|
||||
//¥TODO? release the toolkits and sinks? not if we use COM_auto_ptr.
|
||||
NS_IF_RELEASE(mEventQueue);
|
||||
|
||||
//
|
||||
// release the TSM Message Pump
|
||||
//
|
||||
if (mTSMMessagePump)
|
||||
delete mTSMMessagePump;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
@ -240,6 +254,10 @@ PRBool nsMacMessagePump::GetEvent(EventRecord &theEvent)
|
|||
|
||||
::LMSetSysEvtMask(eventMask); // we need keyUp events
|
||||
PRBool haveEvent = ::WaitNextEvent(eventMask, &theEvent, sleep, mMouseRgn) ? PR_TRUE : PR_FALSE;
|
||||
if (haveEvent && TSMEvent(&theEvent) )
|
||||
{
|
||||
haveEvent = PR_FALSE;
|
||||
}
|
||||
|
||||
if (mMouseRgn)
|
||||
{
|
||||
|
@ -503,6 +521,10 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent)
|
|||
Boolean haveEvent;
|
||||
EventRecord updateEvent;
|
||||
haveEvent = ::WaitNextEvent(updateMask, &updateEvent, 0, nil);
|
||||
if (haveEvent && TSMEvent(&updateEvent))
|
||||
{
|
||||
haveEvent = PR_FALSE;
|
||||
}
|
||||
if (haveEvent)
|
||||
DoUpdate(updateEvent);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
class nsToolkit;
|
||||
class nsMacMessageSink;
|
||||
class nsMacTSMMessagePump;
|
||||
|
||||
//================================================
|
||||
|
||||
|
@ -55,6 +56,7 @@ private:
|
|||
nsToolkit* mToolkit;
|
||||
nsMacMessageSink* mMessageSink;
|
||||
nsIEventQueue* mEventQueue;
|
||||
nsMacTSMMessagePump* mTSMMessagePump;
|
||||
|
||||
// CLASS METHODS
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче